Real Closed Fields
Quantifier Elimination#
Real quantifier elimination by virtual substitution [Sturm-2018].
- logic1.theories.RCF.qe.qe(f: Formula, assume: Iterable[AtomicFormula] = [], **options) Formula | None#
Real quantifier elimination. Returns a quantifier-free equivalent
f'offmodulo the assumptions provided by the attributeqe.assumptions.\[\textsf{RCF} \models \bigwedge \mathtt{qe.assumptions} \longrightarrow (\mathtt{f} \longleftrightarrow \mathtt{f'}).\]With regular quantifier elimination,
qe.assumptionscontains the assumptions passed as theassumeparameter, modulo simplification. In particular, we obtain \(\mathbb{R} \models \mathtt{f} \longleftrightarrow \mathtt{f'}\) with the defaultassume=[]. With generic quantifier elimination [DolzmannSturmWeispfenning-1998], [Sturm-1999], disequalities in the parameters may be added in the course of the elimination.Technically,
logic1.theories.RCF.qe.qeis an instance of the callable classVirtualSubstitution. Its attributes are reset and reused with each call ofqe(). Additional, independent instances of quantifier elimination can be created and used as follows:>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> from logic1.theories.RCF.qe import VirtualSubstitution >>> another_qe = VirtualSubstitution() >>> a, b, c, x = VV.get('a', 'b', 'c', 'x') >>> qe(Ex(x, (a + 1) * x**2 + b * x + c == 0), generic=Generic.FULL) 4*a*c - b**2 + 4*c <= 0 >>> another_qe(Ex(x, a * x + b == 0), generic=Generic.FULL) T >>> qe.assumptions [a + 1 != 0] >>> another_qe.assumptions [a != 0]
In general, our implementation essentially follows [Kosta-2016] up to degree two. For subproblems in which all terms are weakly parametric linear, we use a specialized approach, which we call Xopt, based on [Weispfenning-1997].
See also
Optionsfor the options that can be passed to this function. The documentation of the options also contains some more quantifier elimination examples.
Options.genericexplains generic quantifier elimination in more detail.
Options.workersexplains how to specify parallel computation of subproblems.
logic1.theories.RCF.node.NodeThe subproblems referred to above correspond to instances of this class.
is_weakly_parametric_linear()for the definition of “weakly parametric linear terms”.
logic1.theories.RCF.qe.VirtualSubstitutionqeis an instance of this callable class.
- class logic1.theories.RCF.qe.Options[source]#
Bases:
OptionsRequired by
VirtualSubstitutionfor instantiating the type variableabc.qe.ωofabc.qe.QuantifierElimination.The options specified here, as well as the options
log_level,log_rate,workersinherited fromabc.qe.Options, can be passed toqe()as keyword arguments.- clustering: Clustering#
The clustering strategy to be used by
qe(). The default isClustering.FULL. For theoretical details on clustering see [Kosta-2016].>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b, x = VV.get('a', 'b', 'x')
>>> phi_6 = Ex(x, And(a * x + b <= 0, x <= b)) >>> qe(phi_6, clustering=Clustering.NONE) Or(a > 0, And(b <= 0, a == 0), And(a < 0, a*b + b <= 0)) >>> qe(phi_6, clustering=Clustering.FULL) Or(a > 0, And(b <= 0, a == 0), And(a < 0, a**2*b + a*b >= 0))
>>> phi_7 = Ex(x, a * x**2 + b * x + c == 0) >>> qe(phi_7, clustering=Clustering.NONE) Or(And(c == 0, b == 0, a == 0), And(b < 0, a == 0), And(b > 0, a == 0), And(a < 0, 4*a*c - b**2 == 0), And(a < 0, 4*a*c - b**2 < 0), And(a > 0, 4*a*c - b**2 == 0), And(a > 0, 4*a*c - b**2 < 0)) >>> qe(phi_7, clustering=Clustering.FULL) Or(And(c == 0, b == 0, a == 0), And(b != 0, a == 0), And(a != 0, 4*a*c - b**2 <= 0))
- elimination_order: int#
Strategy for determining the variable elimination order. This option affects only Xopt nodes. With
elimination_order=0, variables in each quantifier block are eliminated from the inside out, i.e., the last variable is eliminated first. Withelimination_order=1(default), dynamic heuristics are used to select the next variable to eliminate.
- generic: Generic#
The degree of genericity used by the quantifier elimination. The default is
Generic.NONE. The principal idea of generic quantifier elimination is to assume certain disequalities on the parameters of the input formula in order to avoid case distinctions during quantifier elimination. Technically, these disequalities are added toqe.assumptions, which is initialized with theassumeargument ofqe(). The following options are available:Generic.NONEuses regular quantifier elimination without making any assumptions.
Generic.MONOMIALadmits assumptions of the form \(m \neq 0\) where \(m\) is a monomial in the parameters of the input formula.
Generic.FULLadmits assumptions of the form \(p \neq 0\) where \(p\) is a polynomial in the parameters of the input formula.
For theoretical details on generic quantifier elimination see [DolzmannSturmWeispfenning-1998], [Sturm-1999].
>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b, c, x = VV.get('a', 'b', 'c', 'x')
>>> qe(Ex(x, (a**2 - 2) * x**2 + b * x + c == 0), ... assume=[c > 0]) Or(And(b != 0, a**2 - 2 == 0), And(a**2 - 2 != 0, 4*a**2*c - b**2 - 8*c <= 0)) >>> qe.assumptions [c > 0]
>>> qe(Ex(x, (a**2 - 2) * x**2 + b * x + c == 0), ... assume=[c > 0], generic=Generic.MONOMIAL) Or(a**2 - 2 == 0, 4*a**2*c - b**2 - 8*c <= 0) >>> qe.assumptions [c > 0, b != 0]
>>> qe(Ex(x, (a**2 - 2) * x**2 + b * x + c == 0), ... assume=[c > 0], generic=Generic.FULL) 4*a**2*c - b**2 - 8*c <= 0 >>> qe.assumptions [c > 0, a**2 - 2 != 0]
- traditional_guards: bool#
The default is
traditional_guards=True. Settingtraditional_guards=Falsestrictly follows the construction of guards as described in [Kosta-2016].>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b, c, x = VV.get('a', 'b', 'c', 'x')
>>> qe(Ex(x, a * x**2 + b * x + c == 0)) Or(And(c == 0, b == 0, a == 0), And(b != 0, a == 0), And(a != 0, 4*a*c - b**2 <= 0))
>>> qe(Ex(x, a * x**2 + b * x + c == 0), traditional_guards=False) Or(And(c == 0, b == 0, a == 0), And(b != 0, Or(c == 0, a == 0)), And(a != 0, 4*a*c - b**2 <= 0))
- workers: int#
Controls the number of CPUs used for processing subproblems:
With the default value
workers=0, the implementation runs sequentially. For all other values, additional processes are started.A positive value
workers=nusesn + 2CPUs:nfor worker processes that process subproblems, one for the master process, and another one for a proxy process that manages shared data.A negative value
workers=-nusesos.cpu_count() - nCPUs for workers, plus two additional CPUs for the master and proxy processes. It follows thatworkers=-2uses all available CPUs, whileworkers=-3leaves one CPU free.
Attention
workers=1uses the parallel implementation with only one worker. Algorithmically, this is similar to the sequential implementation withworkers=0, but introduces overhead.workers=-1usesos.cpu_count() + 1CPUs, which is not a natural choice.
See also
logic1.abc.qe.NodeThe subproblems referred to above correspond to instances of this class.
- xopt: bool#
The default
xopt=Trueadmits Xopt for subproblems in which all terms are weakly parametric linear.See also
qe()for more information on Xopt and the notion of subproblems.
is_weakly_parametric_linear()for the definition of weakly parametric linear terms.
- class logic1.theories.RCF.node.Clustering[source]#
Bases:
EnumAdmissible values of the option
RCF.qe.Options.clustering.- NONE = 1#
- FULL = 2#
- class logic1.theories.RCF.node.Generic[source]#
Bases:
EnumAdmissible values of the option
RCF.qe.Options.generic.- NONE = 1#
- MONOMIAL = 2#
- FULL = 3#
Details#
Attention
The material below addresses implementers rather than users.
- class logic1.theories.RCF.qe.VirtualSubstitution[source]#
Bases:
QuantifierElimination[Node,tuple[Formula[AtomicFormula,Term,Variable,int],frozenset[Term]],Assumptions,list[str],Options,AtomicFormula,Term,Variable,int]Real quantifier elimination by virtual substitution.
Implements the abstract methods
create_options(),create_root_nodes(),create_assumptions(),create_true_node(),final_simplify(),init_env(),init_env_arg()of its super classabc.qe.QuantifierElimination.
- class logic1.theories.RCF.node.Node[source]#
Bases:
Node[AtomicFormula,Term,Variable,int,Assumptions,tuple[tuple[Variable, …],Formula[AtomicFormula,Term,Variable,int],frozenset[Term]]]Implements the abstract methods
copy(),memorize()andprocess()of its super classabc.qe.Node. Required byVirtualSubstitutionfor instantiating the type variableabc.qe.νofabc.qe.QuantifierElimination.
- class logic1.theories.RCF.node.Assumptions[source]#
Bases:
Assumptions[AtomicFormula,Term,Variable,int]Implements the abstract method
simplify()of its super classabc.qe.Assumptions. Required byNodeandVirtualSubstitutionfor instantiating the type variableabc.qe.λofabc.qe.Nodeandabc.qe.QuantifierElimination, respectively.