|
|
|
@ -19,18 +19,20 @@ Implicit Types
|
|
|
|
|
You may use the results from this exercise, in particular the fixpoint combinator and its typing, in other exercises, however (which is why it comes first in this Coq file).
|
|
|
|
|
*)
|
|
|
|
|
Section recursion_combinator.
|
|
|
|
|
Variable (f x: string). (* the template of the recursive function *)
|
|
|
|
|
Variable (f F x: string). (* the template of the recursive function *)
|
|
|
|
|
Hypothesis (Hfx: f ≠ x).
|
|
|
|
|
Hypothesis (HFx: F ≠ x).
|
|
|
|
|
Hypothesis (HfF: f ≠ F).
|
|
|
|
|
|
|
|
|
|
(** Recursion Combinator *)
|
|
|
|
|
(* First, setup a definition [Rec] satisfying the reduction lemmas below. *)
|
|
|
|
|
|
|
|
|
|
(** You may find an auxiliary definition [rec_body] helpful *)
|
|
|
|
|
Definition rec_body (t : expr): expr :=
|
|
|
|
|
roll (λ: f x, #0). (* TODO *)
|
|
|
|
|
roll (λ: f, t (λ: x, (unroll f) f x)).
|
|
|
|
|
|
|
|
|
|
Definition Rec (t: expr): val :=
|
|
|
|
|
λ: x, rec_body t. (* TODO *)
|
|
|
|
|
λ: x, (unroll (rec_body t)) (rec_body t) x.
|
|
|
|
|
|
|
|
|
|
Lemma closed_rec_body t :
|
|
|
|
|
is_closed [] t → is_closed [] (rec_body t).
|
|
|
|
@ -42,8 +44,30 @@ Section recursion_combinator.
|
|
|
|
|
is_val (Rec t).
|
|
|
|
|
Proof. done. Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma bnamed_eq {A : Type} {a b : string} {g h : A} :
|
|
|
|
|
(if decide (BNamed a = BNamed b) then g else h) = if decide (a = b) then g else h.
|
|
|
|
|
Proof.
|
|
|
|
|
induction (decide (a = b)) as [H | H].
|
|
|
|
|
rewrite H.
|
|
|
|
|
rewrite decide_True; reflexivity.
|
|
|
|
|
rewrite decide_False; first reflexivity.
|
|
|
|
|
intro H2.
|
|
|
|
|
injection H2.
|
|
|
|
|
tauto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Ltac is_val_to_val v H :=
|
|
|
|
|
rewrite (is_val_spec _) in H; destruct H as [v H]; apply of_to_val in H; symmetry in H.
|
|
|
|
|
|
|
|
|
|
(*
|
|
|
|
|
(Rec t) e = (λx. (unroll (rec' t)) (rec' t) x) e
|
|
|
|
|
~> (unroll (rec' t)) (rec' t) e
|
|
|
|
|
~> (λ f, t (λ x, (unroll f) f x)) (rec' t) e
|
|
|
|
|
~> (t (λ x, (unroll (rec' t)) (rec' t) x)) e
|
|
|
|
|
= (t (Rec t) e)
|
|
|
|
|
|
|
|
|
|
Do not attempt to understand what is going on in the proof, this clearly isn't meant to be solved by humans.
|
|
|
|
|
*)
|
|
|
|
|
Lemma Rec_red (t e: expr):
|
|
|
|
|
is_val e →
|
|
|
|
|
is_val t →
|
|
|
|
@ -51,10 +75,55 @@ Section recursion_combinator.
|
|
|
|
|
is_closed [] t →
|
|
|
|
|
rtc contextual_step ((Rec t) e) (t (Rec t) e).
|
|
|
|
|
Proof.
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
have Hxf : x ≠ f.
|
|
|
|
|
symmetry; assumption.
|
|
|
|
|
intros.
|
|
|
|
|
|
|
|
|
|
eapply rtc_l.
|
|
|
|
|
eapply base_contextual_step.
|
|
|
|
|
econstructor; [assumption | reflexivity].
|
|
|
|
|
simpl.
|
|
|
|
|
repeat rewrite bnamed_eq.
|
|
|
|
|
repeat (rewrite (decide_False (P := x = f)); last auto).
|
|
|
|
|
repeat (rewrite (decide_True (P := x = x)); last reflexivity).
|
|
|
|
|
rewrite subst_is_closed_nil; last assumption.
|
|
|
|
|
|
|
|
|
|
is_val_to_val v H; subst.
|
|
|
|
|
|
|
|
|
|
eapply rtc_l.
|
|
|
|
|
eapply (Ectx_step _ _ [
|
|
|
|
|
AppLCtx (RollV (λ: (BNamed f),
|
|
|
|
|
App t (λ: (BNamed x),
|
|
|
|
|
App (App (unroll Var f) (Var f)) (Var x)
|
|
|
|
|
))
|
|
|
|
|
);
|
|
|
|
|
AppLCtx v
|
|
|
|
|
]).
|
|
|
|
|
reflexivity.
|
|
|
|
|
reflexivity.
|
|
|
|
|
econstructor.
|
|
|
|
|
eauto.
|
|
|
|
|
simpl.
|
|
|
|
|
|
|
|
|
|
eapply rtc_l.
|
|
|
|
|
eapply (Ectx_step _ _ [
|
|
|
|
|
AppLCtx v
|
|
|
|
|
]).
|
|
|
|
|
reflexivity.
|
|
|
|
|
reflexivity.
|
|
|
|
|
econstructor.
|
|
|
|
|
eauto.
|
|
|
|
|
reflexivity.
|
|
|
|
|
|
|
|
|
|
simpl.
|
|
|
|
|
repeat rewrite bnamed_eq.
|
|
|
|
|
repeat (rewrite (decide_False (P := f = x)); last auto).
|
|
|
|
|
repeat (rewrite (decide_True (P := f = f)); last reflexivity).
|
|
|
|
|
rewrite subst_is_closed_nil; last assumption.
|
|
|
|
|
reflexivity.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Search (?A ⊆ <[?f := ?x]> ?A).
|
|
|
|
|
Lemma rec_body_typing n Γ (A B: type) t :
|
|
|
|
|
Γ !! x = None →
|
|
|
|
|
Γ !! f = None →
|
|
|
|
@ -63,8 +132,20 @@ Section recursion_combinator.
|
|
|
|
|
TY n; Γ ⊢ t : ((A → B) → (A → B)) →
|
|
|
|
|
TY n; Γ ⊢ rec_body t : (μ: #0 → rename (+1) A → rename (+1) B).
|
|
|
|
|
Proof.
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
intros x_notin_Γ f_notin_Γ A_wf B_wf Hty_t.
|
|
|
|
|
unfold rec_body.
|
|
|
|
|
solve_typing.
|
|
|
|
|
simpl.
|
|
|
|
|
asimpl.
|
|
|
|
|
eapply typed_weakening; [exact Hty_t | simplify_list_subseteq | reflexivity ].
|
|
|
|
|
|
|
|
|
|
(* Love the consistency in the naming here: *)
|
|
|
|
|
apply insert_subseteq; assumption.
|
|
|
|
|
asimpl; apply lookup_insert.
|
|
|
|
|
|
|
|
|
|
apply type_wf_rename; [ assumption | intros; simpl; lia ].
|
|
|
|
|
apply type_wf_rename; [ assumption | intros; simpl; lia ].
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma Rec_typing n Γ A B t:
|
|
|
|
@ -75,6 +156,8 @@ Section recursion_combinator.
|
|
|
|
|
TY n; Γ ⊢ t : ((A → B) → (A → B)) →
|
|
|
|
|
TY n; Γ ⊢ (Rec t) : (A → B).
|
|
|
|
|
Proof.
|
|
|
|
|
intros.
|
|
|
|
|
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
|
|
|
|
@ -128,24 +211,34 @@ Admitted.
|
|
|
|
|
|
|
|
|
|
(** ** Exercise 1: Encode arithmetic expressions *)
|
|
|
|
|
|
|
|
|
|
Definition aexpr : type := #0 (* TODO *).
|
|
|
|
|
(*
|
|
|
|
|
int, addition, multiplication:
|
|
|
|
|
(int + (aexpr × aexpr) + (aexpr × aexpr))
|
|
|
|
|
|
|
|
|
|
Definition num_val (v : val) : val := #0 (* TODO *).
|
|
|
|
|
Definition num_expr (e : expr) : expr := #0 (* TODO *).
|
|
|
|
|
(int + ((μα. α × α) + (μα. α × α)))
|
|
|
|
|
*)
|
|
|
|
|
Definition aexpr : type := (μ:
|
|
|
|
|
(Int + (
|
|
|
|
|
(#0 × #0)
|
|
|
|
|
+ (#0 × #0)
|
|
|
|
|
)))
|
|
|
|
|
.
|
|
|
|
|
|
|
|
|
|
Definition plus_val (v1 v2 : val) : val := #0 (* TODO *).
|
|
|
|
|
Definition plus_expr (e1 e2 : expr) : expr := #0 (* TODO *).
|
|
|
|
|
Definition num_val (v : val) : val := RollV (InjLV v).
|
|
|
|
|
Definition num_expr (e : expr) : expr := Roll (InjL e).
|
|
|
|
|
|
|
|
|
|
Definition mul_val (v1 v2 : val) : val := #0 (* TODO *).
|
|
|
|
|
Definition mul_expr (e1 e2 : expr) : expr := #0 (* TODO *).
|
|
|
|
|
Definition plus_val (v1 v2 : val) : val := RollV (InjRV (InjLV (PairV v1 v2))).
|
|
|
|
|
Definition plus_expr (e1 e2 : expr) : expr := Roll (InjR (InjL (Pair e1 e2))).
|
|
|
|
|
|
|
|
|
|
Definition mul_val (v1 v2 : val) : val := RollV (InjRV (InjRV (PairV v1 v2))).
|
|
|
|
|
Definition mul_expr (e1 e2 : expr) : expr := Roll (InjR (InjR (Pair e1 e2))).
|
|
|
|
|
|
|
|
|
|
Lemma num_expr_typed n Γ e :
|
|
|
|
|
TY n; Γ ⊢ e : Int →
|
|
|
|
|
TY n; Γ ⊢ num_expr e : aexpr.
|
|
|
|
|
Proof.
|
|
|
|
|
intros. solve_typing.
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma plus_expr_typed n Γ e1 e2 :
|
|
|
|
@ -153,9 +246,8 @@ Lemma plus_expr_typed n Γ e1 e2 :
|
|
|
|
|
TY n; Γ ⊢ e2 : aexpr →
|
|
|
|
|
TY n; Γ ⊢ plus_expr e1 e2 : aexpr.
|
|
|
|
|
Proof.
|
|
|
|
|
(*intros; solve_typing.*)
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
intros; solve_typing.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma mul_expr_typed n Γ e1 e2 :
|
|
|
|
@ -163,19 +255,27 @@ Lemma mul_expr_typed n Γ e1 e2 :
|
|
|
|
|
TY n; Γ ⊢ e2 : aexpr →
|
|
|
|
|
TY n; Γ ⊢ mul_expr e1 e2 : aexpr.
|
|
|
|
|
Proof.
|
|
|
|
|
(*intros; solve_typing.*)
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
intros; solve_typing.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition eval_aexpr : val :=
|
|
|
|
|
#0. (* TODO *)
|
|
|
|
|
Definition eval_aexpr : val := (fix: "eval" "x" := (
|
|
|
|
|
match: (Unroll "x") with
|
|
|
|
|
InjL "int" => "int"
|
|
|
|
|
| InjR "bin" => (match: "bin" with
|
|
|
|
|
InjL "add" => "eval" (Fst "add") + "eval" (Snd "add")
|
|
|
|
|
| InjR "mul" => "eval" (Fst "mul") * "eval" (Snd "mul")
|
|
|
|
|
end
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
)).
|
|
|
|
|
|
|
|
|
|
Lemma eval_aexpr_typed Γ n :
|
|
|
|
|
TY n; Γ ⊢ eval_aexpr : (aexpr → Int).
|
|
|
|
|
Proof.
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
apply fix_typing; [solve_typing | solve_typing | auto | ].
|
|
|
|
|
solve_typing.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -187,9 +287,18 @@ Definition list_t (A : type) : type :=
|
|
|
|
|
× (∀: #1 → #0 → (A.[ren (+2)] → #1 → #0) → #0)) (* mylistcase *)
|
|
|
|
|
.
|
|
|
|
|
|
|
|
|
|
Definition mylist_impl : val :=
|
|
|
|
|
#0 (* TODO *)
|
|
|
|
|
.
|
|
|
|
|
Definition mylist_impl : val := PackV (
|
|
|
|
|
(#0, (LitV LitUnit)),
|
|
|
|
|
(λ: "a" "l", (#1 + (Fst "l"), ("a", (Snd "")))),
|
|
|
|
|
(Λ, λ: "l" "zero" "cb",
|
|
|
|
|
(* (fix "rec" "l" := *)
|
|
|
|
|
if: (Fst "l") = #0 then
|
|
|
|
|
"zero"
|
|
|
|
|
else
|
|
|
|
|
"cb" (Fst (Snd "l")) (Snd (Snd "l"))
|
|
|
|
|
(* ) "l1" *)
|
|
|
|
|
)
|
|
|
|
|
).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -199,4 +308,3 @@ Lemma mylist_impl_sem_typed A :
|
|
|
|
|
Proof.
|
|
|
|
|
(* TODO: exercise *)
|
|
|
|
|
Admitted.
|
|
|
|
|
|
|
|
|
|