Search code examples
prologswi-prologswi-prolog-for-sharing

Prolog Can't get to the predicate


The prolog is supposed to find the order of five statements statements. Everything is working fine but when i call the query solution([A, B, C, D, E]) I get a sandbox error like this:

The Error:

Sandbox restriction!
Could not derive which predicate may be called from
      call(C)
      all(schoolgirl,[A,B,C,D,E])
      solution([A,B,C,D,E])

Full Prolog Program:

all(_,[]).
all(Pred, [X|Xs]):-
    P =..[Pred,X],
    call(P),
    all(Pred,Xs).
distinct([]).
distinct([X|Xs]):- 
    not(member(X, Xs)), distinct(Xs).
x0r(A, B):- 
    A, not(B).
x0r(A, B):-
    not(A), B.

schoolgirl(betty).
schoolgirl(ethel).
schoolgirl(joan).
schoolgirl(kitty).
schoolgirl(mary).

betty(Snd,Trd):- 
    x0r(Snd=kitty, Trd=betty).
ethel(Fst, Snd):- 
    x0r(Fst=ethel, Snd=joan).
joan(Trd, Fith):- 
    x0r(Trd=joan, Fith=ethel).
kitty(Snd, Forth):- 
    x0r(Snd=kitty, Forth=mary).
mary(Forth, Fst):- 
    x0r(Forth=mary, Fst-betty).

solution([Fst, Snd, Trd, Forth, Fith]):-
    all(schoolgirl, [Fst,Snd, Trd, Forth, Fith]),
    distinct([Fst, Snd, Trd, Forth, Fith]),
    betty(Snd, Trd),
    ethel(Fst, Snd),
    joan(Trd, Fith),
    kitty(Snd, Forth),
    mary(Forth, Fst).

The Call is

solution([A, B, C, D, E])

Solution

  • Like a commenter said, this seems to be a particular restriction when using SWI-Prolog's browser-based SWISH system (https://swish.swi-prolog.org/). It doesn't want you to use call/1 with terms that it doesn't know enough about.

    Fortunately, you can give it a bit more information: You use call/1 in the following context:

    P =..[Pred,X],
    call(P),
    

    That is, for a call to a predicate Pred with exactly one argument X. There is a more direct syntax for this:

    call(Pred, X)
    

    and this is enough to make the error go away, and to make SWISH willing to run your program. (In fact this syntax is a bit more general because it takes exactly one additional argument to be added to the ones already in Pred, so call(f(a), b) would call the goal f(a, b).)

    Your query will now die with a somewhat obscure error:

    procedure `A-B' does not exist
    Reachable from:
          call(_1690-betty)
          not(A-betty)
          x0r(A=mary,B-betty)
          mary(A,B)
          solution(A)
    

    You have a typo in the definition of your mary/2 predicate.