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 proveFalseByLinarith.
Auxiliary functions for assembling proofs #
A typesafe version of mulExpr.
Equations
Instances For
mulExpr n e creates an Expr representing n*e.
When elaborated, the coefficient will be a native numeral of the same type as e.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A type-safe analogue of addExprs.
Equations
- Mathlib.Tactic.Linarith.addExprs' _inst [] = q(0)
- Mathlib.Tactic.Linarith.addExprs' _inst (h :: t) = Mathlib.Tactic.Linarith.addExprs'.go _inst h t
Instances For
Inner loop for addExprs'.
Equations
- Mathlib.Tactic.Linarith.addExprs'.go _inst p [] = p
- Mathlib.Tactic.Linarith.addExprs'.go _inst p [q] = q(«$p» + «$q»)
- Mathlib.Tactic.Linarith.addExprs'.go _inst p (q :: t) = Mathlib.Tactic.Linarith.addExprs'.go _inst q(«$p» + «$q») t
Instances For
If our goal is to add together two inequalities t1 R1 0 and t2 R2 0,
addIneq 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.
Equations
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.eq Mathlib.Ineq.eq = (`Mathlib.Tactic.Linarith.eq_of_eq_of_eq, Mathlib.Ineq.eq)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.eq Mathlib.Ineq.le = (`Mathlib.Tactic.Linarith.le_of_eq_of_le, Mathlib.Ineq.le)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.eq Mathlib.Ineq.lt = (`Mathlib.Tactic.Linarith.lt_of_eq_of_lt, Mathlib.Ineq.lt)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.le Mathlib.Ineq.eq = (`Mathlib.Tactic.Linarith.le_of_le_of_eq, Mathlib.Ineq.le)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.le Mathlib.Ineq.le = (`Mathlib.Tactic.Linarith.add_nonpos, Mathlib.Ineq.le)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.le Mathlib.Ineq.lt = (`Mathlib.Tactic.Linarith.add_lt_of_le_of_neg, Mathlib.Ineq.lt)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.lt Mathlib.Ineq.eq = (`Mathlib.Tactic.Linarith.lt_of_lt_of_eq, Mathlib.Ineq.lt)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.lt Mathlib.Ineq.le = (`Mathlib.Tactic.Linarith.add_lt_of_neg_of_le, Mathlib.Ineq.lt)
- Mathlib.Tactic.Linarith.addIneq Mathlib.Ineq.lt Mathlib.Ineq.lt = (`Mathlib.Tactic.Linarith.add_neg, Mathlib.Ineq.lt)
Instances For
mkLTZeroProof coeffs pfs takes a list of proofs of the form tᵢ Rᵢ 0,
paired with coefficients cᵢ.
It produces a proof that ∑cᵢ * tᵢ R 0, where R is as strong as possible.
Equations
- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Linarith.mkLTZeroProof [] = Lean.throwError (Lean.toMessageData "no linear hypotheses found")
- Mathlib.Tactic.Linarith.mkLTZeroProof [(h, c)] = do let __discr ← Mathlib.Tactic.Linarith.mkSingleCompZeroOf c h match __discr with | (fst, t) => pure t
Instances For
step 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 mkSingleCompZeroOf to prove t1 + coeff*t2 R 0, and returns R
along with this proof.
Equations
- One or more equations did not get rendered due to their size.
Instances For
If prf is a proof of t R s, leftOfIneqProof prf returns t.
Equations
- Mathlib.Tactic.Linarith.leftOfIneqProof prf = do let __do_lift ← Lean.Meta.inferType prf let __discr ← __do_lift.ineq? match __discr with | (fst, fst_1, t, snd) => pure t
Instances For
If prf is a proof of t R s, typeOfIneqProof prf returns the type of t.
Equations
- Mathlib.Tactic.Linarith.typeOfIneqProof prf = do let __do_lift ← Lean.Meta.inferType prf let __discr ← __do_lift.ineq? match __discr with | (fst, ty, snd) => pure ty
Instances For
mkNegOneLtZeroProof tp returns a proof of -1 < 0,
where the numerals are natively of type tp.
Equations
- One or more equations did not get rendered due to their size.
Instances For
addNegEqProofs l inspects the list of proofs l for proofs of the form t = 0. For each such
proof, it adds a proof of -t = 0 to the list.
Equations
Instances For
proveEqZeroUsing tac e tries to use tac to construct a proof of e = 0.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The main method #
proveFalseByLinarith 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.
oracle : CertificateOracle is used to search for a certificate of unsatisfiability.
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 provided discharger
tactic, which is typically ring. We prove (2) by folding over the set of hypotheses.
transparency : TransparencyMode controls the transparency level with which atoms are identified.
Equations
- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Linarith.proveFalseByLinarith transparency oracle discharger x✝ [] = Lean.throwError (Lean.toMessageData "no args to linarith")
Instances For
Log f under linarith.detail, with exception emojis and the provided name.
Equations
- One or more equations did not get rendered due to their size.