Source code for logic1.firstorder.atomic

"""Generic abstract classes specify atomic formulas at the first-order level,
where the syntax and semantics of the underlying theories is unknown. The
classes primarily act as interfaces specifying methods that are used as black
boxes within :class:`.Formula` methods.
"""

from __future__ import annotations

from abc import abstractmethod
from typing import final, Iterator, TypeVar

from logic1.firstorder.formula import α, τ, χ, σ, Formula

from logic1.support.tracing import trace


κ = TypeVar('κ')
"""A type variable denoting a sort key.
"""

[docs] class AtomicFormula(Formula[α, τ, χ, σ]): """This abstract class primarily specifies an interface via the definition of abstract methods on atomic formulas that are required by :class:`.Formula`. In addition, it provides some final implementations of such methods, where they do not depend on the syntax or sematic of the specific theory. .. seealso:: Derived classes in various theories: :class:`.RCF.atomic.AtomicFormula` for Real Closed Fields and :class:`.Sets.atomic.AtomicFormula` for Sets. """
[docs] @abstractmethod def __le__(self, other: Formula[α, τ, χ, σ]) -> bool: """Returns :external:obj:`True` if `self` should be sorted before or is equal to other. This method is required by the corresponding first-order method :meth:`.Formula.__le__`. """ ...
[docs] @abstractmethod def __str__(self) -> str: """Representation of this atomic formula used in printing. This method is required by the corresponding recursive first-order method. """ # Overloading here breaks an infinite recursion in the inherited # method. ...
[docs] @abstractmethod def as_latex(self) -> str: """Latex representation as a string. This method is required by the corresponding recursive first-order method :meth:`.Formula.as_latex`. """ ...
[docs] def as_redlog(self) -> str: """Redlog representation as a string. This method is required by the corresponding recursive first-order method :meth:`.Formula.as_redlog`. """ raise NotImplementedError()
@final def atoms(self: α) -> Iterator[α]: yield self
[docs] @abstractmethod def bvars(self, quantified: frozenset[χ] = frozenset()) -> Iterator[χ]: """Iterate over occurrences of variables that are elements of `quantified`. Yield each such variable once for each term that it occurs in. This method is required by the corresponding recursive first-order method :meth:`.Formula.bvars`. """ ...
[docs] @classmethod @abstractmethod def complement(cls) -> type[α]: """The complement operator of an atomic formula, i.e., :code:`a.complement(*a.args)` is an atomic formula equivalent to :code:`Not(a.op(*a.args))`. .. seealso:: * :meth:`.to_complement` -- \ generalization from relations to atomic formulas """ ...
[docs] @abstractmethod def fvars(self, quantified: frozenset[χ] = frozenset()) -> Iterator[χ]: """Iterate over occurrences of variables that are *not* elements of `quantified`. Yield each such variable once for each term that it occurs in. This method is required by the corresponding recursive first-order method :meth:`.Formula.fvars`. """ ...
[docs] @abstractmethod def simplify(self) -> Formula[α, τ, χ, σ]: """Fast basic simplification. The result is equivalent to self. This method is required by the corresponding recursive first-order method :meth:`.Formula.simplify`. """ ...
[docs] @abstractmethod def subs(self, substitution: dict[χ, τ | σ]) -> α: """Simultaneous substitution of terms from `τ` or constants from `σ` for variables from `χ`. This method is required by the corresponding recursive first-order method :meth:`.Formula.subs`. """ ...
[docs] @final def to_complement(self) -> α: """Returns an :class:`AtomicFormula` equivalent to ``Not(self)``. .. seealso:: :attr:`complement` -- complement relation """ return self.complement()(*self.args)