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];
}](../../../_images/graphviz-9987ed1f15689ba83b00141a6a8a460e7d3ea095.png)
![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];
}](../../../_images/graphviz-687c7718ab2d67423df6b620db97055a9f2176a1.png)
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 toVV.See also
Final methods inherited from the parent class:
firstorder.term.VariableSet.get()– obtain several variables simultaneously
firstorder.term.VariableSet.imp()– import variables into global namespace
- property stack: list[set[str]]#
The class internally keeps track of variables already used. This is relevant when creating unused variables via
fresh(). Thestackcan hold such internal states.
- __getitem__(index: str) Variable[source]#
Return the variable with the name
index. Implements abstract methodfirstorder.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’sgensym(). If the optional argumentsuffixis specified, the sequenceG0001<suffix>,G0002<suffix>, … is used instead.
- abstractmethod pop() None[source]#
- abstractmethod push() None[source]#
Implement abstract methods
logic1.firstorder.term.VariableSet.pop()andlogic1.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
EqandNeis 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
Trueif this atomic formula should be sorted before or is equal to other. Implements abstract methodfirstorder.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 methodfirstorder.atomic.AtomicFormula.bvars().
- classmethod complement() type[AtomicFormula][source]#
Complement relation. Implements the abstract method
firstorder.atomic.AtomicFormula.complement().See also
Inherited method
firstorder.atomic.AtomicFormula.to_complement()
- fvars(quantified: frozenset[Variable] = frozenset({})) Iterator[Variable][source]#
Iterate over occurrences of variables that are not elements of
quantified. Implements the abstract methodfirstorder.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().
- class logic1.theories.Sets.atomic.Eq[source]#
- class logic1.theories.Sets.atomic.Ne[source]#
Bases:
AtomicFormulaEquations and inequalities between variables.
- logic1.theories.Sets.atomic.Index: TypeAlias = int | float#
An index, which is either a positive integer or the
float('inf'), which is represented byoo.
- 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 asoo.C(n)holds iff there are at leastndifferent elements in the universe. This is not a statement about the indexnbut about a range of models where this constant relation holds.In the following example,
fstates 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 toC; more precisely, for every indexn, we have thatC_(n)is the dual relation ofC(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