linarith — Linear Arithmetic
Solve linear arithmetic goals over ordered rings. linarithhandles inequalities and equalities involving addition and scalar multiplication. When you have a chain of inequalities and need to derive a conclusion, linarith finds the proof automatically.
linarith requires Mathlib. Add import Mathlib.Tactic.Linarith to use this tactic.The Problem linarith Solves
Suppose you know x < y and y < z, and need to prove x < z. This is "obviously" true by transitivity, but spelling it out in Lean requires finding and applying the right lemmas. linarith handles this automatically—and much more complex chains too:
1import Mathlib.Tactic.Linarith23-- Simple transitivity4example (x y z : Int) (h1 : x < y) (h2 : y < z) : x < z := by linarith56-- More complex chains7example (a b c d e : Int) 8 (h1 : a ≤ b) (h2 : b < c) (h3 : c ≤ d) (h4 : d < e) 9 : a < e := by linarith1011-- Combining many constraints12example (x y z : Int) 13 (h1 : x + y ≤ 10) (h2 : y + z ≤ 10) (h3 : z + x ≤ 10) 14 : x + y + z ≤ 15 := by linarithBasic Usage
linarith automatically proves goals that follow from linear arithmetic over ordered rings. It examines all hypotheses involving addition, subtraction, and scalar multiplication, then determines if the goal follows logically.
1import Mathlib.Tactic.Linarith23-- Basic inequalities4example (x y : Int) (h1 : x < y) (h2 : y < x + 2) : y = x + 1 := by5 linarith67example (a b c : Int) (h1 : a ≤ b) (h2 : b ≤ c) : a ≤ c := by8 linarith910example (x : Int) (h : x > 0) : x ≥ 1 := by11 linarith1213-- Works with equalities too14example (a b : Int) (h1 : a ≤ b) (h2 : b ≤ a) : a = b := by15 linarithlinarith proves goals by finding linear combinations of hypotheses that establish the result. It automatically uses all relevant inequalities in your context.Understanding "Linear"
Like omega, linarith handles linear expressions—where variables appear with degree 1. You can have 3 * x but notx * y or x².
1import Mathlib.Tactic.Linarith23-- ✅ Linear: coefficients are constants4example (x y : Int) (h : 3*x + 2*y ≤ 10) (hx : x ≥ 0) (hy : y ≥ 0) : x ≤ 3 := by5 linarith67-- ✅ Subtraction and negation are fine8example (a b : Int) (h : a ≤ b) : -b ≤ -a := by linarith910-- ❌ Non-linear: variable times variable11-- example (x y : Int) : x * y = y * x := by linarith -- Fails!1213-- ❌ Non-linear: squaring14-- example (x : Int) : x^2 ≥ 0 := by linarith -- Fails!How linarith Reasons
Under the hood, linarith finds a linear combination of your hypotheses that implies the goal. It multiplies inequalities by non-negative constants and adds them together:
1import Mathlib.Tactic.Linarith23-- Example: Prove a ≤ c from a ≤ b and b ≤ c4-- linarith adds: 1*(a ≤ b) + 1*(b ≤ c) gives a ≤ c56example (a b c : Int) (h1 : a ≤ b) (h2 : b ≤ c) : a ≤ c := by linarith78-- Example: Prove x ≤ 3 from x + y ≤ 5 and y ≥ 29-- linarith uses: (x + y ≤ 5) + (-1)*(y ≥ 2) which gives x ≤ 31011example (x y : Int) (h1 : x + y ≤ 5) (h2 : y ≥ 2) : x ≤ 3 := by linarithProving False from Contradictions
A powerful use case is proving False when your hypotheses are contradictory. If the constraints are impossible to satisfy simultaneously,linarith finds the contradiction:
1import Mathlib.Tactic.Linarith23-- Direct contradiction4example (x : Int) (h1 : x > 5) (h2 : x < 3) : False := by linarith56-- More subtle: these three together are impossible7example (a b c : Int) 8 (h1 : a + b > c) 9 (h2 : b + c > a) 10 (h3 : c + a > b)11 (h4 : a + b + c ≤ 0) : False := by linarith1213-- Finding implicit contradictions14example (x y : Int) (h1 : x > y) (h2 : y > x) : False := by linarithlinarith vs omega
Both tactics handle linear arithmetic, but they have different strengths:
| Feature | omega | linarith |
|---|---|---|
| Part of | Lean 4 core | Mathlib |
| Nat support | ✅ Excellent | ⚠️ Often needs omega |
| Int support | ✅ Good | ✅ Excellent |
| Rat/Real support | ❌ No | ✅ Yes |
| Div/mod | ✅ Yes | ❌ No |
| Disjunctions | ✅ Yes | ❌ No |
Nat arithmetic, preferomega (core Lean 4). Use linarithfor Int, Rat, andReal.Working with Different Types
1import Mathlib.Tactic.Linarith23-- Integers4example (x y : Int) (h : x ≤ y) : -y ≤ -x := by linarith56-- Rationals7example (p q : Rat) (h1 : p ≤ q) (h2 : q ≤ p) : p = q := by linarith89-- With Mathlib, also works on:10-- ℝ (reals), ℚ (rationals), and other ordered ringsProviding Extra Hypotheses
Sometimes linarith needs extra facts that aren't in your context. You can provide them in brackets:
1import Mathlib.Tactic.Linarith23-- Provide additional lemmas in brackets4example (x y : Int) (h : x * x + y * y = 0) (hx : x * x ≥ 0) (hy : y * y ≥ 0) 5 : x * x = 0 := by linarith67-- Combining with computed facts8example (n : Int) (h : n ≥ 0) : 2 * n ≥ n := by linarithnlinarith: The Non-linear Extension
For goals involving products of variables, use nlinarith:
1import Mathlib.Tactic.Linarith23-- nlinarith handles some nonlinear cases4example (x : Int) (h : x ≥ 2) : x * x ≥ 4 := by5 nlinarith [sq_nonneg x, sq_nonneg (x - 2)]67-- Square is always ≥ 08example (x : Int) : x * x ≥ 0 := by nlinarith [sq_nonneg x]910-- Product of positive numbers is positive11example (x y : Int) (hx : x > 0) (hy : y > 0) : x * y > 0 := by nlinarithDeep Dive: How linarith Works: The Simplex Algorithm
linarith uses techniques from linear programming to find proofs:
- Collection: Gather all linear inequalities from the context
- Negation: Add the negation of the goal as an additional constraint
- Feasibility Check: Use the Simplex algorithm to check if the constraint system is satisfiable
- Certificate: If unsatisfiable, extract a proof certificate (the linear combination)
If the negated goal creates an unsatisfiable system, the original goal must be true.
Real-World Examples
Triangle Inequality
1import Mathlib.Tactic.Linarith23-- Given sides of a valid triangle, prove bounds4theorem triangle_sides (a b c : Int) 5 (h1 : a + b > c) (h2 : b + c > a) (h3 : c + a > b)6 (ha : a > 0) (hb : b > 0) (hc : c > 0) :7 a < b + c := by linarithBounds Propagation
1import Mathlib.Tactic.Linarith23-- If we know bounds on parts, derive bounds on whole4theorem bound_sum (x y z : Int) 5 (hx : 0 ≤ x) (hx' : x ≤ 10)6 (hy : 0 ≤ y) (hy' : y ≤ 10)7 (hz : 0 ≤ z) (hz' : z ≤ 10) :8 x + y + z ≤ 30 := by linarith910-- Tighter bound when we know the sum11theorem bound_from_sum (x y : Int) (h : x + y = 10) (hx : x ≥ 3) : y ≤ 7 := by12 linarithOrdering Proofs
1import Mathlib.Tactic.Linarith23-- Mixed strict and non-strict inequalities4example (a b c d : Int) (h1 : a ≤ b) (h2 : b < c) (h3 : c ≤ d) : a < d := by5 linarith67-- Averaging8example (a b m : Int) (h : 2 * m = a + b) (hab : a ≤ b) : a ≤ m := by9 linarithCommon Patterns
1import Mathlib.Tactic.Linarith23-- Absolute value bounds (given expanded form)4example (x : Int) (h1 : -5 ≤ x) (h2 : x ≤ 5) : -5 ≤ x ∧ x ≤ 5 := by5 constructor <;> linarith67-- Sandwich theorem setup8example (a b c : Int) (h1 : a ≤ b) (h2 : b ≤ c) (h3 : a = c) : b = a := by9 linarith1011-- Interval arithmetic12example (x y : Int) (hx : 1 ≤ x) (hx' : x ≤ 3) (hy : 2 ≤ y) (hy' : y ≤ 4) 13 : 3 ≤ x + y := by linarithUse linarith to prove transitivity.
1import Mathlib.Tactic.Linarith23example (a b c : Int) (h1 : a < b) (h2 : b < c) : a < c := by linarithFind the contradiction in these constraints.
1import Mathlib.Tactic.Linarith23example (x : Int) (h1 : x > 10) (h2 : x < 5) : False := by linarithDerive a bound from constraints.
1import Mathlib.Tactic.Linarith23example (x y : Int) (h1 : x + y ≤ 100) (h2 : y ≥ 60) : x ≤ 40 := by linarith