Skip to content

Commit 9a5a9c2

Browse files
authored
feat: add is_value and is_strict_value grind_pattern constraints (#11409)
This PR implements support for the `grind_pattern` constraints `is_value` and `is_strict_value`.
1 parent 6eeb215 commit 9a5a9c2

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/Lean/Meta/Tactic/Grind/EMatch.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,20 @@ where
694694
go arg
695695
| _ => return ()
696696

697+
/-- Helper function for testing constraints of the form `is_value e` and `is_strict_value e` -/
698+
private partial def isValue (e : Expr) (strict : Bool) : MetaM Bool := do
699+
match_expr e with
700+
| Neg.neg _ _ e => isValue e strict
701+
| OfNat.ofNat _ n _ => return (← getNatValue? n).isSome
702+
| HDiv.hDiv _ _ _ _ a b => isValue a strict <&&> isValue b strict
703+
| _ =>
704+
if e.isLambda && !strict then return true
705+
if (← isLitValue e) then return true
706+
let some (ctorVal, args) ← constructorApp'? e | return false
707+
for h : i in ctorVal.numParams...args.size do
708+
unless (← isValue args[i] strict) do return false
709+
return true
710+
697711
/--
698712
Checks whether `vars` satisfies the `grind_pattern` constraints attached at `thm`.
699713
Example:
@@ -718,6 +732,7 @@ private def checkConstraints (thm : EMatchTheorem) (gen : Nat) (proof : Expr) (a
718732
| .defEq lhs rhs => checkDefEq (expectedResult := true) info.levelParams us args lhs rhs
719733
| .depthLt lhs n => return (← getLHS args lhs).approxDepth.toNat < n
720734
| .isGround lhs => let lhs ← getLHS args lhs; return !lhs.hasFVar && !lhs.hasMVar
735+
| .isValue lhs strict => isValue (← getLHS args lhs) strict
721736
| .sizeLt lhs n => checkSize (← getLHS args lhs) n
722737
| .genLt n => return gen < n
723738
| .maxInsts n =>

tests/lean/run/grind_pattern_cnstr_2.lean

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,50 @@ example (h : g [1, 2, 3] > 0) : False := by
108108
grind
109109

110110
end Ex6
111+
112+
namespace Ex7
113+
114+
opaque f {α : Type u} : List α × α → Nat
115+
axiom fax : f x > 0
116+
117+
grind_pattern fax => f x where
118+
is_value x
119+
120+
/--
121+
trace: [grind.ematch.instance] fax: f ([true], false) > 0
122+
[grind.ematch.instance] fax: f ([1, 2], 4) > 0
123+
[grind.ematch.instance] fax: f ([fun x => x], fun x => x) > 0
124+
-/
125+
#guard_msgs (drop error, trace) in
126+
set_option trace.grind.ematch.instance true in
127+
example
128+
: f (as, bs) = f ([1], c) →
129+
f ([fun x : Nat => x], fun y => y) = d →
130+
f ([1, 2], 4) = f ([true], false) →
131+
False := by
132+
grind
133+
134+
end Ex7
135+
136+
namespace Ex8
137+
138+
opaque f {α : Type u} : List α × α → Nat
139+
axiom fax : f x > 0
140+
141+
grind_pattern fax => f x where
142+
is_strict_value x
143+
144+
/--
145+
trace: [grind.ematch.instance] fax: f ([true], false) > 0
146+
[grind.ematch.instance] fax: f ([1, 2], 4) > 0
147+
-/
148+
#guard_msgs (drop error, trace) in
149+
set_option trace.grind.ematch.instance true in
150+
example
151+
: f (as, bs) = f ([1], c) →
152+
f ([fun x : Nat => x], fun y => y) = d →
153+
f ([1, 2], 4) = f ([true], false) →
154+
False := by
155+
grind
156+
157+
end Ex8

0 commit comments

Comments
 (0)