Deriving a proof of false
linarith
uses an untrusted oracle to produce a certificate of unsatisfiability.
It needs to do some proof reconstruction work to turn this into a proof term.
This file implements the reconstruction.
Main declarations
The public facing declaration in this file is prove_false_by_linarith
.
Auxiliary functions for assembling proofs
If our goal is to add together two inequalities t1 R1 0
and t2 R2 0
,
ineq_const_nm R1 R2
produces the strength of the inequality in the sum R
,
along with the name of a lemma to apply in order to conclude t1 + t2 R 0
.
mk_lt_zero_pf_aux c pf npf coeff
assumes that pf
is a proof of t1 R1 0
and npf
is a proof
of t2 R2 0
. It uses mk_single_comp_zero_pf
to prove t1 + coeff*t2 R 0
, and returns R
along with this proof.
If prf
is a proof of t R s
, term_of_ineq_prf prf
returns t
.
If prf
is a proof of t R s
, ineq_prf_tp prf
returns the type of t
.
mk_neg_one_lt_zero_pf tp
returns a proof of -1 < 0
,
where the numerals are natively of type tp
.
If e
is a proof that t = 0
, mk_neg_eq_zero_pf e
returns a proof that -t = 0
.
The main method
prove_false_by_linarith
is the main workhorse of linarith
.
Given a list l
of proofs of tᵢ Rᵢ 0
,
it tries to derive a contradiction from l
and use this to produce a proof of false
.
An oracle is used to search for a certificate of unsatisfiability.
In the current implementation, this is the Fourier Motzkin elimination routine in
elimination.lean
, but other oracles could easily be swapped in.
The returned certificate is a map m
from hypothesis indices to natural number coefficients.
If our set of hypotheses has the form {tᵢ Rᵢ 0}
,
then the elimination process should have guaranteed that
1.\ ∑ (m i)*tᵢ = 0
,
with at least one i
such that m i > 0
and Rᵢ
is <
.
We have also that
2.\ ∑ (m i)*tᵢ < 0
,
since for each i
, (m i)*tᵢ ≤ 0
and at least one is strictly negative.
So we conclude a contradiction 0 < 0
.
It remains to produce proofs of (1) and (2). (1) is verified by calling the discharger
tactic
of the linarith_config
object, which is typically ring
. We prove (2) by folding over the
set of hypotheses.