# Metainterpreter puzzler with \`member/2\`

**URL:** <https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482>\
**Category:** Help!\
**Created:** [April 3, 2019, 4:52pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482 "2019-04-03T16:52:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dklyons81](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dklyons81/32/29_2.png) [@dklyons81](https://swi-prolog.discourse.group/u/dklyons81)\
**Post date:** [April 3, 2019, 4:52pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/1 "2019-04-03T16:52:12Z")

</div>

I’m using: SWI-Prolog version 8.0.1, but I see the same problem in 8.0.2 and 7.2.3.

I’m using the simple metainterpreter at [my S.O. question](https://stackoverflow.com/questions/46537856/prolog-vanilla-metainterpreter-with-builtins):

```prolog
solve(true) :- !.
solve((A,B)) :- !, solve(A), solve(B).
solve(H) :- clause(H,B), solve(B).
solve(T) :- call(T).

```

When I run this query the first time, it works fine:

```prolog
?- solve(member(X, [elizabeth,socrates])).
X = elizabeth ;
X = socrates.

```

The second time, however, it gives me this:

```prolog
?- solve(member(X, [elizabeth,socrates])).
ERROR: Undefined procedure: member_/3
ERROR: However, there are definitions for:
ERROR: member/2
ERROR: 
ERROR: In:
ERROR: [10] member_([socrates],_2556,elizabeth)
ERROR: [9] solve(member_([socrates],_2594,elizabeth)) at /users/dlyons/test.pl:15
ERROR: [8] solve(member(_2630,[elizabeth|...])) at /users/dlyons/test.pl:14
ERROR: [7] <user>
   Exception: (10) member_([socrates], _1808, elizabeth) ? abort

```

You can induce the second-case behavior by doing `[library(lists)]` at the start. Is this a problem with my metainterpreter? If so, what should I do to fix it?

---

<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:** [April 3, 2019, 5:52pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/2 "2019-04-03T17:52:57Z")

</div>

You are seeing a rather odd behaviour. In the initial call there are no clauses for member/2, so you call it. That traps the autoloader, creating clauses for it (and running them). Next time the clause call works as clauses have been added, but the emulation needs to be aware of modules and you simple one is not.

---

<div class="post-metadata">

**Author:** ![dklyons81](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dklyons81/32/29_2.png) [@dklyons81](https://swi-prolog.discourse.group/u/dklyons81)\
**Post date:** [April 3, 2019, 5:55pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/3 "2019-04-03T17:55:11Z")

</div>

What can I do to improve this metainterpreter? It has another shortcoming as well, that you get multiple solutions because the behavior of `call/1` includes the behavior using `clause/2`.

---

<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:** [April 3, 2019, 6:02pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/4 "2019-04-03T18:02:18Z")

</div>

Is this part of the problem? (in `library(lists)`):

```prolog
:- set_prolog_flag(generate_debug_info, false).

```

---

<div class="post-metadata">

**Author:** ![dklyons81](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dklyons81/32/29_2.png) [@dklyons81](https://swi-prolog.discourse.group/u/dklyons81)\
**Post date:** [April 3, 2019, 8:42pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/5 "2019-04-03T20:42:19Z")

</div>

I don’t think so. What Jan is saying is that on the first call, there are no clauses for me to pick up with `clause/2` so it goes into `call/1` which invokes the autoloader and then successfully calls it (as a builtin). On my second attempt, there _are_ clauses to pick up with `clause/2` (the autoloader dragged them in on the previous attempt), _but_ when I subsequently use `call/1` on the body of the clause, I’m failing to take into account the module system somehow and those calls fail.

The first problem thus is that I don’t know how to make this work with modules. The second problem is that, even if I do, I will get spurious results when I enter my “last resort” of just using `call/1`. And the third problem is that, for the purposes of [this S.O. answer](https://stackoverflow.com/a/55500492/812818) I probably don’t want to disassemble predicates not supplied by the user anyhow, if there is a convenient way to distinguish “system” predicates from “user” predicates.

---

<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:** [April 4, 2019, 7:05am UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/6 "2019-04-04T07:05:19Z")

</div>

The simplest solution is probably to use as condition

```
\+ predicate_property(Goal, imported_from(_)).

```

A full meta interpreter that deals with the module system has to keep track of the module context, use the above as well as `predicate_property(Goal, meta_predicate(Spec))` to properly resolve the module context for the arguments of meta-predicates. And … deal with cuts, etc.

This is all doable, but pretty complex. Meta interpreters are nice for tutorial purposes. You rarely find them in real life. In cases you would need them the rules are typically represented as facts rather than Prolog clauses.

---

<div class="post-metadata">

**Author:** ![dklyons81](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dklyons81/32/29_2.png) [@dklyons81](https://swi-prolog.discourse.group/u/dklyons81)\
**Post date:** [April 4, 2019, 8:01pm UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/7 "2019-04-04T20:01:06Z")

</div>

Thank you for the help! I am wondering if you could elaborate on what you mean by meta-interpreter rules being represented as facts rather than clauses.

---

<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:** [April 5, 2019, 6:49am UTC](https://swi-prolog.discourse.group/t/metainterpreter-puzzler-with-member-2/482/8 "2019-04-05T06:49:53Z")

</div>

There is not that much point in meta-interpreting Prolog. Even for debugging reasons there are other ways such as hooking into the debugger or use source code rewriting to _wrap_ goals whose execution you want to track. You may want to use a Prolog-like rule language for some domain and use rule interpretation such that you can explain which rules have been used to get to some conclusion.

In that case you typically design a syntax that fits your need, write down the rules using this syntax and interpret these rules. The interpretation may look at lot like a Prolog meta-interpreter, but you probably  
have no cuts, modules and other complications. Prolog dynamic operators allow you to easily invent a rule syntax that should suit your domain.

I’m not much into rule based systems so I do not have an example right here. I did once write one for recognising typical (near) alignments of elements in diagrams.
