Zulip Chat Archive
Stream: lean4
Topic: addAndCompile a structure?
James Gallicchio (Oct 04 2023 at 22:14):
I have a list of field names and elaborated Expr
s for the field types. How do I turn that into a structure declaration to compile? I can't seem to find any relevant functions... :(
To slightly un-XY: I want a syntax for defining structures as
object Name {
"key1" : something
}
where something : SchemaM ?type
(SchemaM
is a monad). Idea is I want to generate a structure with field key1 : <type>
. Then I can define other stuff that makes use of the actual something
value.
So in order to find what <type>
is, I'm elaborating something
to an expression with expected type SchemaM ?type
and then instantiating the ?type
expression.
But now I've no idea how to get this into a structure (.. an inductive I know how to do. but not a structure).
Is there a different way I should be going about it?
James Gallicchio (Oct 04 2023 at 22:17):
One thing I've tried is to just build the syntax for a structure and then elabCommand
it. But I think I am encountering issues where liftTermElabM
throws out (?) the metavariable assignments:
import Lean
import Std
def SchemaM : Type → Type := Id
open Lean Macro Elab Meta Term Command in
elab "object " name:ident "{" keyStx:( str ":" "required "? term ),* "}" : command => do
-- name, required, (Lean) type, schema
let keys : Array (String × Bool × TSyntax `term × TSyntax `term) ←
liftTermElabM <| keyStx.getElems.mapM (fun s =>
-- unsure if this is actually necessary
-- but we use the mvar identifier `type` so /shrug
withFreshMacroScope do
let key := s.raw[0].isStrLit?.get!
let isReq := s.raw[2].hasArgs
let val : Term := .mk s.raw[3]
-- make a new metavariable for the type
let type : Term ← `(?type)
let typeExpr : Expr ← elabTermEnsuringType type (some (.sort (Level.ofNat 1)))
let elabVal ← elabTermEnsuringType val (some (.app (.const ``SchemaM []) typeExpr))
return (key, isReq, type, ← elabVal.toSyntax)
)
let typeId := mkIdent (name.getId ++ "type")
let fields : TSyntaxArray _ ← keys.mapM (fun (name, _req, type, _schema) =>
`(Lean.Parser.Command.structExplicitBinder| ($(mkIdent name) : $type))
)
elabCommand <| ← `(
structure $typeId where
$fields:structExplicitBinder*
)
def string : SchemaM Unit := ()
set_option pp.rawOnError true
object Hi { -- don't know how to synthesize placeholder
-- context:
-- case type
-- ⊢ Sort ?u.12896-/
"hi" : string
}
James Gallicchio (Oct 04 2023 at 22:21):
(sidenote: it lists that ?type : Sort ?u.12896
there, but I quite clearly call ensureHasType
with Sort 1
. Why is that information not reflected in the error?)
James Gallicchio (Oct 04 2023 at 22:37):
Another option would be to use the delaborator instead of metavariables. But it feels like a bad idea to rely on the delaborator...
Tomas Skrivan (Oct 04 2023 at 23:03):
I'm not sitting in front of a computer so I can't check but isn't structure just an inductive with some flag? Now I'm guessing, maybe create an inductive and then call some function that generates all the projection functions?
James Gallicchio (Oct 04 2023 at 23:08):
That is what I am hoping. But I can't seem to find a function to generate the right stuff. The Declaration
itself has a few flags that are related to being a structure, but nothing labelled as being a structure.
Tomas Skrivan (Oct 04 2023 at 23:11):
I think you have to register structure with registerStructure
https://github.com/leanprover/lean4/blob/dceed634a05e1d62588f89b9f1d7b7b4cf79f676/src/Lean/Structure.lean#L57 but there has to be a streamlined function that generates StructureDescr
from struct like inductive
Tomas Skrivan (Oct 04 2023 at 23:12):
Maybe this one https://github.com/leanprover/lean4/blob/dceed634a05e1d62588f89b9f1d7b7b4cf79f676/src/Lean/Elab/Structure.lean#L699
Tomas Skrivan (Oct 04 2023 at 23:16):
I think this is the crucial line, just above it you create projections
https://github.com/leanprover/lean4/blob/dceed634a05e1d62588f89b9f1d7b7b4cf79f676/src/Lean/Elab/Structure.lean#L835
Tomas Skrivan (Oct 04 2023 at 23:29):
But I'm very confused why is it sooo complicated. Maybe the extends
business is really complicated. It would be definitely nice to have a nice streamlined API that creates a simple structure given a set of field names, types and structure parameters.
I'm thinking about implementing "struct of arrays" support and such API would be useful for that.
Tomas Skrivan (Oct 04 2023 at 23:38):
Wow, the function mkProjections
is opaque, what is going on? Is it because the kernel needs to know about projections such that it can deal with Expr.proj
?
James Gallicchio (Oct 04 2023 at 23:49):
oof
Last updated: Dec 20 2023 at 11:08 UTC