lean4-htt/src/Lean
Leonardo de Moura 075f1d66eb
feat: guard and check in grind_pattern (#11428)
This PR implements support for **guards** in `grind_pattern`. The new
feature provides additional control over theorem instantiation. For
example, consider the following monotonicity theorem:

```lean
opaque f : Nat → Nat
theorem fMono : x ≤ y → f x ≤ f y := ...
```

We can use `grind_pattern` to instruct `grind` to instantiate the
theorem for every pair `f x` and `f y` occurring in the goal:

```lean
grind_pattern fMono => f x, f y
```

Then we can automatically prove the following simple example using
`grind`:

```lean
/--
trace: [grind.ematch.instance] fMono: f a ≤ b → f (f a) ≤ f b
[grind.ematch.instance] fMono: f a ≤ c → f (f a) ≤ f c
[grind.ematch.instance] fMono: f a ≤ a → f (f a) ≤ f a
[grind.ematch.instance] fMono: f a ≤ f (f a) → f (f a) ≤ f (f (f a))
[grind.ematch.instance] fMono: f a ≤ f a → f (f a) ≤ f (f a)
[grind.ematch.instance] fMono: f (f a) ≤ b → f (f (f a)) ≤ f b
[grind.ematch.instance] fMono: f (f a) ≤ c → f (f (f a)) ≤ f c
[grind.ematch.instance] fMono: f (f a) ≤ a → f (f (f a)) ≤ f a
[grind.ematch.instance] fMono: f (f a) ≤ f (f a) → f (f (f a)) ≤ f (f (f a))
[grind.ematch.instance] fMono: f (f a) ≤ f a → f (f (f a)) ≤ f (f a)
[grind.ematch.instance] fMono: a ≤ b → f a ≤ f b
[grind.ematch.instance] fMono: a ≤ c → f a ≤ f c
[grind.ematch.instance] fMono: a ≤ a → f a ≤ f a
[grind.ematch.instance] fMono: a ≤ f (f a) → f a ≤ f (f (f a))
[grind.ematch.instance] fMono: a ≤ f a → f a ≤ f (f a)
[grind.ematch.instance] fMono: c ≤ b → f c ≤ f b
[grind.ematch.instance] fMono: c ≤ c → f c ≤ f c
[grind.ematch.instance] fMono: c ≤ a → f c ≤ f a
[grind.ematch.instance] fMono: c ≤ f (f a) → f c ≤ f (f (f a))
[grind.ematch.instance] fMono: c ≤ f a → f c ≤ f (f a)
[grind.ematch.instance] fMono: b ≤ b → f b ≤ f b
[grind.ematch.instance] fMono: b ≤ c → f b ≤ f c
[grind.ematch.instance] fMono: b ≤ a → f b ≤ f a
[grind.ematch.instance] fMono: b ≤ f (f a) → f b ≤ f (f (f a))
[grind.ematch.instance] fMono: b ≤ f a → f b ≤ f (f a)
-/
#guard_msgs in
example : f b = f c → a ≤ f a → f (f a) ≤ f (f (f a)) := by
  set_option trace.grind.ematch.instance true in
  grind
```

However, many unnecessary theorem instantiations are generated.

With the new `guard` feature, we can instruct `grind` to instantiate the
theorem **only if** `x ≤ y` is already known to be true in the current
`grind` state:

```lean
grind_pattern fMono => f x, f y where
  guard x ≤ y
  x =/= y
```

If we run the example again, only three instances are generated:

```lean
/--
trace: [grind.ematch.instance] fMono: a ≤ f a → f a ≤ f (f a)
[grind.ematch.instance] fMono: f a ≤ f (f a) → f (f a) ≤ f (f (f a))
[grind.ematch.instance] fMono: a ≤ f (f a) → f a ≤ f (f (f a))
-/
#guard_msgs in
example : f b = f c → a ≤ f a → f (f a) ≤ f (f (f a)) := by
  set_option trace.grind.ematch.instance true in
  grind
```

Note that `guard` does **not** check whether the expression is
*implied*. It only checks whether the expression is *already known* to
be true in the current `grind` state. If this fact is eventually
learned, the theorem will be instantiated.

If you want `grind` to check whether the expression is implied, you
should use:

```lean
grind_pattern fMono => f x, f y where
  check x ≤ y
  x =/= y
```

Remark: we can use multiple `guard`/`check`s in a `grind_pattern`
command.
2025-11-29 03:56:53 +00:00
..
Compiler perf: sort before elim dead branches (#11366) 2025-11-27 22:21:06 +00:00
Data refactor: String functions foldr, all, any, contains to go trough String.Slice (#11357) 2025-11-25 15:42:43 +00:00
DocString refactor: String functions foldr, all, any, contains to go trough String.Slice (#11357) 2025-11-25 15:42:43 +00:00
Elab feat: some grind_pattern constraints (#11405) 2025-11-27 18:05:47 +00:00
ErrorExplanations chore: keep error explanations in sync (#11360) 2025-11-25 19:03:07 +00:00
Language chore: revert "refactor: port shell option processing to Lean" (#11378) 2025-11-26 09:28:48 +00:00
LibrarySuggestions feat: set_library_suggestions makes auxiliary def, rather than storing Syntax 2025-11-29 01:08:47 +11:00
Linter feat: document that backward options may disappear (#11304) 2025-11-24 17:49:46 +00:00
Meta feat: guard and check in grind_pattern (#11428) 2025-11-29 03:56:53 +00:00
Parser refactor: String functions foldr, all, any, contains to go trough String.Slice (#11357) 2025-11-25 15:42:43 +00:00
ParserCompiler chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
PrettyPrinter refactor: deprecate String.posOf and variants in favor of unified String.find (#11276) 2025-11-23 18:39:53 +00:00
Server fix: move the monad argument for ForIn, ForIn', and ForM (#10204) 2025-11-25 12:20:37 +00:00
Util feat: document that backward options may disappear (#11304) 2025-11-24 17:49:46 +00:00
Widget chore: rename String.Range to Lean.Syntax.Range (#10852) 2025-10-21 07:32:25 +00:00
AddDecl.lean test: avoid testing colliding private inductives (#11041) 2025-11-01 11:47:52 +00:00
Attributes.lean chore: make declMetaExt persistent for shake (#11201) 2025-11-16 20:11:56 +00:00
AuxRecursor.lean feat: sparse casesOn constructions (#11072) 2025-11-05 15:49:11 +00:00
BuiltinDocAttr.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Class.lean
Compiler.lean chore: remove public section from end of files (#10684) 2025-10-06 13:30:48 +00:00
CoreM.lean feat: catch and provide context for misuse of NNG-style induction pattern (#11347) 2025-11-25 18:44:40 +00:00
Data.lean chore: remove public section from end of files (#10684) 2025-10-06 13:30:48 +00:00
Declaration.lean chore: >6 month old deprecations (#10969) 2025-10-26 22:48:41 +00:00
DeclarationRange.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
DefEqAttrib.lean
DocString.lean
Elab.lean feat: with_weak_namespace command (#11338) 2025-11-25 02:37:40 +00:00
EnvExtension.lean feat: shake import minimizer aware of the module system and arbitrary elaboration dependencies (#10575) 2025-09-28 16:00:00 +00:00
Environment.lean chore: CI: enable leak sanitizer again (#11339) 2025-11-27 18:32:35 +00:00
ErrorExplanation.lean chore: rename String.ValidPos to String.Pos (#11240) 2025-11-24 16:40:21 +00:00
ErrorExplanations.lean feat: improve error message in the case of type class synthesis failure (#11245) 2025-11-21 21:24:27 +00:00
Exception.lean feat: hint about inaccessible private declaration on dot notation failure (#10803) 2025-10-17 09:31:56 +00:00
Expr.lean fix: move the monad argument for ForIn, ForIn', and ForM (#10204) 2025-11-25 12:20:37 +00:00
ExtraModUses.lean chore: make declMetaExt persistent for shake (#11201) 2025-11-16 20:11:56 +00:00
HeadIndex.lean
Hygiene.lean chore: do not set unused Option.Decl.group (#11307) 2025-11-21 16:44:38 +00:00
ImportingFlag.lean chore: miscellaneous documentation typos (#10009) 2025-08-20 21:39:03 +00:00
InternalExceptionId.lean chore: reorganize Init imports around strings (#10289) 2025-09-07 17:09:14 +00:00
KeyedDeclsAttribute.lean fix: some ExtraModUses (#10620) 2025-10-03 15:50:40 +00:00
LabelAttribute.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Level.lean fix: move the monad argument for ForIn, ForIn', and ForM (#10204) 2025-11-25 12:20:37 +00:00
LibrarySuggestions.lean fix: make library suggestions available in module files (#11373) 2025-11-26 05:39:27 +00:00
Linter.lean chore: remove public section from end of files (#10684) 2025-10-06 13:30:48 +00:00
LoadDynlib.lean refactor: use String.Slice in String.take and variants (#11180) 2025-11-18 16:13:48 +00:00
LocalContext.lean fix: move the monad argument for ForIn, ForIn', and ForM (#10204) 2025-11-25 12:20:37 +00:00
Log.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Message.lean refactor: use String.split instead of String.splitOn or String.splitToList (#11250) 2025-11-19 09:35:19 +00:00
Meta.lean feat: @[method_specs] to generate specification theorems from class instances (#10302) 2025-09-15 11:17:06 +00:00
MetavarContext.lean fix: remove superfluous Monad instances from some spec lemmas (#10564) (#10618) 2025-09-29 15:02:43 +00:00
Modifiers.lean chore: more module system fixes and refinements for finishing batteries port (#10819) 2025-10-21 08:19:50 +00:00
MonadEnv.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Namespace.lean
Parser.lean feat: hexnum parser (#10716) 2025-10-08 21:12:03 +00:00
ParserCompiler.lean chore: make declMetaExt persistent for shake (#11201) 2025-11-16 20:11:56 +00:00
PrettyPrinter.lean chore: do not set unused Option.Decl.group (#11307) 2025-11-21 16:44:38 +00:00
PrivateName.lean
ProjFns.lean
ReducibilityAttrs.lean feat: allow setting reducibilityCoreExt in async contexts (#11301) 2025-11-21 09:23:14 +00:00
Replay.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
ReservedNameAction.lean
ResolveName.lean chore: more module system fixes and refinements for finishing batteries port (#10819) 2025-10-21 08:19:50 +00:00
Runtime.lean
ScopedEnvExtension.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Server.lean feat: revamp server logging (#10787) 2025-10-28 16:26:59 +00:00
Setup.lean fix: symbol clashes between packages (#11082) 2025-11-19 02:24:44 +00:00
Shell.lean chore: revert "refactor: port shell option processing to Lean" (#11378) 2025-11-26 09:28:48 +00:00
Structure.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
SubExpr.lean refactor: use String.split instead of String.splitOn or String.splitToList (#11250) 2025-11-19 09:35:19 +00:00
Syntax.lean fix: move the monad argument for ForIn, ForIn', and ForM (#10204) 2025-11-25 12:20:37 +00:00
ToExpr.lean feat: support for Rat scientific literals (#10961) 2025-10-26 02:05:26 +00:00
ToLevel.lean
Util.lean feat: instantiate tactic parameter optimizer (#10916) 2025-10-23 01:22:33 +00:00
Widget.lean chore: remove public section from end of files (#10684) 2025-10-06 13:30:48 +00:00