Documentation

Mathlib.Tactic.Positivity.Core

positivity core functionality #

This file sets up the positivity tactic and the @[positivity] attribute, which allow for plugging in new positivity functionality around a positivity-based driver. The actual behavior is in @[positivity]-tagged definitions in Tactic.Positivity.Basic and elsewhere.

A definition of type PositivityExt tagged @[positivity t] extends the positivity tactic. The term (with underscores) t indicates which expressions this extension accepts. An extension will be given an expression e : α, together with hypotheses [Zero α] [PartialOrder α] and attempts to prove e > 0, e ≥ 0, or e ≠ 0.

When Positivity.core calls this extension on an expression e, it does not guarantee that e matches t perfectly: validate the form of the expression (using e.g. match_expr (← withReducible (whnf e))) before building a proof. See also the let .app ... ← withReducible (whnf e) | throwError ... lines in the example below.

An extension can call Mathlib.Meta.Positivity.core to recursively solve subgoals.

Example:

@[positivity ite _ _ _] def evalIte : PositivityExt where eval {u α} zα pα e := do
  let .app (.app (.app (.app f (p : Q(Prop))) (_ : Q(Decidable $p))) (a : Q($α))) (b : Q($α))
    ← withReducible (whnf e) | throwError "not ite"
  haveI' : $e =Q ite $p $a $b := ⟨⟩
  guard <| ← withDefault <| withNewMCtxDepth <| isDefEq f q(ite (α := $α))
  let ra ← core zα pα a; let rb ← core zα pα b
  ...
Equations
  • One or more equations did not get rendered due to their size.
