41f1407ca8
Bug: Change-Id: Ib7272cbe377f9e8c71ca4d289d170a0cc173ba6b Reviewed-on: https://dart-review.googlesource.com/12640 Reviewed-by: Samir Jindel <sjindel@google.com>
718 lines
21 KiB
V
718 lines
21 KiB
V
(* 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.
|