I am trying to implement a meta-program in ECLiPSe Prolog, and here's the code that i have written -
:- dynamic go/1.
sol(true):- !.
sol((A,B)):- !, sol(A), sol(B).
sol(A):- clause(A, Body), sol(Body).
go(X):- X is 5.
Now when I query with sol(go(X)).
, I get the error accessing a procedure defined in another module in clause(X is 5, _292)
and it aborts. I tried clearing all toplevel modules and reopening ECLiPSe and then running, but still the same error.
What could be the reason?
Thanks!
Predicate p/1
is using the built-in predicate (is)/2
. Note that X is 5
is a syntactically more convenient way of writing is(X,5)
. But your meta-interpreter is only expecting user defined predicates and the control constructs (',')/2
and true/0
. If you want to handle (is)/2
you have to introduce a separate clause for it.
sol(X is Y) :- !, X is Y.
Within ISO Prolog, the goal predicate_property(Goal,built_in)
can be used to test if Goal
is a built-in predicate. This works in many systems like B, GNU, SICStus, SWI, XSB, YAP. So you can write:
sol(Bip) :- predicate_property(Bip, built_in), !, Bip.
In ECLiPSe this built-in is not directly available. You have to load a library. The index of the manual suggests to use library swi
or quintus
. For some (unclear) reason it is not part of the ECLiPSe library iso
, yet it is ISO. So state
:- use_module(library(swi)).
in your file (or at the toplevel) first.
If you want a meta-interpreter to cover the full Prolog language you will have to handle all control constructs explicitly. Here they are - as defined in the standard (7.8 Control constructs).
true/0
fail/0
call/1
!/0
(',')/2
(;)/2
- disjunction(->)/2
(;)/2
- if-then-elsecatch/3
throw/1
Please be aware that only a few of them can be handled by directly calling the goal. Most of them must be handled explicitly!