Prolog Can't get to the predicate - prolog

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])

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.

Related

Prolog: existentially quantifying

I am trying to understand the usage of existentially quantifying. What I know by now is this technique is used with setof, findall, bagof. Further, I found a tutorial. However, I am not sure when and how I do the Vars^Goal (existentially quantifying) in Prolog.
Here is the example, my goal is to find two employees who know each other but work at different companies, binding the result with L showing Name1-Name2:
company('Babbling Books', 500, 10000000).
company('Crafty Crafts', 5, 250000).
company('Hatties Hats', 25, 10000).
employee(mary, 'Babbling Books').
employee(julie, 'Babbling Books').
employee(michelle, 'Hatties Hats').
employee(mary, 'Hatties Hats').
employee(javier, 'Crafty Crafts').
knows(javier, michelle).
My first instinct is to use the query
?-employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2).
The query found the answer but doesn't render it into the correct format. The correct one is:
?-setof(N1-N2, (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)), L).
How could I understand the (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) ? And what's the concept of it? Thanks.
I am not sure when and how I do the Vars^Goal (existentially quantifying) in Prolog.
The easiest answer is: Don't do it, ever. You can always introduce an auxiliary predicate that captures exactly the query you want, exposing exactly the arguments you want and nothing else (that would require quantification), and with a nice self-documenting name.
In your example, you can define:
different_company_acquaintances(N1, N2) :-
employee(N1, C1),
employee(N2, C2),
C1 \= C2,
knows(N1, N2).
and then express your setof query as:
?- setof(N1-N2, different_company_acquaintances(N1, N2), L).
L = [javier-michelle].
This is easier to read because of the predicate name and because it hides the irrelevant implementation details. Note that in the predicate definition the arguments are only the data the caller cares about (the employees), and there are no arguments for the data the caller doesn't care about (the companies).
How could I understand the (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) ?
The ^ syntax, whatever the exact correct form is, is meant to signal variables that, if you wrote out a separate predicate definition, would only occur in the predicate's body, not as its arguments. This tells setof and friends that every time it tries to execute the goal (employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)) it should do so with unbound variables C1 and C2. In other words, it should not try to retain the values of C1 and C2 from one attempt to the next.

How to check whether some variable returns something in predicate

Lets assume I have facts as follows:
airport(nyc,'newyork').
I want want to display a message if the user inputs an airport that doesn't exist.
My Attempt:
isAirport(Air) :-
airport(Air,T),
(var(T) -> true
;
write('Airport not found'),
fail
).
However, this doesn't seem to work.
First let's see what happens if you query a conjunction (the , operator) first:
?- airport(nyc, _), write('found!').
found!
true.
?- airport(abc, _), write('found!').
false.
This means, isAirport(abc) directly fails after trying airport(abc,_) without the rest of your predicate being evaluated. In many cases, you can therefore get by without an explicit if-then-else construct and just write something of the form
predicate(X) :-
first_condition(X),
second_condition(X).
and it will only succeed if both conditions are fulfilled for X.
In case you really want to create some user interface, this is a bit more tricky, because I/O is inherently non-logical, in particular when there is backtracking involved. We usually call a program which behaves like we would expect from a logical formula pure and when it contains non-logical constructs like I/O or the cut operator ! are called impure.
Unfortunately, the if-then-else construct (-> and ;) and negation (\+) are implemented via cut and therefore impure as well. Luckily, most of the time people want a conditional, a pure disjunction is sufficient:
case(1,a).
case(2,b).
We have an automatic branching from the execution mechanism of Prolog:
?- case(X,Y).
X = 1,
Y = a ;
X = 2,
Y = b.
But sometimes we really want to do something that needs the impure constructs, like user input. Then the easiest way to keep the nice logical properties of our program is to separate the task into pure and impure ones:
main :-
uinput(Data),
pure_predicate(Data, Result),
write(Result).
After we have done all the impure parts, Data is unified with the user data we wanted. Let's have a look at the implementation of uinput/1:
uinput(data(Airport,D-M-Y)) :-
format('~nAirport? '),
read(Airport),
( ground(Airport), airport(Airport, _) )
->
(
format('~nDay? '),
read(D),
format('~nMonth? '),
read(M),
format('~nYear? '),
read(Y),
( ground(D-M-Y), isDate(D-M-Y) )
->
true
;
throw(failure('unknown date'))
)
;
throw(failure('unknown airport'))
.
We successively read terms from the input and throw an exception if we can't handle it. For the if-then-else construct to work, we need to take special care. If we compare the two queries:
?- between(1,3,X), write(X).
1
X = 1 ;
2
X = 2 ;
3
X = 3.
and
?- between(1,3,X) -> write(X); false.
1
X = 1.
you can see that the if-then-else is losing solutions. This means we need to make sure that our condition is deterministic. Asking for a user input term to be ground is already a good idea, because without variables, there is only one solution term. Still, a call to one of the data-predicates airport/1 and isDate/1 might generate the same term multiple times or not terminate at all. In this particular case, we just need to make sure that each airport has a unique shortcut name, we can also generate dates without repetition:
airport(nyc, 'New York City').
airport(wdc, 'Washington DC').
isDate(X-Y-Z) :-
between(1,31,X),
between(1,12,Y),
between(1970,2100,Z).
Another trick in the implementation of uinput is that we just succeed with true when we have validated everything. The only effect of is now that Data is instantiated with whatever the user entered.
If we give a dummy implementation of the actual implementation, we can already try the implementation oursevles:
pure_predicate(_Data, Result) :-
% here goes the actual stuff
Result='we have found something awesome'.
On the prompt we can use the pure predicate without trouble:
?- pure_predicate(someinputdata,Y).
Y = 'we have computed something awesome'.
On the other hand, we can also use the full predicate as follows:
?- main(_).
Airport? wdc.
Day? |: 1.
Month? |: 2.
Year? |: 2000.
we have found something awesome
true.
Since we are using read, we have to input prolog terms and terminate with a dot ., but everything worked as expected.
In case the user input fails, we get:
?- main(_).
Airport? bla(X).
ERROR: Unhandled exception: failure('unknown airport')
Please note that we only went through this trouble to actually fail early and give a user message in that case. For the actual computation, this is completely unneccessary.
In the code below you are making false assumption that T will remain unbound in case if airport will not be found in database:
airport(Air, T)
What happens actually is that call to airport(Air, T) will make isAirport(Air) to fail immediately and your var(T) and other parts will not be executed at all.
Try this code instead:
isAirport(Air) :-
airport(Air, _T), ! ; write('Airport not found'), fail.

