You are on page 1of 68

Lecture 10: Cuts and Negation

• Theory
– Explain how to control Prolog’s
backtracking behaviour with the help
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

of the cut predicate


– Introduce negation
– Explain how cut can be packaged
into a more structured form, namely
“negation as failure”
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2).
d(2).
?- c(1),d(1),e(1).
e(2).
f(3).
?- p(X).
X=1;
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2).
d(2).
?- c(1),d(1),e(1).
e(2).
f(3).
?- p(X). ?- d(1), e(1).
X=1;
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2).
d(2).
?- c(1),d(1),e(1).
e(2).
f(3).
?- p(X). ?- d(1), e(1).
X=1;

Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1).
e(2).
f(3).
?- p(X). ?- d(1), e(1).
X=1;

Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1).
X=1;

Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;

Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;
† ?- e(2).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;
X=2 † ?- e(2).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X). ?- f(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;
X=2; † ?- e(2).
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X). ?- f(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1 X=3


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;
X=2; † ?- e(2).
X=3
Example: cut-free code
p(X):- a(X).
p(X):- b(X), c(X), d(X), e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),d(X),e(X). ?- f(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1 X=1 X=3


c(1). c(2). X=2
d(2).
?- c(1),d(1),e(1). ?- c(2),d(2),e(2).
e(2).
f(3).
?- p(X). ?- d(1), e(1). ?- d(2), e(2).
X=1;
X=2; † ?- e(2).
X=3;
no
Adding a cut

• Suppose we insert a cut in the second


clause:
p(X):- b(X), c(X), !, d(X), e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

• If we now pose the same query we will


get the following response:
?- p(X).
X=1;
no
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2).
c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2).
d(2).
e(2).
f(3).
?- p(X).
X=1;
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2). X=1
d(2).
e(2). ?- c(1),!,d(1),e(1).
f(3).
?- p(X).
X=1;
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2). X=1
d(2).
e(2). ?- c(1), !, d(1), e(1).
f(3).
?- p(X). ?- !, d(1), e(1).
X=1;
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X). X
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2). X=1
X
d(2).
e(2). ?- c(1), !, d(1), e(1).
f(3).
?- p(X). ?- !, d(1), e(1).
X=1;
?- d(1), e(1).
Example: cut
p(X):- a(X).
p(X):- b(X),c(X),!,d(X),e(X). ?- p(X).
p(X):- f(X).
a(1). ?- a(X). ?- b(X),c(X),!,d(X),e(X).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

b(1). b(2). X=1


c(1). c(2). X=1
d(2).
e(2). ?- c(1), !, d(1), e(1).
f(3).
?- p(X). ?- !, d(1), e(1).
X=1;
no ?- d(1), e(1).


What the cut does

• The cut only commits us to choices made


since the parent goal was unified with the
left-hand side of the clause containing the cut
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

• For example, in a rule of the form

q:- p1, … , pm, !, r1, … , rn.

when we reach the cut it commits us:


– to this particular clause of q
– to the choices made by p1, … , pm
– NOT to choices made by r1, … , rn
Another build-in predicate: fail/0

• As the name suggests, this is a goal


that will immediately fail when Prolog
tries to proof it
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

• That may not sound too useful


• But remember:
when Prolog fails, it tries to backtrack
Negation as Failure

• The cut-fail combination seems to be


offering us some form of negation
• It is called negation as failure, and
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

defined as follows:

neg(Goal):- Goal, !, fail.


neg(Goal).
Database Manipulation

• Prolog has five basic database


manipulation commands:

– assert/1
– asserta/1
– assertz/1

– retract/1
– retractall/1
Database Manipulation

• Prolog has five basic database


manipulation commands:
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

– assert/1
– asserta/1 Adding information
– assertz/1

– retract/1
Removing information
– retractall/1
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

Start with an empty database


© Patrick Blackburn, Johan Bos & Kristina Striegnitz

yes
?- listing.
Start with an empty database
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

yes
Using assert/1

?- assert(happy(mia)).
Using assert/1

happy(mia). ?- assert(happy(mia)).
yes
?-
© Patrick Blackburn, Johan Bos & Kristina Striegnitz
Using assert/1

happy(mia). ?- assert(happy(mia)).
yes
?- listing.
happy(mia).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

?-
Using assert/1

happy(mia). ?- assert(happy(mia)).
yes
?- listing.
happy(mia).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

?- assert(happy(vincent)),
assert(happy(marsellus)),
assert(happy(butch)),
assert(happy(vincent)).
Using assert/1

happy(mia). ?- assert(happy(mia)).
happy(vincent). yes
?- listing.
happy(marsellus).
happy(mia).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(butch). ?- assert(happy(vincent)),
happy(vincent). assert(happy(marsellus)),
assert(happy(butch)),
assert(happy(vincent)).
yes
?-
Changing meaning of predicates

• The database manipulations have


changed the meaning of the predicate
happy/1
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

• More generally:
database manipulation commands give
us the ability to change the meaning of
predicates during runtime
Dynamic and Static Predicates

• Predicates which meaning change


during runtime are called dynamic
predicates
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

– happy/1 is a dynamic predicate


– Some Prolog interpreters require a
declaration of dynamic predicates
• Ordinary predicates are sometimes
referred to as static predicates
Asserting rules

happy(mia). ?- assert( (naive(X):- happy(X) ).


happy(vincent).
happy(marsellus).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(butch).
happy(vincent).
Asserting rules

happy(mia). ?- assert( (naive(X):- happy(X) ).


happy(vincent). yes
?-
happy(marsellus).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(butch).
happy(vincent).

naive(A):- happy(A).
Removing information

• Now we know how to add information


to the Prolog database
– We do this with the assert/1 predicate
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

• How do we remove information?


– We do this with the retract/1 predicate,
this will remove one clause
– We can remove several clauses
simultaneously with the retractall/1
predicate
Using retract/1

happy(mia). ?- retract(happy(marsellus)).
happy(vincent).
happy(marsellus).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(butch).
happy(vincent).

naive(A):- happy(A).
Using retract/1

happy(mia). ?- retract(happy(marsellus)).
happy(vincent). yes
?-
happy(butch).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(vincent).

naive(A):- happy(A).
Using retract/1

happy(mia). ?- retract(happy(marsellus)).
happy(vincent). yes
?- retract(happy(vincent)).
happy(butch).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

happy(vincent).

naive(A):- happy(A).
Using retract/1

happy(mia). ?- retract(happy(marsellus)).
happy(butch). yes
?- retract(happy(vincent)).
happy(vincent).
yes
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

naive(A):- happy(A).
Using retract/1

happy(mia). ?- retract(happy(X)).
happy(butch).
happy(vincent).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

naive(A):- happy(A).
Using retract/1

naive(A):- happy(A). ?- retract(happy(X)).


X=mia;
X=butch;
X=vincent;
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

no
?-
Consider this database

child(martha,charlotte). ?- descend(martha,X).
child(charlotte,caroline). X=charlotte;
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). X=caroline;
child(laura,rose). X=laura;
X=rose;
descend(X,Y):- child(X,Y). no
descend(X,Y):- child(X,Z),
descend(Z,Y).
Collecting solutions

• There may be many solutions to a


Prolog query
• However, Prolog generates solutions
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

one by one
• Sometimes we would like to have all
the solutions to a query in one go
• Needless to say, it would be handy to
have them in a neat, usable format
Collecting solutions

• Prolog has three built-in predicates that


do this: findall/3, bagof/3 and setof/3
• In essence, all these predicates collect
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

all the solutions to a query and put


them into a single list
• But there are important differences
between them
findall/3

• The query
?- findall(O,G,L).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

produces a list L of all the objects O


that satisfy the goal G
– Always succeeds
– Unifies L with empty list if G cannot be
satisfied
A findall/3 example

child(martha,charlotte). ?- findall(X,descend(martha,X),L).
child(charlotte,caroline). L=[charlotte,caroline,laura,rose]
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). yes
child(laura,rose).

descend(X,Y):- child(X,Y).
descend(X,Y):- child(X,Z),
descend(Z,Y).
Other findall/3 examples

child(martha,charlotte). ?- findall(f:X,descend(martha,X),L).
child(charlotte,caroline). L=[f:charlotte,f:caroline,f:laura,f:rose]
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). yes
child(laura,rose).

descend(X,Y):- child(X,Y).
descend(X,Y):- child(X,Z),
descend(Z,Y).
Other findall/3 examples

child(martha,charlotte). ?- findall(X,descend(rose,X),L).
child(charlotte,caroline). L=[ ]
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). yes
child(laura,rose).

descend(X,Y):- child(X,Y).
descend(X,Y):- child(X,Z),
descend(Z,Y).
Other findall/3 examples

child(martha,charlotte). ?- findall(d,descend(martha,X),L).
child(charlotte,caroline). L=[d,d,d,d]
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). yes
child(laura,rose).

descend(X,Y):- child(X,Y).
descend(X,Y):- child(X,Z),
descend(Z,Y).
findall/3 is sometimes rather crude

child(martha,charlotte). ?- findall(Chi,descend(Mot,Chi),L).
child(charlotte,caroline). L=[charlotte,caroline,laura, rose,
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). caroline,laura,rose,laura,rose,rose]
child(laura,rose). yes

descend(X,Y):- child(X,Y).
descend(X,Y):- child(X,Z),
descend(Z,Y).
bagof/3

• The query
?- bagof(O,G,L).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

produces a list L of all the objects O


that satisfy the goal G
– Only succeeds if the goal G succeeds
– Binds free variables in G
Using bagof/3

?- bagof(Chi,descend(Mot,Chi),L).
child(martha,charlotte). Mot=caroline
child(charlotte,caroline). L=[laura, rose];
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura).
Mot=charlotte
child(laura,rose).
L=[caroline,laura,rose];
descend(X,Y):- Mot=laura
child(X,Y). L=[rose];
descend(X,Y):- Mot=martha
child(X,Z), L=[charlotte,caroline,laura,rose];
descend(Z,Y). no
Using bagof/3 with ^

?- bagof(Chi,Mot^descend(Mot,Chi),L).
child(martha,charlotte). L=[charlotte, caroline, laura, rose,
child(charlotte,caroline). caroline,laura,rose,laura, rose, rose]
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura).
child(laura,rose).

descend(X,Y):-
child(X,Y).
descend(X,Y):-
child(X,Z),
descend(Z,Y).
setof/3

• The query
?- setof(O,G,L).
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

produces a sorted list L of all the


objects O that satisfy the goal G
– Only succeeds if the goal G succeeds
– Binds free variables in G
– Remove duplicates from L
– Sorts the answers in L
Recall using bagof/3

?- bagof(Chi,Mot^descend(Mot,Chi),L).
child(martha,charlotte). L=[charlotte, caroline, laura, rose,
child(charlotte,caroline). caroline, laura, rose, laura, rose,
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). rose]
child(laura,rose). yes

descend(X,Y):- ?-
child(X,Y).
descend(X,Y):-
child(X,Z),
descend(Z,Y).
Compare this to using setof/3

?- bagof(Chi,Mot^descend(Mot,Chi),L).
child(martha,charlotte). L=[charlotte, caroline, laura, rose,
child(charlotte,caroline). caroline, laura, rose, laura, rose,
© Patrick Blackburn, Johan Bos & Kristina Striegnitz

child(caroline,laura). rose]
child(laura,rose). yes

descend(X,Y):- ?- setof(Chi,Mot^descend(Mot,Chi),L).
child(X,Y).
L=[caroline, charlotte, laura, rose]
descend(X,Y):-
yes
child(X,Z),
descend(Z,Y).
?-

You might also like