From 18ceef136e6d36c93c48db0ccae47949ead0a8a0 Mon Sep 17 00:00:00 2001 From: Nils Husung Date: Wed, 16 Oct 2024 16:01:58 +0200 Subject: [PATCH] Python: make the cofactor methods return Optionals as described in the docstrings Also don't raise a `MemoryError` for terminals but actually return None --- bindings/python/oxidd/bcdd.py | 15 ++++++++++----- bindings/python/oxidd/bdd.py | 15 ++++++++++----- bindings/python/oxidd/protocols.py | 6 +++--- bindings/python/oxidd/zbdd.py | 15 ++++++++++----- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/bindings/python/oxidd/bcdd.py b/bindings/python/oxidd/bcdd.py index 9447c66..5b7d242 100644 --- a/bindings/python/oxidd/bcdd.py +++ b/bindings/python/oxidd/bcdd.py @@ -196,20 +196,25 @@ def manager(self) -> BCDDManager: return BCDDManager._from_raw(_lib.oxidd_bcdd_containing_manager(self._func)) @override - def cofactors(self) -> tuple[Self, Self]: + def cofactors(self) -> Optional[tuple[Self, Self]]: raw_pair = _lib.oxidd_bcdd_cofactors(self._func) + if raw_pair.first._p == _ffi.NULL: + return None + assert raw_pair.second._p != _ffi.NULL return ( self.__class__._from_raw(raw_pair.first), self.__class__._from_raw(raw_pair.second), ) @override - def cofactor_true(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_bcdd_cofactor_true(self._func)) + def cofactor_true(self) -> Optional[Self]: + raw = _lib.oxidd_bcdd_cofactor_true(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override - def cofactor_false(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_bcdd_cofactor_false(self._func)) + def cofactor_false(self) -> Optional[Self]: + raw = _lib.oxidd_bcdd_cofactor_false(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override def level(self) -> Optional[int]: diff --git a/bindings/python/oxidd/bdd.py b/bindings/python/oxidd/bdd.py index eb07e5e..b3a8771 100644 --- a/bindings/python/oxidd/bdd.py +++ b/bindings/python/oxidd/bdd.py @@ -194,20 +194,25 @@ def manager(self) -> BDDManager: return BDDManager._from_raw(_lib.oxidd_bdd_containing_manager(self._func)) @override - def cofactors(self) -> tuple[Self, Self]: + def cofactors(self) -> Optional[tuple[Self, Self]]: raw_pair = _lib.oxidd_bdd_cofactors(self._func) + if raw_pair.first._p == _ffi.NULL: + return None + assert raw_pair.second._p != _ffi.NULL return ( self.__class__._from_raw(raw_pair.first), self.__class__._from_raw(raw_pair.second), ) @override - def cofactor_true(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_bdd_cofactor_true(self._func)) + def cofactor_true(self) -> Optional[Self]: + raw = _lib.oxidd_bdd_cofactor_true(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override - def cofactor_false(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_bdd_cofactor_false(self._func)) + def cofactor_false(self) -> Optional[Self]: + raw = _lib.oxidd_bdd_cofactor_false(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override def level(self) -> Optional[int]: diff --git a/bindings/python/oxidd/protocols.py b/bindings/python/oxidd/protocols.py index ad688cc..5e79f32 100644 --- a/bindings/python/oxidd/protocols.py +++ b/bindings/python/oxidd/protocols.py @@ -131,7 +131,7 @@ class BooleanFunction(Function, Protocol): """Boolean function represented as decision diagram""" @abstractmethod - def cofactors(self) -> tuple[Self, Self]: + def cofactors(self) -> Optional[tuple[Self, Self]]: r"""Get the cofactors ``(f_true, f_false)`` of ``self`` Let f(x₀, …, xₙ) be represented by ``self``, where x₀ is (currently) the @@ -157,7 +157,7 @@ def cofactors(self) -> tuple[Self, Self]: raise NotImplementedError @abstractmethod - def cofactor_true(self) -> Self: + def cofactor_true(self) -> Optional[Self]: """Get the cofactor ``f_true`` of ``self`` This method is slightly more efficient than :meth:`Self::cofactors` in @@ -172,7 +172,7 @@ def cofactor_true(self) -> Self: raise NotImplementedError @abstractmethod - def cofactor_false(self) -> Self: + def cofactor_false(self) -> Optional[Self]: """Get the cofactor ``f_true`` of ``self`` This method is slightly more efficient than :meth:`Self::cofactors` in diff --git a/bindings/python/oxidd/zbdd.py b/bindings/python/oxidd/zbdd.py index 9906199..8e49646 100644 --- a/bindings/python/oxidd/zbdd.py +++ b/bindings/python/oxidd/zbdd.py @@ -192,20 +192,25 @@ def manager(self) -> ZBDDManager: return ZBDDManager._from_raw(_lib.oxidd_zbdd_containing_manager(self._func)) @override - def cofactors(self) -> tuple[Self, Self]: + def cofactors(self) -> Optional[tuple[Self, Self]]: raw_pair = _lib.oxidd_zbdd_cofactors(self._func) + if raw_pair.first._p == _ffi.NULL: + return None + assert raw_pair.second._p != _ffi.NULL return ( self.__class__._from_raw(raw_pair.first), self.__class__._from_raw(raw_pair.second), ) @override - def cofactor_true(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_zbdd_cofactor_true(self._func)) + def cofactor_true(self) -> Optional[Self]: + raw = _lib.oxidd_zbdd_cofactor_true(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override - def cofactor_false(self) -> Self: - return self.__class__._from_raw(_lib.oxidd_zbdd_cofactor_false(self._func)) + def cofactor_false(self) -> Optional[Self]: + raw = _lib.oxidd_zbdd_cofactor_false(self._func) + return self.__class__._from_raw(raw) if raw._p != _ffi.NULL else None @override def level(self) -> Optional[int]: