Zulip Chat Archive
Stream: lean4
Topic: Adding a declaration but with non-quoted value
Andrej Bauer (Apr 17 2024 at 09:21):
I know how to use CoreM.addAndCompile
to add a new declaration, given a quoted expression and its type. But what if I have an honest expression (not quoted), and would like to bind it to a declaration? (I need this so that in the next step I can add a instance using Meta.addInstance
).
Mario Carneiro (Apr 17 2024 at 09:25):
when you say a "quoted expression" I guess you mean an element of type Expr
?
Mario Carneiro (Apr 17 2024 at 09:27):
For things of other types, these are just runtime values and not really expressions at all. E.g if you have a Nat
in a metaprogram it can only ever be a numeral. You can reflect things of various types into Expr
using the ToExpr
class but it won't be the same as the original expression, it will be a representation of the normal form itself. And of course for function types you can't do it at all.
Mario Carneiro (Apr 17 2024 at 09:28):
This all leads me to believe there is some element of #xy problem here. How did you obtain this "unquoted expression"?
Andrej Bauer (Apr 17 2024 at 09:31):
The whole scenario is this:
- Using
Lean.FromJson
I obtain a valuev
of typestructure CowData .... deriving Lean.FromJson
. - There is a type class
class Cow (P : Pasture) extends CowData
(it's literally just that). Note that I do not have aP
whenv
is created in step 1. - I obtain a
P : Pasture
and would like to installCow.mk v
as an instance ofCow P
.
Mario Carneiro (Apr 17 2024 at 09:34):
In that case you most likely do want to use ToExpr
on the CowData
. Whether you need it for the P : Pasture
depends on how it is "obtained"
Andrej Bauer (Apr 17 2024 at 09:35):
It's generated by JsonData.loadJsonData
from a file.
Mario Carneiro (Apr 17 2024 at 09:37):
The only thing that lean knows how to handle in its generic infrastructure is the Expr
type. If you want to make a declaration the contents of that declaration have to be an Expr
. There are very few places which allow general types, usually as opaque blobs for "user data" which lean can preserve
Eric Wieser (Apr 17 2024 at 09:37):
Does the eval%
elaborator help at all here?
Andrej Bauer (Apr 17 2024 at 09:38):
I am happy to use ToExpr
if that won't anger the Lean high priests.
Mario Carneiro (Apr 17 2024 at 09:39):
@Eric Wieser my guess is that Andrej is doing all of this inside an elab
which plays a role similar to eval%
Mario Carneiro (Apr 17 2024 at 09:40):
(eval%
also uses ToExpr
to perform the conversion: docs#Mathlib.Meta.elabEvalExpr )
Andrej Bauer (Apr 17 2024 at 09:41):
CowData
is just a bunch of optional Nat
and Bool
fields, but like 30, so it would be nice not to have to write too much boiler-plate code. (And yes, it's all inside Elab
.)
Andrej Bauer (Apr 17 2024 at 09:41):
It can't find an instance of ToExpr
for CowData
.
Mario Carneiro (Apr 17 2024 at 09:41):
you should be able to derive ToExpr
on your type
Mario Carneiro (Apr 17 2024 at 09:42):
oh but you will need file#Mathlib/Tactic/DeriveToExpr
Mario Carneiro (Apr 17 2024 at 09:42):
@Kyle Miller should this be upstreamed to std4 or lean core?
Eric Wieser (Apr 17 2024 at 09:48):
This was held up by #5952, which perhaps I should go back to (but adds a Qq
dependency which makes upstreaming impossible)
Andrej Bauer (Apr 17 2024 at 09:48):
I can derive ToExpr
on CowData
easily, but not on Cow
because Pasture
is "complicated". So I could do it if there were a way to convert CowData
to Q(CowData)
.
Mario Carneiro (Apr 17 2024 at 09:49):
That's exactly ToExpr
(on CowData
)
Andrej Bauer (Apr 17 2024 at 09:50):
Ah, perhaps I should not force it to have type Expr
...
Mario Carneiro (Apr 17 2024 at 09:50):
The return value of toExpr (c : CowData)
is Expr
but you can coerce it to Q(CowData)
Mario Carneiro (Apr 17 2024 at 09:51):
(Does Qq have a well typed version of ToExpr
?)
Eric Wieser (Apr 17 2024 at 09:51):
(In #5952, yes)
Andrej Bauer (Apr 17 2024 at 09:53):
ToExpr
did the trick, it seems. Thanks. Also, why are you people awake?
Mario Carneiro (Apr 17 2024 at 09:53):
You will probably have to implement ToExpr (Cow P)
manually, or write a function that does what you want with some related type signature. You can make use of ToExpr CowData
in the implementation though
Andrej Bauer (Apr 17 2024 at 09:56):
I just derived ToExpr CowData
and then used $(@Cow.mk $cowData)
to circumvent deriving ToExpr (Cow P)
.
Last updated: May 02 2025 at 03:31 UTC