Zulip Chat Archive

Stream: lean4

Topic: Prevent aesop from unfolding specific definitions


Arend Mellendijk (Jun 29 2023 at 11:53):

I've been playing around with a custom aesop ruleset for dispensing with simple (Nat) divisibility goals. I basically just want it to compute the transitive closure of , and to deal properly with a ∈ b.divisors, which involves occasionally proving b≠0 by substituting until it finds a contradiction.

I've disabled the simp step as it has a tendency to do unwanted rewrites, but I'm still running into the issue with slightly longer proofs that aesop has a tendency to unfold a ∣ b into b=a*w and start rewriting, making it blind to the fact that it's already proved the goal.

MWE

As you can see in the first subcase of the failed proof aesop decided to substitute P=n*w to eliminate P, not realising it could have just proved the goal by transitivity. Is there a good way to just prevent aesop from unfolding a ∣ b into ∃w, b=a*w?

Alex Keizer (Jun 29 2023 at 12:03):

You can erase lemmas for a specific Aesop call, so presumably you should erase the rule that does that unfold

Jannis Limperg (Jun 29 2023 at 12:16):

What happens here is that divisibilty on Nat is defined as ∃ c, b = a * c. The builtin destructProducts rule therefore matches hypotheses of the form . | . and splits them into c and b = a * c. (I found this out by inspecting the trace output from set_option trace.aesop true.) As a workaround, you can try to disable the destructProducts rule as Alex suggests.

A more radical approach would be to change the definition of divisibility so that . | . is no longer reducibly defeq to an existential. I imagine this would create a lot of breakage.

Jannis Limperg (Jun 29 2023 at 12:20):

I could probably also implement an option that lets destructProducts match only syntactically, not up to defeq.

Arend Mellendijk (Jun 29 2023 at 12:45):

Thanks for the help!
I've tried disabling destructProducts altogether, but it has the unintended (yet expected) side effect that it won't unfold in the hypotheses, which means it still fails on the same examples. In particular it can't prove a ∣ b ∧ b ∣ c → a ∣ c, whereas it can prove a ∣ b → b ∣ c → a ∣ c. In effect this doesn't seem to change the strength of the ruleset at all since destructProducts only gets called when there is an in a hypothesis that it needs to prove the goal.

Arend Mellendijk (Jun 29 2023 at 12:49):

I guess if there is a way to disable only terms that would work

Jannis Limperg (Jun 29 2023 at 12:56):

Makes sense. There's currently no way to disable specifically, and anyway it would be a big hack.

Another possibly way to address the root problem (that . | . reducibly reduces to an existential):

  • Define def MyDvd a b := a | b.
  • Add a preprocessing step or Aesop rule which rewrites a | b to MyDvd a b.
  • Formulate the Aesop rules in terms of MyDvd.

Scott Morrison (Jun 29 2023 at 22:46):

In the longer term changing the reducibility of | seems like a great idea.

Gabriel Ebner (Jun 29 2023 at 23:10):

I don't expect this to break much (or anything). #5603

Gabriel Ebner (Jun 30 2023 at 00:24):

I think this requires a larger refactoring, since we have a Dvd α instance for every semigroup, and that instance should be (reducibly!) defeq to the Nat/Int instances.

Gabriel Ebner (Jun 30 2023 at 00:25):

That is, a Nat.dvd definition doesn't cut it. We need some generic (semireducible) divides [Mul α] predicate (in std!), and then use that to define all three instances.

Gabriel Ebner (Jun 30 2023 at 00:46):

#5604

Arend Mellendijk (Jun 30 2023 at 09:51):

I've made a MyDvd definition, and now the tactic works when I make it irreducible, but when it's semireducible it still gets unfolded by destructProducts, even with an explicit destructProductsTransparency := .reducible.
I'm frankly not sure if this is me misunderstanding transparency settings or if this is a bug in aesop.

MWE

Jannis Limperg (Jun 30 2023 at 09:55):

Could well be a bug. I'll look at it later.

Jannis Limperg (Jul 07 2023 at 09:53):

This was indeed an Aesop bug: destructProducts would use destructProductsTransparency when first matching a hyp, but would then use default for recursive matching. Now fixed in Aesop. No breakage in mathlib, but the PR must wait for #5409.


Last updated: Dec 20 2023 at 11:08 UTC