File: Mathlib/Tactic/Linarith/Datatypes.lean

full_name: initFn._@.Mathlib.Tactic.Linarith.Datatypes._hyg.5
code: initialize registerTraceClass `linarith
goal: IO Unit

full_name: initFn._@.Mathlib.Tactic.Linarith.Datatypes._hyg.42
code: initialize registerTraceClass `linarith.detail
goal: IO Unit

full_name: Linarith.linarithTraceProofs
code: /--
A shorthand for tracing the types of a list of proof terms
when the `trace.linarith` option is set to true.
-/
def linarithTraceProofs {α} [ToMessageData α] (s : α) (l : List Expr) : MetaM Unit 
goal: Lean.MetaM Unit

full_name: Linarith.Linexp
code: /--
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.
-/
abbrev Linexp : Type 
goal: Type

full_name: Linarith.Linexp.add
code: /--
Add two `Linexp`s together componentwise.
Preserves sorting and uniqueness of the first argument.
-/
partial def add : Linexp → Linexp → Linexp

goal: Linarith.Linexp → Linarith.Linexp → Linarith.Linexp

full_name: Linarith.Linexp.scale
code: /-- `l.scale c` scales the values in `l` by `c` without modifying the order or keys. -/
def scale (c : Int) (l : Linexp) : Linexp 
goal: Linarith.Linexp

full_name: Linarith.Linexp.get
code: /--
`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`.
-/
def get (n : Nat) : Linexp → Option Int
  
goal: Linarith.Linexp → Option ℤ

full_name: Linarith.Linexp.contains
code: /--
`l.contains n` is true iff `n` is the first element of a pair in `l`.
-/
def contains (n : Nat) : Linexp → Bool 
goal: Linarith.Linexp → Bool

full_name: Linarith.Linexp.zfind
code: /--
`l.zfind n` returns the value associated with key `n` if there is one, and 0 otherwise.
-/
def zfind (n : Nat) (l : Linexp) : Int 
goal: ℤ

full_name: Linarith.Linexp.vars
code: /-- `l.vars` returns the list of variables that occur in `l`. -/
def vars (l : Linexp) : List Nat 
goal: List ℕ

full_name: Linarith.Linexp.cmp
code: /--
Defines a lex ordering on `Linexp`. This function is performance critical.
-/
def cmp : Linexp → Linexp → Ordering
  
goal: Linarith.Linexp → Linarith.Linexp → Ordering

full_name: Linarith.Ineq.lt
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Linarith.Ineq

full_name: Linarith.instReprIneq
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Repr Linarith.Ineq

full_name: Linarith.instInhabitedIneq
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Inhabited Linarith.Ineq

full_name: Linarith.Ineq.le
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Linarith.Ineq

full_name: Linarith.Ineq
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Type

full_name: Linarith.instDecidableEqIneq
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: DecidableEq Linarith.Ineq

full_name: Linarith.Ineq.eq
code: /-- The three-element type `Ineq` is used to represent the strength of a comparison between
terms. -/
inductive Ineq : Type
  | eq | le | lt
deriving DecidableEq, Inhabited, Repr
goal: Linarith.Ineq

full_name: Linarith.Ineq.max
code: /--
`max R1 R2` computes the strength of the sum of two inequalities. If `t1 R1 0` and `t2 R2 0`,
then `t1 + t2 (max R1 R2) 0`.
-/
def max : Ineq → Ineq → Ineq
  
goal: Linarith.Ineq → Linarith.Ineq → Linarith.Ineq

full_name: Linarith.Ineq.cmp
code: /-- `Ineq` is ordered `eq < le < lt`. -/
def cmp : Ineq → Ineq → Ordering
  
goal: Linarith.Ineq → Linarith.Ineq → Ordering

full_name: Linarith.Ineq.toString
code: /-- Prints an `Ineq` as the corresponding infix symbol. -/
def toString : Ineq → String
  
goal: Linarith.Ineq → String

full_name: Linarith.Ineq.toConstMulName
code: /-- Finds the name of a multiplicative lemma corresponding to an inequality strength. -/
def toConstMulName : Ineq → Name
  
goal: Linarith.Ineq → Lean.Name

full_name: Linarith.Ineq.instToString
code: instance : ToString Ineq 
goal: ToString Linarith.Ineq

full_name: Linarith.Ineq.instToFormat
code: instance : ToFormat Ineq 
goal: Lean.ToFormat Linarith.Ineq

full_name: Linarith.Comp.str
code: /--
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?
-/
structure Comp : Type where
  /-- The strength of the comparison, `<`, `≤`, or `=`. -/
  str : Ineq
  /-- 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. -/
  coeffs : Linexp
deriving Inhabited, Repr
goal: Linarith.Ineq

full_name: Linarith.instInhabitedComp
code: /--
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?
-/
structure Comp : Type where
  /-- The strength of the comparison, `<`, `≤`, or `=`. -/
  str : Ineq
  /-- 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. -/
  coeffs : Linexp