My first prolog tiny program doesn't work

I've thrown a glance at Prolog, and this is my first little try at writing it: it directly bugs at my first queries. (in the example below i asked for word('test').)
I meant to state:
word/1
alias/2
alias is commutative
if a variable is an alias of another then it is a word
A, C, and D are word
B is an alias of A.
this is the knowledge base when I do a listing. in SWI-Prolog console.
?- listing.
word(A) :-
alias(A, B).
word('A').
word('C').
word('D').
alias(A, B) :-
alias(B, A).
alias('A', 'B').
Yes
3 ?- word('test').
ERROR: Out of local stack
Exception: (59,743) alias(_L147, test) ?
Any clue what's going wrong with my knwoledge base?
alias(A, B) :-
alias(B, A).
alias('A', 'B').
this is an infinite loop.
for example, if you call alias(2,4) then the trace would be something like:
alias(2,4)
alias(4,2)
alias(2,4)
alias(4,2)
alias(2,4)
alias(4,2)
alias(2,4)
alias(4,2)
....
you have a left recursively issue.
Look here at page 133: http://books.google.com/books?id=w-XjuvpOrjMC&pg=PA132&lpg=PA132&dq=prolog+commutativity&source=bl&ots=4Xz2WMBUNt&sig=pj1blZvMvHXoQPBHEPBNnVo2f6E&hl=en&sa=X&ei=xpAcT_ieMIj00gGdhq3oCw&ved=0CCAQ6AEwAA#v=onepage&q=prolog%20commutativity&f=false

Prolog print statement does not work as expected

I was trying to define a functor and print each individual items of list in Prolog, but Prolog is not printing in correct format.
rint(L):-
write(H).
the output is like
rint([a, s,v ,c]).
_L139
true.
This is what I expect to achieve by calling the functor, any help or thought is appreciated, I'm new to Prolog and learning it.
?- rint([a,b,c,d]).
.(a, .(b, .(c, .(d, []))))
I think it should be
rint(L) :- write(L).
Also if you want .(a, .(b, .(c, .(d, [])))) and not [a, b, c, d] in output, use display:
rint(L) :- display(L).
The problem is an error in your rule for rint.
Your definition says that rint(L) succeeds if write(H) succeeds. At that point, the interpreter knows nothing about H. So it writes a value it doesn't know, which is why you see the _L139, the internal representation of an uninitialised variable.
Having done that, write(H) has succeed, is true, so rint(L) is true. The interpreter tells you that: true.
To define your own rint/1 without relying on built-ins such as display/1, you would need to do something like
rint([]) :-
write([]).
rint([H|T]) :-
write('.('),
write(H),
write(', '),
rint(T),
write(')').
If you're trying to display an empty list, just write it. If you're trying to display any other list, write the opening period and parenthesis, write the Head, write the following comma and space, then call itself for the Tail of the list, then write the closing parenthesis.

Defining a rule that the user cannot query

