Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: grind #6440

Merged
merged 5 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Lean/Meta/Tactic/Grind/Types.lean
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ def getENode? (e : Expr) : GoalM (Option ENode) :=

/-- Returns node associated with `e`. It assumes `e` has already been internalized. -/
def getENode (e : Expr) : GoalM ENode := do
let some n := (← get).enodes.find? (unsafe ptrAddrUnsafe e) | unreachable!
let some n := (← get).enodes.find? (unsafe ptrAddrUnsafe e)
| throwError "internal `grind` error, term has not been internalized{indentExpr e}"
return n

/-- Returns `true` is the root of its equivalence class. -/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ elab "grind_test" : tactic => withMainContext do
let nodes ← filterENodes fun e => return e.self.isAppOf ``HMul.hMul
logInfo (nodes.toList.map (·.self))

set_option grind.debug true

class Semigroup (α : Type u) extends Mul α where
mul_assoc (a b c : α) : a * b * c = a * (b * c)

Expand Down
34 changes: 34 additions & 0 deletions tests/lean/run/grind_many_eqs.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Lean

def f (a : Nat) := a + a + a
def g (a : Nat) := a + a
def h (n : Nat) : Prop :=
match n with
| 0 => f 0 = f 1
| n+1 => f (n+1) = f n ∧ g (2*n + 1) = g (2*n) ∧ h n

-- Prints the equivalence class containing a `f` application
open Lean Meta Elab Tactic Grind in
elab "grind_test" n:num : tactic => withMainContext do
let n := n.getNat
let declName := (← Term.getDeclName?).getD `_main
Meta.Grind.preprocessAndProbe (← getMainGoal) declName do
let f0 ← Grind.shareCommon (mkApp (mkConst ``f) (mkNatLit 0))
-- The `f 0` equivalence class contains `n+1` elements
assert! (← getEqc f0).length == n + 1
forEachENode fun node => do
if node.self.isAppOf ``g then
-- Any equivalence class containing a `g`-application contains 2 elements
assert! (← getEqc (← getRoot node.self)).length == 2

set_option grind.debug true in
example : h 5 → False := by
simp [h]
grind_test 5
sorry

set_option maxRecDepth 2048
example : h 100 → False := by
simp [h]
grind_test 100
sorry
26 changes: 26 additions & 0 deletions tests/lean/run/grind_nested_proofs.lean
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,43 @@ elab "grind_test" : tactic => withMainContext do
Meta.Grind.preprocessAndProbe (← getMainGoal) declName do
let nodes ← filterENodes fun e => return e.self.isAppOf ``Lean.Grind.nestedProof
logInfo (nodes.toList.map (·.self))
let nodes ← filterENodes fun e => return e.self.isAppOf ``GetElem.getElem
let [_, n, _] := nodes.toList | unreachable!
logInfo (← getEqc n.self)

set_option grind.debug true

/-
Recall that array access terms, such as `a[i]`, have nested proofs.
The following test relies on `grind` `nestedProof` wrapper to
detect equalities between array access terms.
-/

/--
info: [Lean.Grind.nestedProof (i < a.toList.length) (_example.proof_1 i j a b h1 h2),
Lean.Grind.nestedProof (j < a.toList.length) h1,
Lean.Grind.nestedProof (j < b.toList.length) h]
---
info: [a[i], b[j], a[j]]
---
warning: declaration uses 'sorry'
-/
#guard_msgs in
example (i j : Nat) (a b : Array Nat) (h1 : j < a.size) (h : j < b.size) (h2 : i ≤ j) : a[i] < a[j] + b[j] → i = j → a = b → False := by
grind_test
sorry


/--
info: [Lean.Grind.nestedProof (i < a.toList.length) (_example.proof_1 i j a b h1 h2),
Lean.Grind.nestedProof (j < a.toList.length) h1,
Lean.Grind.nestedProof (j < b.toList.length) h]
---
info: [a[i], a[j]]
---
warning: declaration uses 'sorry'
-/
#guard_msgs in
example (i j : Nat) (a b : Array Nat) (h1 : j < a.size) (h : j < b.size) (h2 : i ≤ j) : a[i] < a[j] + b[j] → i = j → False := by
grind_test
sorry
Loading