deriving Inhabited, Repr
goal: Inhabited Linarith.Comp

full_name: Linarith.Comp
code: /--
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?
-/
structure Comp : Type where
  /-- The strength of the comparison, `<`, `≤`, or `=`. -/
  str : Ineq
  /-- 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. -/
  coeffs : Linexp
deriving Inhabited, Repr
goal: Type

full_name: Linarith.instReprComp
code: /--
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?
-/
structure Comp : Type where
  /-- The strength of the comparison, `<`, `≤`, or `=`. -/
  str : Ineq
  /-- 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. -/
  coeffs : Linexp
deriving Inhabited, Repr
goal: Repr Linarith.Comp

full_name: Linarith.Comp.coeffs
code: /--
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?
-/
structure Comp : Type where
  /-- The strength of the comparison, `<`, `≤`, or `=`. -/
  str : Ineq
  /-- 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. -/
  coeffs : Linexp
deriving Inhabited, Repr
goal: Linarith.Linexp

full_name: Linarith.Comp.vars
code: /-- `c.vars` returns the list of variables that appear in the linear expression contained in `c`. -/
def Comp.vars : Comp → List Nat 
goal: Linarith.Comp → List ℕ

full_name: Linarith.Comp.coeffOf
code: /-- `c.coeffOf a` projects the coefficient of variable `a` out of `c`. -/
def Comp.coeffOf (c : Comp) (a : Nat) : Int 
goal: ℤ

full_name: Linarith.Comp.scale
code: /-- `c.scale n` scales the coefficients of `c` by `n`. -/
def Comp.scale (c : Comp) (n : Nat) : Comp 
goal: Linarith.Comp

full_name: Linarith.Comp.add
code: /--
`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`.
 -/
def Comp.add (c1 c2 : Comp) : Comp 
goal: Linarith.Comp

full_name: Linarith.Comp.cmp
code: /-- `Comp` has a lex order. First the `ineq`s are compared, then the `coeff`s. -/
def Comp.cmp : Comp → Comp → Ordering
  
goal: Linarith.Comp → Linarith.Comp → Ordering

full_name: Linarith.Comp.isContr
code: /--
A `Comp` represents a contradiction if its expression has no coefficients and its strength is <,
that is, it represents the fact `0 < 0`.
 -/
def Comp.isContr (c : Comp) : Bool 
goal: Bool

full_name: Linarith.Comp.ToFormat
code: instance Comp.ToFormat : ToFormat Comp 
goal: Lean.ToFormat Linarith.Comp

full_name: Linarith.Preprocessor.name
code: /--
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.
-/
structure Preprocessor : Type where
  /-- The name of the preprocessor, used in trace output. -/
  name : String
  /-- Replace a hypothesis by a list of hypotheses. These expressions are the proof terms. -/
  transform : Expr → MetaM (List Expr)
goal: String

full_name: Linarith.Preprocessor.transform
code: /--
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.
-/
structure Preprocessor : Type where
  /-- The name of the preprocessor, used in trace output. -/
  name : String
  /-- Replace a hypothesis by a list of hypotheses. These expressions are the proof terms. -/
  transform : Expr → MetaM (List Expr)
goal: Lean.Expr → Lean.MetaM (List Lean.Expr)

full_name: Linarith.Preprocessor
code: /--
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.
-/
structure Preprocessor : Type where
  /-- The name of the preprocessor, used in trace output. -/
  name : String
  /-- Replace a hypothesis by a list of hypotheses. These expressions are the proof terms. -/
  transform : Expr → MetaM (List Expr)
goal: Type

full_name: Linarith.GlobalPreprocessor
code: /--
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.
-/
structure GlobalPreprocessor : Type where
  /-- The name of the global preprocessor, used in trace output. -/
  name : String
  /-- Replace the collection of all hypotheses with new hypotheses.
  These expressions are proof terms. -/
  transform : List Expr → MetaM (List Expr)
goal: Type

full_name: Linarith.GlobalPreprocessor.transform
code: /--
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.
-/
structure GlobalPreprocessor : Type where
  /-- The name of the global preprocessor, used in trace output. -/
  name : String
  /-- Replace the collection of all hypotheses with new hypotheses.
  These expressions are proof terms. -/
  transform : List Expr → MetaM (List Expr)
goal: List Lean.Expr → Lean.MetaM (List Lean.Expr)

full_name: Linarith.GlobalPreprocessor.name
code: /--
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.
-/
structure GlobalPreprocessor : Type where
  /-- The name of the global preprocessor, used in trace output. -/
  name : String
  /-- Replace the collection of all hypotheses with new hypotheses.
  These expressions are proof terms. -/
  transform : List Expr → MetaM (List Expr)
goal: String

full_name: Linarith.Branch
code: /--
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.
-/
def Branch : Type 
goal: Type

