|
| 1 | +import Std.Data.HashSet |
| 2 | + |
| 3 | +open Std |
| 4 | + |
| 5 | +example (seen : HashSet Int) (xs : List Int) (x : Int) (h : ¬-x ∈ seen) : |
| 6 | + (∃ a, a ∈ seen.insert x ∧ ∃ b, b ∈ xs ∧ a + b = 0) ↔ |
| 7 | + (∃ y, y ∈ xs ∧ x + y = 0) ∨ ∃ a, a ∈ seen ∧ ∃ b, b ∈ x :: xs ∧ a + b = 0 := by |
| 8 | + -- In 4.22.0-rc2, this example used to work without the `simp only` because patterns containing `+` were being selected. |
| 9 | + -- By unfolding `HashSet.mem_insert` before invoking `grind` we change the pattern that is selected. That is, `_ ∈ seen` is selected. |
| 10 | + simp only [HashSet.mem_insert] |
| 11 | + grind |
| 12 | + |
| 13 | +-- The example also works when we restore `HAdd.hAdd` priority. |
| 14 | +-- We say this example worked by "accident" before. |
| 15 | +attribute [local grind symbol default] HAdd.hAdd in |
| 16 | +example (seen : HashSet Int) (xs : List Int) (x : Int) (h : ¬-x ∈ seen) : |
| 17 | + (∃ a, a ∈ seen.insert x ∧ ∃ b, b ∈ xs ∧ a + b = 0) ↔ |
| 18 | + (∃ y, y ∈ xs ∧ x + y = 0) ∨ ∃ a, a ∈ seen ∧ ∃ b, b ∈ x :: xs ∧ a + b = 0 := by |
| 19 | + grind |
| 20 | + |
| 21 | +/- |
| 22 | +Here is an encoding trick used in the SMT community. |
| 23 | +Terms like `x + y` are rarely used in patterns because |
| 24 | +they generate too many instances, and because arithmetical |
| 25 | +terms are often normalized by SMT solvers. However, for E-matching, |
| 26 | +`+` is just another symbol. The E-matcher does not know that it is, |
| 27 | +for example, associative and commutative (AC). |
| 28 | +If you want to E-match against an arithmetical relation, you can |
| 29 | +introduce an auxiliary definition to make the pattern matching more effective. |
| 30 | +Example: |
| 31 | +-/ |
| 32 | +@[grind] def IsAddInv (a b : Int) : Prop := a = -b |
| 33 | +example (seen : HashSet Int) (xs : List Int) (x : Int) (h : ¬-x ∈ seen) : |
| 34 | + (∃ a, a ∈ seen.insert x ∧ ∃ b, b ∈ xs ∧ IsAddInv a b) ↔ |
| 35 | + (∃ y, y ∈ xs ∧ IsAddInv x y) ∨ ∃ a, a ∈ seen ∧ ∃ b, b ∈ x :: xs ∧ IsAddInv a b := by |
| 36 | + grind |
0 commit comments