From stdpp Require Import gmap base relations. From iris Require Import prelude. From semantics.lib Require Export debruijn. From semantics.ts.systemf Require Import lang notation types. From Equations Require Import Equations. (** * Big-step semantics *) Implicit Types (Δ : nat) (Γ : typing_context) (v : val) (α : var) (e : expr) (A : type). Inductive big_step : expr → val → Prop := | bs_lit (l : base_lit) : big_step (Lit l) (LitV l) | bs_lam (x : binder) (e : expr) : big_step (λ: x, e)%E (λ: x, e)%V | bs_binop e1 e2 v1 v2 v' op : big_step e1 v1 → big_step e2 v2 → bin_op_eval op v1 v2 = Some v' → big_step (BinOp op e1 e2) v' | bs_unop e v v' op : big_step e v → un_op_eval op v = Some v' → big_step (UnOp op e) v' | bs_app e1 e2 x e v2 v : big_step e1 (LamV x e) → big_step e2 v2 → big_step (subst' x (of_val v2) e) v → big_step (App e1 e2) v | bs_tapp e1 e2 v : big_step e1 (TLamV e2) → big_step e2 v → big_step (e1 <>) v | bs_tlam e : big_step (Λ, e)%E (Λ, e)%V | bs_pack e v : big_step e v → big_step (pack e)%E (pack v)%V | bs_unpack e1 e2 v1 v2 x : big_step e1 (pack v1)%V → big_step (subst' x (of_val v1) e2) v2 → big_step (unpack e1 as x in e2) v2 | bs_if_true e0 e1 e2 v : big_step e0 #true → big_step e1 v → big_step (if: e0 then e1 else e2) v | bs_if_false e0 e1 e2 v : big_step e0 #false → big_step e2 v → big_step (if: e0 then e1 else e2) v | bs_pair e1 e2 v1 v2 : big_step e1 v1 → big_step e2 v2 → big_step (e1, e2) (v1, v2) | bs_fst e v1 v2 : big_step e (v1, v2) → big_step (Fst e) v1 | bs_snd e v1 v2 : big_step e (v1, v2) → big_step (Snd e) v2 | bs_injl e v : big_step e v → big_step (InjL e) (InjLV v) | bs_injr e v : big_step e v → big_step (InjR e) (InjRV v) | bs_casel e e1 e2 v v' : big_step e (InjLV v) → big_step (e1 (of_val v)) v' → big_step (Case e e1 e2) v' | bs_caser e e1 e2 v v' : big_step e (InjRV v) → big_step (e2 (of_val v)) v' → big_step (Case e e1 e2) v' . #[export] Hint Constructors big_step : core. #[export] Hint Constructors base_step : core. #[export] Hint Constructors contextual_step : core. Lemma fill_rtc_contextual_step {e1 e2} K : rtc contextual_step e1 e2 → rtc contextual_step (fill K e1) (fill K e2). Proof. induction 1 as [ | x y z H1 H2 IH]; first done. etrans; last apply IH. econstructor 2; last constructor 1. by apply fill_contextual_step. Qed. Lemma big_step_contextual e v : big_step e v → rtc contextual_step e (of_val v). Proof. induction 1 as [ | | e1 e2 v1 v2 v' op H1 IH1 H2 IH2 Hop | e v v' op H1 IH1 Hop | e1 e2 x e v2 v H1 IH1 H2 IH2 H3 IH3 | e1 e2 v1 H1 IH1 H2 IH2 | | | e1 e2 v1 v2 x H1 IH1 H2 IH2 | e0 e1 e2 v H1 IH1 H2 IH2 | e0 e1 e2 v H1 IH1 H2 IH2| e1 e2 v1 v2 H1 IH1 H2 IH2 | e v1 v2 H IH | e v1 v2 H IH | e v H IH | e v H IH | e e1 e2 v v' H1 IH1 H2 IH2 | e e1 e2 v v' H1 IH1 H2 IH2 ]. - constructor. - constructor. - (* binop *) etrans. { eapply (fill_rtc_contextual_step (BinOpRCtx _ _ HoleCtx)). apply IH2. } etrans. { eapply (fill_rtc_contextual_step (BinOpLCtx _ HoleCtx _)). apply IH1. } simpl. etrans. { econstructor 2; last econstructor 1. apply base_contextual_step. econstructor; last done. all: apply to_of_val. } constructor. - (* unop *) etrans. { eapply (fill_rtc_contextual_step (UnOpCtx _ HoleCtx)). apply IH1. } simpl. etrans. { econstructor 2; last econstructor 1. apply base_contextual_step. econstructor; last done. all: apply to_of_val. } constructor. - etrans. { eapply (fill_rtc_contextual_step (AppRCtx _ HoleCtx)). apply IH2. } etrans. { eapply (fill_rtc_contextual_step (AppLCtx HoleCtx _)). apply IH1. } simpl. etrans. { econstructor 2; last econstructor 1. apply base_contextual_step. constructor; [| reflexivity]. apply is_val_of_val. } apply IH3. - etrans. { eapply (fill_rtc_contextual_step (TAppCtx HoleCtx)). apply IH1. } etrans. { econstructor 2; last constructor. apply base_contextual_step. by constructor. } done. - constructor. - etrans. { eapply (fill_rtc_contextual_step (PackCtx HoleCtx)). done. } done. - etrans. { eapply (fill_rtc_contextual_step (UnpackCtx x HoleCtx e2)). done. } etrans. { econstructor 2; last constructor. apply base_contextual_step. simpl. constructor; last reflexivity. apply is_val_spec. rewrite to_of_val. eauto. } done. - etrans. { eapply (fill_rtc_contextual_step (IfCtx HoleCtx _ _)). done. } etrans. { econstructor; last constructor. eapply base_contextual_step. econstructor. } done. - etrans. { eapply (fill_rtc_contextual_step (IfCtx HoleCtx _ _)). done. } etrans. { econstructor; last constructor. eapply base_contextual_step. econstructor. } done. - etrans. { eapply (fill_rtc_contextual_step (PairRCtx e1 HoleCtx)). done. } etrans. { eapply (fill_rtc_contextual_step (PairLCtx HoleCtx v2)). done. } econstructor. - etrans. { eapply (fill_rtc_contextual_step (FstCtx HoleCtx)). done. } econstructor. { eapply base_contextual_step. simpl. constructor; apply is_val_of_val. } econstructor. - etrans. { eapply (fill_rtc_contextual_step (SndCtx HoleCtx)). done. } econstructor. { eapply base_contextual_step. simpl. constructor; apply is_val_of_val. } econstructor. - etrans. { eapply (fill_rtc_contextual_step (InjLCtx HoleCtx)). done. } econstructor. - etrans. { eapply (fill_rtc_contextual_step (InjRCtx HoleCtx)). done. } econstructor. - etrans. { eapply (fill_rtc_contextual_step (CaseCtx HoleCtx e1 e2)). done. } simpl. econstructor. { eapply base_contextual_step. constructor. apply is_val_of_val. } done. - etrans. { eapply (fill_rtc_contextual_step (CaseCtx HoleCtx e1 e2)). done. } simpl. econstructor. { eapply base_contextual_step. constructor. apply is_val_of_val. } done. Qed. Lemma big_step_of_val e v : e = of_val v → big_step e v. Proof. intros ->. induction v; simpl; eauto. Qed. Lemma big_step_val v v' : big_step (of_val v) v' → v' = v. Proof. enough (∀ e, big_step e v' → e = of_val v → v' = v) by naive_solver. intros e Hb. induction Hb in v |-*; intros Heq; subst; destruct v; inversion Heq; subst; naive_solver. Qed. Lemma big_step_preserve_closed e v : is_closed [] e → big_step e v → is_closed [] v. Proof. intros Hcl. induction 1; try done. all: simpl in Hcl; repeat match goal with | H : Is_true (_ && _) |- _ => apply andb_True in H; destruct H end; try naive_solver. - (* binOP *) destruct v1 as [[] | | | | | |], v2 as [[] | | | | | |]; simpl in H1; try congruence. destruct op; simpl in H1; inversion H1; done. - (* unop *) destruct v as [[] | | | | | |]; destruct op; simpl in H0; inversion H0; done. - (* app *) apply IHbig_step3. apply is_closed_do_subst'; naive_solver. - (* unpack *) apply IHbig_step2. apply is_closed_do_subst'; naive_solver. Qed.