From 9e18501a2b9eae80ba8c5a69a3ec36ced45efd45 Mon Sep 17 00:00:00 2001 From: Ralf Jung <jung@mpi-sws.org> Date: Fri, 28 Jun 2019 13:11:17 +0200 Subject: [PATCH] heap_lang: Make binary "=" operator partial, to sync with CmpXchg This also gets rid of [val_for_compare]-normalization; instead we introduce a [LitErased] literal that is suited for use by erasure theorems. --- tests/heap_lang.v | 5 +- theories/heap_lang/lang.v | 69 +++++++++++++++------------- theories/heap_lang/lib/atomic_heap.v | 14 +++--- theories/heap_lang/lifting.v | 41 +++++++++++------ theories/heap_lang/proofmode.v | 50 ++++++++++---------- 5 files changed, 97 insertions(+), 82 deletions(-) diff --git a/tests/heap_lang.v b/tests/heap_lang.v index df044f7f6..4f55ecbdd 100644 --- a/tests/heap_lang.v +++ b/tests/heap_lang.v @@ -76,8 +76,9 @@ Section tests. Definition heap_e6 : val := λ: "v", "v" = "v". - Lemma heap_e6_spec (v : val) : (WP heap_e6 v {{ w, ⌜ w = #true ⌠}})%I. - Proof. wp_lam. wp_op. by case_bool_decide. Qed. + Lemma heap_e6_spec (v : val) : + val_is_unboxed v → (WP heap_e6 v {{ w, ⌜ w = #true ⌠}})%I. + Proof. intros ?. wp_lam. wp_op. by case_bool_decide. Qed. Definition heap_e7 : val := λ: "v", CmpXchg "v" #0 #1. diff --git a/theories/heap_lang/lang.v b/theories/heap_lang/lang.v index 84ac31eac..e02449f21 100644 --- a/theories/heap_lang/lang.v +++ b/theories/heap_lang/lang.v @@ -61,7 +61,7 @@ Open Scope Z_scope. Definition proph_id := positive. Inductive base_lit : Set := - | LitInt (n : Z) | LitBool (b : bool) | LitUnit + | LitInt (n : Z) | LitBool (b : bool) | LitUnit | LitErased | LitLoc (l : loc) | LitProphecy (p: proph_id). Inductive un_op : Set := | NegOp | MinusUnOp. @@ -151,38 +151,32 @@ Ignoring (as usual) the fact that we have to fit the infinite Z/loc into 61 bits, this means every value is machine-word-sized and can hence be atomically read and written. Also notice that the sets of boxed and unboxed values are disjoint. *) +Definition lit_is_unboxed (l: base_lit) : Prop := + match l with + (* disallow comparing (erased) prophecies with (erased) prophecies, by considering them boxed *) + | LitProphecy _ | LitErased => False + | _ => True + end. Definition val_is_unboxed (v : val) : Prop := match v with - | LitV _ => True - | InjLV (LitV _) => True - | InjRV (LitV _) => True + | LitV l => lit_is_unboxed l + | InjLV (LitV l) => lit_is_unboxed l + | InjRV (LitV l) => lit_is_unboxed l | _ => False end. -(** CmpXchg just compares the word-sized representation of two values, it cannot -look into boxed data. This works out fine if at least one of the to-be-compared +Instance lit_is_unboxed_dec l : Decision (lit_is_unboxed l). +Proof. destruct l; simpl; exact (decide _). Defined. +Instance val_is_unboxed_dec v : Decision (val_is_unboxed v). +Proof. destruct v as [ | | | [] | [] ]; simpl; exact (decide _). Defined. + +(** We just compare the word-sized representation of two values, without looking +into boxed data. This works out fine if at least one of the to-be-compared values is unboxed (exploiting the fact that an unboxed and a boxed value can never be equal because these are disjoint sets). *) -Definition vals_cmpxchg_compare_safe (vl v1 : val) : Prop := +Definition vals_compare_safe (vl v1 : val) : Prop := val_is_unboxed vl ∨ val_is_unboxed v1. -Arguments vals_cmpxchg_compare_safe !_ !_ /. - -(** We don't compare the logical program values, but we first normalize them -to make sure that prophecies are treated like unit. -Also all functions become the same, but still distinct from anything else. *) -Definition lit_for_compare (l : base_lit) : base_lit := - match l with - | LitProphecy p => LitUnit - | l => l - end. -Fixpoint val_for_compare (v : val) : val := - match v with - | LitV l => LitV (lit_for_compare l) - | PairV v1 v2 => PairV (val_for_compare v1) (val_for_compare v2) - | InjLV v => InjLV (val_for_compare v) - | InjRV v => InjRV (val_for_compare v) - | RecV f x e => RecV BAnon BAnon (Val $ LitV $ LitUnit) - end. +Arguments vals_compare_safe !_ !_ /. (** The state: heaps of vals. *) Record state : Type := { @@ -263,12 +257,18 @@ Proof. solve_decision. Defined. Instance base_lit_countable : Countable base_lit. Proof. refine (inj_countable' (λ l, match l with - | LitInt n => (inl (inl n), None) | LitBool b => (inl (inr b), None) - | LitUnit => (inr (inl ()), None) | LitLoc l => (inr (inr l), None) - | LitProphecy p => (inr (inl ()), Some p) + | LitInt n => (inl (inl n), None) + | LitBool b => (inl (inr b), None) + | LitUnit => (inr (inl false), None) + | LitErased => (inr (inl true), None) + | LitLoc l => (inr (inr l), None) + | LitProphecy p => (inr (inl false), Some p) end) (λ l, match l with - | (inl (inl n), None) => LitInt n | (inl (inr b), None) => LitBool b - | (inr (inl ()), None) => LitUnit | (inr (inr l), None) => LitLoc l + | (inl (inl n), None) => LitInt n + | (inl (inr b), None) => LitBool b + | (inr (inl false), None) => LitUnit + | (inr (inl true), None) => LitErased + | (inr (inr l), None) => LitLoc l | (_, Some p) => LitProphecy p end) _); by intros []. Qed. @@ -519,7 +519,10 @@ Definition bin_op_eval_bool (op : bin_op) (b1 b2 : bool) : option base_lit := Definition bin_op_eval (op : bin_op) (v1 v2 : val) : option val := if decide (op = EqOp) then (* Crucially, this compares the same way as [CmpXchg]! *) - Some $ LitV $ LitBool $ bool_decide (val_for_compare v1 = val_for_compare v2) + if bool_decide (vals_compare_safe v1 v2) then + Some $ LitV $ LitBool $ bool_decide (v1 = v2) + else + None else match v1, v2 with | LitV (LitInt n1), LitV (LitInt n2) => LitV <$> bin_op_eval_int op n1 n2 @@ -635,10 +638,10 @@ Inductive head_step : expr → state → list observation → expr → state → (Val $ LitV LitUnit) (state_upd_heap <[l:=v]> σ) [] | CmpXchgS l v1 v2 vl σ b : - vals_cmpxchg_compare_safe vl v1 → σ.(heap) !! l = Some vl → (* Crucially, this compares the same way as [EqOp]! *) - b = bool_decide (val_for_compare vl = val_for_compare v1) → + vals_compare_safe vl v1 → + b = bool_decide (vl = v1) → head_step (CmpXchg (Val $ LitV $ LitLoc l) (Val v1) (Val v2)) σ [] (Val $ PairV vl (LitV $ LitBool b)) (if b then state_upd_heap <[l:=v2]> σ else σ) diff --git a/theories/heap_lang/lib/atomic_heap.v b/theories/heap_lang/lib/atomic_heap.v index fc059f5c9..7fc424dd6 100644 --- a/theories/heap_lang/lib/atomic_heap.v +++ b/theories/heap_lang/lib/atomic_heap.v @@ -37,8 +37,8 @@ Class atomic_heap {Σ} `{!heapG Σ} := AtomicHeap { cmpxchg_spec (l : loc) (w1 w2 : val) : val_is_unboxed w1 → <<< ∀ v, mapsto l 1 v >>> cmpxchg #l w1 w2 @ ⊤ - <<< if decide (val_for_compare v = val_for_compare w1) then mapsto l 1 w2 else mapsto l 1 v, - RET (v, #if decide (val_for_compare v = val_for_compare w1) then true else false) >>>; + <<< if decide (v = w1) then mapsto l 1 w2 else mapsto l 1 v, + RET (v, #if decide (v = w1) then true else false) >>>; }. Arguments atomic_heap _ {_}. @@ -68,8 +68,8 @@ Section derived. Lemma cas_spec (l : loc) (w1 w2 : val) : val_is_unboxed w1 → <<< ∀ v, mapsto l 1 v >>> CAS #l w1 w2 @ ⊤ - <<< if decide (val_for_compare v = val_for_compare w1) then mapsto l 1 w2 else mapsto l 1 v, - RET #if decide (val_for_compare v = val_for_compare w1) then true else false >>>. + <<< if decide (v = w1) then mapsto l 1 w2 else mapsto l 1 v, + RET #if decide (v = w1) then true else false >>>. Proof. iIntros (? Φ) "AU". awp_apply cmpxchg_spec; first done. iApply (aacc_aupd_commit with "AU"); first done. @@ -119,12 +119,12 @@ Section proof. val_is_unboxed w1 → <<< ∀ (v : val), l ↦ v >>> primitive_cmpxchg #l w1 w2 @ ⊤ - <<< if decide (val_for_compare v = val_for_compare w1) then l ↦ w2 else l ↦ v, - RET (v, #if decide (val_for_compare v = val_for_compare w1) then true else false) >>>. + <<< if decide (v = w1) then l ↦ w2 else l ↦ v, + RET (v, #if decide (v = w1) then true else false) >>>. Proof. iIntros (? Φ) "AU". wp_lam. wp_pures. iMod "AU" as (v) "[H↦ [_ Hclose]]". - destruct (decide (val_for_compare v = val_for_compare w1)) as [Heq|Hne]; + destruct (decide (v = w1)) as [Heq|Hne]; [wp_cmpxchg_suc|wp_cmpxchg_fail]; iMod ("Hclose" with "H↦") as "HΦ"; done. Qed. diff --git a/theories/heap_lang/lifting.v b/theories/heap_lang/lifting.v index 7df887249..a006612fa 100644 --- a/theories/heap_lang/lifting.v +++ b/theories/heap_lang/lifting.v @@ -161,8 +161,19 @@ Instance pure_unop op v v' : Proof. solve_pure_exec. Qed. Instance pure_binop op v1 v2 v' : - PureExec (bin_op_eval op v1 v2 = Some v') 1 (BinOp op (Val v1) (Val v2)) (Val v'). + PureExec (bin_op_eval op v1 v2 = Some v') 1 (BinOp op (Val v1) (Val v2)) (Val v') | 10. Proof. solve_pure_exec. Qed. +(* Higher-priority instance for EqOp. *) +Instance pure_eqop v1 v2 : + PureExec (vals_compare_safe v1 v2) 1 + (BinOp EqOp (Val v1) (Val v2)) + (Val $ LitV $ LitBool $ bool_decide (v1 = v2)) | 1. +Proof. + intros Hcompare. + cut (bin_op_eval EqOp v1 v2 = Some $ LitV $ LitBool $ bool_decide (v1 = v2)). + { intros. revert Hcompare. solve_pure_exec. } + rewrite /bin_op_eval /= bool_decide_true //. +Qed. Instance pure_if_true e1 e2 : PureExec True 1 (If (Val $ LitV $ LitBool true) e1 e2) e1. Proof. solve_pure_exec. Qed. @@ -375,7 +386,7 @@ Proof. Qed. Lemma wp_cmpxchg_fail s E l q v' v1 v2 : - val_for_compare v' ≠val_for_compare v1 → vals_cmpxchg_compare_safe v' v1 → + v' ≠v1 → vals_compare_safe v' v1 → {{{ ▷ l ↦{q} v' }}} CmpXchg (Val $ LitV $ LitLoc l) (Val v1) (Val v2) @ s; E {{{ RET PairV v' (LitV $ LitBool false); l ↦{q} v' }}}. Proof. @@ -386,7 +397,7 @@ Proof. iModIntro; iSplit=> //. iFrame. by iApply "HΦ". Qed. Lemma twp_cmpxchg_fail s E l q v' v1 v2 : - val_for_compare v' ≠val_for_compare v1 → vals_cmpxchg_compare_safe v' v1 → + v' ≠v1 → vals_compare_safe v' v1 → [[{ l ↦{q} v' }]] CmpXchg (Val $ LitV $ LitLoc l) (Val v1) (Val v2) @ s; E [[{ RET PairV v' (LitV $ LitBool false); l ↦{q} v' }]]. Proof. @@ -398,7 +409,7 @@ Proof. Qed. Lemma wp_cmpxchg_suc s E l v1 v2 v' : - val_for_compare v' = val_for_compare v1 → vals_cmpxchg_compare_safe v' v1 → + v' = v1 → vals_compare_safe v' v1 → {{{ ▷ l ↦ v' }}} CmpXchg (Val $ LitV $ LitLoc l) (Val v1) (Val v2) @ s; E {{{ RET PairV v' (LitV $ LitBool true); l ↦ v2 }}}. Proof. @@ -410,7 +421,7 @@ Proof. iModIntro. iSplit=>//. iFrame. by iApply "HΦ". Qed. Lemma twp_cmpxchg_suc s E l v1 v2 v' : - val_for_compare v' = val_for_compare v1 → vals_cmpxchg_compare_safe v' v1 → + v' = v1 → vals_compare_safe v' v1 → [[{ l ↦ v' }]] CmpXchg (Val $ LitV $ LitLoc l) (Val v1) (Val v2) @ s; E [[{ RET PairV v' (LitV $ LitBool true); l ↦ v2 }]]. Proof. @@ -534,7 +545,7 @@ Proof. Qed. Lemma wp_resolve_cmpxchg_suc s E l (p : proph_id) (pvs : list (val * val)) v1 v2 v : - vals_cmpxchg_compare_safe v1 v1 → + vals_compare_safe v1 v1 → {{{ proph p pvs ∗ ▷ l ↦ v1 }}} Resolve (CmpXchg #l v1 v2) #p v @ s; E {{{ RET (v1, #true) ; ∃ pvs', ⌜pvs = ((v1, #true)%V, v)::pvs'⌠∗ proph p pvs' ∗ l ↦ v2 }}}. @@ -547,7 +558,7 @@ Proof. Qed. Lemma wp_resolve_cmpxchg_fail s E l (p : proph_id) (pvs : list (val * val)) q v' v1 v2 v : - val_for_compare v' ≠val_for_compare v1 → vals_cmpxchg_compare_safe v' v1 → + v' ≠v1 → vals_compare_safe v' v1 → {{{ proph p pvs ∗ ▷ l ↦{q} v' }}} Resolve (CmpXchg #l v1 v2) #p v @ s; E {{{ RET (v', #false) ; ∃ pvs', ⌜pvs = ((v', #false)%V, v)::pvs'⌠∗ proph p pvs' ∗ l ↦{q} v' }}}. @@ -604,8 +615,8 @@ Qed. Lemma wp_cmpxchg_suc_offset s E l off vs v' v1 v2 : vs !! off = Some v' → - val_for_compare v' = val_for_compare v1 → - vals_cmpxchg_compare_safe v' v1 → + v' = v1 → + vals_compare_safe v' v1 → {{{ ▷ l ↦∗ vs }}} CmpXchg #(l +ₗ off) v1 v2 @ s; E {{{ RET (v', #true); l ↦∗ <[off:=v2]> vs }}}. @@ -617,8 +628,8 @@ Proof. Qed. Lemma wp_cmpxchg_suc_offset_vec s E l sz (off : fin sz) (vs : vec val sz) v1 v2 : - val_for_compare (vs !!! off) = val_for_compare v1 → - vals_cmpxchg_compare_safe (vs !!! off) v1 → + (vs !!! off) = v1 → + vals_compare_safe (vs !!! off) v1 → {{{ ▷ l ↦∗ vs }}} CmpXchg #(l +ₗ off) v1 v2 @ s; E {{{ RET (vs !!! off, #true); l ↦∗ vinsert off v2 vs }}}. @@ -629,8 +640,8 @@ Qed. Lemma wp_cmpxchg_fail_offset s E l off vs v0 v1 v2 : vs !! off = Some v0 → - val_for_compare v0 ≠val_for_compare v1 → - vals_cmpxchg_compare_safe v0 v1 → + v0 ≠v1 → + vals_compare_safe v0 v1 → {{{ ▷ l ↦∗ vs }}} CmpXchg #(l +ₗ off) v1 v2 @ s; E {{{ RET (v0, #false); l ↦∗ vs }}}. @@ -644,8 +655,8 @@ Proof. Qed. Lemma wp_cmpxchg_fail_offset_vec s E l sz (off : fin sz) (vs : vec val sz) v1 v2 : - val_for_compare (vs !!! off) ≠val_for_compare v1 → - vals_cmpxchg_compare_safe (vs !!! off) v1 → + (vs !!! off) ≠v1 → + vals_compare_safe (vs !!! off) v1 → {{{ ▷ l ↦∗ vs }}} CmpXchg #(l +ₗ off) v1 v2 @ s; E {{{ RET (vs !!! off, #false); l ↦∗ vs }}}. diff --git a/theories/heap_lang/proofmode.v b/theories/heap_lang/proofmode.v index fae672972..cde60d399 100644 --- a/theories/heap_lang/proofmode.v +++ b/theories/heap_lang/proofmode.v @@ -65,6 +65,12 @@ Ltac wp_finish := pm_prettify. (* prettify ▷s caused by [MaybeIntoLaterNEnvs] and λs caused by wp_value *) +Ltac solve_vals_compare_safe := + (* The first branch is for when we have [vals_compare_safe] in the context. + The other two branches are for when either one of the branches reduces to + [True] or we have it in the context. *) + fast_done || (left; fast_done) || (right; fast_done). + (** The argument [efoc] can be used to specify the construct that should be reduced. For example, you can write [wp_pure (EIf _ _ _)], which will search for an [EIf _ _ _] in the expression, and reduce it. @@ -81,7 +87,7 @@ Tactic Notation "wp_pure" open_constr(efoc) := unify e' efoc; eapply (tac_wp_pure _ _ _ _ (fill K e')); [iSolveTC (* PureExec *) - |try fast_done (* The pure condition for PureExec *) + |try solve_vals_compare_safe (* The pure condition for PureExec -- handles trivial goals, including [vals_compare_safe] *) |iSolveTC (* IntoLaters *) |wp_finish (* new goal *) ]) @@ -282,15 +288,15 @@ Lemma tac_wp_cmpxchg Δ Δ' Δ'' s E i K l v v1 v2 Φ : MaybeIntoLaterNEnvs 1 Δ Δ' → envs_lookup i Δ' = Some (false, l ↦ v)%I → envs_simple_replace i false (Esnoc Enil i (l ↦ v2)) Δ' = Some Δ'' → - vals_cmpxchg_compare_safe v v1 → - (val_for_compare v = val_for_compare v1 → + vals_compare_safe v v1 → + (v = v1 → envs_entails Δ'' (WP fill K (Val $ PairV v (LitV $ LitBool true)) @ s; E {{ Φ }})) → - (val_for_compare v ≠val_for_compare v1 → + (v ≠v1 → envs_entails Δ' (WP fill K (Val $ PairV v (LitV $ LitBool false)) @ s; E {{ Φ }})) → envs_entails Δ (WP fill K (CmpXchg (LitV l) (Val v1) (Val v2)) @ s; E {{ Φ }}). Proof. rewrite envs_entails_eq=> ???? Hsuc Hfail. - destruct (decide (val_for_compare v = val_for_compare v1)) as [Heq|Hne]. + destruct (decide (v = v1)) as [Heq|Hne]. - rewrite -wp_bind. eapply wand_apply. { eapply wp_cmpxchg_suc; eauto. } rewrite into_laterN_env_sound -later_sep /= {1}envs_simple_replace_sound //; simpl. @@ -303,15 +309,15 @@ Qed. Lemma tac_twp_cmpxchg Δ Δ' s E i K l v v1 v2 Φ : envs_lookup i Δ = Some (false, l ↦ v)%I → envs_simple_replace i false (Esnoc Enil i (l ↦ v2)) Δ = Some Δ' → - vals_cmpxchg_compare_safe v v1 → - (val_for_compare v = val_for_compare v1 → + vals_compare_safe v v1 → + (v = v1 → envs_entails Δ' (WP fill K (Val $ PairV v (LitV $ LitBool true)) @ s; E [{ Φ }])) → - (val_for_compare v ≠val_for_compare v1 → + (v ≠v1 → envs_entails Δ (WP fill K (Val $ PairV v (LitV $ LitBool false)) @ s; E [{ Φ }])) → envs_entails Δ (WP fill K (CmpXchg (LitV l) v1 v2) @ s; E [{ Φ }]). Proof. rewrite envs_entails_eq=> ??? Hsuc Hfail. - destruct (decide (val_for_compare v = val_for_compare v1)) as [Heq|Hne]. + destruct (decide (v = v1)) as [Heq|Hne]. - rewrite -twp_bind. eapply wand_apply. { eapply twp_cmpxchg_suc; eauto. } rewrite /= {1}envs_simple_replace_sound //; simpl. @@ -325,7 +331,7 @@ Qed. Lemma tac_wp_cmpxchg_fail Δ Δ' s E i K l q v v1 v2 Φ : MaybeIntoLaterNEnvs 1 Δ Δ' → envs_lookup i Δ' = Some (false, l ↦{q} v)%I → - val_for_compare v ≠val_for_compare v1 → vals_cmpxchg_compare_safe v v1 → + v ≠v1 → vals_compare_safe v v1 → envs_entails Δ' (WP fill K (Val $ PairV v (LitV $ LitBool false)) @ s; E {{ Φ }}) → envs_entails Δ (WP fill K (CmpXchg (LitV l) v1 v2) @ s; E {{ Φ }}). Proof. @@ -336,7 +342,7 @@ Proof. Qed. Lemma tac_twp_cmpxchg_fail Δ s E i K l q v v1 v2 Φ : envs_lookup i Δ = Some (false, l ↦{q} v)%I → - val_for_compare v ≠val_for_compare v1 → vals_cmpxchg_compare_safe v v1 → + v ≠v1 → vals_compare_safe v v1 → envs_entails Δ (WP fill K (Val $ PairV v (LitV $ LitBool false)) @ s; E [{ Φ }]) → envs_entails Δ (WP fill K (CmpXchg (LitV l) v1 v2) @ s; E [{ Φ }]). Proof. @@ -349,7 +355,7 @@ Lemma tac_wp_cmpxchg_suc Δ Δ' Δ'' s E i K l v v1 v2 Φ : MaybeIntoLaterNEnvs 1 Δ Δ' → envs_lookup i Δ' = Some (false, l ↦ v)%I → envs_simple_replace i false (Esnoc Enil i (l ↦ v2)) Δ' = Some Δ'' → - val_for_compare v = val_for_compare v1 → vals_cmpxchg_compare_safe v v1 → + v = v1 → vals_compare_safe v v1 → envs_entails Δ'' (WP fill K (Val $ PairV v (LitV $ LitBool true)) @ s; E {{ Φ }}) → envs_entails Δ (WP fill K (CmpXchg (LitV l) v1 v2) @ s; E {{ Φ }}). Proof. @@ -362,7 +368,7 @@ Qed. Lemma tac_twp_cmpxchg_suc Δ Δ' s E i K l v v1 v2 Φ : envs_lookup i Δ = Some (false, l ↦ v)%I → envs_simple_replace i false (Esnoc Enil i (l ↦ v2)) Δ = Some Δ' → - val_for_compare v = val_for_compare v1 → vals_cmpxchg_compare_safe v v1 → + v = v1 → vals_compare_safe v v1 → envs_entails Δ' (WP fill K (Val $ PairV v (LitV $ LitBool true)) @ s; E [{ Φ }]) → envs_entails Δ (WP fill K (CmpXchg (LitV l) v1 v2) @ s; E [{ Φ }]). Proof. @@ -530,12 +536,6 @@ Tactic Notation "wp_store" := | _ => fail "wp_store: not a 'wp'" end. -Ltac solve_vals_cmpxchg_compare_safe := - (* The first branch is for when we have [vals_cmpxchg_compare_safe] in the context. - The other two branches are for when either one of the branches reduces to - [True] or we have it in the context. *) - fast_done || (left; fast_done) || (right; fast_done). - Tactic Notation "wp_cmpxchg" "as" simple_intropattern(H1) "|" simple_intropattern(H2) := let solve_mapsto _ := let l := match goal with |- _ = Some (_, (?l ↦{_} _)%I) => l end in @@ -549,7 +549,7 @@ Tactic Notation "wp_cmpxchg" "as" simple_intropattern(H1) "|" simple_intropatter [iSolveTC |solve_mapsto () |pm_reflexivity - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |intros H1; wp_finish |intros H2; wp_finish] | |- envs_entails _ (twp ?E ?e ?Q) => @@ -558,7 +558,7 @@ Tactic Notation "wp_cmpxchg" "as" simple_intropattern(H1) "|" simple_intropatter |fail 1 "wp_cmpxchg: cannot find 'CmpXchg' in" e]; [solve_mapsto () |pm_reflexivity - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |intros H1; wp_finish |intros H2; wp_finish] | _ => fail "wp_cmpxchg: not a 'wp'" @@ -577,7 +577,7 @@ Tactic Notation "wp_cmpxchg_fail" := [iSolveTC |solve_mapsto () |try (simpl; congruence) (* value inequality *) - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |wp_finish] | |- envs_entails _ (twp ?s ?E ?e ?Q) => first @@ -585,7 +585,7 @@ Tactic Notation "wp_cmpxchg_fail" := |fail 1 "wp_cmpxchg_fail: cannot find 'CmpXchg' in" e]; [solve_mapsto () |try (simpl; congruence) (* value inequality *) - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |wp_finish] | _ => fail "wp_cmpxchg_fail: not a 'wp'" end. @@ -604,7 +604,7 @@ Tactic Notation "wp_cmpxchg_suc" := |solve_mapsto () |pm_reflexivity |try (simpl; congruence) (* value equality *) - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |wp_finish] | |- envs_entails _ (twp ?s ?E ?e ?Q) => first @@ -613,7 +613,7 @@ Tactic Notation "wp_cmpxchg_suc" := [solve_mapsto () |pm_reflexivity |try (simpl; congruence) (* value equality *) - |try solve_vals_cmpxchg_compare_safe + |try solve_vals_compare_safe |wp_finish] | _ => fail "wp_cmpxchg_suc: not a 'wp'" end. -- GitLab