quotients-and-lifts
Work effectively with Lean 4 quotients in ComputationalPaths (Quot.lift/Quot.ind/Quot.sound), including nested lifts and common proof obligations.
When & Why to Use This Skill
This Claude skill provides expert guidance and implementation patterns for working with Lean 4 quotients and lifts, specifically within the ComputationalPaths framework. It streamlines the process of defining functions via Quot.lift, performing quotient induction with Quot.ind, and proving equalities using Quot.sound, while offering specialized strategies for complex nested lifts and formal proof obligations.
Use Cases
- Defining well-defined functions on quotient types (e.g., LoopQuot, PiOne) by proving they respect underlying equivalence relations.
- Simplifying complex formal proofs by reducing quotient-based goals to their representatives using induction patterns.
- Implementing multi-argument functions over quotients in Homotopy Type Theory (HoTT) using nested Quot.lift and functional extensionality.
- Debugging and resolving common Lean 4 proof errors related to 'respects relation' obligations and direction mismatches in quotient sounds.
| name | quotients-and-lifts |
|---|---|
| description | Work effectively with Lean 4 quotients in ComputationalPaths (Quot.lift/Quot.ind/Quot.sound), including nested lifts and common proof obligations. |
Quotients & Lifts (Lean 4)
This skill is a practical guide to working with Quot-based quotients in the ComputationalPaths codebase (e.g. LoopQuot, PiOne, group presentations, rewrite quotients).
Core patterns
1) Defining a function out of a quotient: Quot.lift
To define a map Quot r → B, provide:
- a function on representatives
f : A → B - a proof it respects the relation
hf : ∀ a b, r a b → f a = f b
def encode : Quot r → B :=
Quot.lift f (by
intro a b hab
-- show f a = f b
exact hf a b hab)
In this repo, the “respects” proof is often built from an RwEq lemma, e.g. circleEncodePath_rweq in ComputationalPaths/Path/HIT/Circle.lean.
2) Proving something for all quotient elements: Quot.ind
Use quotient induction to reduce to representatives:
theorem myThm (x : Quot r) : P x := by
induction x using Quot.ind with
| _ a =>
-- goal becomes P (Quot.mk _ a) (up to definitional equality)
...
3) Proving equality in a quotient: Quot.sound
When the goal is an equality of quotient terms, typically:
-- goal: Quot.mk r a = Quot.mk r b
exact Quot.sound hab
hab must have the quotient’s underlying relation type (often RwEq in this project). If you have the relation in the “wrong direction”, use symmetry (e.g. rweq_symm).
Nested quotient lifts (Lean 4)
Lean 4 does not provide some Lean 3 conveniences (e.g. patterns like Quot.liftOn2 in older code). Prefer nested Quot.lift:
def f2 : Quot r1 → Quot r2 → C :=
fun x => Quot.lift
(fun a => Quot.lift (fun b => g a b) (by intro b b' hb; exact ...) )
(by intro a a' ha; funext y; -- prove functions are equal
induction y using Quot.ind with
| _ b => ... )
x
This pattern appears in HIT / SVK developments where you map pairs of quotient classes into another quotient.
Practical checklist for “respects relation” proofs
When Quot.lift fails due to the second argument:
- Identify the quotient relation
r(often a rewrite equivalence). - Prove a lemma of the shape
r a b → f a = f b(or→ RwEq (f a) (f b)then turn into equality viaQuot.soundwhere appropriate). - If the lemma naturally produces the reverse direction, wrap with symmetry.
- Use
simplemmas for quotient constructors (e.g.LoopQuot.ofLoop) when applicable.
Common pitfalls (and fixes)
- Wrong obligation shape:
Quot.liftwants equality in the codomain, not a relation proof. If your codomain is itself a quotient, you usually finish withQuot.sound. - Direction mismatch:
Quot.soundexpectsr a b; use symmetry of the relation when you haver b a. - Getting stuck on function equality (nested lifts): use
funext+Quot.indon the remaining quotient argument(s).