Compare commits

...

19 Commits

Author SHA1 Message Date
Kim Morrison
0f9aa00ff6 . 2025-09-24 06:48:31 +02:00
Kim Morrison
c55dbd9526 . 2025-09-24 06:45:15 +02:00
Kim Morrison
c07ce8cbb3 cleanup 2025-09-24 05:55:26 +02:00
Kim Morrison
6617dad2fa revert 2025-09-24 05:54:44 +02:00
Kim Morrison
cb39bbb3c8 merge master 2025-09-24 05:51:28 +02:00
Kim Morrison
ca1f80bdd4 Merge branch 'feat/reprove-command' into analyze_grind_notes 2025-09-18 08:11:40 +02:00
Kim Morrison
8d4606a83c . 2025-09-18 08:11:05 +02:00
Kim Morrison
1780f742f6 different implementation 2025-09-18 08:10:11 +02:00
Kim Morrison
491ac4120c . 2025-09-18 07:47:44 +02:00
Kim Morrison
e868071180 ble 2025-09-18 07:41:42 +02:00
Kim Morrison
c19ba37276 respect namespaces 2025-09-18 07:39:41 +02:00
Kim Morrison
11b94b343c . 2025-09-18 07:29:37 +02:00
Kim Morrison
768598c7af Merge branch 'master' into analyze_grind_notes 2025-09-18 07:27:42 +02:00
Kim Morrison
473f922909 . 2025-09-18 07:26:34 +02:00
Kim Morrison
975724c1c7 feat: add reprove command for re-proving declarations
Adds a new `reprove` command that allows re-proving existing declarations
with different tactics. This is useful for testing new tactics or proof
automation.

Usage:
- `reprove X by tactic` - re-prove declaration X with the given tactic
- `reprove X Y Z by tactic` - re-prove multiple declarations

The command looks up each declaration in the environment, retrieves its type,
and creates an `example` with that type to be proved by the provided tactic.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 07:25:55 +02:00
Kim Morrison
2f523ec945 feat: add reprove command for re-proving declarations
Adds a new `reprove` command that allows re-proving existing declarations
with different tactics. This is useful for testing new tactics or proof
automation.

Usage:
- `reprove X by tactic` - re-prove declaration X with the given tactic
- `reprove X Y Z by tactic` - re-prove multiple declarations

The command looks up each declaration in the environment, retrieves its type,
and creates an `example` with that type to be proved by the provided tactic.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 07:22:30 +02:00
Kim Morrison
5dec44e905 . 2025-09-18 07:21:54 +02:00
Kim Morrison
11b63ea6a0 . 2025-09-17 09:12:18 +02:00
Kim Morrison
56affc7eb6 chore: record some notes 2025-09-17 09:02:10 +02:00
2 changed files with 50 additions and 33 deletions

View File