How do I define a rule that the user cannot query?
I only want the program itself to call this rule through another rule.
Ex:
rule1():- rule2().
rule2():- 1<5.
?-rule1().
true
?-rule2().
(I don't know what the answer will be, I just want this query to fail!)
Use a Logtalk object to encapsulate your predicates. Only the predicates that you declare public can be called (from outside the object). Prolog modules don't prevent calling any predicate as using explcit qualification bypasses the list of explicitly exported predicates.
A simple example:
:- object(rules).
:- public(rule1/1).
rule1(X) :-
rule2(X).
rule2(X) :-
X < 5.
:- end_object.
After compiling and loading the object above:
?- rules::rule1(3).
true.
?- rules::rule2(3).
error(existence_error(predicate_declaration,rule2(3)),rules::rule2(3),user)
If you edit the object code and explicitly declare rule2/1 as private you would get instead the error:
?- rules::rule2(3).
error(permission_error(access,private_predicate,rule2(3)),rules::rule2(3),user)
More information and plenty of examples at http://logtalk.org/
First, some notes:
I think you mean "predicate" instead of "rule". A predicate is a name/k thing such as help/0 (and help/1 is another) and can have multiple clauses, among them facts and rules, e.g. length([], 0). (a fact) and length([H|T], L) :- ... . (a rule) are two clauses of one predicate length/2.
Do not use empty parenthesis for predicates with no arguments – in SWI-Prolog at least, this will not work at all. Just use predicate2 instead of predicate2() in all places.
If you try to call an undefined predicate, SWI-Prolog will say ERROR: toplevel: Undefined procedure: predicate2/0 (DWIM could not correct goal) and Sicstus-Prolog will say {EXISTENCE ERROR: predicate2: procedure user:predicate2/0 does not exist}
Now, to the answer. Two ideas come to my mind.
(1) This is a hack, but you could assert the predicate(s) every time you need them and retract them immediately afterwards:
predicate1 :-
assert(predicate2), predicate2, retractall(predicate2).
If you want a body and arguments for predicate2, do assert(predicate2(argument1, argument2) :- (clause1, clause2, clause3)).
(2) Another way to achieve this would be to introduce an extra argument for the predicate which you do not want to be called by the user and use it for an identification that the user cannot possibly provide, but which you can provide from your calling predicate. This might be a large constant number which looks random, or even a sentence. This even enables you to output a custom error message in case the wrong identification was provided.
Example:
predicate1 :-
predicate2("Identification: 2349860293587").
predicate2(Identification) :-
Identification = "Identification: 2349860293587",
1 < 5.
predicate2(Identification) :- Identification \= "Identification: 2349860293587",
write("Error: this procedure cannot be called by the user. Use predicate1/0 instead."),
fail.
I don't use the equivalent predicate2("Identification: 2349860293587") for the first clause of predicate2/0, because I'm not sure where the head of the clause might appear in Prolog messages and you don't want that. I use a fail in the end of the second clause just so that Prolog prints false instead of true after the error message. And finally, I have no idea how to prevent the user from looking up the source code with listing(predicate2) so that will still make it possible to simply look up the correct identification code if s/he really wants to. If it's just to keep the user from doing accidental harm, it should however suffice as a protection.
This reminds me to facility found in Java. There one can query the
curent call stack, and use this to regulate permissions of calling
a method. Translated to Prolog we find in the old DEC-10 Prolog the
following predicate:
ancestors(L)
Unifies L with a list of ancestor goals for the current clause.
The list starts with the parent goal and ends with the most recent
ancestor coming from a call in a compiled clause. The list is printed
using print and each entry is preceded by the invocation number in
parentheses followed by the depth number (as would be given in a
trace message). If the invocation does not have a number (this will
occur if Debug Mode was not switched on until further into the execution)
then this is marked by "-". Not available for compiled code.
Since the top level is usually a compiled predicate prolog/0, this could be
used to write a predicate that inspects its own call stack, and then decides
whether it wants to go into service or not.
rule2 :- ancestors(L), length(L,N), N<2, !, write('Don't call me'), fail.
rule2 :- 1<5.
In modern Prologs we don't find so often the ancestors/1 predicate anymore.
But it can be simulated along the following lines. Just throw an error, and
in case that the error is adorned with a stack trace, you get all you need:
ancestors(L) :- catch(sys_throw_error(ignore),error(ignore,L),true).
But beware stack eliminiation optimization might reduce the stack and thus
the list returned by ancestors/1.
Best Regards
P.S.: Stack elimination optimization is already explained here:
[4] Warren, D.H.D. (1983): An Abstract Prolog Instruction Set, Technical Note 309, SRI International, October, 1983
A discussion for Jekejeke Prolog is found here:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/10_pro08/13_press/03_bench/05_optimizations/03_stack.html

Resources