Commit c8613be0 authored by Adam Chlipala's avatar Adam Chlipala

Switch DepList to inductive, not recursive, types

parent b87eea7b
...@@ -841,7 +841,7 @@ Qed. ...@@ -841,7 +841,7 @@ Qed.
(** remove printing * *) (** remove printing * *)
(** Some of the type family definitions from this chapter are duplicated in the [DepList] module of the book source. Only the recursive versions of length-indexed and heterogeneous lists are included, and they are renamed without the [f] prefixes, e.g., [ilist] in place of [filist]. (** Some of the type family definitions and associated functions from this chapter are duplicated in the [DepList] module of the book source. Some of their names have been changed to be more sensible in a general context.
%\begin{enumerate}%#<ol># %\begin{enumerate}%#<ol>#
......
This diff is collapsed.
(* Copyright (c) 2008, Adam Chlipala (* Copyright (c) 2008-2009, Adam Chlipala
* *
* This work is licensed under a * This work is licensed under a
* Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
...@@ -499,7 +499,7 @@ Module PatMatch. ...@@ -499,7 +499,7 @@ Module PatMatch.
Fixpoint patDenote t ts (p : pat t ts) {struct p} : typeDenote t -> option (hlist typeDenote ts) := Fixpoint patDenote t ts (p : pat t ts) {struct p} : typeDenote t -> option (hlist typeDenote ts) :=
match p in (pat t ts) return (typeDenote t -> option (hlist typeDenote ts)) with match p in (pat t ts) return (typeDenote t -> option (hlist typeDenote ts)) with
| PVar _ => fun v => Some (v, tt) | PVar _ => fun v => Some (v ::: HNil)
| PPair _ _ _ _ p1 p2 => fun v => | PPair _ _ _ _ p1 p2 => fun v =>
match patDenote p1 (fst v), patDenote p2 (snd v) with match patDenote p1 (fst v), patDenote p2 (snd v) with
| Some tup1, Some tup2 => Some (happ tup1 tup2) | Some tup1, Some tup2 => Some (happ tup1 tup2)
...@@ -525,18 +525,18 @@ Module PatMatch. ...@@ -525,18 +525,18 @@ Module PatMatch.
: (forall ts, member ts tss -> option (hlist typeDenote ts)) : (forall ts, member ts tss -> option (hlist typeDenote ts))
-> (forall ts, member ts tss -> hlist typeDenote ts -> typeDenote t2) -> (forall ts, member ts tss -> hlist typeDenote ts -> typeDenote t2)
-> typeDenote t2 := -> typeDenote t2 :=
match tss return (forall ts, member ts tss -> _) match tss return (forall ts, member ts tss -> option (hlist typeDenote ts))
-> (forall ts, member ts tss -> _) -> (forall ts, member ts tss -> hlist typeDenote ts -> typeDenote t2)
-> _ with -> _ with
| nil => fun _ _ => | nil => fun _ _ =>
default default
| ts :: tss' => fun (envs : forall ts', member ts' (ts :: tss') -> option (hlist typeDenote ts')) | ts :: tss' => fun (envs : forall ts', member ts' (ts :: tss') -> option (hlist typeDenote ts'))
(bodies : forall ts', member ts' (ts :: tss') -> hlist typeDenote ts' -> typeDenote t2) => (bodies : forall ts', member ts' (ts :: tss') -> hlist typeDenote ts' -> typeDenote t2) =>
match envs _ (hfirst (refl_equal _)) with match envs _ HFirst with
| None => matchesDenote tss' | None => matchesDenote
(fun _ mem => envs _ (hnext mem)) (fun _ mem => envs _ (HNext mem))
(fun _ mem => bodies _ (hnext mem)) (fun _ mem => bodies _ (HNext mem))
| Some env => (bodies _ (hfirst (refl_equal _))) env | Some env => (bodies _ HFirst) env
end end
end. end.
End matchesDenote. End matchesDenote.
...@@ -735,23 +735,23 @@ Module PatMatch. ...@@ -735,23 +735,23 @@ Module PatMatch.
match p in (pat t1 ts) return ((hlist (exp var) ts -> result) match p in (pat t1 ts) return ((hlist (exp var) ts -> result)
-> result -> choice_tree var t1 result) with -> result -> choice_tree var t1 result) with
| PVar _ => fun succ fail => | PVar _ => fun succ fail =>
everywhere (fun disc => succ (disc, tt)) everywhere (fun disc => succ (disc ::: HNil))
| PPair _ _ _ _ p1 p2 => fun succ fail => | PPair _ _ _ _ p1 p2 => fun succ fail =>
elaboratePat _ p1 elaboratePat p1
(fun tup1 => (fun tup1 =>
elaboratePat _ p2 elaboratePat p2
(fun tup2 => (fun tup2 =>
succ (happ tup1 tup2)) succ (happ tup1 tup2))
fail) fail)
(everywhere (fun _ => fail)) (everywhere (fun _ => fail))
| PInl _ _ _ p' => fun succ fail => | PInl _ _ _ p' => fun succ fail =>
(elaboratePat _ p' succ fail, (elaboratePat p' succ fail,
everywhere (fun _ => fail)) everywhere (fun _ => fail))
| PInr _ _ _ p' => fun succ fail => | PInr _ _ _ p' => fun succ fail =>
(everywhere (fun _ => fail), (everywhere (fun _ => fail),
elaboratePat _ p' succ fail) elaboratePat p' succ fail)
end. end.
Implicit Arguments elaboratePat [var t1 ts result]. Implicit Arguments elaboratePat [var t1 ts result].
...@@ -760,8 +760,8 @@ Module PatMatch. ...@@ -760,8 +760,8 @@ Module PatMatch.
-> hlist (exp var) ts -> exp var t := -> hlist (exp var) ts -> exp var t :=
match ts return ((hlist var ts -> exp var t) match ts return ((hlist var ts -> exp var t)
-> hlist (exp var) ts -> exp var t) with -> hlist (exp var) ts -> exp var t) with
| nil => fun f _ => f tt | nil => fun f _ => f HNil
| _ :: _ => fun f tup => letify _ (fun tup' => x <- fst tup; f (x, tup')) (snd tup) | _ :: _ => fun f tup => letify (fun tup' => x <- hhd tup; f (x ::: tup')) (htl tup)
end. end.
Implicit Arguments letify [var t ts]. Implicit Arguments letify [var t ts].
...@@ -809,14 +809,14 @@ Module PatMatch. ...@@ -809,14 +809,14 @@ Module PatMatch.
| ts :: tss' => fun (ps : forall ts', member ts' (ts :: tss') -> pat t1 ts') | ts :: tss' => fun (ps : forall ts', member ts' (ts :: tss') -> pat t1 ts')
(es : forall ts', member ts' (ts :: tss') -> hlist var ts' -> Elab.exp var t2) => (es : forall ts', member ts' (ts :: tss') -> hlist var ts' -> Elab.exp var t2) =>
merge (@mergeOpt _) merge (@mergeOpt _)
(elaboratePat (ps _ (hfirst (refl_equal _))) (elaboratePat (ps _ HFirst)
(fun ts => Some (letify (fun ts => Some (letify
(fun ts' => es _ (hfirst (refl_equal _)) ts') (fun ts' => es _ HFirst ts')
ts)) ts))
None) None)
(elaborateMatches tss' (elaborateMatches
(fun _ mem => ps _ (hnext mem)) (fun _ mem => ps _ (HNext mem))
(fun _ mem => es _ (hnext mem))) (fun _ mem => es _ (HNext mem)))
end. end.
Implicit Arguments elaborateMatches [var t1 t2 tss]. Implicit Arguments elaborateMatches [var t1 t2 tss].
...@@ -926,7 +926,7 @@ Module PatMatch. ...@@ -926,7 +926,7 @@ Module PatMatch.
result (succ : hlist (Elab.exp typeDenote) ts -> result) result (succ : hlist (Elab.exp typeDenote) ts -> result)
(fail : result) v env, (fail : result) v env,
patDenote p v = Some env patDenote p v = Some env
-> exists env', grab (elaboratePat typeDenote p succ fail) v = succ env' -> exists env', grab (elaboratePat p succ fail) v = succ env'
/\ env = hmap Elab.expDenote env'. /\ env = hmap Elab.expDenote env'.
Hint Resolve hmap_happ. Hint Resolve hmap_happ.
...@@ -935,11 +935,11 @@ Module PatMatch. ...@@ -935,11 +935,11 @@ Module PatMatch.
| [ |- context[grab (everywhere ?succ) ?v] ] => | [ |- context[grab (everywhere ?succ) ?v] ] =>
generalize (everywhere_correct succ (#v)%elab) generalize (everywhere_correct succ (#v)%elab)
| [ H : forall result sudc fail, _ |- context[grab (elaboratePat _ _ ?S ?F) ?V] ] => | [ H : forall result succ fail, _ |- context[grab (elaboratePat _ ?S ?F) ?V] ] =>
generalize (H _ S F V); clear H generalize (H _ S F V); clear H
| [ H1 : context[match ?E with Some _ => _ | None => _ end], | [ H1 : context[match ?E with Some _ => _ | None => _ end],
H2 : forall env, ?E = Some env -> _ |- _ ] => H2 : forall env, ?E = Some env -> _ |- _ ] =>
destruct E destruct E
| [ H : forall env, Some ?E = Some env -> _ |- _ ] => | [ H : forall env, Some ?E = Some env -> _ |- _ ] =>
generalize (H _ (refl_equal _)); clear H generalize (H _ (refl_equal _)); clear H
end; crush); eauto. end; crush); eauto.
...@@ -949,14 +949,14 @@ Module PatMatch. ...@@ -949,14 +949,14 @@ Module PatMatch.
result (succ : hlist (Elab.exp typeDenote) ts -> result) result (succ : hlist (Elab.exp typeDenote) ts -> result)
(fail : result) v, (fail : result) v,
patDenote p v = None patDenote p v = None
-> grab (elaboratePat typeDenote p succ fail) v = fail. -> grab (elaboratePat p succ fail) v = fail.
Hint Resolve everywhere_fail. Hint Resolve everywhere_fail.
induction p; try solve [ crush ]; induction p; try solve [ crush ];
simpl; fold choice_tree; intuition; simpl in *; simpl; fold choice_tree; intuition; simpl in *;
repeat match goal with repeat match goal with
| [ IH : forall result succ fail v, patDenote ?P v = _ -> _ | [ IH : forall result succ fail v, patDenote ?P v = _ -> _
|- context[grab (elaboratePat _ ?P ?S ?F) ?V] ] => |- context[grab (elaboratePat ?P ?S ?F) ?V] ] =>
generalize (IH _ S F V); clear IH; intro IH; generalize (IH _ S F V); clear IH; intro IH;
generalize (elaboratePat_correct P S F V); intros; generalize (elaboratePat_correct P S F V); intros;
destruct (patDenote P V); try discriminate destruct (patDenote P V); try discriminate
...@@ -973,7 +973,7 @@ Module PatMatch. ...@@ -973,7 +973,7 @@ Module PatMatch.
(env : hlist (Elab.exp typeDenote) ts), (env : hlist (Elab.exp typeDenote) ts),
Elab.expDenote (letify f env) Elab.expDenote (letify f env)
= Elab.expDenote (f (hmap Elab.expDenote env)). = Elab.expDenote (f (hmap Elab.expDenote env)).
induction ts; crush. induction ts; crush; dep_destruct env; crush.
Qed. Qed.
Theorem elaborate_correct : forall t (e : Source.exp typeDenote t), Theorem elaborate_correct : forall t (e : Source.exp typeDenote t),
...@@ -986,7 +986,7 @@ Module PatMatch. ...@@ -986,7 +986,7 @@ Module PatMatch.
| [ tss : list (list type) |- _ ] => | [ tss : list (list type) |- _ ] =>
induction tss; crush; induction tss; crush;
match goal with match goal with
| [ |- context[grab (elaboratePat _ ?P ?S ?F) ?V] ] => | [ |- context[grab (elaboratePat ?P ?S ?F) ?V] ] =>
case_eq (patDenote P V); [intros env Heq; case_eq (patDenote P V); [intros env Heq;
destruct (elaboratePat_correct P S F _ Heq); crush; destruct (elaboratePat_correct P S F _ Heq); crush;
match goal with match goal with
......
(* Copyright (c) 2008, Adam Chlipala (* Copyright (c) 2008-2009, Adam Chlipala
* *
* This work is licensed under a * This work is licensed under a
* Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
...@@ -70,17 +70,17 @@ Notation "[ v , r # n ~> x ]" := ((fun v r => x) : constructorDenote _ (Con _ n) ...@@ -70,17 +70,17 @@ Notation "[ v , r # n ~> x ]" := ((fun v r => x) : constructorDenote _ (Con _ n)
(* begin thide *) (* 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 :=
[!, ! ~> tt] ::: hnil. [!, ! ~> tt] ::: HNil.
Definition bool_den : datatypeDenote bool bool_dt := Definition bool_den : datatypeDenote bool bool_dt :=
[!, ! ~> true] ::: [!, ! ~> false] ::: hnil. [!, ! ~> true] ::: [!, ! ~> false] ::: HNil.
Definition nat_den : datatypeDenote nat nat_dt := Definition nat_den : datatypeDenote nat nat_dt :=
[!, ! ~> O] ::: [!, r # 1 ~> S (hd r)] ::: hnil. [!, ! ~> O] ::: [!, r # 1 ~> S (hd r)] ::: HNil.
Definition list_den (A : Type) : datatypeDenote (list A) (list_dt A) := 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 *) (* end thide *)
...@@ -100,36 +100,36 @@ Definition Empty_set_fix : fixDenote Empty_set Empty_set_dt := ...@@ -100,36 +100,36 @@ Definition Empty_set_fix : fixDenote Empty_set Empty_set_dt :=
Eval compute in size Empty_set_fix. Eval compute in size Empty_set_fix.
Definition unit_fix : fixDenote unit unit_dt := Definition unit_fix : fixDenote unit unit_dt :=
fun R cases _ => (fst cases) tt inil. fun R cases _ => (hhd cases) tt INil.
Eval compute in size unit_fix. Eval compute in size unit_fix.
Definition bool_fix : fixDenote bool bool_dt := Definition bool_fix : fixDenote bool bool_dt :=
fun R cases b => if b fun R cases b => if b
then (fst cases) tt inil then (hhd cases) tt INil
else (fst (snd cases)) tt inil. else (hhd (htl cases)) tt INil.
Eval compute in size bool_fix. Eval compute in size bool_fix.
Definition nat_fix : fixDenote nat nat_dt := Definition nat_fix : fixDenote nat nat_dt :=
fun R cases => fix F (n : nat) : R := fun R cases => fix F (n : nat) : R :=
match n with match n with
| O => (fst cases) tt inil | O => (hhd cases) tt INil
| S n' => (fst (snd cases)) tt (icons (F n') inil) | S n' => (hhd (htl cases)) tt (ICons (F n') INil)
end. end.
Eval cbv beta iota delta -[plus] in size nat_fix. Eval cbv beta iota delta -[plus] in size nat_fix.
Definition list_fix (A : Type) : fixDenote (list A) (list_dt A) := Definition list_fix (A : Type) : fixDenote (list A) (list_dt A) :=
fun R cases => fix F (ls : list A) : R := fun R cases => fix F (ls : list A) : R :=
match ls with match ls with
| nil => (fst cases) tt inil | nil => (hhd cases) tt INil
| x :: ls' => (fst (snd cases)) x (icons (F ls') inil) | x :: ls' => (hhd (htl cases)) x (ICons (F ls') INil)
end. end.
Eval cbv beta iota delta -[plus] in fun A => size (@list_fix A). Eval cbv beta iota delta -[plus] in fun A => size (@list_fix A).
Definition tree_fix (A : Type) : fixDenote (tree A) (tree_dt A) := Definition tree_fix (A : Type) : fixDenote (tree A) (tree_dt A) :=
fun R cases => fix F (t : tree A) : R := fun R cases => fix F (t : tree A) : R :=
match t with match t with
| Leaf x => (fst cases) x inil | Leaf x => (hhd cases) x INil
| Node t1 t2 => (fst (snd cases)) tt (icons (F t1) (icons (F t2) inil)) | Node t1 t2 => (hhd (htl 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 *) (* end thide *)
...@@ -157,15 +157,15 @@ Definition print T dt (pr : print_datatype dt) (fx : fixDenote T dt) : T -> stri ...@@ -157,15 +157,15 @@ Definition print T dt (pr : print_datatype dt) (fx : fixDenote T dt) : T -> stri
++ foldr (fun s acc => ", " ++ s ++ acc) ")" r) pr). ++ foldr (fun s acc => ", " ++ s ++ acc) ")" r) pr).
(* end thide *) (* 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.
Eval compute in print (^ "true" (fun _ => "") Eval compute in print (^ "true" (fun _ => "")
::: ^ "false" (fun _ => "") ::: ^ "false" (fun _ => "")
::: hnil) bool_fix. ::: HNil) bool_fix.
Definition print_nat := print (^ "O" (fun _ => "") Definition print_nat := print (^ "O" (fun _ => "")
::: ^ "S" (fun _ => "") ::: ^ "S" (fun _ => "")
::: hnil) nat_fix. ::: HNil) nat_fix.
Eval cbv beta iota delta -[append] in print_nat. Eval cbv beta iota delta -[append] in print_nat.
Eval simpl in print_nat 0. Eval simpl in print_nat 0.
Eval simpl in print_nat 1. Eval simpl in print_nat 1.
...@@ -174,11 +174,11 @@ Eval simpl in print_nat 2. ...@@ -174,11 +174,11 @@ Eval simpl in print_nat 2.
Eval cbv beta iota delta -[append] in fun A (pr : A -> string) => Eval cbv beta iota delta -[append] in fun A (pr : A -> string) =>
print (^ "nil" (fun _ => "") print (^ "nil" (fun _ => "")
::: ^ "cons" pr ::: ^ "cons" pr
::: hnil) (@list_fix A). ::: HNil) (@list_fix A).
Eval cbv beta iota delta -[append] in fun A (pr : A -> string) => Eval cbv beta iota delta -[append] in fun A (pr : A -> string) =>
print (^ "Leaf" pr print (^ "Leaf" pr
::: ^ "Node" (fun _ => "") ::: ^ "Node" (fun _ => "")
::: hnil) (@tree_fix A). ::: HNil) (@tree_fix A).
(** ** Mapping *) (** ** Mapping *)
...@@ -225,16 +225,15 @@ Section ok. ...@@ -225,16 +225,15 @@ Section ok.
forall (R : Type) (cases : datatypeDenote R dt) forall (R : Type) (cases : datatypeDenote R dt)
c (m : member c dt) c (m : member c dt)
(x : nonrecursive c) (r : ilist T (recursive c)), (x : nonrecursive c) (r : ilist T (recursive c)),
fx R cases ((hget dd m) x r) fx cases ((hget dd m) x r)
= (hget cases m) x (imap (fx R cases) r). = (hget cases m) x (imap (fx cases) r).
End ok. End ok.
Implicit Arguments datatypeDenoteOk [T dt]. Implicit Arguments datatypeDenoteOk [T dt].
Lemma foldr_plus : forall n (ils : ilist nat n), Lemma foldr_plus : forall n (ils : ilist nat n),
foldr plus 1 ils > 0. foldr plus 1 ils > 0.
induction n; crush. induction ils; crush.
generalize (IHn b); crush.
Qed. Qed.
(* end thide *) (* end thide *)
...@@ -265,12 +264,11 @@ Theorem map_id : forall T dt ...@@ -265,12 +264,11 @@ Theorem map_id : forall T dt
end; crush. end; crush.
induction (recursive c); crush. induction (recursive c); crush.
destruct r; reflexivity. dep_destruct r; reflexivity.
destruct r; crush. dep_destruct r; crush.
rewrite (H None). rewrite (H First).
unfold icons.
f_equal. f_equal.
apply IHn; crush. apply IHn; crush.
apply (H (Some i0)). apply (H (Next i)).
Qed. Qed.
(* end thide *) (* 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