# Datatypes for `linarith` #

Some of the data structures here are used in multiple parts of the tactic. We split them into their own file.

This file also contains a few convenient auxiliary functions.

source
def Mathlib.Tactic.Linarith.linarithGetProofsMessage (l : List Lean.Expr) :
Lean.MetaM Lean.MessageData

A shorthand for getting the types of a list of proofs terms, to trace.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
def Mathlib.Tactic.Linarith.linarithTraceProofs {α : Type} [Lean.ToMessageData α] (s : α) (l : List Lean.Expr) :
Lean.MetaM Unit

A shorthand for tracing the types of a list of proof terms when the `trace.linarith` option is set to true.

Equations

- One or more equations did not get rendered due to their size.

Instances For

### Linear expressions #

source
@[reducible, inline]
abbrev Mathlib.Tactic.Linarith.Linexp :
Type

A linear expression is a list of pairs of variable indices and coefficients, representing the sum of the products of each coefficient with its corresponding variable.

Some functions on `Linexp` assume that `n : Nat` occurs at most once as the first element of a pair, and that the list is sorted in decreasing order of the first argument. This is not enforced by the type but the operations here preserve it.

Equations

- Mathlib.Tactic.Linarith.Linexp = List (ℕ × ℤ)

Instances For

source
partial def Mathlib.Tactic.Linarith.Linexp.add :
Linexp → Linexp → Linexp

Add two `Linexp`s together componentwise. Preserves sorting and uniqueness of the first argument.

source
def Mathlib.Tactic.Linarith.Linexp.scale (c : ℤ) (l : Linexp) :
Linexp

`l.scale c` scales the values in `l` by `c` without modifying the order or keys.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
def Mathlib.Tactic.Linarith.Linexp.get (n : ℕ) :
Linexp → Option ℤ

`l.get n` returns the value in `l` associated with key `n`, if it exists, and `none` otherwise. This function assumes that `l` is sorted in decreasing order of the first argument, that is, it will return `none` as soon as it finds a key smaller than `n`.

Equations

- Mathlib.Tactic.Linarith.Linexp.get n [] = none
- Mathlib.Tactic.Linarith.Linexp.get n ((a, b) :: t) = if a < n then none else if a = n then some b else Mathlib.Tactic.Linarith.Linexp.get n t

Instances For

source
def Mathlib.Tactic.Linarith.Linexp.contains (n : ℕ) :
Linexp → Bool

`l.contains n` is true iff `n` is the first element of a pair in `l`.

Equations

- Mathlib.Tactic.Linarith.Linexp.contains n = Option.isSome ∘ Mathlib.Tactic.Linarith.Linexp.get n

Instances For

source
def Mathlib.Tactic.Linarith.Linexp.zfind (n : ℕ) (l : Linexp) :
ℤ

`l.zfind n` returns the value associated with key `n` if there is one, and 0 otherwise.

Equations

- Mathlib.Tactic.Linarith.Linexp.zfind n l = match Mathlib.Tactic.Linarith.Linexp.get n l with | none => 0 | some v => v

Instances For

source
def Mathlib.Tactic.Linarith.Linexp.vars (l : Linexp) :
List ℕ

`l.vars` returns the list of variables that occur in `l`.

Equations

- l.vars = List.map Prod.fst l

Instances For

source
def Mathlib.Tactic.Linarith.Linexp.cmp :
Linexp → Linexp → Ordering

Defines a lex ordering on `Linexp`. This function is performance critical.

Equations

- One or more equations did not get rendered due to their size.
- Mathlib.Tactic.Linarith.Linexp.cmp [] [] = Ordering.eq
- Mathlib.Tactic.Linarith.Linexp.cmp [] x✝ = Ordering.lt
- x.cmp [] = Ordering.gt

Instances For

### Comparisons with 0 #

source
structure Mathlib.Tactic.Linarith.Comp :
Type

The main datatype for FM elimination. Variables are represented by natural numbers, each of which has an integer coefficient. Index 0 is reserved for constants, i.e. `coeffs.find 0` is the coefficient of 1. The represented term is `coeffs.sum (fun ⟨k, v⟩ ↦ v * Var[k])`. str determines the strength of the comparison -- is it < 0, ≤ 0, or = 0?

- str : Ineq

  The strength of the comparison, `<`, `≤`, or `=`.

- coeffs : Linexp

  The coefficients of the comparison, stored as list of pairs `(i, a)`, where `i` is the index of a recorded atom, and `a` is the coefficient.

Instances For

source
def Mathlib.Tactic.Linarith.instInhabitedComp.default :
Comp
Equations

- Mathlib.Tactic.Linarith.instInhabitedComp.default = { str := default, coeffs := default }

Instances For

source
instance Mathlib.Tactic.Linarith.instInhabitedComp :
Inhabited Comp
Equations

