Tactic proofs
Due to the kernel being small, we were able to give a brief summary of the most important kernel-level concepts. In contrast, tactics implement heterogeneous automation. They cannot be summarized briefly, and learning them is more challenging than understanding the kernel-level concepts. We now illustrate two tactics, grind and simp.
Automation with grind
The factorization of the difference of two squares can be proven by grind.
example (x y : β)
: x^2 - y^2 = (x + y) * (x - y)
:= x:βy:ββ’ x ^ 2 - y ^ 2 = (x + y) * (x - y)
All goals completed! π
When the elaborator encounters by, signifying a tactic block, it runs the tactic interpreter. Tactics are imperative programs. Within a tactic block they manipulate the proof state consisting of the hypotheses and the goal, and the block as a whole must produce an expression having the proposition as its type.
Above, grind is the only tactic in the block. It produces an expression of type x^2 - y^2 = (x + y) * (x - y).
We can give a name to a proven proposition in several ways, and use it in subsequent proofs.
def diff_sqβ (x y : β) : x^2 - y^2 = (x + y) * (x - y)
:= x:βy:ββ’ x ^ 2 - y ^ 2 = (x + y) * (x - y) All goals completed! π
lemma diff_sqβ (x y : β) : x^2 - y^2 = (x + y) * (x - y)
:= x:βy:ββ’ x ^ 2 - y ^ 2 = (x + y) * (x - y) All goals completed! π
theorem diff_sqβ (x y : β) : x^2 - y^2 = (x + y) * (x - y)
:= diff_sqβ x y
Despite the syntactic differences, all these define the same function.
The expression produced by grind can be inspected using #print. The actual proof has an auto-generated name.
#print diff_sqβ
#print diff_sqβ._proof_1
The proof refers to several functions and is already long even without expanding them. Writing just grind amounts to significant compression. This is achieved by using algorithms inspired by modern SMT solvers.
Rewriting with simp
Semigroup is a set with an associative binary operation. In Lean, semigroups are defined as a type class.[β¦]Type classes are inductive types with special elaboration-level features. We return to them later.
Here is a fact about a semigroup together with a commutativity hypothesis.
example (G : Type) [Semigroup G] (a b c : G)
(h : β x y : G, x * y = y * x)
: a * b * c = b * c * a
:= G:Typeinstβ:Semigroup Ga:Gb:Gc:Gh:β (x y : G), x * y = y * xβ’ a * b * c = b * c * a
calc
(a * b) * c
_ = (b * a) * c := G:Typeinstβ:Semigroup Ga:Gb:Gc:Gh:β (x y : G), x * y = y * xβ’ a * b * c = b * a * c All goals completed! π
_ = b * (a * c) := G:Typeinstβ:Semigroup Ga:Gb:Gc:Gh:β (x y : G), x * y = y * xβ’ b * a * c = b * (a * c) All goals completed! π
_ = b * (c * a) := G:Typeinstβ:Semigroup Ga:Gb:Gc:Gh:β (x y : G), x * y = y * xβ’ b * (a * c) = b * (c * a) All goals completed! π
_ = (b * c) * a := G:Typeinstβ:Semigroup Ga:Gb:Gc:Gh:β (x y : G), x * y = y * xβ’ b * (c * a) = b * c * a All goals completed! π
We use the grind and simp tactics to prove the steps in the calc block.[β¦]The calc block chains equalities and other transitive relations. The simp tactic uses the commutativity hypothesis h as a rewrite rule.
Further proofs
example : diff_sqβ = diff_sqβ := rfl
example : diff_sqβ = diff_sqβ := rfl