Expand description
Equation lemmas — Lean’s f.eq_def, f.eq_1 … f.eq_n — the NAME a proof cites when it appeals to a
definition’s behaviour, which is what rw [f] / simp [f] / unfold f all need.
A LOGOS definition is δ-transparent and its Fix/Match ι-compute, so the facts about a
recursive function are all TRUE by conversion the moment it is declared: dbl 3 ≡ 6, and
dbl (Succ n) ≡ Succ (Succ (dbl n)) for a free n. What was missing is a name. Every appeal
to a definition in a real proof — rw [f], simp [f], unfold f — cites a CONSTANT, and
without one every such appeal degrades to a full normalize whose fuel silently returns a
partially reduced term when it runs out.
§What Lean does, and where
- The names.
Lean/Meta/Eqns.lean:59-68fixes them:eqnThmSuffixBase := "eq",eqn1ThmSuffix := "eq_1",unfoldThmSuffix := "eq_def". In Lean’s hierarchical namespace those aref.eq_defandf.eq_1 … f.eq_n; LOGOS’s context is flat, so the same suffixes are spelledf_eq_defandf_eq_1 … f_eq_n. - The shape and the proof.
Lean/Meta/Eqns.lean:149-162(mkSimpleEqThm) telescopes the definition’s VALUE, states∀ xs, f xs = body, and proves it withEq.refl (f xs)under the same telescope. That is exactly the shape built here: the theorem is true by conversion, soreflis the whole proof, and the kernel’s own registration gateway re-checks it. - When.
Lean/Meta/Eqns.lean:142-144— “We generate the equations on demand” — viagetEqnsFor?and the reserved-name action atLean/Meta/Eqns.lean:281-289. LOGOS generates EAGERLY instead, and the reason is a signature rather than a preference:Context::get_globalreturnsOption<&Term>, a reference into the context, so a lookup cannot synthesise a term it does not already hold. Eager generation costs onereflper definition and makes the lemma visible to every reader, includingCheck.
§The three hazards, and how each is closed
- Re-entrancy. A lemma is itself a definition, so generating one would generate its own.
is_equation_nameis checked first and an equation name generates nothing. - Bootstrap.
Eqandreflare registered part-way through the prelude (prelude.rs::register_eq), so everything declared before them has no equality to state an equation IN. Generation is a no-op while they are absent, andgenerate_missing_for_allback-fills once they exist. - Displacement.
Context::declaredisplaces the name it registers. A lemma is skipped whenever its name is already taken, so generation can never remove something a user wrote.
Constants§
- EQUATION_
INFIX - Lean’s
eqnThmSuffixBasePrefix(Lean/Meta/Eqns.lean:60), flattened. - UNFOLD_
SUFFIX - Lean’s
unfoldThmSuffix(Lean/Meta/Eqns.lean:68), flattened.
Functions§
- equation_
lemmas - The equation lemmas a definition owes, as
(name, statement, proof)in Lean’s order: the unfold theorem first, then one equation per constructor of the matched argument. - generate
- Generate and REGISTER the equation lemmas a definition owes.
- generate_
missing_ for_ all - Back-fill every definition that was registered before
Eq/reflexisted. - is_
equation_ name - Whether a name is one this module MINTS, rather than one it generates lemmas for.