Prolog: "Vanilla" metainterpreter with builtins
Asked Answered
A

2

6

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?

Adalbertoadalheid answered 3/10, 2017 at 5:41 Comment(1)
In some Prolog systems, the more ISO compatible ones, you need to mark the predicates dynamic, so that clause/2 can find them. This is SWI-Prolog specific that it returns also static predicates.Gabar
N
2

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

Nog answered 3/10, 2017 at 8:33 Comment(1)
This solution leaves a choice point, and then calls predicates twice. I now get: ?- solve(pet(X)). X = cat ; X = cat ; X = cat ; X = cat ; X = cat ; false. Instead only ?- solve(pet(X)). X = cat ; false.Gabar
H
3

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.

Hide answered 6/10, 2017 at 14:59 Comment(0)
N
2

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

Nog answered 3/10, 2017 at 8:33 Comment(1)
This solution leaves a choice point, and then calls predicates twice. I now get: ?- solve(pet(X)). X = cat ; X = cat ; X = cat ; X = cat ; X = cat ; false. Instead only ?- solve(pet(X)). X = cat ; false.Gabar

© 2022 - 2024 — McMap. All rights reserved.