Commit d565f371 authored by Adam Chlipala's avatar Adam Chlipala

Templatize Generic

parent 53400ba8
...@@ -25,6 +25,9 @@ Set Implicit Arguments. ...@@ -25,6 +25,9 @@ Set Implicit Arguments.
(** * Reflecting Datatype Definitions *) (** * Reflecting Datatype Definitions *)
(* EX: Define a reflected representation of simple algebraic datatypes. *)
(* begin thide *)
Record constructor : Type := Con { Record constructor : Type := Con {
nonrecursive : Type; nonrecursive : Type;
recursive : nat recursive : nat
...@@ -37,6 +40,7 @@ Definition unit_dt : datatype := Con unit 0 :: nil. ...@@ -37,6 +40,7 @@ Definition unit_dt : datatype := Con unit 0 :: nil.
Definition bool_dt : datatype := Con unit 0 :: Con unit 0 :: nil. Definition bool_dt : datatype := Con unit 0 :: Con unit 0 :: nil.
Definition nat_dt : datatype := Con unit 0 :: Con unit 1 :: nil. Definition nat_dt : datatype := Con unit 0 :: Con unit 1 :: nil.
Definition list_dt (A : Type) : datatype := Con unit 0 :: Con A 1 :: nil. Definition list_dt (A : Type) : datatype := Con unit 0 :: Con A 1 :: nil.
(* end thide *)
Section tree. Section tree.
Variable A : Type. Variable A : Type.
...@@ -46,6 +50,7 @@ Section tree. ...@@ -46,6 +50,7 @@ Section tree.
| Node : tree -> tree -> tree. | Node : tree -> tree -> tree.
End tree. End tree.
(* begin thide *)
Definition tree_dt (A : Type) : datatype := Con A 0 :: Con unit 2 :: nil. Definition tree_dt (A : Type) : datatype := Con A 0 :: Con unit 2 :: nil.
Section denote. Section denote.
...@@ -56,12 +61,14 @@ Section denote. ...@@ -56,12 +61,14 @@ Section denote.
Definition datatypeDenote := hlist constructorDenote. Definition datatypeDenote := hlist constructorDenote.
End denote. End denote.
(* end thide *)
Notation "[ ! , ! ~> x ]" := ((fun _ _ => x) : constructorDenote _ (Con _ _)). Notation "[ ! , ! ~> x ]" := ((fun _ _ => x) : constructorDenote _ (Con _ _)).
Notation "[ v , ! ~> x ]" := ((fun v _ => x) : constructorDenote _ (Con _ _)). Notation "[ v , ! ~> x ]" := ((fun v _ => x) : constructorDenote _ (Con _ _)).
Notation "[ ! , r # n ~> x ]" := ((fun _ r => x) : constructorDenote _ (Con _ n)). Notation "[ ! , r # n ~> x ]" := ((fun _ r => x) : constructorDenote _ (Con _ n)).
Notation "[ v , r # n ~> x ]" := ((fun v r => x) : constructorDenote _ (Con _ n)). Notation "[ v , r # n ~> x ]" := ((fun v r => x) : constructorDenote _ (Con _ n)).
(* begin thide *)
Definition Empty_set_den : datatypeDenote Empty_set Empty_set_dt := Definition Empty_set_den : datatypeDenote Empty_set Empty_set_dt :=
hnil. hnil.
Definition unit_den : datatypeDenote unit unit_dt := Definition unit_den : datatypeDenote unit unit_dt :=
...@@ -74,10 +81,14 @@ Definition list_den (A : Type) : datatypeDenote (list A) (list_dt A) := ...@@ -74,10 +81,14 @@ Definition list_den (A : Type) : datatypeDenote (list A) (list_dt A) :=
[!, ! ~> nil] ::: [x, r # 1 ~> x :: hd r] ::: hnil. [!, ! ~> nil] ::: [x, r # 1 ~> x :: hd r] ::: hnil.
Definition tree_den (A : Type) : datatypeDenote (tree A) (tree_dt A) := Definition tree_den (A : Type) : datatypeDenote (tree A) (tree_dt A) :=
[v, ! ~> Leaf v] ::: [!, r # 2 ~> Node (hd r) (hd (tl r))] ::: hnil. [v, ! ~> Leaf v] ::: [!, r # 2 ~> Node (hd r) (hd (tl r))] ::: hnil.
(* end thide *)
(** * Recursive Definitions *) (** * Recursive Definitions *)
(* EX: Define a generic [size] function. *)
(* begin thide *)
Definition fixDenote (T : Type) (dt : datatype) := Definition fixDenote (T : Type) (dt : datatype) :=
forall (R : Type), datatypeDenote R dt -> (T -> R). forall (R : Type), datatypeDenote R dt -> (T -> R).
...@@ -121,10 +132,14 @@ Definition tree_fix (A : Type) : fixDenote (tree A) (tree_dt A) := ...@@ -121,10 +132,14 @@ Definition tree_fix (A : Type) : fixDenote (tree A) (tree_dt A) :=
| Node t1 t2 => (fst (snd cases)) tt (icons (F t1) (icons (F t2) inil)) | Node t1 t2 => (fst (snd cases)) tt (icons (F t1) (icons (F t2) inil))
end. end.
Eval cbv beta iota delta -[plus] in fun A => size (@tree_fix A). Eval cbv beta iota delta -[plus] in fun A => size (@tree_fix A).
(* end thide *)
(** ** Pretty-Printing *) (** ** Pretty-Printing *)
(* EX: Define a generic pretty-printing function. *)
(* begin thide *)
Record print_constructor (c : constructor) : Type := PI { Record print_constructor (c : constructor) : Type := PI {
printName : string; printName : string;
printNonrec : nonrecursive c -> string printNonrec : nonrecursive c -> string
...@@ -140,6 +155,7 @@ Definition print T dt (pr : print_datatype dt) (fx : fixDenote T dt) : T -> stri ...@@ -140,6 +155,7 @@ Definition print T dt (pr : print_datatype dt) (fx : fixDenote T dt) : T -> stri
fx string (hmap (B1 := print_constructor) (B2 := constructorDenote string) fx string (hmap (B1 := print_constructor) (B2 := constructorDenote string)
(fun _ pc x r => printName pc ++ "(" ++ printNonrec pc x (fun _ pc x r => printName pc ++ "(" ++ printNonrec pc x
++ foldr (fun s acc => ", " ++ s ++ acc) ")" r) pr). ++ foldr (fun s acc => ", " ++ s ++ acc) ")" r) pr).
(* end thide *)
Eval compute in print hnil Empty_set_fix. Eval compute in print hnil Empty_set_fix.
Eval compute in print (^ "tt" (fun _ => "") ::: hnil) unit_fix. Eval compute in print (^ "tt" (fun _ => "") ::: hnil) unit_fix.
...@@ -167,9 +183,13 @@ Eval cbv beta iota delta -[append] in fun A (pr : A -> string) => ...@@ -167,9 +183,13 @@ Eval cbv beta iota delta -[append] in fun A (pr : A -> string) =>
(** ** Mapping *) (** ** Mapping *)
(* EX: Define a generic [map] function. *)
(* begin thide *)
Definition map T dt (dd : datatypeDenote T dt) (fx : fixDenote T dt) (f : T -> T) : T -> T := Definition map T dt (dd : datatypeDenote T dt) (fx : fixDenote T dt) (f : T -> T) : T -> T :=
fx T (hmap (B1 := constructorDenote T) (B2 := constructorDenote T) fx T (hmap (B1 := constructorDenote T) (B2 := constructorDenote T)
(fun _ c x r => f (c x r)) dd). (fun _ c x r => f (c x r)) dd).
(* end thide *)
Eval compute in map Empty_set_den Empty_set_fix. Eval compute in map Empty_set_den Empty_set_fix.
Eval compute in map unit_den unit_fix. Eval compute in map unit_den unit_fix.
...@@ -186,6 +206,7 @@ Eval simpl in map_nat S 2. ...@@ -186,6 +206,7 @@ Eval simpl in map_nat S 2.
(** * Proving Theorems about Recursive Definitions *) (** * Proving Theorems about Recursive Definitions *)
(* begin thide *)
Section ok. Section ok.
Variable T : Type. Variable T : Type.
Variable dt : datatype. Variable dt : datatype.
...@@ -215,23 +236,27 @@ Lemma foldr_plus : forall n (ils : ilist nat n), ...@@ -215,23 +236,27 @@ Lemma foldr_plus : forall n (ils : ilist nat n),
induction n; crush. induction n; crush.
generalize (IHn b); crush. generalize (IHn b); crush.
Qed. Qed.
(* end thide *)
Theorem size_positive : forall T dt Theorem size_positive : forall T dt
(dd : datatypeDenote T dt) (fx : fixDenote T dt) (dd : datatypeDenote T dt) (fx : fixDenote T dt)
(dok : datatypeDenoteOk dd) (fok : fixDenoteOk dd fx) (dok : datatypeDenoteOk dd) (fok : fixDenoteOk dd fx)
(v : T), (v : T),
size fx v > 0. size fx v > 0.
(* begin thide *)
Hint Rewrite hget_hmake : cpdt. Hint Rewrite hget_hmake : cpdt.
Hint Resolve foldr_plus. Hint Resolve foldr_plus.
unfold size; intros; pattern v; apply dok; crush. unfold size; intros; pattern v; apply dok; crush.
Qed. Qed.
(* end thide *)
Theorem map_id : forall T dt Theorem map_id : forall T dt
(dd : datatypeDenote T dt) (fx : fixDenote T dt) (dd : datatypeDenote T dt) (fx : fixDenote T dt)
(dok : datatypeDenoteOk dd) (fok : fixDenoteOk dd fx) (dok : datatypeDenoteOk dd) (fok : fixDenoteOk dd fx)
(v : T), (v : T),
map dd fx (fun x => x) v = v. map dd fx (fun x => x) v = v.
(* begin thide *)
Hint Rewrite hget_hmap : cpdt. Hint Rewrite hget_hmap : cpdt.
unfold map; intros; pattern v; apply dok; crush. unfold map; intros; pattern v; apply dok; crush.
...@@ -248,3 +273,4 @@ Theorem map_id : forall T dt ...@@ -248,3 +273,4 @@ Theorem map_id : forall T dt
apply IHn; crush. apply IHn; crush.
apply (H (Some i0)). apply (H (Some i0)).
Qed. Qed.
(* end thide *)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment