I have the followings:
mother(grimalde).
daughter(biancaneve, grimalde).
love(X, Y) :- mother(X), daughter(Y, X).
\+(kill(X, Y)) :- mother(X), daughter(Y, X), love(X, Y).
when I run consult('ex.pl'). I get:
?- consult('ex.pl').
ERROR: /home/antonio/Scrivania/ex.pl:4:
No permission to modify static procedure `(\+)/1'
Defined at /usr/lib/swi-prolog/boot/init.pl:242
% ex.pl compiled 0.00 sec, 0 clauses
And I don't understand why...
In Prolog you cannot use negation in a clause head.
Definite clauses
Remember that Prolog clauses are definite clauses, i.e. conjunctions of literals of which exactly one is positive. This positive literal is called the head of the clause and is the part preceding the ":-".
Abstracting a bit, your clause looks like this:
\+H :- B1, B2, B3
which corresponds to the following clause:
\+H, \+B1, \+B2, \+B3
which is not definite.
Negation as failure
Also remember that Prolog negation is not logical negation but negation as failure. In that sense \+(kill(X,Y)) should be read "In this Prolog program it cannot be derived that X kills Y."
Permission error
So why do you get a permission error? Since \+/1 is not interpreted negating the clause head (since the Prolog language does not allow this), it seems like you are redefining \+/1. Since \+/1 is the outer functor of the clause head, it looks as if you are defining it. But redefining this predicate is not allowed.
Related
The tag logical purity mentions (=)/2 as pure. Is it
"intrinsically" pure or "operational" pure? To the
best of my knowledge it can be defined by this Horn clause:
∀x(=(x, x))
Which is this Prolog fact, if were not already a built-in:
X = X.
This means (=)/2 would be "intrinsically" pure, as SWI-Prolog already remarks. So what is
then the difference to first order equality (FOL=), if there
are any differences?
The "intrinsinc" definition of (=)/2 I guess does assure that the unify predicate is reflexive, symmetric and transitive. Requirements that are also satisfied by FOL=. But FOL= also requires congruence, which is this axiom schema:
/* Predicate Congruence in FOL= */
∀x1..∀xn∀yj(=(xj, yj) & p(x1, .., xn) -> p(x1, .., xj-1, yj, xj+1, .., xn))
Which is not represented by the only Horn clause for the unify predicate. And since the unify predicate is a built-in, the missing Horn clauses can also not be added. So what can go wrong? Can we make an example that would go wrong?
The classical example is this fact:
p(morning_star).
Obviously this query succeeds in Prolog:
?- p(morning_star).
true
But this query fails in Prolog, whereas in FOL= it would succeed:
?- morning_star = evening_star, p(evening_star).
false
The situation is different in so called unification modulo theories, where the unification and also the unify predicate might change their meaning.
Consider the following Prolog program.
a(X) :- b(_), c(X).
b(1).
b(2).
b(3).
c(1).
Running the query:
a(X).
in SWI-Prolog, we get three results, all X = 1.
Given that we do not care about the anonymous variable, what is preventing SWI-Prolog to return a single result? Why isn't this optimization performed?
Thanks
Well for Prolog the underscore is simply an anonymous variable. So the a/1 predicate is equivalent to:
a(X) :-
b(Y),
c(X).
Now it may look useless to backtrack over the b(Y) clause, since once it is satisfied, the Y is nowhere used, and thus should not have impact on the rest of the program. Furthermore Y has no effect on X so b(Y) should not have the slightest influence on X.
In real Prolog however, there are some things that might have impact:
the b/1 predicate might perform I/O. Say that the predicate is implemented as:
b(a) :-
print(a).
b(a) :-
print(b).
then it will print a in the first branch and b in the second one.
b/1 might raise an exception in a second, third, ... path. In which case we probably want to handle the error;
b/1 might use asserta/1, assertz/1, etc. and alter the program. It might for instance add facts for c/1 such that in the second run c/1 has other results.
A lot of Prolog interpreters have a non-backtrackable store such that the different backtracking paths, can share information with each other.
other coding facilities such that the outcome of b/1 might have impact on c/1.
You can avoid this backtracking over b/1 by using the once/1 meta-predicate. For instance:
a(X) :-
once(b(_)),
c(X).
I was reading a code piece in Prolog and I saw the below code :
r(a).
q(b).
p(X) :- not r(X)
Questions :
?-q(X), p(X) // Result: b
?-p(X), q(X) // Result: no
So, why for ?-q(X), p(X) we get "b" and for ?-p(X), q(X) which is exactly the same as ?-q(X), p(X) we get "no" ?
?-q(X), p(X) // Result: b
q(X) eventually unifies with q(b), which then calls p(b), which calls not r(b), which is true.
?-p(X), q(X) // Result: no
p(X) calls not r(X), which causes X to unify with a, which causes the preceding clause to evaluate to not r(a), which is false, and the conjuction operator short circuits to no.
In fact the two queries are not exactly the same because Prolog "conjunction" operator (the comma) is usually not commutative:
the execution is from left to right and so the order in which the variables are instantiated is different in those queries
if you only use pure logical predicates, that is predicates that are defined not using extra-logical predicates (like not/1 or if-then-else constructs), nor predicates having side-effects (like I/O ones), nor predicates that require some of its arguments to be instantiated beforehand (like is/2), the change in instantiation order does not affect commutativity
but as one of your predicates uses not/1 and it behaves differently when its argument is r(_) or r(b) as explained in C.B. answer, commutativity does not hold.
As you may know not/1 does not implement pure logical negation: it implements so-called negation as failure meaning that it succeeds if the execution of its argument fails and otherwise fails (if the argument is a free variable you get an instantiation error). As the execution is from left to right you cannot expect that its behaviour is affected by some instantiation made after its call.
So I just started Prolog and I was wondering two things:
1) Is there built in functions (or are they all called predicates?) for simple things like max of 2 numbers, or sine of a number, etc... If so, how do I access them?
2) How can I call a predicate from another one? I wrote two predicates called car and cdr. car returns the head of a list and cdr returns the list without the head. But now I want to call car on the cdr. Here are some examples for clarification:
car([3,4,5,5], H). would return H = 3
cdr([3,4,5,5],L). would return L = [4,5,5]
and what I am asking is how can I do this:
car(cdr[3,4,5,5]))
??
As others have pointed out, the predicates in Prolog are called that for a reason: they really aren't functions. Many newcomers to Prolog start out by trying to map the functionality they know in other languages over to Prolog and it generally fails. Prolog is a very different programming tool than most other languages. So it's a bit like using a variety of hammers for a long time, then having someone hand you a wrench, and you wonder why it doesn't make a good hammer.
In Prolog, predicates are a means of declaring relations between entities. If you say foo(a, b) it means there's a relationship between a and b called foo. You've probably seen the examples: knows(joe, jim). and knows(jim, sally). And you can define a relation, like:
remotely_acquainted(X, Y) :- knows(X, Z), knows(Z, Y), \+ knows(X, Y).
Or something like that.
A predicate does not return a value. It either succeeds or it fails. If you have a sequence of predicates separated by commas (an "and" relationship) and Prolog encounters a predicate that fails, it backs up (backtracks) to the nearest prior predicate which it can make succeed again with different instantiation of its arguments and moves forward again.
Just to add a little to the confusion, there are some predicates in Prolog designed specifically for the evaluation of arithmetic expressions. These act like functions, but they are special case. For example:
X is Y / gcd(Z, 4).
Here, gcd of Z and 4 is computed an its value returned, and then Y is divided by that value and the result is instantiated into X. There are a variety of other functions as well, such as max/2, sin/1, etc. You can look them up in the documentation.
Arithmetic comparative operators function this way as well (using =:=/2, >/2, </2, etc with numeric expressions). So if you say:
X < Y + Z
The Prolog will consider numerical evaluation of these arguments and then compare them.
So having said all that, Prolog does allow embedding of term structures. You could have something like:
car(cdr([1,2,3]))
as a term. Prolog will not interpret it. Interpretation is left up to the programmer. I could then create a predicate which defines an evaluation of such terms:
car([H|_], H).
cdr([_|T], T).
proc_list(car(X), Result) :-
proc_list(X, R1),
car(R1, Result), !.
proc_list(cdr(X), Result) :-
proc_list(X, R1),
cdr(R1, Result), !.
proc_list(X, X).
The cut in the above clauses prevents backtracking to proc_list(X, X) when I don't want it.
Then:
| ?- proc_list(car(cdr([1,2,3])), R).
R = 2
yes
| ?- proc_list(car(cdr(cdr([1,2,3]))), R).
R = 3
yes
| ?-
Note this is a simple case and I may not have captured all of the subtleties of doing a proper sequence of car and cdr. It can also be made more general using =.. and call, etc, instead of discrete terms car and cdr in the parameters. For example, a slightly more general proc_list might be:
proc_list(Term, Result) :-
Term =.. [Proc, X], % Assumes terms have just one argument
member(Proc, [car, cdr]), % True only on recognized terms
proc_list(X, R1), % Recursively process embedded term
ProcCall =.. [Proc, R1, Result], % Construct a calling term with Result
call(ProcCall), !.
proc_list(X, X).
This technique of processing a term does step away from relational behavior which Prolog is best at, and leans into functional behavior, but with an understand of how Prolog works.
Prolog has a really different attitude to computing...
You don't define functions, but relations among arguments. The most similar and well known language I'm aware of is SQL. Think of predicates as tables (or stored procedures, when some computation not predefined by database engine is required).
car([H|_],H).
cdr([_|T],T).
car_of_cdr(L, Car) :- cdr(L, Cdr), car(Cdr, Car).
but since lists' syntax is a core part of the language, a better definition could be
car_of_cdr([_,X|_], X).
Anyway, I think you should spend some time on some Prolog tutorial. SO info page has much more information...
:- use_module(support).
This means the module will use predicates written in other modules.
<module_name>:<predicate_name>(<atoms / Variables>).
This way you can call a predicate in another module.
I want to know how Prolog solves this program:
test(X, Y).
test(X, X):-!, fail.
I googled "negation as failure" but I am confused!
Consider the following example:
father(nick, john).
We use the predicate father(X,Y) to denote that the father of X is Y.
Let's query the database:
?- father(nick,X).
X = john.
?- father(john,Y).
false.
In both cases we asked who is the father of someone (nick, john respectively). In the first case, prolog knew the answer (john) however in the second it didn't and so the answer was false, meaning that john does not have any father. We might expect that, as we gave prolog no information about john's father, it would respond with unknown. That would be an open-world where if something is not known we don't assume that it's false. On the contrary, in the closed world of prolog, if we don't know something, we assume that it's false.
Note that a world where we say that we don't know who the father of john is, based on knowing that anyone must have a father is not an open world; it can be easily modelled in prolog:
data_father(nick, john).
father(X,Y):-
data_father(X,Y) -> true ; true.
On the other hand, in an open world prolog you would write facts and counter facts:
father(nick, john).
not father(adam, X).
And this is negation as failure. However, this is not what happens in your program:
test(X, Y).
test(X, X):-!, fail.
The first clause will always succeed, regardless of the value of the arguments. In fact, exactly because of that, there is no point in naming the arguments and prolog will give you a singleton warning; you can write the clause as test(_, _).
On the other hand, the second clause will always fail. It can fail in two ways: (1) the arguments may be different (2) the arguments are unifiable so prolog moves to the body and then fails.
Precisely because prolog is using a closed world model there is no point of having clauses (without side-effects (but that's considered bad practise anyway)) that always fail. On the contrary, these extra calls cause your program to run slower and use more memory.
It is also worth noting that the cut (!/0) does nothing here since when you reach it there are no more choice points. Consider however this example:
test(X, Y).
test(X, X):-!, fail.
test(X, 42).
?- test(1,42).
true ;
true.
?- test(42,42).
true ;
false.
In both cases prolog will create 3 choice points, one for each clause.
In the first case, Prolog will successfully match the head of the first clause and succeed since there is no body.
Then, it will fail matching the head of the second clause and the body will not be "executed".
Finally, it will match the head of the third clause and succeed since there is no body.
However, on the second case:
Prolog will succeed in matching the head of the first clause and succeed since there is no body.
Then, it will succeed in matching the head of the second clause; the cut will remove all other choice points and then it will fail due to fail.
Therefore, prolog will not try the third clause.
A few words about negation as failure since you mentioned it. Negation as failure is based on the closed world assumption; since we assume that anything that cannot be deduced from the facts we already have is wrong, if we fail to prove something it means that the opposite of it is considered true. For example, consider this:
father(nick, john).
fatherless(X) :- \+ father(X, _).
And
?- fatherless(nick).
false.
?- fatherless(john).
true.
On the contrary, in an open world prolog with the following code:
father(nick, john).
not father(adam, X).
fatherless(X) :- \+ father(X, _).
fatherless/1 would succeed only for adam, fail for nick and return unknown for anything else
the first clause test(X, Y). says that test/2 is unconditionally true, for whatsoever argument pattern.
the second clause test(X, X):-!, fail. says that, when test/2 is called with unifiable first and second argument, there are not more alternative, then fail (note that will fail always, because argument schema is ruling out the instantiation pattern where first argument \= second implicitly).
The operational effect if the same as a logical negation, under 'Closed World Assumption'.