16.11. Reducibility
Reducible definitions in terms are eagerly unfolded by grind.
This enables more efficient definitional equality comparisons and indexing.
Reducibility and Congruence Closure
The definition of one is not reducible:
def one := 1
This means that grind does not unfold it:
example : one = 1 := ⊢ one = 1 All goals completed! 🐙
two, on the other hand, is an abbreviation and thus reducible:
abbrev two := 2
grind unfolds two before adding it to the “whiteboard”, allowing the proof to be completed immediately:
example : two = 2 := ⊢ two = 2 All goals completed! 🐙
E-matching patterns also unfold reducible definitions.
The patterns generated for theorems about abbreviations are expressed in terms of the unfolded abbreviations.
Abbreviations should not generally be recursive; in particular, when using grind, recursive abbreviations can result in poor indexing performance and unpredictable patterns.
E-matching and Unfolding Abbreviations
When adding grind annotations to theorems, E-matching patterns are generated based on the theorem statement.
These patterns determine when the theorem is instantiated.
The theorem one_eq_1 mentions the semireducible definition one, and the resulting pattern is also one:
def one := 1
@[grind? =]
theorem one_eq_1 : one = 1 := ⊢ one = 1 All goals completed! 🐙
Applying the same annotation to a theorem about the reducible abbreviation two results in a pattern in which two is unfolded:
abbrev two := 2
@[grind? =]
theorem two_eq_2: two = 2 := ⊢ two = 2 All goals completed! 🐙
Recursive Abbreviations and grind
Using the grind attribute to add E-matching patterns for a recursive abbreviation's equational lemmas does not result in useful patterns for recursive abbreviations.
The @[grind?] attribute on this definition of the Fibonacci function results in three patterns, each corresponding to one of the three possibilities:
@[grind?]
def fib : Nat → Nat
| 0 => 0
| 1 => 1
| n + 2 => fib n + fib (n + 1)
Replacing the definition with an abbreviation results in patterns in which occurrences of the function are unfolded. These patterns are not particularly useful:
@[grind?]
abbrev fib : Nat → Nat
| 0 => 0
| 1 => 1
| n + 2 => fib n + fib (n + 1)