I wrote a small “Prolog in Prolog” interpreter based on clause/2 to fix a strange bug in my CGI in prolog. After fixing the trouble I wanted to extend a little bit the interpreter to cover the “deep cut (!)” for future use.

As once I saw an elegant and small such “prolog in prolog” in middle 1980’s, following my vague memory, I have managed to reproduce it, I hope. As far as the running the following typical sample queries, it seems to work correctly.

?- solve(true).

?- solve(false).

?- solve(false -> true). % Prolog behaviour.

?- solve(1=2 -> 1=2; 2=2).

?- solve(((X=1, X=2) -> (Y = 1; Y=2)); Y =3; Y=4).

?- solve(((X=1; X=2) -> (Y = 1; Y=2)); Y =3; Y=4).

?- solve(solve(((X=1, X=2) -> (Y = 1; Y=2)); Y =3; Y=4)). % idempotency.

?- solve(solve(((X=1; X=2) -> (Y = 1; Y=2)); Y =3; Y=4)).

?- solve(solve((member(X, [1,2,3]), !,

member(Y, [a,b,c]), !,

member(Z, [u,v,w])))).

The following were useful for the interpreter going down only to user-defined predicates:

```
predicate_property(_, built_in)
predicate_property(_, imported_from(_))
predicate_property(_, interpreted)
```

Also, now I “qcompile” every my codes, but the builtin clause/2 works as if it traces on source codes in text. Very impressive !

After the success, I tried to improve further the interpreter to avoid using the “deep cut” (in solve/1), because the code itself I saw might have not used “deep cut.”

After several “try and error”, although I could not find a way for “pure prolog” codes, now I have another solve/1 which behaves equally to the first one.

The both codes have almost the same structure, but the second one uses nb_setarg/3 term arguments in stead to keep track the cut (!) occurrences to cut alternatves. The nb_setarg is not “pure”, but the effect was drastic and the impureness was very local, I hope. This is the reason why I uploaded also the nb_setarg version. Of course, it is not my intention to recommend to use impure primitives.

I have uploaded both codes in my pack library(pac) pac-v1.5.1.

```
library(pac)/misc/prolog-in-prolog.pl % deep cut version.
library(pac)/misc/prolog-in-prolog2.pl % nb_setarg version.
```

$ swipl

?- use_module(pac).

?- [misc(‘prolog-in-prolog’)]. % “deep cut” version.

?- module(prog_in_prog).

(queries above)

[

?- [misc(‘prolog-in-prolog2’)]. % nb_setarg version.

?- module(prog_in_prog2).

(the same queries above)

]

Kuniaki Mukai