Reasoning often alternates between propositional equality `a = b` and boolean equality `a == b`.
Reasoning often alternates between propositional equality a = b and boolean equality a == b. In Lean, this bridge is mediated by decidable equality. It allows you to move between computation and proof.
Decidable equality
A type has decidable equality if for any a b : α, you can decide whether a = b or a ≠ b. This is captured by:
Decidable (a = b)For many standard types such as Nat, instances are available:
#check inferInstance : Decidable (3 = 5)This enables case analysis on equality:
example (a b : Nat) : a = b ∨ a ≠ b := by
by_cases h : a = b
· left; exact h
· right; exact hThe tactic by_cases relies on decidability.
Boolean equality
Boolean equality is written a == b. It computes to true or false. It is useful in executable code and algorithms.
#eval (3 == 3) -- true
#eval (3 == 5) -- falseHowever, == lives in Bool, while = lives in Prop. Bridging between them requires lemmas.
Bridging lemmas
Lean provides standard connections:
#check decide_eq_true_eq
-- (a == b) = true ↔ a = bIn practice, simp handles many conversions automatically:
example (a b : Nat) :
(a == b) = true → a = b := by
intro h
simpa using hAnd conversely:
example (a b : Nat) (h : a = b) :
(a == b) = true := by
simpa [h]The simplifier knows how to translate between boolean and propositional equality when instances are available.
Using decide
The function decide converts a decidable proposition into a boolean:
#eval decide (3 = 3) -- true
#eval decide (3 = 5) -- falseThis allows you to compute with propositions. It is useful when integrating proofs with executable code.
example (a b : Nat) :
decide (a = b) = true → a = b := by
intro h
exact of_decide_eq_true hRewriting with boolean conditions
In proofs involving conditionals, boolean equality appears frequently:
example (a b : Nat) (h : a = b) :
if a == b then 1 else 0 = 1 := by
simp [h]The rewrite converts a == b to true, and the conditional simplifies.
Case analysis on equality
Decidable equality supports branching:
example (a b : Nat) :
(if a = b then 1 else 0) = (if b = a then 1 else 0) := by
by_cases h : a = b
· simp [h]
· simp [h]Each branch simplifies independently.
Practical guidance
- Use propositional equality
=for proofs. - Use boolean equality
==for computation. - Bridge between them with
simp,decide, or explicit lemmas. - Use
by_casesfor case splits on equality. - Normalize boolean expressions early to simplify goals.
Summary
Decidable equality connects computation and reasoning. It allows equality to be tested, branched on, and rewritten across the boundary between Bool and Prop. This bridge is essential for combining algorithms with formal proofs.