diff --git a/CHANGELOG.md b/CHANGELOG.md index ccdb039403016480dedf737cbd0e6ddd7fbdafac..0282b1e86d32da7f644c78c31e4a637482cc06af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,7 +112,8 @@ API-breaking change is listed. - Add `mk_evar` tactic to generate evars (intended as a more useful replacement for Coq's `evar` tactic). - Make `solve_ndisj` able to solve more goals of the form `_ ⊆ ⊤ ∖ _`, - `_ ∖ _ ## _`, `_ ## _ ∖ _`, as well as `_ ## ∅` and `∅ ## _`. + `_ ∖ _ ## _`, `_ ## _ ∖ _`, as well as `_ ## ∅` and `∅ ## _`, + and goals containing `_ ∖ _ ∖ _`. - Improvements to curry: + Swap names of `curry`/`uncurry`, `curry3`/`uncurry3`, `curry4`/`uncurry4`, `gmap_curry`/`gmap_uncurry`, and `hcurry`/`huncurry` to be consistent with diff --git a/tests/solve_ndisj.v b/tests/solve_ndisj.v index fe6aebdb361fabaa0e2cc52c5bea1a262e8b63cc..662824d0e3a5afe98d6c3d50fc683e97697dbdae 100644 --- a/tests/solve_ndisj.v +++ b/tests/solve_ndisj.v @@ -43,3 +43,7 @@ Proof. solve_ndisj. Qed. Lemma test9 N1 N2 : ⊤ ∖ (↑N1 ∪ ↑N2) ⊆@{coPset} ⊤ ∖ ↑N1.@"counter" ∖ ↑N1.@"state" ∖ ↑N2. Proof. solve_ndisj. Qed. + +Lemma test10 N1 N2 E : + ↑N1 ∪ E ## ⊤ ∖ ↑N1 ∖ ↑N2 ∖ E. +Proof. solve_ndisj. Qed. diff --git a/theories/namespaces.v b/theories/namespaces.v index 094afabc818ee2cedd4f09e9f4a6ee4f24f22828..975d7f48fd73448c7e453b7e33b0b4bc58adc4f6 100644 --- a/theories/namespaces.v +++ b/theories/namespaces.v @@ -97,13 +97,7 @@ Global Hint Resolve nclose_subseteq' | 100 : ndisj. (** Rules for goals of the form [_ ## _] *) (** The base rule that we want to ultimately get down to. *) Global Hint Extern 0 (_ ## _) => apply ndot_ne_disjoint; congruence : ndisj. -(** Fallback, loses lots of information but lets other rules make progress. -Tests show trying [disjoint_difference_l1] first gives better performance. *) -Local Definition coPset_disjoint_difference_l1 := disjoint_difference_l1 (C:=coPset). -Global Hint Resolve coPset_disjoint_difference_l1 | 50 : ndisj. -Local Definition coPset_disjoint_difference_l2 := disjoint_difference_l2 (C:=coPset). -Global Hint Resolve coPset_disjoint_difference_l2 | 100 : ndisj. -Global Hint Resolve ndot_preserve_disjoint_l ndot_preserve_disjoint_r | 100 : ndisj. +(** Trivial cases. *) Local Definition coPset_disjoint_empty_l := disjoint_empty_l (C:=coPset). Global Hint Resolve coPset_disjoint_empty_l : ndisj. Local Definition coPset_disjoint_empty_r := disjoint_empty_r (C:=coPset). @@ -115,6 +109,20 @@ Global Hint Extern 10 (_ ## (_ ∖ _)) => | |- (_ ∖ _) ## _ => fail (* ∖ on both sides, leave it be *) | |- _ => symmetry end : ndisj. +(** Before we apply disjoint_difference, let's make sure we normalize the goal +to [_ ∖ (_ ∪ _)]. *) +Local Lemma coPset_difference_difference (X1 X2 X3 Y : coPset) : + X1 ∖ (X2 ∪ X3) ## Y → + X1 ∖ X2 ∖ X3 ## Y. +Proof. set_solver. Qed. +Global Hint Resolve coPset_difference_difference | 20 : ndisj. +(** Fallback, loses lots of information but lets other rules make progress. +Tests show trying [disjoint_difference_l1] first gives better performance. *) +Local Definition coPset_disjoint_difference_l1 := disjoint_difference_l1 (C:=coPset). +Global Hint Resolve coPset_disjoint_difference_l1 | 50 : ndisj. +Local Definition coPset_disjoint_difference_l2 := disjoint_difference_l2 (C:=coPset). +Global Hint Resolve coPset_disjoint_difference_l2 | 100 : ndisj. +Global Hint Resolve ndot_preserve_disjoint_l ndot_preserve_disjoint_r | 100 : ndisj. Ltac solve_ndisj := repeat match goal with