Atomic rules
-
ref (
(ref <name>)
): returns a proof previously defined usingstepc
(see composite proofs below) or a unit clause corresponding to a local assumption ofsteps
. There is no need to re-prove anything, we assume the step was valid and just reuse its conclusion.In other words,
(ref c5)
coming after(defc c5 (cl (+ p) (+ q)) <proof>)
is a trivial proof of the clause(cl (+ p) (+ q))
.The serialization might use "@" instead of "ref".
-
refl (
(refl <term>)
):(refl t)
is a proof of the clause(cl (+ (= t t)))
. -
assert (
(assert <term>)
): proves a unit clause(cl (+ t))
(if the term ist
), but only if it matches exactly an assertion/hypothesis of the original problem.(TODO: be able to refer to the original formula by file+name if it was provided)
-
hres (
(hres <proof> <hstep>+)
): a fold-like operation on the initial proof's result. It can represent a resolution step, or hyper-resolution, or some boolean paramodulation steps. As opposed to the other rules which are mostly useful for preprocessing/simplification of the original problem, this is expected to be one of the main inference rules for resolution/superposition provers.The proof step
(hres (init p0) h1 h2 … hn)
starts with the clauseC0
obtained by validatingp0
. It then applies each "h-step" in the order they are presented. Assuming the current clause isC == (cl l1 … lm)
, each h-step can be one of the following:-
resolution (
(r <term> <proof>)
):(r t proof)
resolvesproof
into a clauseD
which must contain a literal(+ t)
or(- t)
. Then it performs boolean resolution between the current clauseC
and the clauseD
with pivot literal(+ t)
.Without loss of generality let's assume the proof returns
D
where \( D \triangleq D' \lor (+ t) \), and \( C \triangleq C' \lor (- t) \). Then the new clause is \( C' \lor D' \). -
unit resolution (
(r1 <proof>)
):(r1 proof)
resolvesproof
into a clauseD
which must be a unit-clause (i.e. exactly one literal). Since there is not ambiguity on the pivot, it performs unit resolution betweenC
andD
on the unique literal ofD
. -
boolean-paramodulation (
(p <term> <term> <proof>)
):(p lhs rhs proof)
resolvesproof
into a clauseD
which must contain a literal(+ (= lhs rhs))
, where bothlhs
andrhs
are boolean terms. In other words, \( D \triangleq lhs = rhs \lor D' \).The current clause
C
must contain a literal(± lhs)
; ie. \( C \triangleq C' \lor ± lhs \).the result is obtained by replacing
lhs
withrhs
inC
and addingD'
back. Mathematically:\[ \cfrac{ lhs = rhs \lor D' \qquad lhs \lor C' }{ C' \lor D' \lor rhs } \]
-
unit-boolean-paramodulation (
(p1 <proof>)
): Same asp
but the proof must return a unit clause(+ (= lhs rhs))
.
-
-
r (
(r <term> <proof> <proof>)
): resolution on the given pivot between the two clauses.The proof term
(r pivot p1 p2)
corresponds to(hres p1 (r pivot p2))
. -
r1 (
(r1 <proof> <proof>)
): unit resolution. The shortcut(r1 p1 p2)
allows the user to omit the pivot if one the the two proofs is unit (ie. has exactly one literal). It is the same as(hres p1 (r1 p2))
. -
rup (
(rup <clause> <proof>+)
):(rup c steps)
proves the clausec
by reverse unit propagation (RUP) on the results ofsteps
. This corresponds to linear resolution but without specifying pivots nor the order. -
cc-lemma (
(ccl <clause>)
): proves a clausec
if it's a tautology of the theory of equality. There should generally be n negative literals and one positive literal, all of them equations.An example:
(cc-lemma (cl (- (= a b)) (- (= (f b) c)) (- (= c c2)) (- (= (f c2) d)) (+ (= (f (f a)) d))))
-
cc-imply (
(cc-imply (<proof>*) <term> <term>)
): a shortcut step that combinescc-lemma
andhres
for more convenient proof production. Internally the checker should be able to reuse most of the implementation logic ofcc-lemma
.(cc-imply (p1 … pn) t u)
takesn
proofs, all of which must have unit equations as their conclusions (say,p_i
proves(cl (+ (= t_i u_i)))
); and two termst
andu
; and it returns a proof of(cl (+ (= t u)))
if the clause(cl (- (= t_1 u_1)) (- (= t_2 u_2)) … (- (= t_n u_n)) (+ (= t u)))
is a valid equality lemma (one thatcc-lemma
would validate).In other words,
(cc-lemma (p1…pn) t u)
could be expanded (using fresh names for steps) to:(steps () ((stepc c_1 (cl (+ (= t_1 u_1))) p_1) (stepc c_2 (cl (+ (= t_2 u_2))) p_2) … (stepc c_n (cl (+ (= t_n u_n))) p_n) (stepc the_lemma (cl (- (= t_1 u_1)) (- (= t_2 u_2)) … (- (= t_n u_n)) (+ (= t u))) (cc-lemma (cl (- (= t_1 u_1)) (- (= t_2 u_2)) … (- (= t_n u_n)) (+ (= t u))))) (stepc res (cl (+ (= t u))) (hres (init (ref the_lemma)) (r1 (ref c_1)) (r1 (ref c_2)) … (r1 (ref c_n))))))
-
clause-rw (
(clause-rw <clause> <proof> (<proof>*))
): the term(clause-rw c p steps)
provesc
from the resultc0
ofp
using a series of equations insteps
. Each equation in step is used to rewrite at least one literal ofc0
; no new literal is added,c
is obtained purely by rewriting literals ofc0
, (or simplifying away if the literal rewrites tofalse
).A possible way to check this step is as follows.
- Compute
c0
and the results of stepsd1, …, dn
which should be positive equations or positive atoms (a
standing fora=true
). - Given
c == (a1 \/ a2 \/ … \/ a_m)
, assert¬a1, ¬a2, …, ¬a_m
into a congruence closure (where assertinga
means assertinga = true
, and asserting¬a
means assertinga = false
). - For each literal
b
ofc0
in turn, assertb
into the congruence closure and query fortrue == false
before undoing the assertion ofb
. Iftrue == false
can be proved from each case ofb
, then the step is valid, becausec0 /\ d1 … dn |= c
.
This rule is convenient for preprocessing of clauses. Each term can be preprocessed (rewritten into a simpler form) individually, possibly leading to the literal beeing removed (when shown absurd by preprocessing), and
clause-rw
can be used to tie together all these rewriting steps.For example,
(cl (+ (ite (x+1 > x) p q)) (+ false) (+ t))
could be simplified into(cl (+ p) (+ u))
assumingt
simplifies tou
. The proof would look like:(stepc c (cl (+ p) (+ u)) (clause-rw (cl (+ p) (+ u)) (<proof of input clause) ((<proof of t=u) (<proof of ite simplification>))))
- Compute
-
nn (
(nn <proof>)
): not-normalization: a normalization step that transforms some literals in a clause. It turns(- (not a))
into(+ a)
, and(+ (not a))
into(- a)
. -
true is true (
t-is-t
): the lemma(cl (+ true))
. -
true neq false (
t-ne-f
): the lemma(cl (- (= true false)))
. -
bool-c (
(bool-c <name> <term>+)
):(bool-c <name> <terms>)
proves a boolean tautology of depth 1 using the particular sub-rule named<name>
with some term argument(s). In other words, it corresponds to one construction or destruction axioms for the boolean connectiveand
,or
,=>
, boolean=
,xor
,not
,forall
,exists
.The possible axioms are:
rule axiom (and-i (and A1…An))
(cl (- A1) … (- An) (+ (and A1…An)))
(and-e (and A1…An) Ai)
(cl (- (and A1…An)) (+ Ai))
(or-e (or A1…An))
(cl (- (or A1…An)) (+ A1) … (+ An))
(or-i (or A1…An) Ai)
(cl (- Ai) (+ (or A1…An)))
(imp-e (=> A1…An B))
(cl (- (=> A1…An B)) (- A1)…(- An) (+ B))
(imp-i (=> A1…An B) Ai)
(cl (+ Ai) (+ (=> A1…An B)))
(imp-i (=> A1…An B) B)
(cl (- B) (+ (=> A1…An B)))
(not-e (not A))
(cl (- (not A)) (+ A))
(not-i (not A))
(cl (- A) (+ (not A))
(eq-e (= A B) A)
(cl (- (= A B)) (- A) (+ B))
(eq-e (= A B) B)
(cl (- (= A B)) (- B) (+ A))
(eq-i+ (= A B))
(cl (+ A) (+ B) (+ (= A B)))
(eq-i- (= A B))
(cl (- A) (- B) (+ (= A B)))
(xor-e- (xor A B))
(cl (- (xor A B)) (- A) (- B))
(xor-e+ (xor A B))
(cl (- (xor A B)) (+ A) (+ B))
(xor-i (xor A B) B)
(cl (+ A) (- B) (+ (xor A B)))
(xor-i (xor A B) A)
(cl (- A) (+ B) (+ (xor A B)))
(forall-e P E)
(cl (- (forall P)) (+ (P E)))
(forall-i P
(cl (- (= (\x. P x) true)) (+ (forall P)))
(exists-e P)
(cl (- (exists P)) (+ (P (select P))))
(exists-i P)
cl (- (P x)) (+ (exists P))
(wherex
fresh) -
bool-eq (
(bool-eq <term> <term>)
):(bool-eq t u)
proves the clause(cl (+ (= t u)))
(wheret
andu
are both boolean terms) ift
simplifies tou
via a basic simplification step.This rule corresponds to the axioms:
TODO: also give names to sub-rules here
axiom (= (not true) false)
(= (not false) true)
(= (not (not t)) t)
(= (= true A) A)
(= (= false A) (not A))
(= (xor true A) (not A))
(= (xor false A) A)
(= (= t t) true)
(= (or t1…tn true u1…um) true)
(= (or false false) false)
(= (=> true A) A)
(= (=> false A) true)
(= (=> A true) true)
(= (=> A false) (not A))
(= (or false false) false)
(= (and t1…tn false u1…um) false)
(= (and true true) true)
-
\( \beta \)-reduction (
(beta-red <term> <term>)
): Given(lambda (x:τ) body)
andu
, returns the clause(cl (+ (= ((lambda (x:τ) body) u) body[x := u])))
wherebody[x := u]
denotes the term obtained by substitutingx
withu
inbody
in a capture avoiding way.Mathematically: \[ \vdash (\lambda x:\tau. t)~ u = t[x := u] \]
-
substitution (
(subst <subst> <proof>)
):(subst sigma p)
returns the same claues asp
, but where free variables have been replaced according to the substitution. A substitution has the form(x1 e1 x2 e2 … xn en)
wherex_i
are names (variables) ande_i
are expressions. Bindings are parallel (substitution doesn't apply recursively).For example,
(subst (x a y (f x)) p)
, whenp
proves(cl (+ (p x)) (+ q y))
, proves(cl (+ (p a)) (+ q (f x)))
.x
is not substituted again in the image ofy
.
TODO: lra (in own file) TODO: datatypes (in own file)
TODO: instantiation
TODO: reasoning under quantifiers