Closed JasonGross closed 9 years ago
This is not meant to be the purpose of this plugin. The idea is to produce something as close as possible to the kernel's representation. For example,
quote ("a" ++ "b")
should produce
App (App (append) (quoting of "a")) (quoting of "b")
Your implementation of quote_string
does not do this. It will reduce and quote the result.
The actual idea of this plugin is to use Ast.term to be able to write programs that generate programs like this. I.e. can you write a function generate_to_string : Ast.inductive_body -> Ast.term
that will take a description of an inductive data type and produce an Ast.term
that when internalized will run like to_string
.
The actual thing I need (for mathematical reasons) is a function quote : Ast.term -> Ast.term
which takes any syntactic program and adds an extra layer of syntax on top of it. That is, if we have the sequence Gallina; term of type Ast.term
; term of type Ast.term
which, when denoted, gives a term of type Ast.term
; ..., quote
should add one level of indirection in this sequence. This is, again, for quining and Löb's theorem.
In case anyone else comes looking, here's some python code that does, basically, this:
def make_quote_definition(q_i_idents):
for qi, i in q_i_idents:
print('Quote Definition %s := %s.' % (qi, i))
def make_quote_for_type_match(q_i_n_idents):
for qi, i, n in q_i_n_idents:
ls1 = ' '.join('x%d' % idx for idx in range(n))
ls2 = '[' + '; '.join('quote x%d' % idx for idx in range(n)) + ']'
yield ' | %s %s => Ast.tApp %s %s' % (i, ls1, qi, ls2)
def make_quote_for_type(q_i_n_idents, qtype_name, type_name, rec=True):
q_i_n_idents = list(q_i_n_idents)
make_quote_definition([(q, i) for q, i, n in q_i_n_idents])
print('')
print('''%s quote_%s (x : %s) : Preterm
:= %smatch x with
%s
end.
''' % (('Fixpoint' if rec else 'Definition'), qtype_name, type_name,
("""let x' := (quote_%s : Quotable %s) in
""" % (qtype_name, type_name) if rec else ''),
'\n'.join(make_quote_for_type_match(q_i_n_idents))))
print('Instance %s_quotable : Quotable %s := quote_%s.' % (qtype_name, type_name, qtype_name))
print('')
ls_inductive = (('mkInd', 2), )
make_quote_for_type((('q' + i, 'Ast.' + i, n) for i, n in ls_inductive), 'inductive', 'Ast.inductive', rec=False)
#ls_sort = (('sProp', 0), ('sSet', 0), ('sType', 1))
#make_quote_for_type((('q' + i, 'Ast.' + i, n) for i, n in ls_sort), 'sort', 'Ast.sort', rec=False)
#ls_name = (('nAnon', 0), ('nNamed', 1))
#make_quote_for_type((('q' + i, 'Ast.' + i, n) for i, n in ls_name), 'name', 'Ast.name', rec=False)
#ls_cast_kind = (('VmCast', 0), ('NativeCast', 0), ('Cast', 0), ('RevertCast', 0))
#make_quote_for_type((('q' + i, 'Ast.' + i, n) for i, n in ls_cast_kind), 'cast_kind', 'Ast.cast_kind', rec=False)
#qds = (('Rel', 1), ('Var', 1), ('Meta', 1), ('Evar', 1), ('Sort', 1), ('Cast', 3), ('Prod', 3), ('Lambda', 3), ('LetIn', 4), ('App', 2), ('Const', 1), ('Ind', 1), ('Construct', 2), ('Case', 4), ('Fix', 2), ('Unknown', 1))
#make_quote_for_type((('qt' + i, 'Ast.t' + i, n) for i, n in qds), 'term', 'Ast.term')
For example,
quote ("a" ++ "b")
should produce
App (App (append) (quoting of "a")) (quoting of "b")
This is impossible if quote
is a gallina function. I agree that there should be an Ltac function that does just this, but I also need a gallina function, primarily to be used on terms already in normal form.
If you are just quoting constants (i.e. everything is a constructor) then it should be pretty easy to implement this as a Coq function.
Is there any way to script this process? It might make a nice addition to this plugin: