Compare commits

...

4 Commits

Author SHA1 Message Date
Leonardo de Moura
e139c2d4d4 chore: move test 2025-04-11 19:21:07 -07:00
Leonardo de Moura
a7e22ee701 chore: cleanup test 2025-04-11 19:19:26 -07:00
Leonardo de Moura
e64bf4bb5b test: add new test 2025-04-11 19:04:47 -07:00
Leonardo de Moura
12d009ad3c chore: improve error message 2025-04-11 19:03:53 -07:00
3 changed files with 35 additions and 24 deletions

View File

@@ -97,7 +97,8 @@ def _root_.Lean.MVarId.clearAuxDecls (mvarId : MVarId) : MetaM MVarId := mvarId.
try
mvarId mvarId.clear fvarId
catch _ =>
throwTacticEx `grind.clear_aux_decls mvarId "failed to clear local auxiliary declaration"
let userName := ( fvarId.getDecl).userName
throwTacticEx `grind mvarId m!"the goal mentions the declaration `{userName}`, which is being defined. To avoid circular reasoning, try rewriting the goal to eliminate `{userName}` before using `grind`."
return mvarId
/--

View File

@@ -0,0 +1,17 @@
reset_grind_attrs%
set_option grind.warning false
attribute [grind] List.not_mem_nil
/--
error: tactic 'grind' failed, the goal mentions the declaration `incList`, which is being defined. To avoid circular reasoning, try rewriting the goal to eliminate `incList` before using `grind`.
as✝ : List Nat
a : Nat
as : List Nat
⊢ ∀ (a : Nat), a ∈ (incList as).val → a > 0
-/
#guard_msgs (error) in
def incList (as : List Nat) : { as : List Nat // a, a as a > 0 } :=
match as with
| [] => [], by grind
| a::as => (incList as).1, by grind

View File

@@ -187,9 +187,6 @@ def IfNormalization : Type := { Z : IfExpr → IfExpr // ∀ e, (Z e).normalized
See `Statement.lean` for background.
-/
macro "" : tactic => `(tactic| grind)
macro "" : term => `(term| by grind)
set_option grind.warning false
namespace IfExpr
@@ -228,6 +225,9 @@ We don't want a `simp` lemma for `(ite i t e).eval` in general, only once we kno
| var _ => 1
| .ite i t e => 2 * normSize i + max (normSize t) (normSize e) + 1
notation "g⟨" a "" => a, by grind
macro "c⟨" a:term "" : term => `(have aux := $a; aux.1, by grind)
/-- Normalizes the expression at the same time as assigning all variables in
`e` to the literal booleans given by `l` -/
def normalize (l : AList (fun _ : Nat => Bool)) :
@@ -235,40 +235,33 @@ def normalize (l : AList (fun _ : Nat => Bool)) :
( f, e'.eval f = e.eval (fun w => (l.lookup w).elim (f w) id))
e'.normalized
(v : Nat), v vars e' l.lookup v = none }
| lit b => lit b,
| lit b => glit b
| var v =>
match h : l.lookup v with
| none => var v,
| some b => lit b,
| .ite (lit true) t e =>
-- Fails with `tactic 'grind.clear_aux_decls' failed`:
(normalize l t).1,
-- Workaround:
-- have t' := normalize l t; ⟨t'.1, ◾⟩
| .ite (lit false) t e => have e' := normalize l e; e'.1,
| .ite (.ite a b c) t e => have i' := normalize l (.ite a (.ite b t e) (.ite c t e)); i'.1,
| none => gvar v
| some b => glit b
| .ite (lit true) t e => cnormalize l t
| .ite (lit false) t e => cnormalize l e
| .ite (.ite a b c) t e => cnormalize l (.ite a (.ite b t e) (.ite c t e))
| .ite (var v) t e =>
match h : l.lookup v with
| none =>
have t', _ := normalize (l.insert v true) t
have e', _ := normalize (l.insert v false) e
if t' = e' then t' else .ite (var v) t' e', by
-- TODO: automate this proof
refine fun f => ?_, ?_, fun w b => ?_
· -- eval = eval
simp only [apply_ite, eval_ite_var]
cases hfv : f v
· simp_all
·
· simp_all; grind
· grind
· -- normalized
split
·
· simp only [normalized, disjoint]
· -- lookup = none
| some b =>
have i' := normalize l (.ite (lit b) t e); i'.1,
· grind
· simp only [normalized, disjoint]; grind
· grind
| some b => cnormalize l (.ite (lit b) t e)
termination_by e => e.normSize
/-