Zulip Chat Archive
Stream: general
Topic: simp local confluence checker
Kim Morrison (Aug 17 2024 at 23:45):
@Joachim Breitner has a working implementation of something close to this. It remains high on my TODO list to actually try it out, and report on how useful it is re: List
lemmas (which I've been working on). But it's been sitting on my TODO list for some time now. :-)
Jared green (Aug 17 2024 at 23:56):
link?
Andrés Goens (Aug 18 2024 at 10:47):
that sounds really interesting! looking forward to seeing more of that
Joachim Breitner (Aug 18 2024 at 10:55):
https://github.com/nomeata/lean-simplc/blob/master/Simplc.lean
Happy to explain what I am doing, or help anyone to use it who wants to check their simp API’s for local confluence.
Kim Morrison (Aug 19 2024 at 11:49):
I am finally trying this out. It's indeed very helpful. :-)
It would be really nice if the output for inspect
could also show what simp
does to each of the results, in the case that joining fails. I think this would make it easier to identify missing lemmas.
EDIT: oh, I was misread the output: the "Joining failed with" output essentially shows this.
Kim Morrison (Aug 19 2024 at 11:53):
Another thing that would be useful is for simp_lc inspect
could show a warning if either of the named lemmas is not actually @[simp]
.
(Because I expect a typical workflow will be to remove some @[simp]
statements, and then when returning to the simp_lc
file there is an indication that that inspect
line can now be removed.)
Joachim Breitner (Aug 19 2024 at 12:34):
I was assuming that simp_lc inspect
is only used while investigating a specific pair, but only simp_lc whitelist
, simp_lc ignore
and simp_lc check
are non-termporary.
Kim Morrison (Aug 19 2024 at 12:35):
Could whitelist
show a warning if there isn't actually a problem with that pair?
Kim Morrison (Aug 19 2024 at 12:35):
Otherwise if the problem goes away independently I will never know to delete that line.
Joachim Breitner (Aug 19 2024 at 12:37):
That’s more plausible, at least until one starts using simp_lc check [domain_specific_simpset]
or so. And then there could be variants, or an option to disable the warning.
Joachim Breitner (Aug 19 2024 at 12:44):
Warning implemented and pushed
Kim Morrison (Aug 19 2024 at 12:45):
Maybe you didn't push? I don't see it.
Joachim Breitner (Aug 19 2024 at 12:45):
Now pushed for real
Kim Morrison (Aug 19 2024 at 12:45):
Also -- i'm finding that try repeat simp_all
is often needed, and gives better results than try simp_all
Joachim Breitner (Aug 19 2024 at 12:46):
Ever since I banned lake
into a container that doesn’t have access to my ssh keys, I fall prey of git push
–switch windows–missed the error message
Joachim Breitner (Aug 19 2024 at 12:46):
Kim Morrison said:
Also -- i'm finding that
try repeat simp_all
is often needed, and gives better results thantry simp_all
Sounds like a bug in simp_all
?
Kim Morrison (Aug 19 2024 at 12:47):
Yeah, I'm not certain. I think this has come up before and we decided it was not a bug, ...
Kim Morrison (Aug 19 2024 at 12:48):
open List
@[simp] theorem range'_head (n : Nat) (h) : (range' s n).head h = s := by
sorry
example (s n : Nat) (h : range' s n ≠ []) : s ≤ (List.range' s n).head h ∧ (List.range' s n).head h < s + n := by
simp_all
simp_all
omega
Kim Morrison (Aug 19 2024 at 12:48):
I agree that looks like simp_all
's fault.
Kim Morrison (Aug 19 2024 at 12:51):
Joachim Breitner (Aug 19 2024 at 12:53):
More likely https://github.com/leanprover/lean4/issues/5094
Kim Morrison (Aug 20 2024 at 02:19):
Oh, after encountering another instance of needing simp_all; simp_all
, I am back to believing that this is the correct behaviour of simp_all
.
The point is that simp_all
first tries to simp hypotheses, then the goal. The problem can be that if the goal depends on the hypotheses in interesting ways, this may block simplification of a hypothesis. When we then move to the goal, the dependency can be removed, but simp_all
does not then go back to look at the hypotheses again.
Kim Morrison (Aug 20 2024 at 02:19):
Here's the other example that made it clear:
example (f : α → Option β) (h₁ : (f a).isSome = true) (h₂ : f a = none) : [(none.get (by rw [h₂] at h₁; simp at h₁) : α)] = [] := by
simp_all
simp_all
Kim Morrison (Aug 20 2024 at 05:48):
@Joachim Breitner, it would be helpful to be able to whitelist a lemma entirely. I'm finding some that I think I do want as @[simp]
lemmas, but I just don't care about the non-confluence that it produces.
Kim Morrison (Aug 20 2024 at 05:54):
I guess
attribute [-simp] head_mem getLast_mem get_find?_mem in
simp_lc check in List
suffices for this
Joachim Breitner (Aug 20 2024 at 06:55):
Doesn't simp_lc ignore
do what you want?
Joachim Breitner (Aug 20 2024 at 06:59):
Made it use try repeat simp_all
. I hope that won’t run into too many loops.
Kim Morrison (Aug 21 2024 at 01:05):
Fantastic, thanks.
Kim Morrison (Aug 21 2024 at 01:05):
I would really like whitelist
(or some other command) to still run the confluence check, and to give a warning if it is in fact confluent.
Having the warning if one of the lemmas is not a simp
lemma is great, but the problem is that if I've whitelisted something, and then add a simp lemma that would resolve it, I never know to remove the whitelist.
Kim Morrison (Aug 21 2024 at 01:05):
I could achieve this with #guard_msgs
, but it's very verbose!
Kim Morrison (Aug 21 2024 at 01:07):
Also, for my use case at least, the "Try this:" message from check
would actually be more useful if it produced inspect
rather than whitelist
. I understand the reasoning for making it whitelist, but my first step is always to mass edit it back to inspect
...
Joachim Breitner (Aug 21 2024 at 08:22):
I was worried about the cases where you whitelist something because it loops or crashes or so. But maybe that doesn't happen so often. And I can just make two commands.
Joachim Breitner (Aug 21 2024 at 11:05):
Both implemented. You even get a Try this
action to remove the whitelist
command. And an option to disable this check.
Kim Morrison (Aug 22 2024 at 04:59):
One more tiny request: can the message "Checking 671 simp lemmas for critical pairs" say how many confluent pairs it found?
Kim Morrison (Aug 22 2024 at 05:06):
Oh, yet another: can I write simp_lc check in Foo Bar
to check lemmas in multiple namespaces.
Kim Morrison (Aug 22 2024 at 05:07):
In particular, two namespaces. Since we're doing pairwise checks on lemmas, in principle one could get complete coverage from doing pairwise checks on namespaces.
Joachim Breitner (Aug 22 2024 at 06:08):
Sounds like we need a general algebra of lemma restrictions, for use in loogle and in tools like this :-)
Joachim Breitner (Aug 22 2024 at 06:28):
Both implemented.
Kim Morrison (Aug 26 2024 at 00:03):
@Joachim Breitner, if you have a chance could you take a look at:
simp_lc inspect List.forall_mem_ne' Subtype.forall -- stuck at solving universe constraint
Joachim Breitner (Aug 26 2024 at 07:38):
Hmm, not sure if my tool can do much here: If you set this goal up manually you also get this:
example (p : α → Prop) (a : α) (l : List { a // p a }):
(∀ (a' : { a // p a }), a' ∈ l → ¬a' = a) = (∀ (a' : { a // p a }), a' ∈ l → ¬a' = a) :=
sorry
produces
stuck at solving universe constraint
?u.4466+1 =?= max 1 ?u.4059
while trying to unify
Type ?u.4466 : Type (?u.4466 + 1)
with
Sort (max 1 ?u.4059) : Type (max 1 ?u.4059)
It helps to constrain (α : Type u)
.
Joachim Breitner (Aug 26 2024 at 07:43):
With that you can investigate the pair manually:
example (α : Type u) (p : α → Prop) (a : { a // p a }) (l : List { a // p a }):
(∀ (a' : { a // p a }), a' ∈ l → ¬a' = a) = (∀ (a' : { a // p a }), a' ∈ l → ¬a' = a) := by
conv => lhs; rw [List.forall_mem_ne']
conv => rhs; rw [Subtype.forall]
simp -- fails
Kim Morrison (Aug 26 2024 at 09:44):
That's fine. I can whitelist it with the option to disable whitelist checking.
Joachim Breitner (Aug 26 2024 at 09:53):
Actually, that universe equation at least uniquely sets the first variable to 0. Should lean recognize this or is this equation too arcane?
Kim Morrison (Aug 26 2024 at 12:18):
I don't think it does: if it were min
on the right hand side it would?
Joachim Breitner (Aug 26 2024 at 12:19):
Ah, I keep making that mistake with min
and max
:-)
Kim Morrison (Aug 27 2024 at 01:49):
Could we make simp_lc check in _root_
work, to ignore everything in a namespace?
Joachim Breitner (Aug 27 2024 at 09:45):
It’s a bit odd since in List
will include List.Perm.foo
(should it?) but pragmatically: Sure.
Kim Morrison (Aug 27 2024 at 11:20):
Yeah, I agree it is weird, but I'm not really sure how else to partition up the work...
Joachim Breitner (Aug 27 2024 at 12:06):
Oh, the feature request is fine, merely the syntax is a bit non-uniform. As mentioned before, a more expensive and well designed lemma filtering syntax would be useful, but not worth for just this ad-hoc tool. Maybe eventually for Loogle, and reusable here.
Joachim Breitner (Aug 27 2024 at 13:11):
Added support for in _root_
Kim Morrison (Aug 28 2024 at 05:24):
Thanks!
Kim Morrison (Aug 28 2024 at 05:25):
Minor bug report: simp_lc ignore X
silences simp_lc inspect A X
, but not simp_lc inspect X A
. Whatever the behaviour here, it should be the same in either order.
Joachim Breitner (Aug 28 2024 at 07:58):
Which behavior would you prefer? Ignore ignore
when using inspect
explicitly, or adhere to it?
Joachim Breitner (Aug 28 2024 at 08:00):
Ah, judging from the code I probably wanted to ignore only affect simp_lc check
. Made that change (mostly untested). I think that’s the better choice.
Kim Morrison (Aug 30 2024 at 02:40):
simp_lc check
-- Checking 5753 simp lemmas for critical pairs
-- Investigated 6190 critical pairs
We're getting there. There are still a few whitelist
s that indicate problems about Nat
/Int
/List
, but not many, and BitVec
and Fin
are really bad.
Joachim Breitner (Aug 30 2024 at 05:14):
Happy to hear that it's working as intended, and to see the long list of improvements hitting the standard library that you have been producing this week.
You have not looked at Array
yet, I assume?
Kim Morrison (Aug 30 2024 at 05:26):
Array
was apparently confluent to begin with.
Joachim Breitner (Aug 30 2024 at 05:52):
Now I wonder if my tool is buggy :cold_sweat:
Last updated: May 02 2025 at 03:31 UTC