- Mathlib.Tactic.Linarith.instInhabitedComp = { default := Mathlib.Tactic.Linarith.instInhabitedComp.default }

source
def Mathlib.Tactic.Linarith.instReprComp.repr :
Comp → ℕ → Std.Format
Equations

- One or more equations did not get rendered due to their size.

Instances For

source
instance Mathlib.Tactic.Linarith.instReprComp :
Repr Comp
Equations

- Mathlib.Tactic.Linarith.instReprComp = { reprPrec := Mathlib.Tactic.Linarith.instReprComp.repr }

source
def Mathlib.Tactic.Linarith.Comp.vars :
Comp → List ℕ

`c.vars` returns the list of variables that appear in the linear expression contained in `c`.

Equations

- Mathlib.Tactic.Linarith.Comp.vars = Mathlib.Tactic.Linarith.Linexp.vars ∘ Mathlib.Tactic.Linarith.Comp.coeffs

Instances For

source
def Mathlib.Tactic.Linarith.Comp.coeffOf (c : Comp) (a : ℕ) :
ℤ

`c.coeffOf a` projects the coefficient of variable `a` out of `c`.

Equations

- c.coeffOf a = Mathlib.Tactic.Linarith.Linexp.zfind a c.coeffs

Instances For

source
def Mathlib.Tactic.Linarith.Comp.scale (c : Comp) (n : ℕ) :
Comp

`c.scale n` scales the coefficients of `c` by `n`.

Equations

- c.scale n = { str := c.str, coeffs := Mathlib.Tactic.Linarith.Linexp.scale (↑n) c.coeffs }

Instances For

source
def Mathlib.Tactic.Linarith.Comp.add (c1 c2 : Comp) :
Comp

`Comp.add c1 c2` adds the expressions represented by `c1` and `c2`. The coefficient of variable `a` in `c1.add c2` is the sum of the coefficients of `a` in `c1` and `c2`.

Equations

- c1.add c2 = { str := c1.str.max c2.str, coeffs := c1.coeffs.add c2.coeffs }

Instances For

source
def Mathlib.Tactic.Linarith.Comp.cmp :
Comp → Comp → Ordering

`Comp` has a lex order. First the `ineq`s are compared, then the `coeff`s.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
def Mathlib.Tactic.Linarith.Comp.isContr (c : Comp) :
Bool

A `Comp` represents a contradiction if its expression has no coefficients and its strength is <, that is, it represents the fact `0 < 0`.

Equations

- c.isContr = (List.isEmpty c.coeffs && decide (c.str = Mathlib.Ineq.lt))

Instances For

source
instance Mathlib.Tactic.Linarith.Comp.ToFormat :
Std.ToFormat Comp
Equations

- Mathlib.Tactic.Linarith.Comp.ToFormat = { format := fun (p : Mathlib.Tactic.Linarith.Comp) => Std.format p.coeffs ++ Std.Format.text (toString p.str) ++ Std.Format.text "0" }

### Parsing into linear form #

### Control #

source
structure Mathlib.Tactic.Linarith.PreprocessorBase :
Type

Metadata about preprocessors, for trace output.

- name : Lean.Name

  The name of the preprocessor, populated automatically, to create linkable trace messages.

- description : String

  The description of the preprocessor.

Instances For

source
structure Mathlib.Tactic.Linarith.Preprocessor extends Mathlib.Tactic.Linarith.PreprocessorBase :
Type

A preprocessor transforms a proof of a proposition into a proof of a different proposition. The return type is `List Expr`, since some preprocessing steps may create multiple new hypotheses, and some may remove a hypothesis from the list. A "no-op" preprocessor should return its input as a singleton list.

- name : Lean.Name
- description : String
- transform : Lean.Expr → Lean.MetaM (List Lean.Expr)

  Replace a hypothesis by a list of hypotheses. These expressions are the proof terms.

Instances For

source
structure Mathlib.Tactic.Linarith.GlobalPreprocessor extends Mathlib.Tactic.Linarith.PreprocessorBase :
Type

Some preprocessors need to examine the full list of hypotheses instead of working item by item. As with `Preprocessor`, the input to a `GlobalPreprocessor` is replaced by, not added to, its output.

- name : Lean.Name
- description : String
- transform : List Lean.Expr → Lean.MetaM (List Lean.Expr)

  Replace the collection of all hypotheses with new hypotheses. These expressions are proof terms.

Instances For

source
def Mathlib.Tactic.Linarith.Branch :
Type

Some preprocessors perform branching case splits. A `Branch` is used to track one of these case splits. The first component, an `MVarId`, is the goal corresponding to this branch of the split, given as a metavariable. The `List Expr` component is the list of hypotheses for `linarith` in this branch.

Equations

