Library dependentElimination
Non-dependent Elimination vs Dependent Elimination.
Booleans
Inductive Bool : Type :=
| tt : Bool
| ff : Bool
.
| tt : Bool
| ff : Bool
.
Non dependent elimination
fun t e => if b then t else e
: forall A, A -> A -> A
Definition Bool_elim (b: Bool):
forall A: Type, A->A->A :=
fun (A: Type) (t f: A) =>
match b with
| tt => t
| ff => f
end .
forall A: Type, A->A->A :=
fun (A: Type) (t f: A) =>
match b with
| tt => t
| ff => f
end .
Dependent elimination
Definition Bool_dep_elim (b: Bool):
forall F : Bool -> Type, F tt -> F ff -> F b :=
fun (F: Bool -> Type) (t: F tt) (f: F ff) =>
match b with
| tt => t
| ff => f
end .
forall F : Bool -> Type, F tt -> F ff -> F b :=
fun (F: Bool -> Type) (t: F tt) (f: F ff) =>
match b with
| tt => t
| ff => f
end .
Note that is the above match, t and f have different types, yet it
type-checks!
This requires a non trivial type checking rule. For more details,
you can see the dependentMatch file which shows how match works.
This is a recursive type, corresponding to the initial F-algebra
F X = 1 + X.
Coq, which is based on the Calculus of Inductive Constructions,
allows recursive types only when F is a (covariant) functor. In such
way, it ensures that the logic is kept consistent.
Naturals
Inductive Nat :=
| Zero : Nat
| Succ : Nat -> Nat
.
| Zero : Nat
| Succ : Nat -> Nat
.
Non dependent elimination
Fixpoint Nat_elim (n: Nat):
forall A: Type, A -> (A -> A) -> A :=
fun (A: Type) (z: A) (s: A -> A) =>
match n with
| Zero => z
| Succ m => s (Nat_elim m A z s)
end .
forall A: Type, A -> (A -> A) -> A :=
fun (A: Type) (z: A) (s: A -> A) =>
match n with
| Zero => z
| Succ m => s (Nat_elim m A z s)
end .
Note that the Fixpoint above is checked by Coq to be terminating.
When recursing, each recursive call must be made on a "smaller" term.
This is required to safeguard the logic consistency.
Now the return type depends on n. The resulting elimination principle
is the usual induction principle on naturals.
Dependent elimination
Fixpoint Nat_dep_elim (n: Nat):
forall F: Nat -> Type,
F Zero ->
(forall m: Nat, F m -> F (Succ m)) ->
F n :=
fun (F: Nat -> Type)
(z: F Zero)
(s: forall m: Nat, F m -> F (Succ m)) =>
match n with
| Zero => z
| Succ m => s m (Nat_dep_elim m F z s)
end .
forall F: Nat -> Type,
F Zero ->
(forall m: Nat, F m -> F (Succ m)) ->
F n :=
fun (F: Nat -> Type)
(z: F Zero)
(s: forall m: Nat, F m -> F (Succ m)) =>
match n with
| Zero => z
| Succ m => s m (Nat_dep_elim m F z s)
end .
Inductive List: Type :=
| Nil: List
| Cons: Nat -> List -> List
.
| Nil: List
| Cons: Nat -> List -> List
.
Fixpoint List_elim (l: List):
forall A: Type, A -> (Nat -> A -> A) -> A :=
fun (A: Type) (nil: A) (cons: Nat -> A -> A) =>
match l with
| Nil => nil
| Cons n l2 => cons n (List_elim l2 A nil cons)
end .
forall A: Type, A -> (Nat -> A -> A) -> A :=
fun (A: Type) (nil: A) (cons: Nat -> A -> A) =>
match l with
| Nil => nil
| Cons n l2 => cons n (List_elim l2 A nil cons)
end .
Fixpoint List_dep_elim (l: List):
forall F: List -> Type,
F Nil ->
(forall (n: Nat) (l2: List), F l2 -> F (Cons n l2)) ->
F l :=
fun (F: List -> Type)
(nil: F Nil)
(cons: forall (n: Nat) (l2: List), F l2 -> F (Cons n l2)) =>
match l with
| Nil => nil
| Cons n l2 => cons n l2 (List_dep_elim l2 F nil cons)
end .
forall F: List -> Type,
F Nil ->
(forall (n: Nat) (l2: List), F l2 -> F (Cons n l2)) ->
F l :=
fun (F: List -> Type)
(nil: F Nil)
(cons: forall (n: Nat) (l2: List), F l2 -> F (Cons n l2)) =>
match l with
| Nil => nil
| Cons n l2 => cons n l2 (List_dep_elim l2 F nil cons)
end .
List of naturals, length-indexed
Inductive SizedList: Nat -> Type :=
| NilS : SizedList Zero
| ConsS : Nat -> forall (n: Nat), SizedList n -> SizedList (Succ n)
.
| NilS : SizedList Zero
| ConsS : Nat -> forall (n: Nat), SizedList n -> SizedList (Succ n)
.
Non dependent elimination
Fixpoint SizedList_elim (n: Nat) (l: SizedList n):
forall A: Nat -> Type,
A Zero ->
(Nat -> forall (k: Nat), A k -> A (Succ k)) ->
A n :=
fun (A: Nat -> Type)
(nil: A Zero)
(cons: Nat -> forall (k: Nat), A k -> A (Succ k)) =>
match l with
| NilS => nil
| ConsS m n2 l2 => cons m n2 (SizedList_elim n2 l2 A nil cons)
end .
forall A: Nat -> Type,
A Zero ->
(Nat -> forall (k: Nat), A k -> A (Succ k)) ->
A n :=
fun (A: Nat -> Type)
(nil: A Zero)
(cons: Nat -> forall (k: Nat), A k -> A (Succ k)) =>
match l with
| NilS => nil
| ConsS m n2 l2 => cons m n2 (SizedList_elim n2 l2 A nil cons)
end .
Fixpoint SizedList_dep_elim (n: Nat) (l: SizedList n):
forall F: (forall m: Nat, SizedList m -> Type),
F Zero NilS ->
(forall (n2: Nat) (k: Nat) (l2: SizedList k),
F k l2 -> F (Succ k) (ConsS n2 k l2)) ->
F n l :=
fun (F: forall m: Nat, SizedList m -> Type)
(nil: F Zero NilS)
(cons: forall (n2: Nat) (k: Nat) (l2: SizedList k),
F k l2 -> F (Succ k) (ConsS n2 k l2)) =>
match l with
| NilS => nil
| ConsS m n2 l2 => cons m n2 l2 (SizedList_dep_elim n2 l2 F nil cons)
end .
forall F: (forall m: Nat, SizedList m -> Type),
F Zero NilS ->
(forall (n2: Nat) (k: Nat) (l2: SizedList k),
F k l2 -> F (Succ k) (ConsS n2 k l2)) ->
F n l :=
fun (F: forall m: Nat, SizedList m -> Type)
(nil: F Zero NilS)
(cons: forall (n2: Nat) (k: Nat) (l2: SizedList k),
F k l2 -> F (Succ k) (ConsS n2 k l2)) =>
match l with
| NilS => nil
| ConsS m n2 l2 => cons m n2 l2 (SizedList_dep_elim n2 l2 F nil cons)
end .
Existential quantification
Inductive Ex (T: Type) (P: T -> Type): Type :=
| witness : forall (t: T), P t -> Ex T P
.
| witness : forall (t: T), P t -> Ex T P
.
Non dependent elimination
Definition Ex_elim (T: Type) (P: T -> Type) (w: Ex T P):
(forall A: Type,
(forall (t: T), P t -> A) ->
A) :=
fun (A: Type)
(wit: forall (t: T), P t -> A) =>
match w with
| witness t h => wit t h
end .
(forall A: Type,
(forall (t: T), P t -> A) ->
A) :=
fun (A: Type)
(wit: forall (t: T), P t -> A) =>
match w with
| witness t h => wit t h
end .
Definition Ex_dep_elim (T: Type) (P: T -> Type) (w: Ex T P):
(forall F: Ex T P -> Type,
(forall (t: T) (h: P t), F (witness T P t h)) ->
F w) :=
fun (F: Ex T P -> Type)
(wit: forall (t: T) (h: P t), F (witness T P t h)) =>
match w with
| witness t h => wit t h
end .
(forall F: Ex T P -> Type,
(forall (t: T) (h: P t), F (witness T P t h)) ->
F w) :=
fun (F: Ex T P -> Type)
(wit: forall (t: T) (h: P t), F (witness T P t h)) =>
match w with
| witness t h => wit t h
end .