Prolog: "Vanilla" metainterpreter with builtins

423 views Asked by At

This answer by Jan Burse shows one of the simplest implementations of a metainterpreter in Prolog:

solve(true) :- !.
solve((A,B)) :- !, solve(A), solve(B).
solve(H) :- clause(H,B), solve(B).

I would like to extend this interpreter so that it can call builtins. The vanilla one isn't able to handle calls such as solve(member(X, [1,2,3,4])). Is this possible using ISO predicates? If not, is it possible using SWI-Prolog predicates?

2

There are 2 answers

1
CapelliC On BEST ANSWER

Stackoverflow is refusing to accept my answer :) that was

Just call/1 them

Edit

For instance

?- [user].
solve(true) :- !.
|: solve((A,B)) :- !, solve(A), solve(B).
|: solve(H) :- clause(H,B), solve(B).
|: solve(T) :- call(T).
|: ^Dtrue.

?- solve(member(X, [1,2,3,4])).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4.

The only addition: solve(T) :- call(T).

0
mat On

I think predicate_property/2 may be useful for your task.

As the name already implies, this predicate relates a predicate (head) to one ore more properties.

For example:

?- predicate_property((A,B), P).
P = interpreted ;
P = visible ;
P = built_in ;
P = static ;
P = imported_from(system) ;
etc.

From such properties, you can deduce whether a predicate is built-in, and the call it directly.

It is also available in SICStus.

Beware though: Not all built-in predicates retain their semantics when called directly. I think discussing what they are and how to interpret them would be well worth its own question.