Re: Help: Multiple Proof Trees



On 2005-08-30, Bart Demoen <bmd@xxxxxxxxxxxxxxxxx> wrote:
> Jan Wielemaker wrote:
>> On 2005-08-30, Bart Demoen <bmd@xxxxxxxxxxxxxxxxx> wrote:
>
>>>because SWI make ?- clause((A,B),C). succeed [Jan, is that a bug (using 5.5.3) ?
>>
>>
>> ?- listing((_,_)).
>>
>> :- module_transparent (',')/2.
>>
>> A, B :-
>> A,
>> B.
>>
>> So, there is a clause and that is why clause/2 does its work. This clause
>> is not a loop because the body is compiled.
>
> Sure, it's a trick used by many implementations.

It used to be a trick used by SWI-Prolog. It doesn't deal properly
with call((A, !)) though. These meta-call arguments are compiled if
the principal functor is a control structure.

> However, when I asked "is it a bug", it was because one isn't supposed to
> show the clauses of a "control construct" (as the ISO terminology goes).

>From the ISO specs, I see that clause/2 is supposed to return clauses
for user-defined dynamic and `public static' procedures only. For
private procedures it is supposed to return a permission error.

I've always thought system predicates are amoung private procedures
and thus should officially raise a permission error. I never liked
the error very much, so I return a clause whenever I technically can
produce it.

Closer reading suggests running clause/2 on a system predicate
(built-in) should fail silently, and it should only raise an exception
on user-defined private procedures.

SICstus (3.7.1) raises an exception trying clause on sort/2 as well
as ,/2.

I see no remarks on `control structures' in the ISO spec for clause/2.

??? Puzzled. In think any meta-interpreter must start with:

solve((A,B)) :- !,
solve(A),
solve(B).
solve(<Control-structure>) :- !,
<solve parts>
....

Then it gets hard. You either need a test that ensures clause will
not raise an error or you need to call it and deal with the error.

Here is a not so nice solution for that, which assumes clause/2
either throws an error or produces the clauses (may be none for a
dynamic predicate).

solve(Goal) :-
catch(clause(Goal, Body), E, Goal),
( nonvar(E)
-> solve(Body)
; true % exception
).

Meta-interpreters are more complicated than we teach beginners. The
above only gets pretty if we define clause/2 to return clauses for
user-defined public predicates and failure for any other predicate.

Cheers --- Jan
.