G8d: Pierwszorzędowe kody [TODO]
From Typonomikon Require Import G8c.
Kody dla typów induktywnych (TODO)
Innym pomysłem na jednorodne reprezentowanie typów induktywnych,
trochę podobnym do W-typów, jest stworzenie uniwersum nazw (czyli
kodów), które następnie będziemy mogli zinterpretować jako typy
induktywne.
Inductive I : Type :=
| u : I
| nonind : forall A : Type, (A -> I) -> I
| ind : I -> I.
Fixpoint Arg (i : I) (X : Type) : Type :=
match i with
| u => unit
| nonind A f => {a : A & Arg (f a) X}
| ind i => X * Arg i X
end.
Definition iprod (A B : Type) : I :=
nonind A (fun _ => nonind B (fun _ => u)).
Compute Arg (iprod nat bool) False.
Definition isum (A B : Type) : I :=
nonind bool (fun b => nonind (if b then A else B) (fun _ => u)).
Compute Arg (isum nat bool) False.
Definition inat : I :=
nonind bool (fun b => if b then u else ind u).
Compute Arg inat False.
Definition inat_nat {X : Type} (a : Arg inat X) : unit + X.
Proof.
cbn in a. destruct a as [[] []].
left. exact tt.
right. exact x.
Defined.
Definition ilist (A : Type) : I :=
nonind bool (fun b => if b then u else nonind A (fun _ => ind u)).
Compute Arg (ilist nat) False.
Definition ifalse : I := ind u.
Compute Arg ifalse unit.
Unset Positivity Checking.
Inductive IType (i : I) : Type :=
| intro : Arg i (IType i) -> IType i.
Set Positivity Checking.
Definition iinat := IType inat.
Definition Z : iinat.
Proof.
constructor. cbn. exists true. cbn. exact tt.
Defined.
Definition iS (n : iinat) : iinat.
Proof.
constructor. cbn. exists false. cbn. split.
exact n.
constructor.
Defined.
Unset Guard Checking.
Fixpoint iinat_ind
{P : iinat -> Type}
(z : P Z)
(s : forall n : iinat, P n -> P (iS n))
(n : iinat) {struct n} : P n.
Proof.
destruct n as [[[] []]].
exact z.
destruct a. apply s. apply iinat_ind; assumption.
Qed.
Set Guard Checking.
Fixpoint nat_to_iinat (n : nat) : iinat :=
match n with
| 0 => Z
| Datatypes.S n' => iS (nat_to_iinat n')
end.
Definition pred (n : iinat) : option iinat :=
match n with
| intro _ (existT _ true _) => None
| intro _ (existT _ false (n', _)) => Some n'
end.
Unset Guard Checking.
Fixpoint iinat_to_nat (n : iinat) : nat :=
match n with
| intro _ (existT _ true _) => 0
| intro _ (existT _ false (n', _)) => Datatypes.S (iinat_to_nat n')
end.
Set Guard Checking.
Lemma one_way :
forall n : nat, iinat_to_nat (nat_to_iinat n) = n.
Proof.
induction n as [| n']; cbn.
reflexivity.
f_equal. assumption.
Defined.
Compute one_way 0.
Lemma second_way' :
forall n : iinat, nat_to_iinat (iinat_to_nat n) = n.
Proof.
apply iinat_ind; cbn.
reflexivity.
intros n' IH. f_equal. assumption.
Qed.
Unset Guard Checking.
Fixpoint second_way
(n : iinat) : nat_to_iinat (iinat_to_nat n) = n.
Proof.
destruct n as [[[] []]]; cbn.
reflexivity.
unfold iS. repeat f_equal.
apply second_way.
destruct a. reflexivity.
Defined.
Set Guard Checking.
Compute second_way (iS Z).
Compute second_way (iS (iS Z)).
Kody dla typów induktywno-rekursywnych (TODO)
Inductive IR (D : Type) : Type :=
| iota : D -> IR D
| sigma : forall A : Type, (A -> IR D) -> IR D
| delta : forall A : Type, ((A -> D) -> IR D) -> IR D.