File: Mathlib/Tactic/Linarith/Verification.lean

full_name: Qq.ofNatQ
code: /-- Typesafe conversion of `n : ℕ` to `Q($α)`. -/
def ofNatQ (α : Q(Type $u)) (_ : Q(Semiring $α)) (n : ℕ) : Q($α) 
goal: Q(Semiring «$α») → ℕ → Q(«$α»)

full_name: Linarith.mulExpr'
code: /-- A typesafe version of `mulExpr`. -/
def mulExpr' {u : Level} (n : ℕ) {α : Q(Type $u)} (inst : Q(Semiring $α)) (e : Q($α)) : Q($α) 
goal: Q(«$α»)

full_name: Linarith.mulExpr
code: /--
`mulExpr n e` creates an `Expr` representing `n*e`.
When elaborated, the coefficient will be a native numeral of the same type as `e`.
-/
def mulExpr (n : ℕ) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Linarith.addExprs'
code: /-- A type-safe analogue of `addExprs`. -/
def addExprs' {u : Level} {α : Q(Type $u)} (_inst : Q(AddMonoid $α)) : List Q($α) → Q($α)
  
goal: List Q(«$α») → Q(«$α»)

full_name: Linarith.addExprs'.go
code: /-- A type-safe analogue of `addExprs`. -/
def addExprs' {u : Level} {α : Q(Type $u)} (_inst : Q(AddMonoid $α)) : List Q($α) → Q($α)
  
goal: List Q(«$α») → Q(«$α»)

full_name: Linarith.addExprs
code: /-- `addExprs L` creates an `Expr` representing the sum of the elements of `L`, associated left. -/
def addExprs : List Expr → MetaM Expr
  
goal: List Lean.Expr → Lean.MetaM Lean.Expr

full_name: Linarith.addIneq
code: /--
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`.
-/
def addIneq : Ineq → Ineq → (Name × Ineq)
  
goal: Linarith.Ineq → Linarith.Ineq → Lean.Name × Linarith.Ineq

full_name: Linarith.mkLTZeroProof
code: /--
`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.
-/
def mkLTZeroProof : List (Expr × ℕ) → MetaM Expr
  
goal: List (Lean.Expr × ℕ) → Lean.MetaM Lean.Expr

full_name: Linarith.mkLTZeroProof.step
code: /--
`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.
-/
def mkLTZeroProof : List (Expr × ℕ) → MetaM Expr
  
goal: Lean.MetaM (Linarith.Ineq × Lean.Expr)

full_name: Linarith.leftOfIneqProof
code: /-- If `prf` is a proof of `t R s`, `leftOfIneqProof prf` returns `t`. -/
def leftOfIneqProof (prf : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Linarith.typeOfIneqProof
code: /-- If `prf` is a proof of `t R s`, `typeOfIneqProof prf` returns the type of `t`. -/
def typeOfIneqProof (prf : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Linarith.mkNegOneLtZeroProof
code: /--
`mkNegOneLtZeroProof tp` returns a proof of `-1 < 0`,
where the numerals are natively of type `tp`.
-/
def mkNegOneLtZeroProof (tp : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Linarith.addNegEqProofs
code: /--
`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.
-/
def addNegEqProofs : List Expr → MetaM (List Expr)
  
goal: List Lean.Expr → Lean.MetaM (List Lean.Expr)

full_name: Linarith.proveEqZeroUsing
code: /--
`proveEqZeroUsing tac e` tries to use `tac` to construct a proof of `e = 0`.
-/
def proveEqZeroUsing (tac : TacticM Unit) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Linarith.proveFalseByLinarith
code: /--
`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.
-/
def proveFalseByLinarith (transparency : TransparencyMode) (oracle : CertificateOracle)
    (discharger : TacticM Unit) : MVarId → List Expr → MetaM Expr
  
goal: Lean.MVarId → List Lean.Expr → Lean.MetaM Lean.Expr