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:

  1. Using Lean.FromJson I obtain a value v of type structure CowData .... deriving Lean.FromJson.
  2. There is a type class class Cow (P : Pasture) extends CowData (it's literally just that). Note that I do not have a P when v is created in step 1.
  3. I obtain a P : Pasture and would like to install Cow.mk v as an instance of Cow 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