Skip to content

Lean Tactics Reference

Complete reference for all LeanCert tactics.

Bound Proving

certify_bound

Proves universal bounds over intervals using rational interval arithmetic.

import LeanCert.Tactic.IntervalAuto

-- Basic usage
example :  x  Set.Icc (0 : ) 1, Real.exp x  3 := by certify_bound

-- With Taylor depth (higher = tighter bounds, slower)
example :  x  Set.Icc (0 : ) 1, Real.exp x  2.72 := by certify_bound 15

-- Lower bounds
example :  x  Set.Icc (0 : ) 1, 0  Real.exp x := by certify_bound

-- Strict inequalities
example :  x  Set.Icc (0 : ) 1, Real.exp x < 3 := by certify_bound

Note: interval_bound is an alias for backward compatibility.

Parameters:

Parameter Type Default Description
depth 10 Taylor series depth for transcendentals

Supported functions: +, -, *, sin, cos, exp, sqrt, sinh, cosh, tanh


certify_kernel

Proves bounds using dyadic arithmetic. Attempts kernel-only verification (decide) first, falls back to native_decide.

import LeanCert.Tactic.DyadicAuto

-- Default precision (53 bits)
example :  x  Set.Icc (0 : ) 1, x * x  2 := by certify_kernel

-- Custom precision (bits)
example :  x  Set.Icc (0 : ) 1, Real.exp x  2.72 := by certify_kernel 100

-- Convenience variants
example :  x  Set.Icc (0 : ) 1, Real.exp x  2.72 := by certify_kernel_precise  -- 100 bits
example :  x  Set.Icc (0 : ) 1, x * x  2 := by certify_kernel_quick           -- 30 bits

Note: fast_bound is an alias for backward compatibility.

Trust levels:

Verification Trusted Components
decide (kernel) Lean kernel only
native_decide (fallback) Lean kernel + compiler

Diagnostics: Enable set_option trace.certify_kernel true to see why kernel verification fails.


interval_decide

Proves point inequalities involving specific numbers (transcendentals like π, e).

import LeanCert.Tactic.IntervalAuto

example : Real.pi < 3.15 := by interval_decide
example : Real.exp 1 < 3 := by interval_decide
example : Real.sin 1 + Real.cos 1 < 1.5 := by interval_decide
example : Real.sqrt 2 < 1.42 := by interval_decide

Use this for concrete values. For universally quantified bounds, use certify_bound.


interval_refute

Searches for counter-examples to disprove false bounds.

import LeanCert.Tactic.Refute

-- This bound is false (x² can reach 4 on [-2, 2])
example :  x  Set.Icc (-2 : ) 2, x * x  3 := by
  interval_refute
  -- Output: Counter-example found at x ≈ ±2, where x² = 4 > 3

Output types:

Result Meaning
Verified Rigorous proof that bound fails at this point
Candidate Likely counter-example (may be precision artifact)

Configuration:

-- With custom settings
example : ... := by
  interval_refute (config := { maxIterations := 100, tolerance := 1e-6 })

Discovery Tactics

interval_minimize / interval_maximize

Proves existence of global minimum/maximum via branch-and-bound optimization.

import LeanCert.Tactic.Discovery

-- Find and prove a lower bound exists
example :  m,  x  Set.Icc (0 : ) 2, x * x - x  m := by
  interval_minimize

-- With Taylor depth
example :  m,  x  Set.Icc (0 : ) 1, Real.sin x  m := by
  interval_minimize 15

interval_roots

Proves root existence via sign change detection (Intermediate Value Theorem).

Native syntax (recommended):

import LeanCert.Tactic.Discovery

-- Prove √2 exists in [1, 2]
example :  x  Set.Icc (1 : ) 2, x^2 - 2 = 0 := by
  interval_roots

-- Also supports f(x) = c form
example :  x  Set.Icc (1 : ) 2, x^2 = 2 := by
  interval_roots

-- Transcendental roots
example :  x  Set.Icc (1 : ) 2, Real.cos x = 0 := by
  interval_roots

Expr AST syntax (also supported):

open LeanCert.Core

def I12 : IntervalRat := 1, 2, by norm_num

example :  x  I12, Expr.eval (fun _ => x)
    (Expr.add (Expr.mul (Expr.var 0) (Expr.var 0)) (Expr.neg (Expr.const 2))) = 0 := by
  interval_roots

How it works: 1. Evaluates expression at interval endpoints 2. Detects sign change (f(lo) < 0 < f(hi) or vice versa) 3. Applies IVT to prove existence


interval_unique_root

Proves root uniqueness via Newton contraction mapping.

Native syntax (recommended):

import LeanCert.Tactic.Discovery

