| (* Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| * for details. All rights reserved. Use of this source code is governed by a |
| * BSD-style license that can be found in the LICENSE file. *) |
| |
| |
| Require Import Coq.Lists.SetoidList. |
| Require Import Coq.Init.Wf. |
| Require Import Omega. |
| |
| Require Import Common. |
| Require Import Syntax. |
| Require Import ObjectModel. |
| Require Import OperationalSemantics. |
| |
| Import Common.NatMapFacts. |
| Import Common.MoreNatMapFacts. |
| Import ObjectModel.Subtyping. |
| |
| |
| Section OperationalSemanticsSpec. |
| |
| |
| (** The well-formedness hypothesis is that the environments are built via |
| [lib_to_env] function from the object model module. [program_wf] theorem |
| defined there provides the rest of the well-formedness properties. *) |
| Variable L : library. |
| Variable CE : class_env. |
| Variable ME : member_env. |
| |
| Hypothesis program_wf_hyp: lib_to_env L = (CE, ME). |
| |
| |
| (** Auxiliary well-formedness hypothesis that should be a corollary of |
| [program_wf_hyp], but requires additional facts about the object model to be |
| proven. *) |
| Inductive ref_in_intf : nat -> interface -> Prop := |
| |
| | RI_Method : |
| forall ref proc_desc intf, |
| List.In proc_desc (procedures intf) -> |
| ref_in_dart_type ref (DT_Function_Type (pr_type proc_desc)) -> |
| ref_in_intf ref intf |
| |
| | RI_Getter : |
| forall ref get_desc intf, |
| List.In get_desc (getters intf) -> |
| ref_in_dart_type ref (gt_type get_desc) -> |
| ref_in_intf ref intf. |
| |
| Hypothesis intf_refs_wf: |
| forall class_id intf ref, |
| NatMap.MapsTo class_id intf CE -> |
| ref_in_intf ref intf -> |
| NatMap.In ref CE. |
| |
| |
| (** Yet another hypothesis about well-formedness of getters. *) |
| Hypothesis program_getters_wf: |
| forall class_id intf get_desc, |
| NatMap.MapsTo class_id intf CE -> |
| List.In get_desc (getters intf) -> |
| NatMap.In (gt_ref get_desc) ME. |
| |
| |
| Lemma runtime_value_interface_procedures_wf : |
| forall val intf type_opt proc_desc, |
| value_of_type CE ME val intf type_opt -> |
| List.In proc_desc (procedures intf) -> |
| NatMap.In (pr_ref proc_desc) ME. |
| Proof. |
| intros. destruct H. |
| |
| (* Case 1. Value of Interface Type. *) |
| pose proof (program_wf L CE ME class_id intf proc_desc program_wf_hyp). |
| apply H3. |
| apply NatMapFacts.find_mapsto_iff. auto. |
| auto. |
| |
| (* Case 2. Value of Function Type. *) |
| rewrite H in H0. |
| pose proof (List.in_inv H0). |
| destruct H4. |
| rewrite <- H4. simpl. apply MoreNatMapFacts.maps_in_mapsto. |
| apply MoreNatMapFacts.maps_mapsto_in. exists (M_Procedure proc). |
| auto. |
| pose proof (List.in_nil H4). contradiction. |
| |
| (* Case 3. Null Value. *) |
| rewrite H in H0. pose proof (List.in_nil H0). contradiction. |
| Qed. |
| |
| |
| Lemma method_exists_desc : |
| forall type name, |
| method_exists CE ME type name -> |
| (* TODO(dmitryas): Replace `value_of_type` here with a relation that binds |
| together the interface and the type, avoiding the construction of the |
| value. *) |
| exists intf desc, |
| (value_of_type CE ME (mk_runtime_value type) intf type /\ |
| List.In desc (procedures intf) /\ |
| ((pr_name desc) = name)%string). |
| Proof. |
| intros. destruct H; ( |
| |
| (* Cases of Interface Type and Function Type are analogous. *) |
| exists intf, desc; split; auto |
| |
| ). |
| Qed. |
| |
| |
| Lemma subtype_means_equals : |
| forall type_pair, subtype type_pair = true -> fst type_pair = snd type_pair. |
| Proof. |
| intro. |
| apply well_founded_ind with (R := pair_size_order) (a := type_pair). |
| apply pair_size_order_wf. |
| intros. |
| |
| assert ((fst x) <: (snd x)). |
| destruct x. simpl. auto. |
| destruct (fst x) eqn:?. destruct (snd x) eqn:?. |
| (* t1 : Interface Type, t2 : Interface Type. *) |
| simplify_subtypes. |
| apply N.eqb_eq in H1. rewrite H1. reflexivity. |
| (* t1 : Interface Type, t2 : Function Type. *) |
| simplify_subtypes. |
| destruct (snd x) eqn :?. |
| (* t1 : Function Type, t2 : Interface Type. *) |
| simplify_subtypes. |
| (* t1 : Function Type, t2 : Function Type. *) |
| simplify_subtypes. |
| apply andb_true_iff in H1. destruct H1. |
| assert (d = d1). |
| apply H with (y := (d, d1)). |
| unfold pair_size_order. destruct x. |
| simpl in Heqd. simpl in Heqd0. rewrite Heqd, Heqd0. |
| unfold pair_size. simpl. |
| omega. |
| auto. |
| assert (d2 = d0). |
| apply H with (y := (d2, d0)). |
| unfold pair_size_order. destruct x. |
| simpl in Heqd. simpl in Heqd0. rewrite Heqd, Heqd0. |
| unfold pair_size. simpl. |
| omega. |
| auto. |
| rewrite H3, H4. |
| reflexivity. |
| Qed. |
| |
| |
| Lemma structural_subtype_methods : |
| forall type1 type2 name, |
| method_exists CE ME (Some type1) name -> |
| type2 <: type1 -> |
| method_exists CE ME (Some type2) name. |
| Proof. |
| intros. |
| apply subtype_means_equals in H0. simpl in H0. rewrite H0. auto. |
| Qed. |
| |
| |
| Lemma structural_subtype_getters : |
| forall type1 type2 name, |
| getter_exists CE ME (Some type1) name -> |
| type2 <: type1 -> |
| getter_exists CE ME (Some type2) name. |
| Proof. |
| intros. |
| apply subtype_means_equals in H0. simpl in H0. rewrite H0. auto. |
| Qed. |
| |
| |
| Theorem step_configuration_wf : |
| forall conf1, configuration_wf CE ME conf1 -> |
| exists conf2, step CE ME conf1 conf2. |
| Proof. |
| intros. |
| |
| (* Construct the second configuration from the preconditions of |
| well-formedness of the first configuration. *) |
| destruct H. |
| |
| (* Case 1. Eval Variable Get. *) |
| unfold env_in in H. |
| destruct ( |
| List.find |
| (fun entry : env_entry => Nat.eqb var (var_ref entry)) |
| env |
| ) eqn:?; try contradiction. |
| exists (Value_Passing_Configuration ret_cont (value e)). |
| constructor. |
| unfold env_get. auto. |
| |
| (* Case 2. Eval Method Invocation. *) |
| exists |
| (Eval_Configuration rcvr_expr env |
| (Expression_Continuation |
| (Method_Invocation_Ek name arg_expr env ret_cont) |
| rcvr_type)). |
| constructor. auto. |
| |
| (* Case 3. Eval Property Get. *) |
| exists |
| (Eval_Configuration rcvr_expr env |
| (Expression_Continuation |
| (Property_Get_Ek name ret_cont) |
| rcvr_type)). |
| constructor. auto. |
| |
| (* Case 4. Eval Constructor Invocation. *) |
| pose proof (MoreNatMapFacts.maps_in_mapsto interface CE class_id H). |
| destruct H0 as (intf & H1). |
| set (type := DT_Interface_Type (Interface_Type class_id)). |
| set (new_val := mk_runtime_value (Some type)). |
| exists (Value_Passing_Configuration ret_cont new_val). |
| constructor 14 with (intf := intf) (type_opt := Some type); try auto. |
| constructor 1 with (class_id := class_id); try (simpl; auto). |
| apply NatMapFacts.find_mapsto_iff. auto. |
| |
| (* Case 6. Exec Variable Declaration with Initializer. *) |
| exists |
| (Eval_Configuration init_expr env |
| (Expression_Continuation |
| (Var_Declaration_Ek var var_type env next_cont) |
| init_type)). |
| constructor. auto. |
| |
| (* Case 7. Exec Variable Declaration without Initializer. *) |
| set (null_val := mk_runtime_value None). |
| set (env' := env_extend var var_type null_val env). |
| exists (Forward_Configuration next_cont env'). |
| constructor 15 with (null_val := null_val). |
| constructor 3. simpl. congruence. |
| simpl. congruence. |
| trivial. trivial. |
| |
| (* Case 8. Exec Return Statement. *) |
| exists (Eval_Configuration expr env ret_cont). |
| constructor. |
| |
| (* Case 9. Exec Expression Statement. *) |
| exists |
| (Eval_Configuration expr env |
| (Expression_Continuation |
| (Expression_Ek env ret_cont next_cont) |
| expr_type)). |
| constructor. auto. |
| |
| (* Case 10. Exec Block. *) |
| destruct stmts eqn:?. |
| |
| (* Case 10.1. Exec Empty Block. *) |
| exists (Forward_Configuration next_cont env). |
| constructor. |
| |
| (* Case 10.2. Exec Non-Empty Block. *) |
| exists (Exec_Configuration s env ret_cont |
| (Block_Sk l env ret_cont next_cont)). |
| constructor. |
| |
| (* Case 11. Pass Value to MethodInvocationEK. *) |
| exists |
| (Eval_Configuration arg_expr env |
| (Expression_Continuation |
| (Invocation_Ek rcvr_val name env ret_cont) |
| arg_type)). |
| constructor 9 with (rcvr_type := rcvr_type). auto. auto. |
| |
| (* Case 12. Pass Value to InvocationEK. *) |
| pose proof (method_exists_desc (runtime_type rcvr_val) name H). |
| destruct H0 as (intf & desc & H1). destruct H1. destruct H1. |
| pose proof |
| (runtime_value_interface_procedures_wf |
| (mk_runtime_value (runtime_type rcvr_val)) |
| intf (runtime_type rcvr_val) desc H0). |
| pose proof (H3 H1). |
| apply MoreNatMapFacts.maps_in_mapsto in H4. |
| destruct H4 as (mbr & H5). destruct mbr eqn:?. destruct p eqn:?. |
| destruct f eqn:?. destruct v eqn:?. |
| set (env' := env_extend n0 d0 arg_val empty_env). |
| set (null_val := mk_runtime_value None). |
| set (next_cont := Exit_Sk ret_cont null_val). |
| exists (Exec_Configuration s env' ret_cont next_cont). |
| constructor 10 with |
| (rcvr_intf := intf) |
| (rcvr_type_opt := (runtime_type rcvr_val)) |
| (proc_desc := desc) |
| (func_node := f) |
| (var_id := n0) |
| (var_type := d0) |
| (var_init := o) |
| (ret_type := d) |
| (null_val := null_val) |
| (memb_data := m) |
| (named_data := n). |
| destruct rcvr_val. simpl. simpl in H0. auto. |
| auto. |
| rewrite Heqf0; auto. |
| auto. |
| trivial. |
| trivial. |
| constructor; simpl; congruence. |
| |
| (* Case 13. Pass Value to PropertyGetEK. *) |
| set (type := runtime_type rcvr_val). |
| assert (mk_runtime_value type = rcvr_val). |
| destruct rcvr_val. subst type. simpl. congruence. |
| destruct H0. |
| destruct (gt_type desc) eqn:?. |
| |
| (* Case 13.1. Getting a Value of Interface Type from a Value of Interface |
| Type. *) |
| assert (runtime_type rcvr_val = type). |
| rewrite <- H1. simpl. auto. |
| subst type. rewrite H1 in H2. rewrite H0 in H2. |
| destruct H2 eqn:?; |
| try (rewrite e1 in H5; rewrite H0 in H5; discriminate H5). |
| assert (type0 = type). |
| rewrite e1 in H5. injection H5. intros. auto. |
| destruct i eqn:?. |
| assert (NatMap.In n CE). |
| apply intf_refs_wf with (class_id := class_id0) (intf := intf) (ref := n). |
| apply NatMapFacts.find_mapsto_iff. auto. |
| constructor 2 with (get_desc := desc). |
| auto. |
| rewrite Heqd. constructor. |
| pose proof (MoreNatMapFacts.maps_in_mapsto interface CE n H7). |
| destruct H8 as (el & H9). |
| set (ret_type := DT_Interface_Type (Interface_Type n)). |
| set (ret_intf := el). |
| set (ret_val := mk_runtime_value (Some ret_type)). |
| exists (Value_Passing_Configuration ret_cont ret_val). |
| constructor 12 with |
| (rcvr_intf := intf) |
| (rcvr_type_opt := Some type) |
| (memb_id := gt_ref desc) |
| (ret_intf := ret_intf) |
| (ret_type := ret_type). |
| auto. |
| set (get_desc_alt := mk_getter_desc name (gt_ref desc) ret_type). |
| assert (desc = get_desc_alt). |
| destruct desc. subst get_desc_alt. simpl. |
| simpl in H4. rewrite H4. |
| simpl in Heqd. rewrite Heqd. subst ret_type. |
| congruence. |
| rewrite <- H8. |
| auto. |
| constructor 1 with (class_id := n). |
| auto. |
| apply NatMapFacts.find_mapsto_iff. subst ret_intf. auto. |
| simpl. congruence. |
| |
| (* Case 13.2. Getting a Value of Function Type from a Value of Interface |
| Type. *) |
| set (ret_type := DT_Function_Type f). |
| set (ret_intf := mk_interface |
| ((mk_procedure_desc "call" (gt_ref desc) f) :: nil) |
| ((mk_getter_desc "call" (gt_ref desc) (DT_Function_Type f)) :: nil)). |
| set (ret_val := mk_runtime_value (Some ret_type)). |
| |
| assert (runtime_type rcvr_val = Some type0). |
| subst type. rewrite <- H1. simpl. auto. |
| subst type. rewrite H1 in H2. rewrite H0 in H2. |
| destruct H2 eqn:?; |
| try (rewrite e1 in H5; rewrite H0 in H5; discriminate H5). |
| assert (type0 = type). |
| rewrite e1 in H5. injection H5. intros. auto. |
| assert (class_id0 = class_id). |
| rewrite e in H6. rewrite H0 in H6. |
| injection H6. intros. auto. |
| |
| exists (Value_Passing_Configuration ret_cont ret_val). |
| constructor 12 with |
| (rcvr_intf := intf) |
| (rcvr_type_opt := Some type) |
| (memb_id := gt_ref desc) |
| (ret_intf := ret_intf) |
| (ret_type := ret_type). |
| constructor 1 with (class_id := class_id0); auto. |
| |
| set (get_desc_alt := mk_getter_desc name (gt_ref desc) ret_type). |
| assert (desc = get_desc_alt). |
| destruct desc. subst get_desc_alt. simpl. |
| simpl in H4. rewrite H4. |
| simpl in Heqd. rewrite Heqd. subst ret_type. |
| congruence. |
| rewrite <- H8. auto. |
| |
| clear Heqv. |
| destruct H2; |
| try (rewrite e1 in H5; rewrite H0 in H5; discriminate H5). |
| apply NatMapFacts.find_mapsto_iff in e0. |
| pose proof (program_getters_wf class_id0 intf desc e0). |
| pose proof (H10 H3). |
| apply MoreNatMapFacts.maps_in_mapsto in H11. |
| destruct H11 as (mbr & H12). |
| |
| destruct mbr. |
| constructor 2 with (memb_id := gt_ref desc) (proc := p). |
| simpl. congruence. |
| simpl. congruence. |
| auto. |
| simpl. subst ret_type. congruence. |
| |
| (* Case 13.3. Getting a Value from a Value of Function Type. *) |
| subst type. rewrite H1 in H2. rewrite H in H2. |
| destruct H2 eqn:?; try ( |
| clear Heqv; |
| rewrite <- H1 in e1; |
| simpl in e1; |
| rewrite H0 in e1; |
| rewrite e in e1; |
| discriminate e1 |
| ). |
| |
| assert (ftype0 = ftype). |
| rewrite H0 in H. injection H. intros. auto. |
| |
| exists (Value_Passing_Configuration ret_cont val). |
| constructor 12 with |
| (rcvr_intf := intf) |
| (rcvr_type_opt := Some type0) |
| (memb_id := gt_ref desc) |
| (ret_intf := intf) |
| (ret_type := type0). |
| rewrite H. auto. |
| |
| pose proof H2. |
| rewrite e0 in H3. |
| pose proof (List.in_inv H3). |
| destruct H7. |
| clear Heqv. rewrite H7 in H3. rewrite H7 in e0. rewrite <- H7. simpl. |
| rewrite <- e0 in H3. rewrite H5 in H7. rewrite <- H0 in H7. |
| rewrite H7. auto. |
| pose proof (List.in_nil H7). contradiction. |
| rewrite H0; rewrite <- H5; auto. |
| |
| (* Case 13.4. Getting a Value from Null. *) |
| rewrite e0 in H3. |
| pose proof (List.in_nil H3). |
| contradiction. |
| |
| (* Case 9. Forward. *) |
| destruct next_cont. |
| |
| (* Case 9.1. Forward to Exit. *) |
| exists (Value_Passing_Configuration e r). |
| constructor. |
| |
| (* Case 9.2. Forward to the Next Statement in Block. *) |
| destruct l. |
| |
| (* Case 9.2.1. Block is Empty. *) |
| exists (Forward_Configuration next_cont e). |
| constructor. |
| |
| (* Case 9.2.2. Block is Non-Empty. *) |
| exists (Exec_Configuration s env e0 (Block_Sk l e e0 next_cont)). |
| constructor. |
| |
| (* Case 10. Pass Value to ExpressionEk. *) |
| exists (Forward_Configuration next_cont env). |
| constructor. |
| |
| (* Case 11. Pass Value to VarDeclarationEk. *) |
| set (env' := env_extend var var_type val env). |
| exists (Forward_Configuration next_cont env'). |
| constructor. |
| auto. |
| |
| (* Case 12. Pass Value to MethodInvocationEK: No Such Method. *) |
| exists |
| (Value_Passing_Configuration |
| (Expression_Continuation Halt_Ek rcvr_type) |
| (mk_runtime_value None)). |
| assert (rcvr_val = mk_runtime_value None). |
| destruct rcvr_val. simpl in H. rewrite H. reflexivity. |
| rewrite H0. |
| constructor 19. |
| |
| (* Case 13. Pass Value to PropertyGetEK: No Such Getter. *) |
| exists |
| (Value_Passing_Configuration |
| (Expression_Continuation Halt_Ek rcvr_type) |
| (mk_runtime_value None)). |
| assert (rcvr_val = mk_runtime_value None). |
| destruct rcvr_val. simpl in H. rewrite H. reflexivity. |
| rewrite H0. |
| constructor 20. |
| Qed. |
| |
| |
| Lemma configuration_valid_wf : |
| forall conf, configuration_valid CE ME conf -> configuration_wf CE ME conf. |
| Proof. |
| intros. destruct H. |
| |
| (* Case 1. Eval Configuration. *) |
| destruct H2. |
| |
| (* Case 1.1. Eval Variable Get. *) |
| constructor. auto. |
| |
| (* Case 1.2. Eval Property Get. *) |
| remember (E_Property_Get (Property_Get expr name)) as expr0. |
| destruct H3. |
| assert ( |
| exists rcvr_type, |
| expression_type CE (env_to_type_env env) expr = Some rcvr_type |
| ). |
| rewrite Heqexpr0 in H3. simpl in H3. |
| destruct (expression_type CE (env_to_type_env env) expr) eqn:?; |
| try discriminate H3. |
| exists d. reflexivity. |
| destruct H5 as (rcvr_type & H6). |
| rewrite Heqexpr0. destruct name. |
| constructor 3 with (rcvr_type := rcvr_type). |
| auto. |
| |
| (* Case 1.3. Eval Constructor Invocation. *) |
| constructor. |
| remember |
| (E_Invocation_Expression |
| (IE_Constructor_Invocation |
| (Constructor_Invocation class_id))) |
| as expr. |
| destruct H; try discriminate Heqexpr. |
| assert (ref = class_id). |
| injection Heqexpr. intros. auto. |
| rewrite <- H2. auto. |
| |
| (* Case 1.4. Eval Method Invocation. *) |
| remember |
| (E_Invocation_Expression |
| (IE_Method_Invocation |
| (Method_Invocation rcvr_expr name (Arguments arg_expr) ref))) |
| as expr. |
| destruct H3. |
| assert ( |
| exists rcvr_type, |
| expression_type CE (env_to_type_env env) rcvr_expr = Some rcvr_type |
| ). |
| rewrite Heqexpr in H2. simpl in H2. |
| destruct (expression_type CE (env_to_type_env env) rcvr_expr) eqn:?; |
| try discriminate H2. |
| exists d. reflexivity. |
| destruct H4 as (rcvr_type & H5). |
| rewrite Heqexpr. destruct name. |
| constructor 2 with (rcvr_type := rcvr_type). |
| auto. |
| |
| (* Case 2. Exec Configuration. *) |
| destruct H3. |
| |
| (* Case 2.1. Exec Expression Statement. *) |
| remember |
| (S_Expression_Statement |
| (Expression_Statement expr)) |
| as stmt. |
| destruct H4. |
| assert ( |
| exists expr_type, |
| expression_type CE (env_to_type_env env) expr = Some expr_type |
| ). |
| rewrite Heqstmt in H4. simpl in H4. |
| destruct (expression_type CE (env_to_type_env env) expr) eqn:?; |
| try discriminate H4. |
| exists d. auto. |
| destruct H6 as (expr_type & H7). |
| rewrite Heqstmt. |
| constructor 8 with (expr_type := expr_type). |
| auto. |
| |
| (* Case 2.2. Exec Empty Block. *) |
| constructor. |
| |
| (* Case 2.3. Exec Non-Empty Block. *) |
| constructor. |
| |
| (* Case 2.4. Exec Return Statement. *) |
| constructor. |
| |
| (* Case 2.5. Exec Variable Declaration without Initializer. *) |
| constructor. |
| |
| (* Case 2.6. Exec Variable Declaration with Initializer. *) |
| remember |
| (S_Variable_Declaration |
| (Variable_Declaration var type (Some init_expr))) |
| as stmt. |
| destruct H4. |
| assert ( |
| exists init_type, |
| expression_type CE (env_to_type_env env) init_expr = Some init_type |
| ). |
| rewrite Heqstmt in H4. simpl in H4. |
| destruct (expression_type CE (env_to_type_env env) init_expr) eqn:?; |
| try discriminate H4. |
| exists d. auto. |
| destruct H6 as (init_type & H7). |
| rewrite Heqstmt. |
| constructor 5 with (init_type := init_type). |
| auto. |
| |
| (* Case 3. Value Passing Configuration *) |
| destruct cont. destruct u. |
| |
| (* Case 3.1. Pass Value to ExpressionEK. *) |
| constructor. |
| |
| (* Case 3.2. Pass Value to MethodInvocationEK. *) |
| destruct (runtime_type val) eqn:?. |
| |
| (* Case 3.2.1. Non Null Value. Actual Invocation. *) |
| remember (Expression_Continuation (Method_Invocation_Ek s e e0 e1) d) |
| as econt. |
| destruct H; try discriminate Heqecont. |
| constructor 10 with (arg_type := arg_type) (rcvr_type := d0). |
| auto. |
| auto. |
| |
| (* Case 3.2.2. Null Value. No Such Method. *) |
| assert (val = mk_runtime_value None). |
| destruct val. simpl in Heqo. rewrite Heqo. reflexivity. |
| rewrite H2. |
| constructor. |
| rewrite <- H2. auto. |
| |
| (* Case 3.3. Pass Value to InvocationEK. *) |
| remember (Expression_Continuation (Invocation_Ek r s e e0) d) as econt. |
| destruct H; try discriminate Heqecont. |
| remember (runtime_type rcvr_val) as rcvr_val_type. |
| destruct H3; constructor; rewrite <- Heqrcvr_val_type; auto. |
| |
| (* Case 3.4. Pass Value to PropertyGetEK. *) |
| destruct (runtime_type val) eqn:?. |
| assert (val = mk_runtime_value (Some d0)). |
| destruct val. rewrite <- Heqo. simpl. reflexivity. |
| |
| (* Case 3.4.1. Non Null Value. Actual Invocation. *) |
| constructor 12 with (rcvr_type := d0). |
| auto. |
| rewrite H2. simpl. |
| remember (Expression_Continuation (Property_Get_Ek s e) d) as econt. |
| destruct H1; try discriminate Heqo. |
| assert (type = d0). injection Heqo. intros. auto. |
| rewrite H3 in *. |
| remember (Expression_Continuation cont expected_type) as econt. |
| destruct H; try discriminate Heqecont. |
| remember (Some rcvr_type) as rt. |
| destruct H4. |
| assert (rcvr_type0 = rcvr_type). injection Heqrt. intros. auto. |
| rewrite H11 in *. |
| assert (rcvr_type = expected_type). injection Heqecont0. intros. auto. |
| rewrite H12 in *. |
| apply structural_subtype_getters with |
| (type1 := expected_type) (type2 := d0). |
| auto. |
| assert (name = s). injection Heqecont. intros. auto. |
| rewrite <- H13. |
| auto. |
| auto. |
| |
| (* Case 3.4.2. Null Value. No Such Getter. *) |
| constructor. auto. |
| |
| (* Case 3.5. Pass Value to Var Declaration. *) |
| constructor. |
| |
| (* Case 3.6. Pass Value to Halt. *) |
| remember (Expression_Continuation Halt_Ek d) as econt. |
| destruct H; discriminate Heqecont. |
| |
| (* Case 4. Forward Configuration. *) |
| constructor. |
| Qed. |
| |
| |
| Lemma configuration_valid_step : |
| forall conf1 conf2, |
| configuration_valid CE ME conf1 -> |
| step CE ME conf1 conf2 -> |
| configuration_valid CE ME conf2 \/ configuration_final conf2. |
| Proof. |
| admit. |
| Admitted. |
| |
| |
| Theorem progress: |
| forall conf1, |
| configuration_valid CE ME conf1 -> |
| exists conf2, step CE ME conf1 conf2 /\ |
| (configuration_valid CE ME conf2 \/ configuration_final conf2). |
| Proof. |
| intros. |
| admit. |
| Admitted. |
| |
| |
| Lemma preservation_eval: |
| forall conf1 conf2 exp val env cont val_type exp_type, |
| configuration_valid CE ME conf1 -> |
| conf1 = Eval_Configuration exp env cont -> |
| conf2 = Value_Passing_Configuration cont val -> |
| steps CE ME conf1 conf2 -> |
| expression_type CE (env_to_type_env env) exp = Some exp_type -> |
| (runtime_type val) = Some val_type -> |
| subtype (val_type, exp_type) = true. |
| Proof. |
| admit. |
| Admitted. |
| |
| |
| End OperationalSemanticsSpec. |