This PR implements user-defined `grind` attributes. They are useful for users that want to implement tactics using the `grind` infrastructure (e.g., `progress*` in Aeneas). New `grind` attributes are declared using the command ```lean register_grind_attr my_grind ``` The command is similar to `register_simp_attr`. After the new attribute is declared. Recall that similar to `register_simp_attr`, the new attribute cannot be used in the same file it is declared. ```lean opaque f : Nat → Nat opaque g : Nat → Nat @[my_grind] theorem fax : f (f x) = f x := sorry example theorem fax2 : f (f (f x)) = f x := by fail_if_success grind grind [my_grind] ``` TODO: remove leftovers after update stage0
54 lines
1 KiB
Text
54 lines
1 KiB
Text
import Lean
|
||
|
||
open Lean Meta Tactic Grind
|
||
|
||
def runGrind (x : GrindM α) : MetaM α := do
|
||
GrindM.run x (← mkDefaultParams {})
|
||
|
||
@[noinline] def mkA (x : Nat) := x + 1
|
||
|
||
def tst (a b : Nat) : GrindM Unit := do
|
||
IO.println a
|
||
IO.println b
|
||
let a ← shareCommon (mkNatLit a)
|
||
let b ← shareCommon (mkNatLit b)
|
||
IO.println (isSameExpr a b)
|
||
|
||
/--
|
||
info: 1000000000000000000000000001
|
||
1000000000000000000000000001
|
||
true
|
||
-/
|
||
#guard_msgs (info) in
|
||
run_meta do
|
||
let a := mkA 1000000000000000000000000000
|
||
let b := 1000000000000000000000000001
|
||
runGrind (tst a b)
|
||
|
||
/--
|
||
info: 1001
|
||
1001
|
||
true
|
||
-/
|
||
#guard_msgs (info) in
|
||
run_meta do
|
||
let a := mkA 1000
|
||
let b := 1001
|
||
runGrind (tst a b)
|
||
|
||
def tst2 (a b : Nat) : IO Unit := do
|
||
IO.println a
|
||
IO.println b
|
||
let (a, b) := ShareCommon.shareCommon' (mkNatLit a, mkNatLit b)
|
||
IO.println (isSameExpr a b)
|
||
|
||
/--
|
||
info: 1000000000000000000000000001
|
||
1000000000000000000000000001
|
||
true
|
||
-/
|
||
#guard_msgs (info) in
|
||
run_meta do
|
||
let a := mkA 1000000000000000000000000000
|
||
let b := 1000000000000000000000000001
|
||
tst2 a b
|