Skip to content

Commit 47a1355

Browse files
authored
chore: cleanup grind palindrome test (#8428)
1 parent 79254d0 commit 47a1355

File tree

5 files changed

+46
-10
lines changed

5 files changed

+46
-10
lines changed

src/Init/Data/Array/Lemmas.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ theorem toArray_eq : List.toArray as = xs ↔ as = xs.toList := by
6363

6464
/-! ### size -/
6565

66-
@[grind →] theorem eq_empty_of_size_eq_zero (h : xs.size = 0) : xs = #[] := by
66+
theorem eq_empty_of_size_eq_zero (h : xs.size = 0) : xs = #[] := by
6767
cases xs
6868
simp_all
6969

src/Init/Data/Vector/Lemmas.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ abbrev toArray_mkVector := @toArray_replicate
486486
`Vector.ext` is an extensionality theorem.
487487
Vectors `a` and `b` are equal to each other if their elements are equal for each valid index.
488488
-/
489-
@[ext]
489+
@[ext, grind ext]
490490
protected theorem ext {xs ys : Vector α n} (h : (i : Nat) → (_ : i < n) → xs[i] = ys[i]) : xs = ys := by
491491
apply Vector.toArray_inj.1
492492
apply Array.ext

src/Init/Ext.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ end Lean
8282
attribute [ext] Prod PProd Sigma PSigma
8383
attribute [ext] funext propext Subtype.eq Array.ext
8484

85+
attribute [grind ext] Array.ext
86+
8587
@[ext] protected theorem PUnit.ext (x y : PUnit) : x = y := rfl
8688
protected theorem Unit.ext (x y : Unit) : x = y := rfl
8789

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
set_option grind.warning false
2+
3+
def IsPalindrome (xs : Array Nat) : Prop := xs.reverse = xs
4+
5+
def checkPalin1 (xs : Array Nat) : Bool :=
6+
go 0
7+
where
8+
go (i : Nat) :=
9+
if h : i < xs.size / 2 then
10+
if xs[i] = xs[xs.size - 1 - i] then
11+
go (i + 1)
12+
else
13+
false
14+
else
15+
true
16+
17+
-- This give the more natural proof that we'd like to give in `tests/run/grind_palindrome2.lean`,
18+
-- but in which `grind` currently fails.
19+
20+
theorem checkPalin1_correct' : checkPalin1 xs = true ↔ IsPalindrome xs := by
21+
unfold checkPalin1
22+
suffices ∀ i, checkPalin1.go xs i = true ↔ ∀ j, i ≤ j → (_ : j < xs.size - i) → xs[j] = xs[xs.size - 1 - j] by
23+
grind [IsPalindrome]
24+
intro i
25+
fun_induction checkPalin1.go
26+
· grind (splits := 14)
27+
-- fails, but it would be nice to succeed! The key observations are:
28+
-- [eqc] True propositions ▼
29+
-- [prop] ∀ (a : Nat) (b : a + 1 ≤ xs.toList.length - x), a + 1 ≤ x ∨ xs[a] = xs[xs.toList.length - (a + 1)]
30+
-- [eqc] False propositions ▼
31+
-- [prop] xs[x] = xs[xs.toList.length - (x + 1)]
32+
-- Instantiating the `∀` with `a := x`, we can then easily prove `a + 1 ≤ xs.toList.length - x` and
33+
-- prove that it's not the case that `a + 1 ≤ x`, so we get `xs[x] = xs[xs.toList.length - (x + 1)]`,
34+
-- which is false.
35+
· grind
36+
-- The same argument should apply here.
37+
· grind

tests/lean/run/grind_palindrome2.lean

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,12 @@ where
1414
else
1515
true
1616

17-
example (xs : Array Nat) (w : xs.reverse = xs) (j : Nat) (hj : 0 ≤ j) (hj' : j < xs.size / 2) :
18-
xs[j] = xs[xs.size - 1 - j] := by
19-
grind
20-
21-
attribute [grind ext] Array.ext -- TODO: should we mark it by default?
22-
23-
theorem checkPalin1_correct' : checkPalin1 xs = true ↔ IsPalindrome xs := by
17+
-- This works nicely, but there is some human assistance here:
18+
-- on the right hand side of the `suffices` we've asserted it's enough to check up to `j < xs.size / 2`
19+
-- while the "natural" statement would be all the way to `j < xs.size - i`.
20+
theorem checkPalin1_correct : checkPalin1 xs = true ↔ IsPalindrome xs := by
2421
unfold checkPalin1
2522
suffices ∀ i, checkPalin1.go xs i = true ↔ ∀ j, i ≤ j → (_ : j < xs.size / 2) → xs[j] = xs[xs.size - 1 - j] by
2623
grind [IsPalindrome]
2724
intro i
28-
fun_induction checkPalin1.go <;> grind
25+
fun_induction checkPalin1.go with grind

0 commit comments

Comments
 (0)