full_name: Linarith.GlobalBranchingPreprocessor.transform
code: /--
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.
-/
structure GlobalBranchingPreprocessor : Type where
  /-- The name of the global branching preprocessor, used in trace output. -/
  name : String
  /-- Given a goal, and a list of hypotheses,
  produce a list of pairs (consisting of a goal and list of hypotheses). -/
  transform : MVarId → List Expr → MetaM (List Branch)
goal: Lean.MVarId → List Lean.Expr → Lean.MetaM (List Linarith.Branch)

full_name: Linarith.GlobalBranchingPreprocessor
code: /--
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.
-/
structure GlobalBranchingPreprocessor : Type where
  /-- The name of the global branching preprocessor, used in trace output. -/
  name : String
  /-- Given a goal, and a list of hypotheses,
  produce a list of pairs (consisting of a goal and list of hypotheses). -/
  transform : MVarId → List Expr → MetaM (List Branch)
goal: Type

full_name: Linarith.GlobalBranchingPreprocessor.name
code: /--
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.
-/
structure GlobalBranchingPreprocessor : Type where
  /-- The name of the global branching preprocessor, used in trace output. -/
  name : String
  /-- Given a goal, and a list of hypotheses,
  produce a list of pairs (consisting of a goal and list of hypotheses). -/
  transform : MVarId → List Expr → MetaM (List Branch)
goal: String

full_name: Linarith.Preprocessor.globalize
code: /--
A `Preprocessor` lifts to a `GlobalPreprocessor` by folding it over the input list.
-/
def Preprocessor.globalize (pp : Preprocessor) : GlobalPreprocessor 
goal: Linarith.GlobalPreprocessor

full_name: Linarith.GlobalPreprocessor.branching
code: /--
A `GlobalPreprocessor` lifts to a `GlobalBranchingPreprocessor` by producing only one branch.
-/
def GlobalPreprocessor.branching (pp : GlobalPreprocessor) : GlobalBranchingPreprocessor 
goal: Linarith.GlobalBranchingPreprocessor

full_name: Linarith.GlobalBranchingPreprocessor.process
code: /--
`process pp l` runs `pp.transform` on `l` and returns the result,
tracing the result if `trace.linarith` is on.
-/
def GlobalBranchingPreprocessor.process (pp : GlobalBranchingPreprocessor)
    (g : MVarId) (l : List Expr) : MetaM (List Branch) 
goal: Lean.MetaM (List Linarith.Branch)

full_name: Linarith.PreprocessorToGlobalBranchingPreprocessor
code: instance PreprocessorToGlobalBranchingPreprocessor :
    Coe Preprocessor GlobalBranchingPreprocessor 
goal: Coe Linarith.Preprocessor Linarith.GlobalBranchingPreprocessor

full_name: Linarith.GlobalPreprocessorToGlobalBranchingPreprocessor
code: instance GlobalPreprocessorToGlobalBranchingPreprocessor :
    Coe GlobalPreprocessor GlobalBranchingPreprocessor 
goal: Coe Linarith.GlobalPreprocessor Linarith.GlobalBranchingPreprocessor

full_name: Linarith.CertificateOracle.produceCertificate
code: /--
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).
-/
structure CertificateOracle : Type where
  /-- `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]`. -/
  produceCertificate (hyps : List Comp) (max_var : Nat) : MetaM (Batteries.HashMap Nat Nat)
goal: Lean.MetaM (Batteries.HashMap ℕ ℕ)

full_name: Linarith.CertificateOracle
code: /--
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).
-/
structure CertificateOracle : Type where
  /-- `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]`. -/
  produceCertificate (hyps : List Comp) (max_var : Nat) : MetaM (Batteries.HashMap Nat Nat)
goal: Type

full_name: Linarith.getRelSides
code: /--
`getRelSides e` returns the left and right hand sides of `e` if `e` is a comparison,
and fails otherwise.
This function is more naturally in the `Option` monad, but it is convenient to put in `MetaM`
for compositionality.
 -/
def getRelSides (e : Expr) : MetaM (Expr × Expr) 
goal: Lean.MetaM (Lean.Expr × Lean.Expr)

full_name: Linarith.parseCompAndExpr.throwNotZero
code: /--
`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`.
-/
def parseCompAndExpr (e : Expr) : MetaM (Ineq × Expr) 
goal: Lean.MetaM (Linarith.Ineq × Lean.Expr)

full_name: Linarith.parseCompAndExpr
code: /--
`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`.
-/
def parseCompAndExpr (e : Expr) : MetaM (Ineq × Expr) 
goal: Lean.MetaM (Linarith.Ineq × Lean.Expr)

full_name: Linarith.mkSingleCompZeroOf
code: /--
`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`.
-/
def mkSingleCompZeroOf (c : Nat) (h : Expr) : MetaM (Ineq × Expr) 
goal: Lean.MetaM (Linarith.Ineq × Lean.Expr)