lean4-htt/tests/lean/run/grind_split.lean
Leonardo de Moura 189f5d41fb
feat: case splitting in grind (#6717)
This PR introduces a new feature that allows users to specify which
inductive datatypes the `grind` tactic should perform case splits on.
The configuration option `splitIndPred` is now set to `false` by
default. The attribute `[grind cases]` is used to mark inductive
datatypes and predicates that `grind` may case split on during the
search. Additionally, the attribute `[grind cases eager]` can be used to
mark datatypes and predicates for case splitting both during
pre-processing and the search.

Users can also write `grind [HasType]` or `grind [cases HasType]` to
instruct `grind` to perform case splitting on the inductive predicate
`HasType` in a specific instance. Similarly, `grind [-Or]` can be used
to instruct `grind` not to case split on disjunctions.

Co-authored-by: Leonardo de Moura <leodemoura@amazon.com>
2025-01-20 22:44:56 +00:00

66 lines
1.8 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

set_option trace.grind.split true
set_option trace.grind.eqc true
example (p q : Prop) : p q → p ¬q → ¬p q → ¬p ¬q → False := by
grind
opaque R : Nat → Prop
/--
info: [grind] working on goal `grind`
[grind.eqc] (if p then a else b) = c
[grind.eqc] R a = True
[grind.eqc] R b = True
[grind.eqc] R c = False
[grind.split] if p then a else b, generation: 0
[grind] working on goal `grind.1`
[grind.eqc] p = True
[grind.eqc] (if p then a else b) = a
[grind.eqc] R a = R c
[grind] closed `grind.1`
[grind] working on goal `grind.2`
[grind.eqc] p = False
[grind.eqc] (if p then a else b) = b
[grind.eqc] R b = R c
[grind] closed `grind.2`
-/
#guard_msgs (info) in
set_option trace.grind true in
example (p : Prop) [Decidable p] (a b c : Nat) : (if p then a else b) = c → R a → R b → R c := by
grind
example (p : Prop) [Decidable p] (a b c : Nat) : (if p then a else b) = c → R a → R b → R c := by
fail_if_success grind (splitIte := false)
sorry
namespace grind_test_induct_pred
inductive Expr where
| nat : Nat → Expr
| plus : Expr → Expr → Expr
| bool : Bool → Expr
| and : Expr → Expr → Expr
deriving DecidableEq
inductive Ty where
| nat
| bool
deriving DecidableEq
inductive HasType : Expr → Ty → Prop
| nat : HasType (.nat v) .nat
| plus : HasType a .nat → HasType b .nat → HasType (.plus a b) .nat
| bool : HasType (.bool v) .bool
| and : HasType a .bool → HasType b .bool → HasType (.and a b) .bool
set_option trace.grind true
theorem HasType.det (h₁ : HasType e t₁) (h₂ : HasType e t₂) : t₁ = t₂ := by
grind [HasType]
example (h₁ : HasType e t₁) (h₂ : HasType e t₂) : t₁ = t₂ := by
grind +splitIndPred
example (h₁ : HasType e t₁) (h₂ : HasType e t₂) : t₁ = t₂ := by
fail_if_success grind
sorry
end grind_test_induct_pred