- Mathlib.Tactic.Linarith.Branch = (Lean.MVarId × List Lean.Expr)

Instances For

source
structure Mathlib.Tactic.Linarith.GlobalBranchingPreprocessor extends Mathlib.Tactic.Linarith.PreprocessorBase :
Type

Some preprocessors perform branching case splits. A `GlobalBranchingPreprocessor` produces a list of branches to run. Each branch is independent, so hypotheses that appear in multiple branches should be duplicated. The preprocessor is responsible for making sure that each branch contains the correct goal metavariable.

- name : Lean.Name
- description : String
- transform : Lean.MVarId → List Lean.Expr → Lean.MetaM (List Branch)

  Given a goal, and a list of hypotheses, produce a list of pairs (consisting of a goal and list of hypotheses).

Instances For

source
def Mathlib.Tactic.Linarith.Preprocessor.globalize (pp : Preprocessor) :
GlobalPreprocessor

A `Preprocessor` lifts to a `GlobalPreprocessor` by folding it over the input list.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
def Mathlib.Tactic.Linarith.GlobalPreprocessor.branching (pp : GlobalPreprocessor) :
GlobalBranchingPreprocessor

A `GlobalPreprocessor` lifts to a `GlobalBranchingPreprocessor` by producing only one branch.

Equations

- pp.branching = { toPreprocessorBase := pp.toPreprocessorBase, transform := fun (g : Lean.MVarId) (l : List Lean.Expr) => do let __do_lift ← pp.transform l pure [(g, __do_lift)] }

Instances For

source
def Mathlib.Tactic.Linarith.GlobalBranchingPreprocessor.process (pp : GlobalBranchingPreprocessor) (g : Lean.MVarId) (l : List Lean.Expr) :
Lean.MetaM (List Branch)

`process pp l` runs `pp.transform` on `l` and returns the result, tracing the result if `trace.linarith` is on.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
instance Mathlib.Tactic.Linarith.PreprocessorToGlobalBranchingPreprocessor :
Coe Preprocessor GlobalBranchingPreprocessor
Equations

- Mathlib.Tactic.Linarith.PreprocessorToGlobalBranchingPreprocessor = { coe := Mathlib.Tactic.Linarith.GlobalPreprocessor.branching ∘ Mathlib.Tactic.Linarith.Preprocessor.globalize }

source
instance Mathlib.Tactic.Linarith.GlobalPreprocessorToGlobalBranchingPreprocessor :
Coe GlobalPreprocessor GlobalBranchingPreprocessor
Equations

- Mathlib.Tactic.Linarith.GlobalPreprocessorToGlobalBranchingPreprocessor = { coe := Mathlib.Tactic.Linarith.GlobalPreprocessor.branching }

source
structure Mathlib.Tactic.Linarith.CertificateOracle :
Type

A `CertificateOracle` provides a function `produceCertificate : List Comp → Nat → MetaM (HashMap Nat Nat)`.

The default `CertificateOracle` used by `linarith` is `Linarith.CertificateOracle.simplexAlgorithmSparse`. `Linarith.CertificateOracle.simplexAlgorithmDense` and `Linarith.CertificateOracle.fourierMotzkin` are also available (though the Fourier-Motzkin oracle has some bugs).

- produceCertificate (hyps : List Comp) (max_var : ℕ) : Lean.MetaM (Std.HashMap ℕ ℕ)

  `produceCertificate hyps max_var` tries to derive a contradiction from the comparisons in `hyps` by eliminating all variables ≤ `max_var`. If successful, it returns a map `coeff : Nat → Nat` as a certificate. This map represents that we can find a contradiction by taking the sum `∑ (coeff i) * hyps[i]`.

Instances For

### Auxiliary functions #

These functions are used by multiple modules, so we put them here for accessibility.

source
def Mathlib.Tactic.Linarith.parseCompAndExpr (e : Lean.Expr) :
Lean.MetaM (Ineq × Lean.Expr)

`parseCompAndExpr e` checks if `e` is of the form `t < 0`, `t ≤ 0`, or `t = 0`. If it is, it returns the comparison along with `t`.

Equations

- One or more equations did not get rendered due to their size.

Instances For

source
def Mathlib.Tactic.Linarith.mkSingleCompZeroOf (c : ℕ) (h : Lean.Expr) :
Lean.MetaM (Ineq × Lean.Expr)

`mkSingleCompZeroOf c h` assumes that `h` is a proof of `t R 0`. It produces a pair `(R', h')`, where `h'` is a proof of `c*t R' 0`. Typically `R` and `R'` will be the same, except when `c = 0`, in which case `R'` is `=`. If `c = 1`, `h'` is the same as `h` -- specifically, it does not change the type to `1*t R 0`.

Equations

- One or more equations did not get rendered due to their size.

Instances For