There is a package that transforms programs and queries from
an eval-quote variant of clp(Q,R) into corresponding programs and
queries in a quote-eval variant. Before you use it, you need to
know that in an eval-quote language, all symbols are interpreted unless
explicitly quoted. This means that interpreted terms cannot be
manipulated syntactically directly. Meta-programming in a CLP
context by definition manipulates interpreted terms, therefore you
need quote/1
(just as in LISP) and some means to put
syntactical terms back to their interpreted life:
{}/1
.
In a quote-eval language, meta-programming is (pragmatically) simpler because everything is implicitly quoted until explicitly evaluated. On the other hand, now object programming suffers from the dual inconvenience.
We chose to make our version of clp(Q,R) of the quote-eval type because this matches the intended use of the already existing boolean solver of SICStus. In order to keep the users of the eval-quote variant happy, we provide a source transformation package. It is activated via:
| ?- use_module(library('clpqr/expand')). | ?- expand.
expand/0
puts you in a mode where the arithmetic functors
like +/2
, */2
and all numbers (functors of arity 0)
are interpreted semantically. noexpand/0
gets you out of
the mode.
clp(r) ?- 2+2=X. X = 4.0The package works by purifying programs and queries in the sense that all references to interpreted terms are made explicit. The above query is expanded prior to evaluation into:
{2.0+2.0=X}The same mechanism applies when interpreted terms are nested deeper:
some_predicate(10, f(A+B/2), 2*cos(A))Expands into:
{Xc=2.0*cos(A)}, {Xb=A+B/2}, {Xa=10.0}, some_predicate(Xa, f(Xb), Xc)This process also applies when files are consulted or compiled. In fact, this is the only situation where expansion can be applied with relative safety. To see this, consider what happens when the top-level evaluates the expansion, namely some calls to the clp(Q,R) solver, followed by the call of the purified query. As we learned in Feedback, the solver may bind variables, which produces a goal with interpreted terms in it (numbers), which leads to another stage of expansion, and so on.
We recommend that you only turn on expansion temporarily while
consulting or compiling files needing expansion with
expand/0
and noexpand/0
.