Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog: "Vanilla" metainterpreter with builtins

Tags:

prolog

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?

like image 361
Daniel Lyons Avatar asked Oct 03 '17 05:10

Daniel Lyons


2 Answers

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).

like image 67
CapelliC Avatar answered Sep 27 '22 22:09

CapelliC


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.

like image 36
mat Avatar answered Sep 27 '22 22:09

mat