r"""We provide subclasses of :class:`Formula <.formula.Formula>` that implement
quanitfied formulas in the sense that their toplevel operator is a one of the
quantifiers :math:`\exists` or :math:`\forall`.
"""
from __future__ import annotations
from collections import deque
from typing import final, Sequence
from .atomic import Variable
from .formula import α, τ, χ, σ, Formula
from ..support.tracing import trace # noqa
[docs]
@final
class Ex(QuantifiedFormula[α, τ, χ, σ]):
r"""A class whose instances are existentially quanitfied formulas in the
sense that their toplevel operator represents the quantifier symbol
:math:`\exists`. Besides variables, the quantifier accepts sequences of
variables as a shorthand.
>>> from logic1.firstorder import *
>>> from logic1.theories.RCF import *
>>> x, y, z = VV.get('x', 'y', 'z')
>>> Ex(x, x**2 == y)
Ex(x, x^2 - y == 0)
>>> Ex([x, y], And(x > 0, y > 0, z == x - y))
Ex(x, Ex(y, And(x > 0, y > 0, x - y - z == 0)))
"""
[docs]
@classmethod
def dual(cls) -> type[All[α, τ, χ, σ]]:
r"""A class method yielding the class :class:`All`, which implements
the dual operator :math:`\forall` of :math:`\exists`.
"""
return All
[docs]
@final
class All(QuantifiedFormula[α, τ, χ, σ]):
r"""A class whose instances are universally quanitfied formulas in the
sense that their toplevel operator represents the quantifier symbol
:math:`\forall`. Besides variables, the quantifier accepts sequences of
variables as a shorthand.
>>> from logic1.theories.RCF import *
>>> x, y = VV.get('x', 'y')
>>> All(x, x**2 >= 0)
All(x, x^2 >= 0)
>>> All([x, y], (x + y)**2 >= 0)
All(x, All(y, x^2 + 2*x*y + y^2 >= 0))
"""
[docs]
@classmethod
def dual(cls) -> type[Ex[α, τ, χ, σ]]:
"""A class method yielding the dual class :class:`Ex` of class:`All`.
"""
return Ex
[docs]
class Prefix(deque[tuple[type[All | Ex], list[χ]]]):
"""Holds a quantifier prefix of a formula.
>>> from logic1.theories.RCF import *
>>> x, x0, epsilon, delta = VV.get('x', 'x0', 'epsilon', 'delta')
>>> Prefix((All, [x0, epsilon]), (Ex, [delta]), (All, [x]))
Prefix([(<class 'logic1.firstorder.quantified.All'>, [x0, epsilon]),
(<class 'logic1.firstorder.quantified.Ex'>, [delta]),
(<class 'logic1.firstorder.quantified.All'>, [x])])
>>> print(_)
All [x0, epsilon] Ex [delta] All [x]
.. seealso::
* :external:class:`collections.deque` -- for mehods inherited from double-ended queues
* :meth:`matrix <.Formula.matrix>` -- the matrix of a prenex formula
* :meth:`quantify <.Formula.quantify>` -- add quantifier prefix
"""
def __init__(self, *blocks: tuple[type[All[α, τ, χ, σ] | Ex[α, τ, χ, σ]], list[χ]]) -> None:
return super().__init__(blocks)
def __str__(self) -> str:
return ' '.join(q.__name__ + ' ' + str(vars_) for q, vars_ in self)