diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f9d478f9d27f5ba747a6f62950a810dcf14dc53..5a38620fc1d69118d64858626e052ee411df9797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,8 @@ Changes in Coq: - `cmra_opM_assoc_L` → `cmra_op_opM_assoc_L` - `cmra_opM_assoc'` → `cmra_opM_opM_assoc` * `namespaces` has been moved to std++. -* Changed `IntoVal` to be directly usable for rewriting `e` into `of_val v`. +* Changed `IntoVal` to be directly usable for rewriting `e` into `of_val v`, and + changed `AsVal` to be usable for rewriting via the `[v <-]` destruct pattern. ## Iris 3.1.0 (released 2017-12-19) diff --git a/theories/heap_lang/lifting.v b/theories/heap_lang/lifting.v index 68ef2f8e178c7e2717a83ae017605cd6c9cb4ae1..3822ee5220c9814ed425b57e111839dbee012f49 100644 --- a/theories/heap_lang/lifting.v +++ b/theories/heap_lang/lifting.v @@ -51,8 +51,8 @@ Local Hint Resolve to_of_val. Local Ltac solve_exec_safe := intros; subst; do 3 eexists; econstructor; eauto. Local Ltac solve_exec_puredet := simpl; intros; by inv_head_step. Local Ltac solve_pure_exec := - unfold IntoVal, AsVal in *; subst; - repeat match goal with H : is_Some _ |- _ => destruct H as [??] end; + unfold IntoVal in *; + repeat match goal with H : AsVal _ |- _ => destruct H as [??] end; subst; apply det_head_step_pure_exec; [ solve_exec_safe | solve_exec_puredet ]. Class AsRec (e : expr) (f x : binder) (erec : expr) := @@ -189,7 +189,7 @@ Lemma wp_cas_fail s E l q v' e1 v1 e2 : {{{ ▷ l ↦{q} v' }}} CAS (Lit (LitLoc l)) e1 e2 @ s; E {{{ RET LitV (LitBool false); l ↦{q} v' }}}. Proof. - iIntros (<- [v2 <-%of_to_val] ? Φ) ">Hl HΦ". + iIntros (<- [v2 <-] ? Φ) ">Hl HΦ". iApply wp_lift_atomic_head_step_no_fork; auto. iIntros (σ1) "Hσ !>". iDestruct (@gen_heap_valid with "Hσ Hl") as %?. iSplit; first by eauto. iNext; iIntros (v2' σ2 efs Hstep); inv_head_step. @@ -200,7 +200,7 @@ Lemma twp_cas_fail s E l q v' e1 v1 e2 : [[{ l ↦{q} v' }]] CAS (Lit (LitLoc l)) e1 e2 @ s; E [[{ RET LitV (LitBool false); l ↦{q} v' }]]. Proof. - iIntros (<- [v2 <-%of_to_val] ? Φ) "Hl HΦ". + iIntros (<- [v2 <-] ? Φ) "Hl HΦ". iApply twp_lift_atomic_head_step_no_fork; auto. iIntros (σ1) "Hσ !>". iDestruct (@gen_heap_valid with "Hσ Hl") as %?. iSplit; first by eauto. iIntros (v2' σ2 efs Hstep); inv_head_step. diff --git a/theories/heap_lang/tactics.v b/theories/heap_lang/tactics.v index 0c5c751dadf82d63bc533df86c45ed02d48d4f41..cdb8f85a6ce4494ae892271cd4757271c84f5133 100644 --- a/theories/heap_lang/tactics.v +++ b/theories/heap_lang/tactics.v @@ -138,18 +138,16 @@ Fixpoint to_val (e : expr) : option val := | _ => None end. Lemma to_val_Some e v : - to_val e = Some v → heap_lang.to_val (to_expr e) = Some v. + to_val e = Some v → of_val v = W.to_expr e. Proof. - revert v. induction e; intros; simplify_option_eq; rewrite ?to_of_val; auto. - - do 2 f_equal. apply proof_irrel. - - exfalso. unfold Closed in *; eauto using is_closed_correct. + revert v. induction e; intros; simplify_option_eq; try f_equal; auto using of_to_val. Qed. Lemma to_val_is_Some e : - is_Some (to_val e) → is_Some (heap_lang.to_val (to_expr e)). + is_Some (to_val e) → ∃ v, of_val v = to_expr e. Proof. intros [v ?]; exists v; eauto using to_val_Some. Qed. -Lemma expr_of_val e v : - to_val e = Some v → of_val v = W.to_expr e. -Proof. intros ?. apply of_to_val, to_val_Some. done. Qed. +Lemma to_val_is_Some' e : + is_Some (to_val e) → is_Some (heap_lang.to_val (to_expr e)). +Proof. intros [v ?]%to_val_is_Some. exists v. rewrite -to_of_val. by f_equal. Qed. Fixpoint subst (x : string) (es : expr) (e : expr) : expr := match e with @@ -205,7 +203,7 @@ Proof. unfold subst'; repeat (simplify_eq/=; case_match=>//); eauto. - apply ectxi_language_sub_redexes_are_values=> /= Ki e' Hfill. destruct e=> //; destruct Ki; repeat (simplify_eq/=; case_match=>//); - naive_solver eauto using to_val_is_Some. + naive_solver eauto using to_val_is_Some'. Qed. End W. @@ -221,14 +219,14 @@ Ltac solve_into_val := match goal with | |- IntoVal ?e ?v => let e' := W.of_expr e in change (of_val v = W.to_expr e'); - apply W.expr_of_val; simpl; unfold W.to_expr; reflexivity + apply W.to_val_Some; simpl; unfold W.to_expr; reflexivity end. Hint Extern 10 (IntoVal _ _) => solve_into_val : typeclass_instances. Ltac solve_as_val := match goal with | |- AsVal ?e => - let e' := W.of_expr e in change (is_Some (to_val (W.to_expr e'))); + let e' := W.of_expr e in change (∃ v, of_val v = W.to_expr e'); apply W.to_val_is_Some, (bool_decide_unpack _); vm_compute; exact I end. Hint Extern 10 (AsVal _) => solve_as_val : typeclass_instances. diff --git a/theories/program_logic/language.v b/theories/program_logic/language.v index fb541089779ae76e042d49a91f5c6941e111c4bc..6ceddcaa35739c4cbc751a38e660e402e321d06e 100644 --- a/theories/program_logic/language.v +++ b/theories/program_logic/language.v @@ -162,12 +162,12 @@ Section language. Class IntoVal (e : expr Λ) (v : val Λ) := into_val : of_val v = e. - Class AsVal (e : expr Λ) := as_val : is_Some (to_val e). + Class AsVal (e : expr Λ) := as_val : ∃ v, of_val v = e. (* There is no instance [IntoVal → AsVal] as often one can solve [AsVal] more efficiently since no witness has to be computed. *) Global Instance as_vals_of_val vs : TCForall AsVal (of_val <$> vs). Proof. apply TCForall_Forall, Forall_fmap, Forall_true=> v. - rewrite /AsVal /= to_of_val; eauto. + rewrite /AsVal /=; eauto. Qed. End language.