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>
66 lines
1.8 KiB
Text
66 lines
1.8 KiB
Text
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
|