# Meta interpreter circularity in SWI Prolog

**URL:** <https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639>\
**Category:** Help!\
**Created:** [July 15, 2020, 4:47pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639 "2020-07-15T16:47:36Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jose.de.siqueira](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jose.de.siqueira/32/1717_2.png) [@jose.de.siqueira](https://swi-prolog.discourse.group/u/jose.de.siqueira)\
**Post date:** [July 15, 2020, 4:47pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/1 "2020-07-15T16:47:36Z")

</div>

I’m using: SWI-Prolog version 7.6.4

I wrote a Prolog meta interpreter some years ago, taht worked well in GNU Prolog. However, I can’t make gprolog work on Linux anymore, it seems tehre is no support to it. That’s a pity.  
Now I am porting it to SWI Prolog and it works well, except for a circularity issue.  
When I call the meta-interpreter to execute itself, I get a fail. I traced it and what I got is:

```prolog
^ Call: (13) predicate_property((\==)/2, built_in) ? creep
^ Fail: (13) predicate_property(user:(\==)/2, built_in) ?

```

How can I circumvent this, please?

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [July 15, 2020, 5:05pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/2 "2020-07-15T17:05:20Z")

</div>

> [@jose.de.siqueira](#):
>
> `predicate_property((\==)/2,`

The comment by LogicalCapitain in docs for predicate\_property/2 explain the behaviour: you should ask for

```prolog
?- predicate_property(X \== Y,P).
P = visible ;
P = built_in ;
P = foreign ;

```

---

<div class="post-metadata">

**Author:** ![jose.de.siqueira](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jose.de.siqueira/32/1717_2.png) [@jose.de.siqueira](https://swi-prolog.discourse.group/u/jose.de.siqueira)\
**Post date:** [July 15, 2020, 6:22pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/3 "2020-07-15T18:22:33Z")

</div>

Thank you for your suggestion! It solved my problem!

I was astonished to see that asking for the property, showed it is not built-in anymore, but interpreted.

Cheers!

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [July 15, 2020, 7:08pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/4 "2020-07-15T19:08:53Z")

</div>

Glad my hint was useful. Anyway, I’ve tried to install GNU Prolog (from source) on Ubuntu 16.04 without problems. Just, since I didn’t configured (for laziness) the INSTALL\_DIR I had to use sudo make install as final step.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [July 16, 2020, 2:14am UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/5 "2020-07-16T02:14:09Z")

</div>

> [@CapelliC](#):
>
> ```prolog
> predicate_property(X \== Y,P).
> 
> ```

In your meta-interpreter, I suggest something like this to avoid unnecessary choicepoints:

```prolog
predicate_property(Pred,P), memberchk(P, [built_in,foreign])

```

Also note that (==)/2 has more results (you should read the docs to decide which of these should be added to `[built_in,foreign]`):

```prolog
?- forall(predicate_property(_\==_, P), format('~q~n', [P])).
visible
built_in
foreign
static
imported_from(system)
nodebug
iso
defined
size(144)

```

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [July 18, 2020, 10:59pm UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/6 "2020-07-18T22:59:00Z")

</div>

> [@jose.de.siqueira](#):
>
> However, I can’t make gprolog work on Linux anymore, it seems tehre is no support to it.

Are you certain?

On my computer (with Linux on it):

```plaintext
$ gprolog
GNU Prolog 1.4.5 (64 bits)
Compiled Jul 7 2020, 21:25:21 with gcc
By Daniel Diaz
Copyright (C) 1999-2020 Daniel Diaz
| ?-

```

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 19, 2020, 10:45am UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/7 "2020-07-19T10:45:45Z")

</div>

There are roughly 5 classes of predicates relevant to meta-interpretation:

- With predicate property `foreign`. These are written in C (or have a C wrapper to Java/Python/…). You cannot do clause/2 and thus you cannot meta-interpret them.

- Stuff handled by the compiler that has a clause that is exactly the same. Below is an example. You can get a clause, but this is the same as the original clause and thus you make no progress ☹ You find the full set in `boot/init.pl`, currently from line 318.

- Normal Prolog code that is part of the core system. They are reported as `built_in`.

- Normal Prolog code from the libraries. The way to find them, as @EricGT mentioned is using the `imported_from(Module)` property and module\_property/2, checking for `class(library)`

- User code. This may be local to the module (or not in a module) or imported user code.

The first two cannot be meta-interpreted. The rest is a choice up to the user.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [July 20, 2020, 7:41am UTC](https://swi-prolog.discourse.group/t/meta-interpreter-circularity-in-swi-prolog/2639/10 "2020-07-20T07:41:42Z")

</div>

> [@anon95304481](#):
>
> ```prolog
> :- meta_predicate ','(0,0).
> 
> ```
> 
> But ‘,’/2 should never be called if you have and-inlining.  
> Prior to and-inlining I had also a definition for ‘,’/2,  
> but the above definition is wrong, since it is not  
> cut transparent. You cannot define ‘,’/2 in Prolog.

This gets really tricky. I think the only way to call ,/2 is using call/2 (or call/3), as in

```
?- call(','((between(1,3,X),!)),writeln(X)).
1
X = 1.

```

I think this is correct as the above must be the same as `call((between(1,3,X),!,writeln(X)))`. I think all other ways to call ,/2 are handled by the compiler rather than the predicate.