@@ -90,7 +90,7 @@ def analyzeEMatchTheorems (c : Config := {}) : MetaM Unit := do
/-- Macro for analyzing E-match theorems with unlimited heartbeats -/
macro "#analyzeEMatchTheorems" : command => `(
set_option maxHeartbeats 0 in
set_option maxHeartbeats 2_000_000 in
run_meta analyzeEMatchTheorems
)
@@ -101,32 +101,55 @@ set_option trace.grind.ematch.instance true
-- 1. grind immediately sees `(#[] : Array α) = ([] : List α).toArray` but probably this should be hidden.
-- 2. `Vector.toArray_empty` keys on `Array.mk []` rather than `#v[].toArray`
-- I guess we could add `(#[].extract _ _).extract _ _` as a stop pattern.
-- I guess we could add `(#[].extract _ _).extract _ _` as a global stop pattern,
-- or add `#[].extract _ _` as a forbidden subterm for `Array.extract_extract`.
run_meta analyzeEMatchTheorem ``Array.extract_empty {}
-- Neither `Option.bind_some` nor `Option.bind_fun_some` fire, because the terms appear inside
-- lambdas. So we get crazy things like:
-- `fun x => ((some x).bind some).bind fun x => (some x).bind fun x => (some x).bind some`
-- We could consider replacing `filterMap_some` with
-- `filterMap g (filterMap f xs) = filterMap (f >=> g) xs`
-- to avoid the lambda that `grind` struggles with, but this would require more API around the fish.
-- * Neither `Option.bind_some` nor `Option.bind_fun_some` fire, because the terms appear inside
-- lambdas. So we get crazy things like:
-- `fun x => ((some x).bind some).bind fun x => (some x).bind fun x => (some x).bind some`
-- * We could consider replacing `filterMap_filterMap` with
-- `filterMap g (filterMap f xs) = filterMap (f >=> g) xs`
-- to avoid the lambda that `grind` struggles with, but this would require more API around the fish.
-- * Alternatively, we could investigating splitting equivalence classes into "active" and "passive"
-- buckets, and e.g. when instantianting `filterMap_some : Array.filterMap some xs = xs`,
-- leave `Array.filterMap some xs` in the "passive" bucket.
-- We would use this for merging classes, but not instantiating.
run_meta analyzeEMatchTheorem ``Array.filterMap_some {}
-- Not entirely certain what is wrong here, but certainly
-- `eq_empty_of_append_eq_empty` is firing too often.
-- Ideally we could instantiate this is we fine `xs ++ ys` in the same equivalence class,
-- note just as soon as we see `xs ++ ys`.
-- I've tried removing this in https://github.com/leanprover/lean4/pull/10162
-- * It seems crazy to me that as soon as we have `0 >>> n = 0`, we instantiate based on the
-- pattern `0 >>> n >>> m` by substituting `0` into `0 >>> n` to produce the `0 >>> n >>> n`.
-- * We should add `0 >>> n` as a forbidden subterm for `Int.shiftRight_add`.
run_meta analyzeEMatchTheorem ``Int.zero_shiftRight {}
-- * `eq_empty_of_append_eq_empty` was firing too often, before being removed in https://github.com/leanprover/lean4/pull/10162
-- Ideally we could instantiate this if we find `xs ++ ys` and `[]` in the same equivalence class,
-- not just as soon as we see `xs ++ ys`.
-- * `eq_nil_of_map_eq_nil` is similar.
-- * ban all the variants of `#[] ++ (_ ++ _)` for `Array.append_assoc`?
run_meta analyzeEMatchTheorem ``Array.range'_succ {}
-- Perhaps the same story here.
-- * also ban `a :: ([] ++ l)` etc for `List.cons_append`
-- * just ban `[] ++ l` for *everything* except `List.nil_append`?
-- effectively, just add this as a normalization rule?
run_meta analyzeEMatchTheorem ``Array.range_succ {}
-- `zip_map_left` and `zip_map_right` are bad grind lemmas,
-- checking if they can be removed in https://github.com/leanprover/lean4/pull/10163
run_meta analyzeEMatchTheorem ``Array.zip_map {}
-- * forbid `modifyHead f (modifyHead g [])`
-- * actually just making sure that *only* modifyHead_nil acts on `modifyHead g []`
run_meta analyzeEMatchTheorem ``List.eraseIdx_modifyHead_zero {}
-- It seems crazy to me that as soon as we have `0 >>> n = 0`, we instantiate based on the
-- pattern `0 >>> n >>> m` by substituting `0` into `0 >>> n` to produce the `0 >>> n >>> n`.
-- I don't think any forbidden subterms can help us here. I don't know what to do. :-(
run_meta analyzeEMatchTheorem ``Int.zero_shiftRight {}
-- * forbid `(List.flatMap (List.reverse ∘ f) l).reverse` for `reverse_flatMap`
-- * forbid `List.flatMap (List.reverse ∘ f) l.reverse` for `flatMap_reverse`
run_meta analyzeEMatchTheorem ``List.flatMap_reverse {}
-- * forbid `List.countP p (List.filter p l)` for `countP_eq_length_filter`
-- * this one is just crazy; so over-eager instantiation of unhelpful lemmas
-- I'm changing `countP_eq_length_filter` from `_=_` to `=` in https://github.com/leanprover/lean4/pull/10532
run_meta analyzeEMatchTheorem ``List.getLast_filter {}
-- Another one: `modify_nil` is the only thing we should ever use on `[].modify i f`
run_meta analyzeEMatchTheorem ``List.modify_nil {}
-- `count_eq_length_filter` (and related lemmas) shouldn't fire on lists that are already filters?
-- similarly for `List.filter_subset`?
run_meta analyzeEMatchTheorem ``List.replicate_sublist_iff {}

View File

@@ -2,19 +2,13 @@
-- involving `Nat` modulo and div with variable denominators.
example (a b n : Nat) (ha : a < n) : (n - a) * b % n = (n - a * b % n) % n := by
rw [Nat.sub_mul]
rw [Nat.mod_eq_mod_iff]
rw [Nat.sub_mul, Nat.mod_eq_mod_iff]
match b with
| 0 => refine 1, 0, by simp
| b+1 =>
refine a*(b+1)/n, b, ?_
rw [Nat.mod_def, Nat.mul_add_one, Nat.mul_comm _ n, Nat.mul_comm b n]
refine a * (b + 1) / n, b, ?_
rw [Nat.mod_def]
have : n * (a * (b + 1) / n) a * (b + 1) := Nat.mul_div_le (a * (b + 1)) n
have := Nat.lt_mul_div_succ (a * (b + 1)) (show 0 < n by omega)
rw [Nat.mul_add_one n] at this
have : a * (b + 1) n * b + n := by
rw [Nat.mul_add_one]
have := Nat.mul_le_mul_right b ha
rw [Nat.succ_mul] at this
omega
omega
have := Nat.lt_mul_div_succ (a * (b + 1)) (show 0 < n by cutsat)
have := Nat.mul_le_mul_right b ha
cutsat