Sets with Cardinality Constraints

Variables and Atoms#

There is an infinite set Sets.VV of all Sets variables, which is an instance of the class VariableSet. The variables obtained from VV are instances of the class Variable. There are no composite terms in this theory; in other words, every term is a variable.

There is a class AtomicFormula with subclasses Eq, Ne, C, C_. Atoms are obtained as instances of these subclasses, using the class names as constructors. For equations and diseqalities, one can alternatively use the corresponding operators == and != overloaded in the class Variable. C and C_ accept positive numbers from int and oo from float as indices.

Some examples can be found on the landing page of this section.

digraph RCF_terms {
   graph [
      layout=neato,
      splines=line,
      sep=0.5,
      ranksep=0.5,
      nodesep=0.5
   ];
   bgcolor="transparent";

   node [shape=box, fontsize="10pt",
         fontname="monospace", penwidth=0.8];
   edge [arrowsize=0.75, penwidth=0.8];

   VV [shape=box, label = <<U>Sets.VV : VariableSet</U>>,
       pos="0.5,6.0!"];

   Variable [pos="0.5,4.5!"];
   int [pos="2.5,4.5!"];
   float [pos="3.5,4.5!"];
   intB [label="int", pos="5,4.5!"];
   floatB [label="float", pos="6,4.5!"];

   Comparison [style=rounded,
               label="Variable methods  ==  !=",
               pos="0.5,3!"];
   C [style=rounded, label="Construtor of C", pos="3,3!"];
   CB [style=rounded, label="Constructor of C_", pos="5.5,3!"];

   Eq [pos="0,1.5!"];
   Ne [pos="1,1.5!"];
   C1 [label = "C", pos="3,1.5!"];
   CB1 [label="C_", pos="5.5,1.5!"];

   AtomicFormula [pos="3,0!"];

   VV -> Variable
      [xlabel="yields   ",
       style=dashed, arrowhead=normal,
       fontsize="10pt", fontname="sans-serif"];

   Variable -> Comparison
      [style=dashed, arrowhead=none,
       xlabel="enters   ", fontsize="10pt", fontname="sans-serif"];

   int -> C
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   float -> C
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   intB -> CB
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   floatB -> CB
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   Comparison -> Eq
      [style=dashed, arrowhead=normal,
       xlabel="construct   ", fontsize="10pt", fontname="sans-serif"];

   Comparison -> Ne
      [style=dashed, arrowhead=normal];

   C -> C1
      [style=dashed, arrowhead=normal];

   CB -> CB1
      [style=dashed, arrowhead=normal];

   Eq -> AtomicFormula
      [arrowhead=empty, xlabel="subclass of               ",
       fontsize="10pt", fontname="sans-serif"];

   C1 -> AtomicFormula [arrowhead=empty];
   Ne -> AtomicFormula [arrowhead=empty];
   CB1 -> AtomicFormula [arrowhead=empty];
}
digraph RCF_terms {
   graph [
      layout=neato,
      splines=line,
      sep=0.5,
      ranksep=0.5,
      nodesep=0.5
   ];
   bgcolor="transparent";

   node [shape=box, fontsize="10pt", fontname="monospace", penwidth=0.8,
         color=white, fontcolor=white];
   edge [arrowsize=0.75, penwidth=0.8
         color=white, fontcolor=white];

   VV [shape=box, label = <<U>Sets.VV : VariableSet</U>>,
       pos="0.5,6.0!"];

   Variable [pos="0.5,4.5!"];
   int [pos="2.5,4.5!"];
   float [pos="3.5,4.5!"];
   intB [label="int", pos="5,4.5!"];
   floatB [label="float", pos="6,4.5!"];

   Comparison [style=rounded,
               label="Variable methods  ==  !=",
               pos="0.5,3!"];
   C [style=rounded, label="Construtor of C", pos="3,3!"];
   CB [style=rounded, label="Constructor of C_", pos="5.5,3!"];

   Eq [pos="0,1.5!"];
   Ne [pos="1,1.5!"];
   C1 [label = "C", pos="3,1.5!"];
   CB1 [label="C_", pos="5.5,1.5!"];

   AtomicFormula [pos="3,0!"];

   VV -> Variable
      [xlabel="yields   ",
       style=dashed, arrowhead=normal,
       fontsize="10pt", fontname="sans-serif"];

   Variable -> Comparison
      [style=dashed, arrowhead=none,
       xlabel="enters   ", fontsize="10pt", fontname="sans-serif"];

   int -> C
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   float -> C
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   intB -> CB
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   floatB -> CB
      [style=dashed, arrowhead=none,
       fontsize="10pt", fontname="sans-serif"];

   Comparison -> Eq
      [style=dashed, arrowhead=normal,
       xlabel="construct   ", fontsize="10pt", fontname="sans-serif"];

   Comparison -> Ne
      [style=dashed, arrowhead=normal];

   C -> C1
      [style=dashed, arrowhead=normal];

   CB -> CB1
      [style=dashed, arrowhead=normal];

   Eq -> AtomicFormula
      [arrowhead=empty, xlabel="subclass of               ",
       fontsize="10pt", fontname="sans-serif"];

   C1 -> AtomicFormula [arrowhead=empty];
   Ne -> AtomicFormula [arrowhead=empty];
   CB1 -> AtomicFormula [arrowhead=empty];
}

The Set of All Variables#

class logic1.theories.Sets.atomic.VariableSet[source]#

Bases: VariableSet[Variable]