Instances For
    theorem ne_of_ne_of_eq' {α : Sort u_1} {a c b : α} (hab : a c) (hbc : a = b) :
    b c
    inductive Mathlib.Meta.Positivity.Strictness {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e : Q(«$α»)) :

    The result of positivity running on an expression e of type α.

    Instances For
      def Mathlib.Meta.Positivity.instReprStrictness.repr {u✝ : Lean.Level} {α✝ : Q(Type u✝)} {zα✝ : Q(Zero $α✝)} {pα✝ : Q(PartialOrder $α✝)} {e✝ : Q($α✝)} :
      Strictness zα✝ pα✝ e✝Std.Format
      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        @[implicit_reducible]
        instance Mathlib.Meta.Positivity.instReprStrictness {u✝ : Lean.Level} {α✝ : Q(Type u✝)} {zα✝ : Q(Zero $α✝)} {pα✝ : Q(PartialOrder $α✝)} {e✝ : Q($α✝)} :
        Repr (Strictness zα✝ pα✝ e✝)
        Equations
        def Mathlib.Meta.Positivity.Strictness.toPositive {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) {e : Q(«$α»)} :
        Strictness eOption Q(0 < «$e»)

        Extract a proof that e is positive, if possible, from Strictness information about e.

        Equations
        Instances For
          def Mathlib.Meta.Positivity.Strictness.toNonneg {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) {e : Q(«$α»)} :
          Strictness eOption Q(0 «$e»)

          Extract a proof that e is nonnegative, if possible, from Strictness information about e.

          Equations
          Instances For
            def Mathlib.Meta.Positivity.Strictness.toNonzero {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) {e : Q(«$α»)} :
            Strictness eOption Q(«$e» 0)

            Extract a proof that e is nonzero, if possible, from Strictness information about e.

            Equations
            Instances For

              An extension for positivity.

              Instances For

                Read a positivity extension from a declaration of the right type.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  @[reducible, inline]

                  Each positivity extension is labelled with a collection of patterns which determine the expressions to which it should be applied.

                  Equations
                  Instances For
                    theorem Mathlib.Meta.Positivity.pos_of_isNat {A : Type u_1} {e : A} {n : } [Semiring A] [PartialOrder A] [IsOrderedRing A] [Nontrivial A] (h : NormNum.IsNat e n) (w : Nat.ble 1 n = true) :
                    0 < e
                    theorem Mathlib.Meta.Positivity.pos_of_isNat' {A : Type u_1} {e : A} {n : } [AddMonoidWithOne A] [PartialOrder A] [AddLeftMono A] [ZeroLEOneClass A] [h'' : NeZero 1] (h : NormNum.IsNat e n) (w : Nat.ble 1 n = true) :
                    0 < e
                    theorem Mathlib.Meta.Positivity.pos_of_isNNRat {A : Type u_1} {e : A} {n d : } [Semiring A] [LinearOrder A] [IsStrictOrderedRing A] :
                    NormNum.IsNNRat e n ddecide (0 < n) = true0 < e
                    theorem Mathlib.Meta.Positivity.pos_of_isRat {A : Type u_1} {e : A} {n : } {d : } [Ring A] [LinearOrder A] [IsStrictOrderedRing A] :
                    NormNum.IsRat e n ddecide (0 < n) = true0 < e
                    theorem Mathlib.Meta.Positivity.nonneg_of_isNNRat {A : Type u_1} {e : A} {n d : } [Semiring A] [LinearOrder A] :
                    NormNum.IsNNRat e n ddecide (n = 0) = true0 e
                    theorem Mathlib.Meta.Positivity.nonneg_of_isRat {A : Type u_1} {e : A} {n : } {d : } [Ring A] [LinearOrder A] :
                    NormNum.IsRat e n ddecide (n = 0) = true0 e
                    theorem Mathlib.Meta.Positivity.nz_of_isRat {A : Type u_1} {e : A} {n : } {d : } [Ring A] [LinearOrder A] [IsStrictOrderedRing A] :
                    NormNum.IsRat e n ddecide (n < 0) = truee 0
                    def Mathlib.Meta.Positivity.catchNone {u : Lean.Level} {α : Q(Type u)} { : Q(Zero «$α»)} { : Q(PartialOrder «$α»)} {e : Q(«$α»)} (t : Lean.MetaM (Strictness e)) :

                    Converts a MetaM Strictness which can fail into one that never fails and returns .none instead.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      def Mathlib.Meta.Positivity.throwNone {u : Lean.Level} {α : Q(Type u)} { : Q(Zero «$α»)} { : Q(PartialOrder «$α»)} {e : Q(«$α»)} (t : Lean.MetaM (Strictness e)) :

                      Converts a MetaM Strictness which can return .none into one which never returns .none but fails instead.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        def Mathlib.Meta.Positivity.normNumPositivity {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e : Q(«$α»)) :

                        Attempts to prove a Strictness result when e evaluates to a literal number.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          def Mathlib.Meta.Positivity.positivityCanon {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e : Q(«$α»)) :

                          Attempts to prove that e ≥ 0 using zero_le in a CanonicallyOrderedAdd monoid.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            def Mathlib.Meta.Positivity.compareHypLE {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (lo e : Q(«$α»)) (p₂ : Q(«$lo» «$e»)) :

                            A variation on assumption when the hypothesis is lo ≤ e where lo is a numeral.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For
                              def Mathlib.Meta.Positivity.compareHypLT {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (lo e : Q(«$α»)) (p₂ : Q(«$lo» < «$e»)) :

                              A variation on assumption when the hypothesis is lo < e where lo is a numeral.

                              Equations
                              • One or more equations did not get rendered due to their size.
                              Instances For
                                def Mathlib.Meta.Positivity.compareHypEq {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e x : Q(«$α»)) (p₂ : Q(«$x» = «$e»)) :

                                A variation on assumption when the hypothesis is x = e where x is a numeral.

                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For
                                  def Mathlib.Meta.Positivity.compareHyp {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e : Q(«$α»)) (ldecl : Lean.LocalDecl) :

                                  A variation on assumption which checks if the hypothesis ldecl is a [</≤/=] e where a is a numeral.

                                  Instances For
                                    def Mathlib.Meta.Positivity.orElse {u : Lean.Level} {α : Q(Type u)} { : Q(Zero «$α»)} { : Q(PartialOrder «$α»)} {e : Q(«$α»)} (t₁ : Strictness e) (t₂ : Lean.MetaM (Strictness e)) :

                                    The main combinator which combines multiple positivity results. It assumes t₁ has already been run for a result, and runs t₂ and takes the best result. It will skip t₂ if t₁ is already a proof of .positive, and can also combine .nonnegative and .nonzero to produce a .positive result.

                                    Equations
                                    Instances For
                                      def Mathlib.Meta.Positivity.core {u : Lean.Level} {α : Q(Type u)} ( : Q(Zero «$α»)) ( : Q(PartialOrder «$α»)) (e : Q(«$α»)) :

                                      Run each registered positivity extension on an expression, returning a NormNum.Result.

                                      Equations
                                      • One or more equations did not get rendered due to their size.
                                      Instances For

                                        Given an expression e, use the core method of the positivity tactic to prove it positive, or, failing that, nonnegative; return a Boolean (signalling whether the strict or non-strict inequality was established) together with the proof as an expression.

                                        Equations
                                        • One or more equations did not get rendered due to their size.
                                        Instances For

                                          Given an expression e, use the core method of the positivity tactic to prove it nonnegative.

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For

                                            An auxiliary entry point to the positivity tactic. Given a proposition t of the form 0 [≤/</≠] e, attempts to recurse on the structure of t to prove it. It returns a proof or fails.

                                            Equations
                                            • One or more equations did not get rendered due to their size.
                                            Instances For

                                              The main entry point to the positivity tactic. Given a goal goal of the form 0 [≤/</≠] e, attempts to recurse on the structure of e to prove the goal. It will either close goal or fail.

                                              Equations
                                              Instances For

                                                positivity solves goals of the form 0 ≤ x, 0 < x and x ≠ 0. The tactic works recursively according to the syntax of the expression x, by attempting to prove subexpressions are positive/nonnegative/nonzero and combining this into a final proof. This tactic either closes the goal or fails.

                                                For each subexpression e, positivity will try to:

                                                • try @[positivity]-tagged extensions to recursively prove e is positive/nonnegative/nonzero based on its subexpressions (see the positivity attribute for more details), or
                                                • try the norm_num tactic to prove e is positive/nonnegative/nonzero, or
                                                • try showing e : t is nonnegative because there is a CanonicallyOrderedAdd t instance, or
                                                • use a local hypothesis of the form 0 ≤ e, 0 < e or e ≠ 0.

                                                This tactic is extensible. See the positivity attribute documentation for more details.

                                                • positivity [t₁, …, tₙ] first executes have := t₁; …; have := tₙ in the current goal, then runs positivity. This is useful when positivity needs derived premises such as 0 < y for division/reciprocal, or 0 ≤ x for real powers.

                                                Examples:

                                                example {a : ℤ} (ha : 3 < a) : 0 ≤ a ^ 3 + a := by positivity
                                                
                                                example {a : ℤ} (ha : 1 < a) : 0 < |(3:ℤ) + a| := by positivity
                                                
                                                example {b : ℤ} : 0 ≤ max (-3) (b ^ 2) := by positivity
                                                
                                                example {a b c d : ℝ} (hab : 0 < a * b) (hb : 0 ≤ b) (hcd : c < d) :
                                                    0 < a ^ c + 1 / (d - c) := by
                                                  positivity [sub_pos_of_lt hcd, pos_of_mul_pos_left hab hb]
                                                
                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For

                                                  We set up positivity as a first-pass discharger for gcongr side goals.

                                                  We register positivity with the hint tactic.