Commit cab3db52 authored by Dan Frumin's avatar Dan Frumin

Merge branch 'bind'

parents 6678f0c8 772ff880
......@@ -9,7 +9,7 @@ Inductive dloc :=
| dLoc : nat nat dloc (* index * offset *)
| dLocUnknown : cloc dloc.
Global Instance dloc_decision : EqDecision dloc.
Global Instance dloc_eq_dec : EqDecision dloc.
Proof. solve_decision. Defined.
(* Symbolic integers *)
......@@ -29,7 +29,7 @@ Inductive dbase_lit : Type :=
| dLitUnit : dbase_lit
| dLitUnknown : base_lit dbase_lit.
Global Instance dlit_decision : EqDecision dbase_lit.
Global Instance dbase_lit_eq_dec : EqDecision dbase_lit.
Proof. solve_decision. Defined.
Inductive dval : Type :=
......@@ -38,7 +38,7 @@ Inductive dval : Type :=
| dLocV : dloc dval
| dValUnknown : val dval.
Global Instance dval_EqDecision : EqDecision dval.
Global Instance dval_eq_dec : EqDecision dval.
Proof. solve_decision. Defined.
Definition dloc_interp (E : known_locs) (dl : dloc) : cloc :=
......@@ -248,23 +248,26 @@ Qed.
(** Dexpr *)
Inductive dexpr : Type :=
| dEVal : dval dexpr
| dEVar : string dexpr
| dEPair : dexpr dexpr dexpr
| dEFst : dexpr dexpr
| dESnd : dexpr dexpr
| dEUnknown (e : expr) `{!Closed [] e} : dexpr.
| dEUnknown (e : W.expr) : dexpr.
Fixpoint dexpr_interp (E: known_locs) (de: dexpr) : expr :=
match de with
| dEVal dv => dval_interp E dv
| dEVar x => Var x
| dEPair de1 de2 => (dexpr_interp E de1, dexpr_interp E de2)
| dEFst de => Fst (dexpr_interp E de)
| dESnd de => Snd (dexpr_interp E de)
| dEUnknown e => e
| dEUnknown e => W.to_expr e
end.
(** DCexpr *)
Inductive dcexpr : Type :=
| dCRet : dexpr dcexpr
| dCBind : string dcexpr dcexpr dcexpr
| dCAlloc : dcexpr dcexpr dcexpr
| dCLoad : dcexpr dcexpr
| dCStore : dcexpr dcexpr dcexpr
......@@ -274,11 +277,12 @@ Inductive dcexpr : Type :=
| dCSeq : dcexpr dcexpr dcexpr
| dCPar : dcexpr dcexpr dcexpr
| dCInvoke (f: val) (de: dcexpr)
| dCUnknown (e : expr) `{!Closed [] e}.
| dCUnknown (e : W.expr).
Fixpoint dcexpr_interp (E: known_locs) (de: dcexpr) : expr :=
match de with
| dCRet de => a_ret (dexpr_interp E de)
| dCBind x de1 de2 => x ←ᶜ (dcexpr_interp E de1) ;; (dcexpr_interp E de2)
| dCAlloc de1 de2 => a_alloc (dcexpr_interp E de1) (dcexpr_interp E de2)
| dCLoad de1 => a_load (dcexpr_interp E de1)
| dCStore de1 de2 => a_store (dcexpr_interp E de1) (dcexpr_interp E de2)
......@@ -289,11 +293,10 @@ Fixpoint dcexpr_interp (E: known_locs) (de: dcexpr) : expr :=
| dCSeq de1 de2 => dcexpr_interp E de1 ; dcexpr_interp E de2
| dCPar de1 de2 => dcexpr_interp E de1 ||| dcexpr_interp E de2
| dCInvoke fv de => call (fv, dcexpr_interp E de)
| dCUnknown e1 => e1
| dCUnknown e1 => W.to_expr e1
end.
(** Well-foundness of dcexpr w.r.t. known_locs *)
(** Well-formedness of dcexpr w.r.t. known_locs *)
Definition dloc_wf (E: known_locs) (dl : dloc) : bool :=
match dl with
| dLoc i _ => bool_decide (is_Some (E !! i))
......@@ -307,24 +310,27 @@ Fixpoint dval_wf (E: known_locs) (dv : dval) : bool :=
| _ => true
end.
Fixpoint dexpr_wf (E: known_locs) (de: dexpr) : bool :=
Fixpoint dexpr_wf (X: list string) (E: known_locs) (de: dexpr) : bool :=
match de with
| dEVal dv => dval_wf E dv
| dEFst de | dESnd de => dexpr_wf E de
| dEPair de1 de2 => dexpr_wf E de1 && dexpr_wf E de2
| dEUnknown _ => true
| dEVar x => bool_decide (x X)
| dEFst de | dESnd de => dexpr_wf X E de
| dEPair de1 de2 => dexpr_wf X E de1 && dexpr_wf X E de2
| dEUnknown e => W.is_closed X e
end.
Fixpoint dcexpr_wf (E: known_locs) (de: dcexpr) : bool :=
Fixpoint dcexpr_wf (X: list string) (E: known_locs) (de: dcexpr) : bool :=
match de with
| dCRet de => dexpr_wf E de
| dCLoad de1 | dCUnOp _ de1 | dCInvoke _ de1 => dcexpr_wf E de1
| dCRet de => dexpr_wf X E de
| dCBind x de1 de2 => dcexpr_wf X E de1 && dcexpr_wf (x :: X) E de2
| dCLoad de1 | dCUnOp _ de1 | dCInvoke _ de1 => dcexpr_wf X E de1
| dCAlloc de1 de2 | dCStore de1 de2 | dCBinOp _ de1 de2
| dCPreBinOp _ de1 de2 | dCSeq de1 de2 | dCPar de1 de2 =>
dcexpr_wf E de1 && dcexpr_wf E de2
| dCUnknown _ => true
dcexpr_wf X E de1 && dcexpr_wf X E de2
| dCUnknown e => W.is_closed X e
end.
(*TODO: Fuse wf_mono and interp_mono into one lemma for dval and dcexpr *)
Lemma dval_wf_mono (E E': known_locs) (dv: dval) :
dval_wf E dv E `prefix_of` E' dval_wf E' dv.
......@@ -341,13 +347,19 @@ Proof.
* specialize (prefix_cons_inv_2 _ _ _ _ Hpre). naive_solver.
Qed.
Lemma dexpr_wf_mono (E E': known_locs) (de: dexpr) :
dexpr_wf E de E `prefix_of` E' dexpr_wf E' de.
Lemma dexpr_wf_mono (X: list string) (E E': known_locs) (de: dexpr) :
dexpr_wf X E de E `prefix_of` E' dexpr_wf X E' de.
Proof. induction de; simplify_eq /=; [apply dval_wf_mono|..]; naive_solver. Qed.
Lemma dcexpr_wf_mono (E E': known_locs) (de: dcexpr) :
dcexpr_wf E de E `prefix_of` E' dcexpr_wf E' de.
Proof. induction de; simplify_eq /=; [apply dexpr_wf_mono|..]; naive_solver. Qed.
Lemma dcexpr_wf_mono (X: list string) (E E': known_locs) (de: dcexpr) :
dcexpr_wf X E de E `prefix_of` E' dcexpr_wf X E' de.
Proof.
revert X.
induction de; intros X; simplify_eq /=; [try apply dexpr_wf_mono|..];
naive_solver.
Qed.
Lemma dun_op_eval_Some_wf E dv u dw:
dval_wf E dv dun_op_eval E u dv = Some dw dval_wf E dw.
......@@ -366,7 +378,7 @@ Proof.
simpl. unfold dptr_plus_eval. repeat case_match; naive_solver.
Qed.
(** / Well-foundness of dcexpr w.r.t. known_locs *)
(** / Well-formedness of dcexpr w.r.t. known_locs *)
Lemma dloc_interp_mono (E E': known_locs) (i j: nat) :
dloc_wf E (dLoc i j) E `prefix_of` E'
......@@ -404,8 +416,9 @@ Proof.
* specialize (prefix_cons_inv_2 _ _ _ _ Hpre). naive_solver.
Qed.
Lemma dexpr_interp_mono (E E': known_locs) (de: dexpr) :
dexpr_wf E de E `prefix_of` E' dexpr_interp E de = dexpr_interp E' de.
Lemma dexpr_interp_mono (X: list string) (E E': known_locs) (de: dexpr) :
dexpr_wf X E de E `prefix_of` E' dexpr_interp E de = dexpr_interp E' de.
Proof.
induction de; simplify_eq /=; intros H Hpre;
try (by rewrite IHde ) ||
......@@ -415,24 +428,42 @@ Proof.
by rewrite (dval_interp_mono E E').
Qed.
Lemma dcexpr_interp_mono (E E': known_locs) (de: dcexpr) :
dcexpr_wf E de E `prefix_of` E' dcexpr_interp E de = dcexpr_interp E' de.
Lemma dcexpr_interp_mono (X: list string) (E E': known_locs) (de: dcexpr) :
dcexpr_wf X E de E `prefix_of` E'
dcexpr_interp E de = dcexpr_interp E' de.
Proof.
induction de; simplify_eq /=; intros H Hpre;
try (by rewrite IHde ) ||
(apply andb_prop_elim in H as [H1 H2];
rewrite IHde2; [rewrite IHde1; done | done | done ];
by rewrite (IHde1 H1 Hpre (dcexpr_interp E de1))) || eauto.
by rewrite (dexpr_interp_mono E E').
revert X.
induction de; simplify_eq /=; intros X H Hpre; eauto;
destruct_and?;
try by rewrite (IHde X)
|| (rewrite (IHde2 X) // (IHde1 X) //).
- by rewrite (dexpr_interp_mono X E E').
- rewrite (IHde1 X) //.
by erewrite (IHde2 (_::X)).
Qed.
Global Instance dexpr_closed E de : Closed [] (dexpr_interp E de).
Proof. induction de; simpl; try solve_closed. Qed.
Global Instance dexpr_closed X E de :
dexpr_wf X E de
Closed X (dexpr_interp E de).
Proof.
revert X. induction de; simpl; intros; unfold Closed; simpl; eauto using is_closed_of_val;
try by apply IHde.
destruct_and!. by split_and; [apply IHde1 | apply IHde2].
by apply W.is_closed_correct.
Qed.
Global Instance dcexpr_closed E de : Closed [] (dcexpr_interp E de).
Global Instance dcexpr_closed X E de :
dcexpr_wf X E de
Closed X (dcexpr_interp E de).
Proof.
induction de; simpl; try solve_closed. rewrite /Closed /=.
split_and. change (Closed [] a_ret). solve_closed. apply (dexpr_closed E d).
revert X. induction de; intros; unfold Closed in *; simplify_eq /=;
try (destruct_and!; split_and; first split_and; [ apply is_closed_of_val | by apply IHde2 | by apply IHde1]);
try (destruct_and!; split_and; first split_and; [ apply is_closed_of_val | by apply IHde1 | by apply IHde2]).
- split_and; eauto using is_closed_of_val. by apply dexpr_closed.
- split_and; [ apply is_closed_of_val | by apply IHde].
- split_and; [ apply is_closed_of_val | by apply IHde].
- split_and; first split_and; [ apply is_closed_of_val | apply is_closed_of_val | by apply IHde].
- by apply W.is_closed_correct.
Qed.
(** * Reification of C syntax *)
......@@ -537,96 +568,112 @@ Proof. done. Qed.
(** ** IntoDExpr *)
Class IntoDExpr (E: known_locs) (e: expr) (de: dexpr) :=
{ into_dexpr : e = dexpr_interp E de;
into_dexpr_wf : dexpr_wf E de }.
into_dexpr : e = dexpr_interp E de.
Global Instance into_dexpr_val E e dv :
ExprIntoDVal E e dv
IntoDExpr E e (dEVal dv) | 5.
Proof. intros [-> ?]; split; auto. Qed.
Proof. by intros [-> ?]. Qed.
Global Instance into_dexpr_var E x :
IntoDExpr E (Var x) (dEVar x) | 5.
Proof. done. Qed.
Global Instance into_dexpr_pair E e1 e2 de1 de2 :
IntoDExpr E e1 de1 IntoDExpr E e2 de2
IntoDExpr E (Pair e1 e2) (dEPair de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDExpr=> -> ->. Qed.
Global Instance into_dexpr_fst E e de:
IntoDExpr E e de
IntoDExpr E (Fst e) (dEFst de).
Proof. intros [-> ?]; split; auto. Qed.
Proof. by rewrite /IntoDExpr=> ->. Qed.
Global Instance into_dexpr_snd E e de:
IntoDExpr E e de
IntoDExpr E (Snd e) (dESnd de).
Proof. intros [-> ?]; split; auto. Qed.
Proof. by rewrite /IntoDExpr=> ->. Qed.
Global Instance into_dexpr_unknown E e `{Closed [] e}:
IntoDExpr E e (dEUnknown e) | 100.
Proof. done. Qed.
Lemma into_dexpr_unknown {E e} de :
e = W.to_expr de
IntoDExpr E e (dEUnknown de).
Proof. by intros ->. Qed.
Hint Extern 100 (IntoDExpr _ ?e _) =>
let e' := W.of_expr e in
apply (into_dexpr_unknown e'); reflexivity : typeclass_instances.
(** ** IntoDCExpr *)
Class IntoDCExpr (E: known_locs) (e: expr) (de: dcexpr) :=
{ into_dcexpr : e = dcexpr_interp E de;
into_dcexpr_wf : dcexpr_wf E de }.
into_dcexpr : e = dcexpr_interp E de.
Global Instance into_dcexpr_ret E e de:
IntoDExpr E e de
IntoDCExpr E (a_ret e) (dCRet de).
Proof. intros [-> ?]; split; auto. Qed.
Proof. by rewrite /IntoDExpr=> ->. Qed.
Global Instance into_dcexpr_bind E x e1 e2 de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (BNamed x ←ᶜ e1 ;; e2) (dCBind x de1 de2).
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_alloc E e1 e2 de1 de2 :
IntoDCExpr E e1 de1 IntoDCExpr E e2 de2
IntoDCExpr E (a_alloc e1 e2) (dCAlloc de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_load E e de:
IntoDCExpr E e de
IntoDCExpr E (a_load e) (dCLoad de).
Proof. intros [-> ?]; split; auto. Qed.
Proof. by rewrite /IntoDCExpr=> ->. Qed.
Global Instance into_dcexpr_store E e1 e2 de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (a_store e1 e2) (dCStore de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_binop E e1 e2 op de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (a_bin_op op e1 e2) (dCBinOp op de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_prebinop E e1 e2 op de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (a_pre_bin_op op e1 e2) (dCPreBinOp op de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_unop E e op de:
IntoDCExpr E e de
IntoDCExpr E (a_un_op op e) (dCUnOp op de).
Proof. intros [-> ?]; split; auto. Qed.
Proof. by rewrite /IntoDCExpr=> ->. Qed.
Global Instance into_dcexpr_sequence E e1 e2 de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (e1 ; e2) (dCSeq de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_par E e1 e2 de1 de2:
IntoDCExpr E e1 de1
IntoDCExpr E e2 de2
IntoDCExpr E (e1 ||| e2) (dCPar de1 de2).
Proof. intros [-> ?] [-> ?]; split; simpl; auto. Qed.
Proof. by rewrite /IntoDCExpr=> -> ->. Qed.
Global Instance into_dcexpr_invoke E `{Closed [] e1} ef f `{!IntoVal ef f} de1 :
Global Instance into_dcexpr_invoke e1 E ef f de1 :
IntoVal ef f ->
IntoDCExpr E e1 de1
IntoDCExpr E (call (ef, e1)) (dCInvoke f de1).
Proof.
intros. unfold IntoVal in *. simplify_eq /=.
split; simpl; auto; f_equal; by inversion H0.
Qed.
Proof. by rewrite /IntoVal /IntoDCExpr=> <- ->. Qed.
Global Instance into_dcexpr_unknown E e `{Closed [] e}:
IntoDCExpr E e (dCUnknown e) | 100.
Proof. done. Qed.
Lemma into_dcexpr_unknown {E e} de :
e = W.to_expr de
IntoDCExpr E e (dCUnknown de).
Proof. by intros ->. Qed.
Hint Extern 100 (IntoDCExpr _ ?e _) =>
let e' := W.of_expr e in
apply (into_dcexpr_unknown e'); reflexivity : typeclass_instances.
......@@ -56,22 +56,22 @@ Section factorial_spec.
AWP factorial #n @ R {{ v, v = #(fact n) }}%I.
Proof.
awp_lam.
iApply awp_bind. awp_alloc_ret r "[Hr _]".
iApply awp_bind. awp_alloc_ret c "[Hc _]".
iApply a_sequence_spec'. iNext.
vcg_solver.
iIntros (r) "[Hr _]". vcg_continue. iIntros "Hr".
iIntros (c) "[Hc _]". vcg_continue. iIntros "Hr Hc".
iApply (awp_wand _ (λ _, c C #n r C #(fact n))%I with "[Hr Hc]").
- iApply ((factorial_body_spec n 0 c r) with "[$Hr $Hc]"); eauto with lia.
- iIntros (?) "[Hc Hr]". iModIntro.
awp_load_ret r.
- iIntros (?) "[Hc Hr]". vcg_continue. iModIntro. eauto.
Qed.
Lemma factorial_spec_with_inv (n: nat) R :
awp (factorial #n) R (λ v, v = #(fact n))%I.
Proof.
awp_lam.
iApply awp_bind. awp_alloc_ret r "[Hr _]".
iApply awp_bind. awp_alloc_ret c "[Hc _]".
iApply a_sequence_spec'. iNext. do 3 awp_lam.
vcg_solver.
iIntros (r) "[Hr _]". vcg_continue. iIntros "Hr".
iIntros (c) "[Hc _]". vcg_continue. iIntros "Hr Hc".
do 3 awp_lam.
iApply (a_while_inv_spec
(k:nat, k n c C #k r C #(fact k))%I with "[Hr Hc]").
- iExists O. eauto with iFrame lia.
......@@ -87,8 +87,9 @@ Section factorial_spec.
{ rewrite Nat.add_1_r /fact. lia. }
assert (Z_of_nat' (k + 1)%nat = (k + 1)) as <- by lia.
iExists (k+1)%nat. eauto with iFrame lia.
+ iLeft. iSplit; eauto. do 2 iModIntro.
+ iLeft. iSplit; eauto. iModIntro.
iRevert "H". iIntros "%". assert (k = n) as -> by lia.
awp_load_ret r.
vcg_continue. eauto.
Qed.
End factorial_spec.
......@@ -93,36 +93,15 @@ Section memcpy.
AWP a_invoke memcpy (♯ₗp ||| (♯ₗq ||| n)) @ R {{ _, p C ls2 q C ls2 }}.
Proof.
iIntros (? ?) "Hp Hq". vcg_solver. awp_lam.
iApply awp_bind. vcg_solver.
iIntros (pp) "[Hpp _]". vcg_continue. iIntros "Hpp". awp_let.
iApply awp_bind. vcg_solver. iIntros "Hpp".
iIntros (qq) "[Hqq _]". vcg_continue. iIntros "Hpp Hqq". awp_let.
repeat awp_proj. awp_let. (* iApply awp_bind hangs without the set *)
set (e :=( while (_) { _ })%E).
iApply awp_bind. unfold e. apply _.
vcg_solver. iIntros "Hpp Hqq".
vcg_solver. iIntros (pp) "[Hpp _]".
vcg_continue. iIntros "Hpp". iIntros (qq) "[Hqq _]".
vcg_continue. iIntros "Hpp Hqq".
repeat awp_proj. awp_let. set (e :=( while (_) { _ })%E).
unfold e. vcg_solver. iIntros "Hpp Hqq".
(* Ouch, this goal is ugly. We either need to embed naturals into the
reified syntax, or let the binop evaluator be total and generate
side-conditions (here 0 ≤ n) for the result to be well-formed. *)
Admitted.
(*
awp_proj. iApply awp_ret; wp_value_head.
iNext. iIntros (? ->). iExists 1%nat. iSplit; eauto.
iIntros (pp) "[Hpp _]". rewrite {3}/cloc_add. etaprod pp.
repeat awp_pure _. iApply awp_bind.
iApply (a_alloc_spec _ _ (λ v, ⌜v = #1⌝))%I; first by (iApply awp_ret; wp_value_head).
do 2 awp_proj. iApply awp_ret; wp_value_head.
iNext. iIntros (? ->). iExists 1%nat. iSplit; eauto.
iIntros (qq) "[Hqq _]". rewrite {3}/cloc_add. etaprod qq.
repeat awp_pure _. iApply awp_bind.
iApply (a_bin_op_spec _ _ (λ v, ⌜v = cloc_to_val p⌝ ∗ pp ↦C (#p.1, #p.2)) (λ v, ⌜v = #n⌝) with "[Hpp]")%I.
- vcg_solver. eauto.
- by vcg_solver.
- iNext. iIntros (? ?) "[% Hpp] %". simplify_eq/=.
iExists (cloc_to_val (p.1,p.2+length ls1))%nat; repeat iSplit; eauto.
{ iPureIntro. repeat (case_option_guard; last omega). simpl.
repeat f_equal. rewrite !Nat2Z.id //. }
awp_let. iApply (memcpy_body_spec with "Hp Hq Hpp Hqq"); auto.
Qed. *) Admitted.
End memcpy.
......@@ -42,7 +42,9 @@ Section tests_vcg.
AWP (swap_with_alloc (cloc_to_val l1)) (cloc_to_val l2) @ R {{ _, l1 C v2 l2 C v1 }}.
Proof.
iIntros "Hl1 Hl2".
do 2 awp_lam. iApply awp_bind. awp_alloc_ret r "[Hr _]".
vcg_solver. iIntros "!> !> !> **". eauto with iFrame.
do 2 awp_lam.
vcg_solver.
iIntros "Hl2 Hl1". iIntros (l3) "[Hl3 _]". vcg_continue.
iIntros "!> !> !> **". eauto with iFrame.
Qed.
End tests_vcg.
......@@ -28,27 +28,29 @@ Section vcg_continue.
FromKnownLocs (PenvItem l x q v :: Γls) E_old (l :: E_new) | 100.
Proof. done. Qed.
Lemma tac_vcg_sound Γs_in Γs_out Γls Γp m c e R Φ E de :
MapstoListFromEnv Γs_in Γs_out Γls
E = penv_to_known_locs Γls
ListOfMapsto Γls E m
IntoDCExpr E e de
dcexpr_wf [] E de
denv_wf (penv_to_known_locs Γls) m
envs_entails (Envs Γp Γs_out c)
(vcg_wp E m de R (λ E m dv,
mapsto_wand_list E m (Φ (dval_interp E dv))))
mapsto_wand_list E m (Φ (dval_interp E dv))) 1024 (*TODO: Fix this*))
envs_entails (Envs Γp Γs_in c) (awp e R Φ).
Proof.
intros Hsplit ->.
rewrite /ListOfMapsto. intros Hpenv [-> Hwf] Hmwf Hgoal.
rewrite /ListOfMapsto. intros Hpenv -> Hwf Hmwf Hgoal.
eapply tac_envs_split_mapsto; try eassumption.
revert Hgoal. rewrite environments.envs_entails_eq.
rewrite (vcg_wp_correct R); last done.
rewrite (vcg_wp_correct R); try done.
iIntros (->) "H1 H2".
iSpecialize ("H2" with "H1"). iApply (awp_wand with "H2").
iIntros (v). iDestruct 1 as (E' dv m' Hpre) "(% & % & % & Hm & Hwp)".
rewrite Hpre.
rewrite mapsto_wand_list_spec. iApply ("Hwp" with "Hm"). done.
rewrite mapsto_wand_list_spec. iApply ("Hwp" with "Hm").
Qed.
Lemma tac_exists_known_locs Γs_in Γs_out Γls Γp c ps v dv E_old E_new (Φ: known_locs denv dval iProp Σ):
......@@ -74,6 +76,7 @@ Section vcg_continue.
* by left.
* right. by apply Hsplit.
Qed.
End vcg_continue.
Arguments vcg_wp_continuation {_ _ _ _}.
......@@ -89,6 +92,7 @@ Ltac vcg_solver :=
| simpl; reflexivity (* Compute the known locations *)
| apply _ (* Compute the symbolic environment based on known locations *)
| apply _ (* Reify the expression *)
| vm_compute[reflexivity]; try done (* Prove that the reified expression is well-formed *)
| done (* Prove that the environment is well-formed *)
| simpl ].
......@@ -99,4 +103,4 @@ Ltac vcg_continue :=
| apply _ (* ListOfMapsto Γls (E_old ++ E_new) ps *)
| apply _ (* IntoDVal (E_old ++ E_new) v dv *)
| done (* ps is well-formed *)
| simpl ].
| simpl; simpl_subst ].
This diff is collapsed.
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