The infinite set of all variables belonging to the theory of Sets. Variables are uniquely identified by their name, which is a str. This class is a singleton, whose single instance is assigned to VV.

See also

Final methods inherited from the parent class:

property stack: list[set[str]]#

The class internally keeps track of variables already used. This is relevant when creating unused variables via fresh(). The stack can hold such internal states.

See also

__getitem__(index: str) Variable[source]#

Return the variable with the name index. Implements abstract method firstorder.term.VariableSet.__getitem__().

>>> from logic1.theories.Sets import VV
>>> VV['x']
x
fresh(suffix: str = '') Variable[source]#

Return a fresh variable, by default from the sequence G0001, G0002, …, G9999, G10000, … This naming convention is inspired by Lisp’s gensym(). If the optional argument suffix is specified, the sequence G0001<suffix>, G0002<suffix>, … is used instead.

abstractmethod pop() None[source]#
abstractmethod push() None[source]#

Implement abstract methods logic1.firstorder.term.VariableSet.pop() and logic1.firstorder.term.VariableSet.push().

logic1.theories.Sets.atomic.VV = VariableSet()#

The unique instance of VariableSet. This is a singleton.

Variables#

class logic1.theories.Sets.atomic.Variable[source]#

Bases: Variable[Variable, Never, str]

==, !=
__eq__(other: Variable) Eq[source]#
__ne__(other: Variable) Ne[source]#

Construction of instances of Eq and Ne is available via these overloaded operators.

as_latex() str[source]#

LaTeX representation as a string. Implements the abstract method firstorder.term.Term.as_latex().

fresh() Variable[source]#

Returns a variable that has not been used so far. Implements abstract method firstorder.term.Variable.fresh().

sort_key() str[source]#

A sort key suitable for ordering instances of this class. Implements the abstract method firstorder.term.Term.sort_key().

subs(d: dict[Variable, Variable]) Variable[source]#

Simultaneous substitution of variables for variables.

>>> from logic1.theories.Sets import VV
>>> x, y, z = VV.get('x', 'y', 'z')
>>> f = x
>>> f.subs({x: y, y: z})
y
vars() Iterator[Variable][source]#

An iterator that yields this variable. Implements the abstract method firstorder.term.Term.vars().

Atoms#

class logic1.theories.Sets.atomic.AtomicFormula[source]#

Bases: AtomicFormula[AtomicFormula, Variable, Variable, Never]

__le__(other: Formula[AtomicFormula, Variable, Variable, Never]) bool[source]#

Returns True if this atomic formula should be sorted before or is equal to other. Implements abstract method firstorder.atomic.AtomicFormula.__le__().

__str__() str[source]#

String representation of this atomic formula. Implements the abstract method firstorder.atomic.AtomicFormula.__str__().

as_latex() str[source]#

Latex representation as a string. Implements the abstract method firstorder.atomic.AtomicFormula.as_latex().

bvars(quantified: frozenset[Variable] = frozenset({})) Iterator[Variable][source]#

Iterate over occurrences of variables that are elements of quantified. Implements the abstract method firstorder.atomic.AtomicFormula.bvars().

classmethod complement() type[AtomicFormula][source]#

Complement relation. Implements the abstract method firstorder.atomic.AtomicFormula.complement().

fvars(quantified: frozenset[Variable] = frozenset({})) Iterator[Variable][source]#

Iterate over occurrences of variables that are not elements of quantified. Implements the abstract method firstorder.atomic.AtomicFormula.fvars().

simplify() Formula[AtomicFormula, Variable, Variable, Never][source]#

Fast basic simplification. The result is equivalent to self. Implements the abstract method firstorder.atomic.AtomicFormula.simplify().

subs(d: dict[Variable, Variable]) Self[source]#

Simultaneous substitution of variables for variables. Implements the abstract method firstorder.atomic.AtomicFormula.subs().

class logic1.theories.Sets.atomic.Eq[source]#
class logic1.theories.Sets.atomic.Ne[source]#

Bases: AtomicFormula

Equations and inequalities between variables.

property lhs: Variable#
property rhs: Variable#

The left hand side variable and the right hand side variable of an equation or inequation, respectively.

logic1.theories.Sets.atomic.oo = inf#

A symbolic name for the float('inf') as an Index.

logic1.theories.Sets.atomic.Index: TypeAlias = int | float#

An index, which is either a positive integer or the float('inf'), which is represented by oo.

class logic1.theories.Sets.atomic.C[source]#
class logic1.theories.Sets.atomic.C_[source]#

Cardinality constraints. From a mathematical perspective, the instances are constant relation symbols with an index, which is either a positive integer or float('inf'), represented as oo. C(n) holds iff there are at least n different elements in the universe. This is not a statement about the index n but about a range of models where this constant relation holds.

In the following example, f states that there should be at least 2 elements but not 3 elements or more:

>>> from logic1.firstorder import *
>>> from logic1.theories.Sets import *
>>> x, y, z = VV.get('x', 'y', 'z')
>>> f = Ex([x, y], x != y) & All([x, y, z], Or(x == y, y == z, z == x))
>>> qe(f)  # quantifier elimination:
And(C(2), C_(3))

The class C_ is dual to C; more precisely, for every index n, we have that C_(n) is the dual relation of C(n), and vice versa.

The class constructors take care that instances with equal indices are identical:

>>> C(1) is C(1)
True
>>> C(1) == C(2)
False
property index: Index#

The index of the constant relation symbol.