-- Prove there's exactly one root of x² - 2 in [1, 2]
example : ∃! x  Set.Icc (1 : ) 2, x^2 - 2 = 0 := by
  interval_unique_root

Expr AST syntax (also supported):

open LeanCert.Core

def I12 : IntervalRat := 1, 2, by norm_num
def expr_x2_minus_2 : Expr := Expr.add (Expr.mul (Expr.var 0) (Expr.var 0)) (Expr.neg (Expr.const 2))

example : ∃! x  I12, Expr.eval (fun _ => x) expr_x2_minus_2 = 0 := by
  interval_unique_root

How it works: 1. Computes Newton operator N(x) = x - f(x)/f'(x) 2. Verifies N maps interval into itself 3. Verifies |N'(x)| < 1 (contraction) 4. Banach fixed-point theorem gives uniqueness


interval_integrate

Proves bounds on definite integrals via verified Riemann sums.

import LeanCert.Tactic.Discovery

-- Prove integral bounds
example :  x in (0:)..1, x^2  0.34 := by
  interval_integrate

How it works: 1. Partitions interval into subintervals 2. Computes interval bounds on each partition 3. Sums (width × bound) for rigorous over/under-approximation


Interactive Commands

#explore

Interactive function analysis in the editor. Shows range, extrema, and roots.

import LeanCert.Tactic.Discovery

-- Explore sin(x) on [0, 4]
#explore (Expr.sin (Expr.var 0)) on [0, 4]

Output includes: - Domain and computed range - Global minimum and maximum with locations - Sign changes (potential roots) - Monotonicity information


Comparison Table

Tactic Purpose Trust Speed
certify_bound Prove bounds native_decide Medium
certify_kernel Prove bounds decide / fallback Fast
interval_decide Point inequalities native_decide Fast
interval_refute Find counter-examples Verified Slow
interval_roots Prove root exists native_decide Medium
interval_unique_root Prove root unique native_decide Slow
interval_minimize Prove min exists native_decide Slow
interval_maximize Prove max exists native_decide Slow
interval_integrate Prove integral bounds native_decide Medium
discover Auto-route min/max native_decide Slow
interval_minimize_mv Multivariate min native_decide Slow
interval_maximize_mv Multivariate max native_decide Slow
multivariate_bound N-dim bounds native_decide Medium
root_bound Prove f(x) ≠ 0 native_decide Medium
interval_bound_subdiv Tight bounds via subdivision native_decide Slow
interval_argmax Find maximizer point native_decide Slow
interval_argmin Find minimizer point native_decide Slow

Additional Tactics

discover

Meta-tactic that analyzes the goal and automatically routes to interval_minimize or interval_maximize.

import LeanCert.Tactic.Discovery

-- Automatically detects ≥ m and calls interval_minimize
example :  m : ,  x  I, f(x)  m := by discover

-- Automatically detects ≤ M and calls interval_maximize
example :  M : ,  x  I, f(x)  M := by discover

interval_minimize_mv / interval_maximize_mv

Multivariate versions of minimize/maximize for N-dimensional domains.

import LeanCert.Tactic.Discovery

-- Find minimum over 2D domain
example :  m : ,  x  Set.Icc (0:) 1,  y  Set.Icc (0:) 1,
    x*x + y*y  m := by
  interval_minimize_mv

-- Find maximum over 2D domain
example :  M : ,  x  Set.Icc (0:) 1,  y  Set.Icc (0:) 1,
    x + y  M := by
  interval_maximize_mv

Uses more samples (300) and iterations (2000) than univariate versions.


multivariate_bound

Proves bounds over multi-variable domains directly.

import LeanCert.Tactic.IntervalAuto

-- Prove x + y ≤ 2 on [0,1] × [0,1]
example :  x  Set.Icc (0:) 1,  y  Set.Icc (0:) 1,
    x + y  (2 : ) := by
  multivariate_bound

root_bound

Proves absence of roots by showing a function is strictly positive or negative.

Native syntax (recommended):

import LeanCert.Tactic.IntervalAuto

-- x² + 1 ≠ 0 on [0, 1] (always positive)
example :  x  Set.Icc (0 : ) 1, x * x + 1  0 := by
  root_bound

-- exp(x) ≠ 0 on [0, 1]
example :  x  Set.Icc (0 : ) 1, Real.exp x  0 := by
  root_bound 15

Expr AST syntax (also supported):

open LeanCert.Core

def I01 : IntervalRat := 0, 1, by norm_num

example :  x  I01, Expr.eval (fun _ => x)
    (Expr.add (Expr.mul (Expr.var 0) (Expr.var 0)) (Expr.const 1))  (0 : ) := by
  root_bound

interval_bound_subdiv

Proves bounds using progressive subdivision when direct interval evaluation is too loose.

import LeanCert.Tactic.IntervalAuto

