Documentation

Mathlib.Tactic.DeriveCountable

Countable deriving handler #

Adds a deriving handler for the Countable class.

Theory #

We use the Nat.pair function to encode an inductive type in the natural numbers, following a pattern similar to the tagged s-expressions used in Scheme/Lisp. We develop a little theory to make constructing the injectivity functions very straightforward.

This is easiest to explain by example. Given a type

inductive T (α : Type)
  | a (n : α)
  | b (n m : α) (t : T α)

the deriving handler constructs the following three declarations:

noncomputable def T.toNat (α : Type) [Countable α] : T α → ℕ
  | a n => Nat.pair 0 (Nat.pair (encode n) 0)
  | b n m t => Nat.pair 1 (Nat.pair (encode n) (Nat.pair (encode m) (Nat.pair t.toNat 0)))

theorem T.toNat_injective (α : Type) [Countable α] : Function.Injective (T.toNat α) := fun
  | a .., a .. => by
    refine cons_eq_imp_init ?_
    refine pair_encode_step ?_; rintro ⟨⟩
    intro; rfl
  | a .., b .. => by refine cons_eq_imp ?_; rintro ⟨⟩
  | b .., a .. => by refine cons_eq_imp ?_; rintro ⟨⟩
  | b .., b .. => by
    refine cons_eq_imp_init ?_
    refine pair_encode_step ?_; rintro ⟨⟩
    refine pair_encode_step ?_; rintro ⟨⟩
    refine cons_eq_imp ?_; intro h; cases T.toNat_injective α h
    intro; rfl

instance (α : Type) [Countable α] : Countable (T α) := ⟨_, T.toNat_injective α⟩
noncomputable def Mathlib.Deriving.Countable.encode {α : Sort u_1} [Countable α] :
α

Encode a Countable type into the natural numbers using the witness produced by Countable.exists_injective_nat. Used internally by the Countable deriving handler.

Equations
Instances For

    The encode function is injective. Used internally by the Countable deriving handler.

    theorem Mathlib.Deriving.Countable.cons_eq_imp_init {p : Prop} {a b b' : } (h : b = b'p) :
    Nat.pair a b = Nat.pair a b'p

    Initialize the injectivity argument. Pops the constructor tag.

    theorem Mathlib.Deriving.Countable.cons_eq_imp {p : Prop} {a b a' b' : } (h : a = a'b = b'p) :
    Nat.pair a b = Nat.pair a' b'p

    Generic step of the injectivity argument, pops the head of the pairs. Used in the recursive steps where we need to supply an additional injectivity argument.

    theorem Mathlib.Deriving.Countable.pair_encode_step {p : Prop} {α : Sort u_1} [Countable α] {a b : α} {m n : } (h : a = bm = np) :
    Nat.pair (encode a) m = Nat.pair (encode b) np

    Specialized step of the injectivity argument, pops the head of the pairs and decodes.

    Implementation #

    Constructing the toNat functions.

    Constructs a function from the inductive type to Nat.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For

      Constructing the injectivity proofs for these toNat functions.

      Constructs a proof that the functions created by mkToNatFuns are injective.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For

        Assembling the Countable instances.

        The deriving handler for the Countable class. Handles non-nested non-reflexive inductive types. They can be mutual too — in that case, there is an optimization to re-use all the generated functions and proofs.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For