Skip to content

Choosing the Right Tactic

Quick reference for picking the right LeanCert tactic for a direct automation goal. For the overall proof-shape chooser, start with Choosing A Proof Shape.

Having issues? See the Troubleshooting Guide for common errors and solutions.

Decision Flowchart

What do you want to prove?
├─► "∀ x ∈ I, f(x) ≤ c" or "∀ x ∈ I, f(x) ≥ c"
│   │
│   ├─► Single variable? ──► certify_bound
│   │                        (or certify_kernel for kernel-only trust)
│   │
│   └─► Multiple variables? ──► multivariate_bound
├─► "∀ x ∈ I, f(x) ≠ 0"
│   └─► root_bound
├─► "∃ x ∈ I, f(x) = 0"
│   └─► interval_roots
├─► "∃! x ∈ I, f(x) = 0"
│   └─► interval_unique_root
├─► "∃ m, ∀ x ∈ I, f(x) ≥ m" (find minimum)
│   │
│   ├─► Single variable? ──► interval_minimize
│   └─► Multiple variables? ──► interval_minimize_mv
├─► "∃ M, ∀ x ∈ I, f(x) ≤ M" (find maximum)
│   │
│   ├─► Single variable? ──► interval_maximize
│   └─► Multiple variables? ──► interval_maximize_mv
├─► "∃ x ∈ I, ∀ y ∈ I, f(x) ≤ f(y)" (find argmin)
│   └─► interval_argmin
├─► "∃ x ∈ I, ∀ y ∈ I, f(y) ≤ f(x)" (find argmax)
│   └─► interval_argmax
├─► Point inequality (π < 3.15, etc.)
│   └─► interval_decide
├─► Integral bound
│   └─► interval_integrate
├─► Simplify vector/matrix indexing (![a,b,c] ⟨1,h⟩ → b)
│   └─► vec_simp
└─► Expand finite sum (∑ k ∈ Icc 1 3, f k → f 1 + f 2 + f 3)
    └─► finsum_expand

Quick Reference Table

I want to prove... Tactic Example
Upper bound on interval certify_bound ∀ x ∈ Set.Icc 0 1, exp x ≤ 3
Lower bound on interval certify_bound ∀ x ∈ Set.Icc 0 1, 0 ≤ exp x
Bound with kernel-only trust certify_kernel Same goals, higher trust
Multivariate bound multivariate_bound ∀ x ∈ I, ∀ y ∈ J, x + y ≤ 2
Function has no roots root_bound ∀ x ∈ I, x² + 1 ≠ 0
Root exists interval_roots ∃ x ∈ I, x² - 2 = 0
Unique root exists interval_unique_root ∃! x ∈ I, x² - 2 = 0
Minimum exists interval_minimize ∃ m, ∀ x ∈ I, f x ≥ m
Maximum exists interval_maximize ∃ M, ∀ x ∈ I, f x ≤ M
Find the minimizer interval_argmin ∃ x ∈ I, ∀ y ∈ I, f x ≤ f y
Find the maximizer interval_argmax ∃ x ∈ I, ∀ y ∈ I, f y ≤ f x
Point inequality interval_decide π < 3.15
Disprove a bound interval_refute Find counterexample
Simplify vector indexing vec_simp ![a,b,c] ⟨1, h⟩ = b
Expand finite sums finsum_expand ∑ k ∈ Icc 1 3, f k = f 1 + f 2 + f 3
Integral bound interval_integrate ∫ x in a..b, f x ∈ I

Trust Levels

Tactic Verification When to use
certify_kernel decide (kernel-only) Maximum trust, slower
certify_kernel_fallback decide, then native_decide Explicit opt-in native fallback
certify_bound native_decide Good balance of trust/speed
certify_kernel_quick decide (30 bits) Fast, lower precision
certify_kernel_precise decide (100 bits) Tight bounds needed

Common Patterns

"My bound is too tight and fails"

-- Try 1: Increase Taylor depth
example :  x  Set.Icc 0 1, exp x  2.72 := by certify_bound 20

-- Try 2: Use subdivision
example :  x  Set.Icc 0 1, exp x  2.72 := by interval_bound_subdiv 15 3

-- Try 3: Use higher precision dyadic
example :  x  Set.Icc 0 1, exp x  2.72 := by certify_kernel_precise

"I don't know what bound to use"

Use discovery tactics to find bounds first:

-- Find the actual minimum/maximum
example :  m,  x  Set.Icc 0 1, x^2 + sin x  m := by interval_minimize
example :  M,  x  Set.Icc 0 1, x^2 + sin x  M := by interval_maximize

Or use interactive commands:

import LeanCert.Discovery.Commands

#find_min (fun x => x^2 + Real.sin x) on [0, 1]
#find_max (fun x => x^2 + Real.sin x) on [0, 1]

"I want to prove both upper and lower bounds"

Prove them separately and combine:

theorem exp_lower :  x  Set.Icc (0:) 1, 1  Real.exp x := by certify_bound
theorem exp_upper :  x  Set.Icc (0:) 1, Real.exp x  3 := by certify_bound

theorem exp_bounded :  x  Set.Icc (0:) 1, 1  Real.exp x  Real.exp x  3 :=
  fun x hx => exp_lower x hx, exp_upper x hx

"Native syntax vs Expr AST"

Most tactics support native syntax, but some require Expr AST:

Tactic Native Syntax Expr AST
certify_bound ✓ Recommended ✓ Supported
multivariate_bound ✓ Recommended ✓ Supported
interval_minimize/maximize ✓ Recommended ✓ Supported
interval_roots ✓ Supported ✓ Works well
root_bound ✓ Supported ✓ Works well
interval_le/ge (low-level) ✓ Required

Native syntax (recommended when it works):

example :  x  Set.Icc (0:) 1, x * x  1 := by certify_bound
example :  x  Set.Icc (0:) 1, Real.exp x  3 := by certify_bound 15

Expr AST syntax (more control, always works):

open LeanCert.Core in
def I01 : IntervalRat := 0, 1, by norm_num

open LeanCert.Core in
example :  x  I01, Expr.eval (fun _ => x) (Expr.mul (Expr.var 0) (Expr.var 0))  (1 : ) := by
  certify_bound

When native syntax fails: If you get unification errors with complex expressions (especially with numeric coefficients like 2 * x * x), switch to Expr AST. See Troubleshooting for details.

"I have a sum over vectors/matrices"

Chain simplification tactics to reduce structured expressions before proving bounds:

-- Expand finite sum, simplify vector indexing, then close with ring
example (a : Fin 3  ) :
     k  Finset.Icc 0 2, (![a 0, a 1, a 2] : Fin 3  ) k, by omega =
    a 0 + a 1 + a 2 := by
  finsum_expand; vec_simp

Common combinations: - finsum_expand; ring — expand sum, simplify arithmetic - finsum_expand; vec_simp; ring — expand sum, reduce vector indexing, simplify - vec_simp; certify_bound — simplify indexing, then prove bounds