Zulip Chat Archive
Stream: mathlib4
Topic: linarith Preprocessor
Patrick Massot (May 04 2023 at 21:36):
Mario, while you're here, I have another question. In Lean3, the linarith preprocessors used the tactic monad (what else?). In Lean 4 they use MetaM. Isn't it a problem for rewriting?
Patrick Massot (May 04 2023 at 21:36):
I mean specifically https://github.com/leanprover-community/mathlib/blob/36b8aa61ea7c05727161f96a0532897bd72aedab/src/tactic/linarith/preprocessing.lean#L202-L207
Mario Carneiro (May 04 2023 at 21:37):
what do you mean by "problem for rewriting"?
Patrick Massot (May 04 2023 at 21:38):
I must confess I didn't try too hard to think about what this function is doing, but a very naive port is at https://github.com/leanprover-community/mathlib4/blob/linarithRat/Mathlib/Tactic/Linarith/Preprocessing.lean#L283-L290 which is in TacticM
Patrick Massot (May 04 2023 at 21:38):
The secret goal of this message is to make you panic and port this yourself to prevent me from writing non-sense.
Mario Carneiro (May 04 2023 at 21:38):
Generally, things should be in TacticM
if they actually use / manipulate the goal state, TermElabM
if they need to elaborate syntax, and MetaM
if they just need to be able to unify metavariables and know the local context
Mario Carneiro (May 04 2023 at 21:40):
the description of the function doesn't sound like it needs anything more than MetaM
but I'm not sure about how the implementation is supposed to work
Mario Carneiro (May 04 2023 at 21:41):
MVarId.rewrite
is in MetaM, what requires more?
Patrick Massot (May 04 2023 at 21:41):
But where would the MVarId come from?
Mario Carneiro (May 04 2023 at 21:41):
a parameter
Patrick Massot (May 04 2023 at 21:42):
This is what was puzzling to me. So I simply assumed it was meant to be the main goal.
Mario Carneiro (May 04 2023 at 21:42):
"tactics" in MetaM just pass MVarIds in and out
Mario Carneiro (May 04 2023 at 21:42):
like MVarId.rewrite
Mario Carneiro (May 04 2023 at 21:42):
for that you don't really need the goal state
Patrick Massot (May 04 2023 at 21:42):
I understand this. I'm talking about my specific case.
Mario Carneiro (May 04 2023 at 21:43):
/-- `normalizeDenominatorsInLHS h lhs` assumes that `h` is a proof of `lhs R 0`.
It creates a proof of `lhs' R 0`, where all numeric division in `lhs` has been cancelled. -/
sounds like it's getting the argument in a parameter
Mario Carneiro (May 04 2023 at 21:44):
I mean this doesn't even care about the goal
Mario Carneiro (May 04 2023 at 21:44):
it's just building a proof of one thing from another
Patrick Massot (May 04 2023 at 21:44):
I agree it sounds like it doesn't care about the goal, but I'm confused about what it is rewriting.
Mario Carneiro (May 04 2023 at 21:45):
I'm confused about your confusion
Mario Carneiro (May 04 2023 at 21:45):
what is "it"?
Patrick Massot (May 04 2023 at 21:46):
I think you would waste a lot less time by actually looking at the Lean 3 code and telling me what the Lean 4 code should be.
Mario Carneiro (May 04 2023 at 21:46):
MVarId.rewrite
rewrites the type of the goal it is passed, by assigning it and returning a new mvar with a different type
Patrick Massot (May 04 2023 at 21:46):
I mean wasting your time
Mario Carneiro (May 04 2023 at 21:46):
I'm working based on github because I will be leaving in a few minutes
Patrick Massot (May 04 2023 at 21:46):
I think the core problem is I couldn't find the actual analogue of docs#tactic.rewrite_core
Mario Carneiro (May 04 2023 at 21:47):
oh I see you are confused by this docstring
/--
Rewrite goal `mvarId`
-/
def _root_.Lean.MVarId.rewrite (mvarId : MVarId) (e : Expr) (heq : Expr)
(symm : Bool := false) (occs : Occurrences := Occurrences.all) (config := { : Rewrite.Config }) : MetaM RewriteResult :=
Mario Carneiro (May 04 2023 at 21:49):
it appears that e
is the expression to rewrite (e.g. the type of the goal or of a hypothesis), and heq
is an equality that you are using to rewrite with
Patrick Massot (May 04 2023 at 21:50):
But what is mvarId
?
Patrick Massot (May 04 2023 at 21:50):
That mvarId
argument is the reason why I went to TacticM
where I can get something which at least has the correct type.
Mario Carneiro (May 04 2023 at 21:51):
it appears to be essentially unused, except that it is used for deriving the names of subgoals and for the local context
Mario Carneiro (May 04 2023 at 21:51):
I think you could just pass mkFreshExprMVar
to it
Patrick Massot (May 04 2023 at 21:54):
Ok, I'll try that, thanks.
Patrick Massot (May 04 2023 at 21:59):
I'll stop for today because I need some sleep, but everybody should feel free to hack on https://github.com/leanprover-community/mathlib4/tree/linarithRat. The current state is everything type-checks but nothing works (see the test file for linarith).
Scott Morrison (May 05 2023 at 00:12):
I'm looking at this now. (Actually I started fresh after looking at the PR, I'll report what I find soon!)
Scott Morrison (May 05 2023 at 01:02):
!4#3801. That took longer than it should have, because I kept mixing up the arguments of MVarId.rewrite
(order of arguments, and expressions vs types :woman_facepalming:). I added Expr.rewrite
and Expr.rewriteType
as helper functions to be less confusing next time around!
Patrick Massot (May 05 2023 at 07:13):
Amazing! Do you understand why my version wasn't working (apart from the fact that I wrote it at least one hour too late instead of sleeping)?
Scott Morrison (May 05 2023 at 11:31):
At least one thing wrong with your code:
lhs.containsConst (λ n => n = `has_div.div)
is looking for a mathlib3 name that doesn't exist anymore, so your code never fired.
Patrick Massot (May 05 2023 at 11:48):
That's indeed a very good reason, and very consistent with the time of the day when this was written.
Scott Morrison (May 05 2023 at 11:54):
Don't worry, I made exactly the same mistake on the first pass. :-)
Alex J. Best (May 05 2023 at 11:54):
Using
``has_div.div
is a way to prevent this btw, it checks that the name actually refers to a declaration at compile time.
Last updated: Dec 20 2023 at 11:08 UTC