Understanding unquoteDecl in Agda
I'm trying to understand that Agda is built in reflection mechanisms, so I decided to write a simple function that takes a string for an identifier, a quoted type and a quoted term, and simply defines a term of a given type with a given string identifier. Thus, I wrote the following:
testDefineName' : String β TC Type β TC Term β TC β€
testDefineName' s t a =
bindTC (freshName s)
(Ξ» n β bindTC t
(Ξ» t' β bindTC a
(Ξ» a' β (bindTC (declareDef (arg (arg-info visible relevant) n) t')
(Ξ» _ β defineFun n ((clause [] a') β· []))))))
unquoteDecl = (testDefineName' "test" (quoteTC β) (quoteTC zero))
This type checks, but when I try to use "test" elsewhere, I get an error Not in scope: test
.
the documentation for unquoteDecl
is opaque. The applause should look like
unquoteDecl x_1 x_2 ... x_n = m
where x_i
is Name
s, and m
has a type TC \top
, so maybe what I'm trying to do is actually impossible, but I still don't understand how this mechanism works: if it m
must have a type TC β€
and therefore cannot be a name function x_1 x_2 ... x_n
, I don't see how it is possible to add any new names to the scope using unquoteDecl
at all!
So, to summarize:
Is it possible to define a function like mine using Agda's reflection mechanism so that I can inject new names into scope using an argument String
? I want something like:
<boilerplate code for unquoting> testDefineName' "test" (quoteTC β) (quoteTC zero)
test' : β
test' = test
to compile (ie I can actually use the new name, "test")
and if not, what mechanism can the m
names be used x_1 ... x_n
? Can it m
be of a type List Name β TC β€
, contrary to the documentation?
source to share
Based on the way Ulf uses itunquoteDecl
, I get the impression that you need to list on the LHS the names that go to expand the scope.
The problem with your setup is that you don't know Name
as you are creating a new one from String
and can't grab it AFAIK. I was under the impression that freshName
it is intended to be used only to create internal names within tactics.
If you do testDefineName'
take Name
and not String
, then everything will work:
testDefineName' : Name β TC Type β TC Term β TC β€
testDefineName' n t a = bindTC t
$ Ξ» t' β bindTC a
$ Ξ» a' β bindTC (declareDef (arg (arg-info visible relevant) n) t')
$ Ξ» _ β defineFun n ((clause [] a') β· [])
unquoteDecl test = testDefineName' test (quoteTC β) (quoteTC zero)
source to share