Real Closed Fields
Simplification#
This module provides an implementation of deep simplifcication based on generating and propagating internal representations during recursion in Real Closed fields. This is essentially the standard simplifier, which has been proposed for Ordered Fields in [DolzmannSturm-1997].
Internal Representations#
- class logic1.theories.RCF.simplify.InternalRepresentation[source]#
Bases:
InternalRepresentation
[AtomicFormula
,Term
,Variable
,int
]Implements the abstract methods
add()
,extract()
, andnext_()
of it super classabc.simplify.InternalRepresentation
. Required bySets.simplify.Simplify
for instantiating the type variableabc.simplify.ρ
ofabc.simplify.Simplify
.
Simplification and Validity#
- class logic1.theories.RCF.simplify.Simplify[source]#
Bases:
Simplify
[AtomicFormula
,Term
,Variable
,int
,InternalRepresentation
]Deep simplification following [DolzmannSturm-1997]. Implements the abstract methods
create_initial_representation
andsimpl_at
of its super classabc.simplify.Simplify
.The simplifier should be called via
simplify()
, as described below. In addition, this class inheritsabc.simplify.Simplify.is_valid()
, which should be called viais_valid()
, as described below.
User Interface#
- logic1.theories.RCF.simplify.simplify(f: Formula[AtomicFormula, Term, Variable, int], assume: Iterable[AtomicFormula] = [], explode_always: bool = True, prefer_order: bool = True, prefer_weak: bool = False) Formula[AtomicFormula, Term, Variable, int] #
Simplify f modulo assume.
- Parameters:
f – The formula to be simplified
assume –
A list of atomic formulas that are assumed to hold. The simplification result is equivalent modulo those assumptions. Note that assumptions do not affect bound variables.
>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b = VV.get('a', 'b') >>> simplify(Ex(a, And(a > 5, b > 10)), assume=[a > 10, b > 20]) Ex(a, a - 5 > 0)
explode_always –
Simplification can split certain atomic formulas built from products or square sums:
Example
\(ab = 0\) is equivalent to \(a = 0 \lor b = 0\)
\(a^2 + b^2 \neq 0\) is equivalent to \(a \neq 0 \lor b \neq 0\);
\(ab \neq 0\) is equivalent to \(a \neq 0 \land b \neq 0\)
\(a^2 + b^2 = 0\) is equivalent to \(a = 0 \land b = 0\).
If explode_always is
False
, the splittings in “1.” are only applied within disjunctions and the ones in “2.” are only applied within conjunctions. This keeps terms more complex but the boolean structure simpler.>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b, c = VV.get('a', 'b', 'c') >>> simplify(And(a * b == 0, c == 0)) And(c == 0, Or(b == 0, a == 0)) >>> simplify(And(a * b == 0, c == 0), explode_always=False) And(c == 0, a*b == 0) >>> simplify(Or(a * b == 0, c == 0), explode_always=False) Or(c == 0, b == 0, a == 0)
prefer_order –
One can sometimes equivalently choose between order inequalities and (in)equations.
Example
\(a > 0 \lor (b = 0 \land a < 0)\) is equivalent to \(a > 0 \lor (b = 0 \land a \neq 0)\)
\(a \geq 0 \land (b = 0 \lor a > 0)\) is equivalent to \(a \geq 0 \land (b = 0 \lor a \neq 0)\)
By default, the left hand sides in the Example are preferred. If prefer_order is
False
, then the right hand sides are preferred.>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b = VV.get('a', 'b') >>> simplify(And(a >= 0, Or(b == 0, a > 0))) And(a >= 0, Or(b == 0, a > 0)) >>> simplify(And(a >= 0, Or(b == 0, a != 0))) And(a >= 0, Or(b == 0, a > 0)) >>> simplify(And(a >= 0, Or(b == 0, a > 0)), prefer_order=False) And(a >= 0, Or(b == 0, a != 0)) >>> simplify(And(a >= 0, Or(b == 0, a != 0)), prefer_order=False) And(a >= 0, Or(b == 0, a != 0))
prefer_weak –
One can sometimes equivalently choose between strict and weak inequalities.
Example
\(a = 0 \lor (b = 0 \land a \geq 0)\) is equivalent to \(a = 0 \lor (b = 0 \land a > 0)\)
\(a \neq 0 \land (b = 0 \lor a \geq 0)\) is equivalent to \(a \neq 0 \land (b = 0 \lor a > 0)\)
By default, the right hand sides in the Example are preferred. If prefer_weak is
True
, then the left hand sides are preferred.>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b = VV.get('a', 'b') >>> simplify(And(a != 0, Or(b == 0, a >= 0))) And(a != 0, Or(b == 0, a > 0)) >>> simplify(And(a != 0, Or(b == 0, a > 0))) And(a != 0, Or(b == 0, a > 0)) >>> simplify(And(a != 0, Or(b == 0, a >= 0)), prefer_weak=True) And(a != 0, Or(b == 0, a >= 0)) >>> simplify(And(a != 0, Or(b == 0, a > 0)), prefer_weak=True) And(a != 0, Or(b == 0, a >= 0))
- Returns:
A simplified equivalent of f modulo assume.
- logic1.theories.RCF.simplify.is_valid(f: Formula[α, τ, χ, σ], assume: Iterable[α] = []) bool | None #
Simplification-based heuristic test for vailidity of a formula.
Mathematical definition
A first-order formula is valid if it holds for all values all free variables.
- Parameters:
f – The formula to be tested for validity
assume – A list of atomic formulas that are assumed to hold. The result of the validity test is correct modulo these assumptions.
- Returns:
Returns
True
orFalse
ifabc.simplify.Simplify.simplify()
succeeds in heuristically simplifying f toT
orF
, respectively. ReturnsNone
in the sense of “don’t know” otherwise.
Some examples
>>> from logic1.firstorder import * >>> from logic1.theories.RCF import * >>> a, b, c = VV.get('a', 'b', 'c')
>>> is_valid(3 * b**2 + c**2 >= 0) True
>>> is_valid(3 * b**2 + c**2 < 0) False
In our last example, validity holds, but the simplifier is not strong enough to deduce
T
:>>> is_valid(a * b**2 + c**2 >= 0, assume=[a > 0]) # returns None