-- Tighter bound requiring subdivision
example :  x  Set.Icc (0:) 1, Real.exp x  (272/100 : ) := by
  interval_bound_subdiv 15 3  -- Taylor depth 15, subdivision depth 3

Parameters:

Parameter Type Default Description
depth 10 Taylor series depth
subdivDepth 2 Number of subdivision levels

interval_argmax / interval_argmin

Find the point where a function achieves its maximum/minimum.

interval_argmax - Native syntax (recommended):

import LeanCert.Tactic.Discovery

-- Find the maximizer of x² on [-1,1] (argmax at endpoints x = ±1)
example :  x  Set.Icc (-1 : ) 1,  y  Set.Icc (-1 : ) 1,
    y * y  x * x := by
  interval_argmax

-- Linear function: max of 2x+1 on [0,1] (argmax at x=1)
example :  x  Set.Icc (0 : ) 1,  y  Set.Icc (0 : ) 1,
    2 * y + 1  2 * x + 1 := by
  interval_argmax

interval_argmin - Native syntax (recommended):

-- Find the minimizer of x on [0,1] (argmin at x=0)
example :  x  Set.Icc (0 : ) 1,  y  Set.Icc (0 : ) 1,
    x  y := by
  interval_argmin

Expr AST syntax (also supported):

open LeanCert.Core

def I_neg1_1 : IntervalRat := -1, 1, by norm_num
def I01 : IntervalRat := 0, 1, by norm_num

-- Argmax with Expr AST
example :  x  I_neg1_1,  y  I_neg1_1,
    Expr.eval (fun _ => y) (Expr.mul (Expr.var 0) (Expr.var 0)) 
    Expr.eval (fun _ => x) (Expr.mul (Expr.var 0) (Expr.var 0)) := by
  interval_argmax

-- Argmin with Expr AST
example :  x  I01,  y  I01,
    Expr.eval (fun _ => x) (Expr.var 0) 
    Expr.eval (fun _ => y) (Expr.var 0) := by
  interval_argmin

How it works: 1. Runs branch-and-bound optimization to find candidate optimizer xOpt 2. Evaluates f(xOpt) to get a concrete bound c 3. For argmax: Proves ∀ y ∈ I, f(y) ≤ c and c ≤ f(xOpt), then applies transitivity 4. For argmin: Proves ∀ y ∈ I, c ≤ f(y) and f(xOpt) ≤ c, then applies transitivity

Limitations: - Works best when the argmax/argmin is at a rational point (e.g., interval endpoints) - For transcendental functions, may require higher Taylor depth - For interior optima at irrational points, consider using interval_maximize/interval_minimize instead


Low-Level Manual Tactics

For fine-grained control, use these macros from LeanCert.Tactic.Interval:

import LeanCert.Tactic.Interval

open LeanCert.Core LeanCert.Engine

def xSq : Expr := Expr.mul (Expr.var 0) (Expr.var 0)
def xSq_supp : ExprSupportedCore xSq :=
  ExprSupportedCore.mul (ExprSupportedCore.var 0) (ExprSupportedCore.var 0)

-- Manual bounds with explicit AST and support proof
example :  x  I01, Expr.eval (fun _ => x) xSq  (1 : ) := by
  interval_le xSq, xSq_supp, I01, 1

example :  x  I01, (0 : )  Expr.eval (fun _ => x) xSq := by
  interval_ge xSq, xSq_supp, I01, 0
Macro Purpose
interval_le ∀ x ∈ I, f(x) ≤ c
interval_ge ∀ x ∈ I, c ≤ f(x)
interval_lt ∀ x ∈ I, f(x) < c
interval_gt ∀ x ∈ I, c < f(x)
interval_le_pt Pointwise f(x) ≤ c given x ∈ I
interval_ge_pt Pointwise c ≤ f(x) given x ∈ I

Extended (noncomputable) versions for expressions with exp: interval_ext_le, interval_ext_ge, interval_ext_lt, interval_ext_gt

These reduce the goal to a rational inequality that must be proved manually.


Common Patterns

Proving a function is bounded

-- Upper and lower bound
example :  x  Set.Icc (0 : ) 1, 0  Real.sin x  Real.sin x  1 := by
  constructor <;> certify_bound

Proving a root exists and is unique

-- First existence, then uniqueness
example :  x  I, f x = 0 := by interval_roots
example : ∃! x  I, f x = 0 := by interval_unique_root

Debugging failed proofs

set_option trace.certify_bound true    -- See computation details
set_option trace.certify_kernel true   -- See kernel verification status

-- If bound too tight, try:
-- 1. Increase Taylor depth: certify_bound 20
-- 2. Use certify_kernel_precise for more bits
-- 3. Use interval_refute to check if bound is actually false