I’m trying to implement a quasiquotation that will effectively produce a list of string commands with embedded prolog variable terms, however it appears that the prolog variables are unground at parse time.
As a contrived simpler example that parse a list of Name=Value arguments:
:- use_module(library(dcg/basics)).
:- use_module(library(dcg/high_order)).
:- use_module(library(quasi_quotations)).
:- quasi_quotation_syntax(assignments).
assignments(Content, Vars, Dict, Result) :-
format("Vars=~w, Dict=~w~n", [Vars, Dict]),
phrase_from_quasi_quotation(sequence(assignment(Dict),",",Result), Content).
assignment(_,[]) --> [].
assignment(Dict,[SVar,"=",V]) --> string_without("=",Var), "=", number_or_var(Dict,V), { string_chars(SVar,Var) }.
number_or_var(_Dict,S) --> number(N), { number_string(N,S) }.
number_or_var(Dict,SV) --> prolog_var_name(S), { member(S=V, Dict), freeze(V, atom_string(V,SV)) }.
If I enter the following query:
?- X = 5, Y = {|assignments(X)||A=1,B=X|}.
Vars=[_1732], Dict=[X=_1732,Y=_1766]
X = 5,
Y = [["A", "=", "1"], ["B", "=", "5"]].
As can be seen, at parse time, the Dict shows X, but it doesn’t appear to have a grounded value, and hence I have froze the goal that adds the string value of X to the output, to prevent an
ERROR: atom_string/2: Arguments are not sufficiently instantiated
Is there a reason the value of X in the above example isn’t available during parse?
I could change the parser to just return the value instead of attempting a conversion:
number_or_var(Dict,V) --> prolog_var_name(S), { member(S=V, Dict) }.
?- X = 5, Y = {|assignments(X)||A=1,B=X|}.
Vars=[_1732], Dict=[X=_1732,Y=_1766]
X = 5,
Y = [["A", "=", "1"], ["B", "=", 5]].
But now I have to traverse the output to convert numbers to strings.
I’m thinking that the variable values are not available during parse time since the parser also executes at compile time, but in that case why provide the dictionary to the parser?