We try to explain inductive types from a
foundational point of view not using match and fix.
Suppose we define
Inductive bool := false | true.
As a result the environment is extended with 4 typings
and 2 computation rules are added:
That's it. The key properties of the underlying calculus of constructions are preserved by this extension (e.g., type preservation, termination, consistency).
The following definitions suggest that bool_rect gives us all we need.
bool : Set false : bool true : bool bool_rect : forall p : bool -> Type, p false -> p true -> forall x : bool, p x bool_rect t t1 t1 false ---> t1 bool_rect t t1 t2 true ---> t2
That's it. The key properties of the underlying calculus of constructions are preserved by this extension (e.g., type preservation, termination, consistency).
The following definitions suggest that bool_rect gives us all we need.
Definition bool_Ind : forall p : bool -> Prop, p false -> p true -> forall x : bool, p x
:=fun p => bool_rect (fun x => p x).
Definition bool_case : forall Z : Type, Z -> Z -> bool ->Z
:= fun Z => bool_rect (fun _ => Z).
Eval compute in bool_case nat 7 9 false.
Eval compute in bool_case nat 7 9 true.
With bool_case one can prove that the constructors
false and true are different, something one cannot do
for the Church-Girard encoding of bool. We do the
proof just using first principles.
Definition False : Prop := forall X:Prop, X.
Definition True : Prop := forall X:Prop, X -> X.
Definition I : True := fun X x => x.
Definition eq (X:Type) (x y : X) : Prop := forall p : X -> Prop, p x -> p y.
Definition false_neq_true : eq bool false true -> False :=
fun f => f (bool_case Prop True False) I.
Coq defines bool_rect with dependent match.
Definition bool_Rect : forall p : bool -> Type, p false -> p true -> forall x : bool, p x
:= fun p a b x => match x return p x with false => a | true => b end.
Let's now consider the inductive type of natural numbers.
Inductive nat := O : nat | S : nat -> nat.
This time we get the following extensions:
Once again nat_rect gives us all we need.
int : Set O : nat S : nat -> nat nat_rect : forall p : nat -> Type, p O -> (forall x : nat, p x -> p(S x)) -> forall x : nat, p x nat_rect t t1 t1 O ---> t1 nat_rect t t1 t2 (S u) ---> t2 u (nat_rect t t1 t2 u)
Once again nat_rect gives us all we need.
Definition nat_Ind : forall p : nat -> Prop, p O -> (forall x : nat, p x -> p(S x)) -> forall x : nat, p x
:= fun p => nat_rect (fun x => p x).
Definition nat_Rec : forall Z : Type, Z -> (nat -> Z -> Z) -> nat -> Z
:= fun Z => nat_rect (fun _ => Z).
Eval compute in nat_Rec nat O (fun _ a => S(S(S a))) (S(S O)).
Definition nat_case : forall Z : Type, Z -> (nat -> Z) -> nat -> Z
:= fun Z a b => nat_Rec Z a (fun x _ => b x).
Definition pred : nat -> nat := nat_case nat O (fun y => y).
Definition O_neq_S : forall n, eq nat O (S n) -> False :=
fun _ f => f (nat_case Prop True (fun _ => False)) I.
Definition S_injective: forall x y, eq nat (S x) (S y) -> eq nat x y
:= fun x _ f => f
( nat_case Prop True (eq nat x))
(fun _ b => b).
Coq defines nat_rect with fix and dependent match.
Definition nat_Rect : forall p : nat -> Type, p O -> (forall x : nat, p x -> p(S x)) -> forall x : nat, p x
:= fun p a b => fix ind x := match x return p x with O => a | S x' => b x' (ind x') end.
This page has been generated by coqdoc