Skip to content

Commit 7199129

Browse files
authored
feat: add not_value constraint to grind_pattern (#11520)
This PR implements the constraint `not_value x` in the `grind_pattern` command. It is the negation of the constraint `is_value`.
1 parent b0a12cb commit 7199129

File tree

6 files changed

+35
-1
lines changed

6 files changed

+35
-1
lines changed

src/Lean/Elab/Tactic/Grind/Main.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ where
115115
else if kind == ``isStrictValue then
116116
let (_, lhs) ← findLHS xs cnstr[1]
117117
return .isValue lhs true
118+
else if kind == ``notValue then
119+
let (_, lhs) ← findLHS xs cnstr[1]
120+
return .notValue lhs false
121+
else if kind == ``notStrictValue then
122+
let (_, lhs) ← findLHS xs cnstr[1]
123+
return .notValue lhs true
118124
else if kind == ``isGround then
119125
let (_, lhs) ← findLHS xs cnstr[1]
120126
return .isGround lhs

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ private def checkConstraints (thm : EMatchTheorem) (gen : Nat) (proof : Expr) (a
736736
| .depthLt lhs n => return (← getLHS args lhs).approxDepth.toNat < n
737737
| .isGround lhs => let lhs ← getLHS args lhs; return !lhs.hasFVar && !lhs.hasMVar
738738
| .isValue lhs strict => isValue (← getLHS args lhs) strict
739+
| .notValue lhs strict => return !(← isValue (← getLHS args lhs) strict)
739740
| .sizeLt lhs n => checkSize (← getLHS args lhs) n
740741
| .genLt n => return gen < n
741742
| .maxInsts n =>

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ inductive EMatchTheoremConstraint where
406406
Similar to `guard`, but checks whether `e` is implied by asserting `¬e`.
407407
-/
408408
check (e : Expr)
409+
| /--
410+
Constraints of the form `not_value x` and `not_strict_value x`.
411+
They are the negations of `is_value x` and `is_strict_value x`.
412+
-/
413+
notValue (bvarIdx : Nat) (strict : Bool)
409414
deriving Inhabited, Repr, BEq
410415

411416
/-- A theorem for heuristic instantiation based on E-matching. -/

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace GrindCnstr
1313

1414
def isValue := leading_parser nonReservedSymbol "is_value " >> ident >> optional ";"
1515
def isStrictValue := leading_parser nonReservedSymbol "is_strict_value " >> ident >> optional ";"
16+
def notValue := leading_parser nonReservedSymbol "not_value " >> ident >> optional ";"
17+
def notStrictValue := leading_parser nonReservedSymbol "not_strict_value " >> ident >> optional ";"
1618
def isGround := leading_parser nonReservedSymbol "is_ground " >> ident >> optional ";"
1719
def sizeLt := leading_parser nonReservedSymbol "size " >> ident >> " < " >> numLit >> optional ";"
1820
def depthLt := leading_parser nonReservedSymbol "depth " >> ident >> " < " >> numLit >> optional ";"
@@ -27,7 +29,7 @@ end GrindCnstr
2729

2830
open GrindCnstr in
2931
def grindPatternCnstr : Parser :=
30-
isValue <|> isStrictValue <|> isGround <|> sizeLt <|> depthLt <|> genLt <|> maxInsts
32+
isValue <|> isStrictValue <|> notValue <|> notStrictValue <|> isGround <|> sizeLt <|> depthLt <|> genLt <|> maxInsts
3133
<|> guard <|> GrindCnstr.check <|> notDefEq <|> defEq
3234

3335
def grindPatternCnstrs : Parser := leading_parser "where " >> many1Indent (ppLine >> grindPatternCnstr)
@@ -92,6 +94,10 @@ a literal (`Nat`, `Int`, `String`, etc.), or a lambda `fun x => t`.
9294
9395
- `is_strict_value x`: Similar to `is_value`, but without lambdas.
9496
97+
- `not_value x`: The term bound to `x` is a **not** value (see `is_value`).
98+
99+
- `not_strict_value x`: Similar to `not_value`, but without lambdas.
100+
95101
- `gen < n`: The theorem instance has generation less than `n`. Recall that each term is assigned a
96102
generation, and terms produced by theorem instantiation have a generation that is one greater than
97103
the maximal generation of all the terms used to instantiate the theorem. This constraint complements

stage0/src/stdlib_flags.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// update me!
12
#include "util/options.h"
23

34
namespace lean {

tests/lean/run/grind_pattern_cnstr_2.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,18 @@ example : f b = f c → a ≤ f a → f (f a) ≤ f (f (f a)) := by
293293
grind
294294

295295
end Ex13
296+
297+
namespace Ex14
298+
299+
opaque f : Nat → Nat
300+
axiom fax : f x ≤ x
301+
grind_pattern fax => f x where
302+
not_value x
303+
304+
/-- trace: [grind.ematch.instance] fax: f x ≤ x -/
305+
#guard_msgs in
306+
example : f 1 = a → f 2 = b → x ≤ y → f x ≤ y := by
307+
set_option trace.grind.ematch.instance true in
308+
grind
309+
310+
end Ex14

0 commit comments

Comments
 (0)