Lecture 10

33
Lecture 10 Logic programming, PROLOG (PROgramming in LOGic)

description

Lecture 10. Logic programming, PROLOG (PROgramming in LOGic). Logic programming. The method of pure logic programming is a special restricted case of the general resolution method. There are two principle constraint s : - PowerPoint PPT Presentation

Transcript of Lecture 10

Page 1: Lecture 10

Lecture 10

Logic programming,

PROLOG

(PROgramming in LOGic)

Page 2: Lecture 10

2

Logic programmingThe method of pure logic programming is a

special restricted case of the general resolution method. There are two principle constraints:

Prolog works only with Horn clauses that contain at most one positive literal;

Prolog applies the linear strategy for the generation of resolvents;This linear strategy is combined with

backtracking

Page 3: Lecture 10

3

Prolog notation & terminology

Rules (conditional statements): P:- Q1, Q2,..,Qn.

Gloss: P, if Q1 and Q2 and … Qn

Note that this is equivalent to these formulas: (Q1 Q2 … Qn P) (Q1 Q2 … Qn) P

The former is a clause with one positive literalwith one positive literal. Facts (unconditional statements): P.

This is a clause without negative literalswithout negative literals. Goals (questions): ?- Q1, Q2,..,Qn.

Note that this is equivalent to the clause without a positive literalwithout a positive literal: Q1 Q2 … Qn

Empty clause: , YES: success, the goals have been met Remark: Unlike in the FOL language, variables are written as

beginning with upper-case letters, other predicates and terms with lower-case letters.

Page 4: Lecture 10

4

Foundations of PrologFoundations of Prolog

A logic program is a sequence of conditional and unconditional statements, that is rules and facts.

A procedureA procedure of a logic program is the set of rules and facts with the same head (positive literal).

The goal clauses represent questions to which the program should answer. The answer is YES, if a goal is entailed by the given set of statements, otherwise the answer is NO.

Hence the way how to answer the questions (that is how to meet the goals) is a matter of the program interpreter. It should decide whether the goals are entailed by the given program knowledge base. Moreover, the interpreter is also able to provide information about the values that yielded a positive answer. These values are obtained by unification of literals.

Note. Logic program is a declarative rather than imperative specification of an algorithm. In this sense we should understand the notion of a statement. It is simply a logical

formula. We specify what to do rather than how to do it.

For details see, e.g.,http://www.ling.helsinki.fi/kit/2004k/ctl272/Bangor/clbook_9.html

Page 5: Lecture 10

5

Prolog & Horn clauses

Prolog works with the language of clauses restricted to Horn clauses.

Example: “All members of a sport club are skiers or rock climbers”.

Problem. The consequent is in the form of disjunction: x [SC(x) (SKI(x) CLIMB(x))]

x [SC(x) SKI(x) SKI(x) CLIMB(x) CLIMB(x)]

This statement/rule cannot be specified in the form of a Horn clause; there are two positive literals.

Page 6: Lecture 10

Example: sport club Tom, Peter and John are members of a sport club. Every member of the

club is a skier or a climber. No climber likes raining. All skiers like snow. Peter does not like what Tom likes, and does like what Tom does not like. Tom likes snow and raining.

Question: Is there in the club a sportsman who is a climber but not a skier?

Knowledge base (+ query 11): 1. SC(t)2. SC(p)3. SC(j)4. x [ SC(x) (SKI(x) CLIMB(x)) ] problem: 2 pozitive literals5. x [ CLIMB(x) LIKE(x,r) ]6. x [ SKI(x) LIKE(x,s)]7. x [LIKE(t,x) LIKE(p,x)]8. x [LIKE(t,x) LIKE(p,x)]9. LIKE(t,s)10. LIKE(t,r)11. ? x [SC(x) CLIMB(x) SKI(x)]

Page 7: Lecture 10

Example: sport club

This problem is easily solvable in the general resolution method of FOL.Try to do it as a homework

However, its specification in Prolog is not possible in a direct way.

Page 8: Lecture 10

Prolog constraints (summary)

1.1. At most one positive literal (Horn clauses)At most one positive literal (Horn clauses)2.2. We cannot directly express negative factsWe cannot directly express negative facts

Negation = fail of deduction; Prolog’s answer NO means this: The answer to your question cannot be derived from the program (knowledge base)(The closed-world assumption)

3. Prolog is a declarative languagedeclarative language. Thus there are only two possibilitiestwo possibilities how to affect program to affect program executionexecution:

The orderThe order of clauses in the program; the order of literals in a clause

Predicate/Command ! (cutcut)

Page 9: Lecture 10

Example All students are younger than Peter’s mother.

Tom and Anne are students. Who is younger than Peter’s mother?

Formalisation in FOL: intended interpretationx [St(x) Y(x, f(a))] St the set of studentsSt(b) Y relation of being younger; St(c) a Peter; b Tom; c Anne; f mother of … y Y(y, f(a)) ???

Program in Prolog: younger(X, mother_of(peter)):- student(X). rule

student(tom). factstudent(anne). fact

?- younger(Y, mother_of(peter)).question/goal

Page 10: Lecture 10

Solution by general resolution

1. St(x) Y(x, f(a))

2. St(b)

3. St(c)4. (y) Y(y, f(a)) negated conclusion5. Y(b, f(a)) rezolution 1,2; b/x6. 4,5 – YES (y = b)7. Y(c, f(a)) rezolution 1,3; c/x8. 4,7 – YES (y = c)

Page 11: Lecture 10

Solution in Prolog younger(X, mother_of(peter)):- student(X).

student(tom).student(anne).?- younger(Y, mother_of(peter)).

The interpreter takes care of unification and resolution; it applies goal-driven linear strategy of program execution:

1) The goal ?- younger(Y, mother_of(peter)) is unified with younger(X, mother_of(peter)), Y=X;

2) A new goal is generated: ?- student(Y)3) This goal is unified with the second fact; success: Y = tom4) Answer: YES, Y = tom;Insertion of the semicolon (;) means that we ask „anybody else?“ This causes backtracking. The interpreter returns to the last goal and tries to meet it again:

?- student(Y). The second clause cannot be used again. Hence the interpreter uses the third fact:5) The answer is again positive: YES, Y = anne; (anybody else?)

NO Note. Semicolon ‘;’ means logical disjunction or

comma ‘,’ means logical conjunction and

Page 12: Lecture 10

Example modified

1. younger(X, mother_of(peter)):- student(X).

2. student(tom).

3. student(anne).

4. younger(X, mother_of(peter)):- child(X, mother(peter)).

5. child(X,Y):-Y=mother_of(X).

?- younger(Y, mother_of(peter)). question (goal)

a) YES, Y = tom;

b) YES, Y = anne;

Anybody else? The answer is Y = peter. (Peter is younger than his mother)

Page 13: Lecture 10

backtracking

younger(Y,mother_of(peter)

1 4

student(Y) child(Y,mother_of(peter))

2 3

5

Yes Yes mother_of(peter)=mother_of(Y)

Y=tom; Y=anne; Y=peter;

No

Page 14: Lecture 10

Example continued1. younger(X, mother_of(peter)):- student(X).2. student(tom).3. student(anne).4. younger(X, mother_of(peter)):- child(X, mother(peter)).5. child(X,Y):-Y=mother_of(X).

?- younger(Y, mother_of(peter)). question (goal) a) YES, Y = tom;b) YES, Y = anne;c) Yes, Y = peter. Now we ask another question:

?- student(pet?- student(peteer).r).Answer: NOThis does not mean that Peter actually is not a student. Rather, due to the closed-world

assumption it only means that the fact that Peter is a student is not entailed by the given program.

Negation is a failure of deduction. We cannot directly insert negative facts to the program.

Page 15: Lecture 10

Negation in Prolog

If we want to express the fact that Marie is not a student, we can use the predicate not:not(student(marie)):- call(student(marie)), !, fail. not(student(marie)).

not(student(marie)) (semanticssemantics) call(student(marie)): If the program entails that Marie is a

student then the call succeeds; another goal ! (cut) also succeeds; but the predicate failfail yields the answer NONO.

cut ! : no backtracking; „do not try again“, it is not true that Marie is not a student.

If call(student(marie)) fails then not(student(marie)) succeeds; it is true that Marie is not a student.

Page 16: Lecture 10

Example: Eukleides algorithmIn mathematics, the greatest common divisor (gcd), also known as the greatest

common factor (gcf), or highest common factor (hcf), of two or more non-zero integers, is the largest positive integer that divides the numbers without a remainder. For example, the GCD of 8 and 12 is 4.

1. gcdX,X,X.2. gcdX,Y,Z:- X>Y, gcdX-Y,Y,Z. 3. gcdX,Y,Z:- Y>X, gcdX,Y-X,Z.

Note. Prolog has built in basic arithmetic.

4. ?- gcd4,6,Z.

Execution:5. ?- 4>6, gcd4-6,6,Z resolution: 4,2.

4. ?- gcd4,6,Z backtracking 5. ?- 6>4, gcd4,6-4,Z resolution: 4,3.6. ?- gcd4,2,Z fact "6>4“; hence calculate gcd4,2,Z 7. ?- 4>2, gcd4-2,2,Z resolution: 6,2.8. ?- gcd2,2,Z Calculating the clause 7, fact "4>2"9. yes, Z=2. resolution: 8,1.

Page 17: Lecture 10

Calculating natural numbers

1. nat0. 0 is a natural number2. nats(X):-nat(X). the successor of a natural number is a natural number3. ?- nats(X). Which are all the natural numbers?

Execution:4. ?-natX resolution 3,2.5. YES, X = 0;3. ?- nats(X) backtracking4. ?-nat(X) resolution 3,5.6. YES, X = s(0);

7. YES, X = s(s(0));8. YES, X = s(s(s(0))); and so on, ad infinity......

Note. This program generates a potential infinitypotential infinity, not actual. Potentially, if we had an infinite time at our disposal, we’d obtain all the naturals.

Page 18: Lecture 10

The order of clauses can change the execution of a program due to the linear strategy

Program A:1. parent(tom, marie).2. parent(anne, marie).3. descendant(X,Y):- ancestor(Y,X).4. child(X,Y):- parent(Y,X).5. ancestor(X,Y):- descendant(Y,X).6. descendant(X,Y):- child(X,Y).7. descendant(X,Y):- child(X,Z), descendant(Z,Y).8. ?- descendant(marie,X).Note. Prolog renames variables, if needed

Page 19: Lecture 10

Execution treedescendant(marie,X)

3 6

ancestor(X,marie) child(marie,X)

5 4

descendant(marie,X) parent(X,marie)

3 1

ancestor(X,marie) X=tom;

etc. .... X=anne (2)The program does not answer though there is a solution;

„first aid“: move the clauses 3, 5 down and cut them off (!); “there is a cycle, it will be corrected later on”

Page 20: Lecture 10

„the first aid“ (carefully): cut !

Program B:

1. parent(tom, marie).

2. parent(anne,marie).

3. descendant(X,Y):- child(X,Y).

4. descendant(X,Y):- child(X,Z), descendant(Z,Y).

5. child(X,Y):- parent(Y,X).

6. descendant(X,Y):- !, ancestor(Y,X).

7. ancestor(X,Y):- !, descendant(Y,X).

8. ?- descendant(marie,X).

Page 21: Lecture 10

The order of literals1. parent(tom, marie).2. parent(anne,marie).3. descendant(X,Y):- child(X,Y).4. descendant(X,Y):- descendant(X,Z)descendant(X,Z), child(Z,Y).5. child(X,Y):- parent(Y,X).6. ?- descendant(marie,W).Execution: ?- child(marie,W), ?-parent(W,marie),

W=tom; W=anne; ????? infinite cycleAfter the second semicolon the program starts looping: ?-parent(W,marie), ?- child(marie,W),

?- descendant(marie,W), ?-descendant(marie,Z), ?- child(Z’,Z), ?- descendant(marie,Z’), ?- child(Z,Z’), ?- child(Z’,Z’’), …

It suffices to change the order of literals in the clause 4.

Page 22: Lecture 10

Correctly:1. parent(tom, marie).2. parent(anne,marie).3. descendant(X,Y):- child(X,Y).4. descendant(X,Y):- child(X,Z), descendant(Z,Y).descendant(Z,Y).5. child(X,Y):- parent(Y,X).6. ?- descendant(marie,W).

Remedial tenet: first facts, then rulesfirst facts, then rules. In the recursive rules, recursive predicate as the last onerecursive predicate as the last one.

Recursive rules: the predicate of a consequent (rule head) is applied again in the antecedent (rule body)

These rules correspond to cycles in imperative languages

Page 23: Lecture 10

The function factorial: x! = x × x – 1 × … × 1, 0! = 1

fact(0, Factorial, Factorial).fact(Number,Help,Factorial) :-

P1 is Number – 1,I1 is Help × Number,fact(P1,I1,Factorial). ?- fact(3,1,X).

Execution:fact(3,1,Factorial) (Help = 1)

fact(2,3,Factorial) (Help = 3)fact(1,6,Factorial) (Help = 6)

fact(0,6,Factorial)YES, Factorial = 6

Page 24: Lecture 10

Goal-driven linear strategy of execution + backtracking

Prolog interpreter examines the execution tree to the depth and left-to-right;

This strategy is not complete; the problem can be left unsolved though there is a solution. This is due to the fact that the interpreter can get stuck in an infinite branch. Reordering clauses and/or literals can solve the problem. There are complete control strategies that examine the execution

tree to the width; all branches simultaneously. However, whereas the above depth strategy needs only one stack (“LIFO” memory structure), the width strategy needs for each execution branch another stack less effective

See, e.g., http://www.ling.helsinki.fi/kit/2004k/ctl272/Bangor/clbook_9.html

Page 25: Lecture 10

Prolog proof strategy When a query has been typed, the interpreter searches for a head that matches

the (first) goal in the query (it tries to prove this goal before attempting to prove a second goal, if there is one). If the goal matches a fact, it has been proven, and the interpreter is finished with it. If it matches the head of a rule, each of the terms in the body becomes a new goal that must be satisfied. The interpreter does not finish until all goals have been satisfied by reaching the level of matching a fact; if one of them does not, the whole query fails.

There are two cases where the interpreter might have to make a decision about how to tackle a query which has nothing to do with the logic of the program. This happens when there is more than one head which matches a goal, and when the body of a rule consists of more than one clause.

Prolog's control strategy works as follows: in the former case, the first matching clause in the files is tried first, and in the second case, the goals in a body are attempted in the order they appear. It makes it possible to write programs such that although a query can be proven by a program in principle, the interpreter fails to do so. This can however to some extent be avoided by ordering the clauses carefully in the program, and if required the programmer can write a meta-interpeter which changes the proof strategy.

Page 26: Lecture 10

example sibling_in_law(X, Y) :- married(X, Z), sibling(Z, Y).

sibling_in_law(X, Y) :- sibling(X, Z), married(Z, Y). This program identifies two ways of being a sibling-in-law: assuming

that you correspond to the first argument of sibling_in_law, the siblings of the person you are married to are your siblings in law (the first case above), as are your siblings' spouses (second case). In attempting to answer the query

?- sibling_in_law(owen, geraint).

there will be several points where the interpreter has to make a choice. Firstly, there are two clauses whose heads match the initial query (this corresponds to the OR of formal logic). Secondly (once one rule has been selected), the two terms in the body are separated by a comma which corresponds to logical conjunction, so from a logical point of view, we could start with either.

Prolog's control strategy works as follows: in the former case, the the first matching clause in the files is tried firstfirst matching clause in the files is tried first, and in the second case, the goals in a body are attempted in the order they appearthe goals in a body are attempted in the order they appear.

Page 27: Lecture 10

Example; incompleteness

Program execution tree1. A:- E. A2. A:- B. 1 23. B:- C. E B4. E:- D. 4 35. C. D C6. D:- E. E 6 57. ?- A. D 4 Yes8. E 69. … There are two ways of computing the procedure A;

the first one does not yield the solution

Page 28: Lecture 10

Clause cutClause cut:: ! (compare with „go to“ in imperative languages)

Controls and restricts backtracking It cuts off “branches that are not needed in this execution” This goal is met only once; if we attempt backtracking over !, the

interpreter omits all the clauses of the procedure being executed and goes back to the goal coming before the procedure

Red cut changes the declarative semantics of the program; it should not be used (wrong programming practice)

Green cut does not change the semantics; it is applied in order to make the program more effective in these cases:

a) Realization of „if, then, else“ (exclusive or)b) Management of exceptions (errors)c) In order to restrict seeking over large knowledge bases (when a

success is reached after the given number of attempts)

Page 29: Lecture 10

„if, then, else“ by means of „fail“ Repeat:

If the temperature is high (more than 30%), then switch off heating, else if the temperature is low (less than 15%), then switch on heating, else don’t do anything.

thermostat(Action) :-temperature(X),action(X,Action),write(‘Do’, Action), nl,fail. % fail yields backtraching

action(X,’switch-on’) :-X < 15, !.

action(X,’switch-off’) :-X > 30, !.

action(X,’don’t do anything’).?- thermostat(X).

Page 30: Lecture 10

„if, then, else“ by means of „fail“thermostat(Action) :-

temperature(X),action(X,Action),write(‘Do’, Action), nl,fail. % fail yields backtraching

action(X,’switch-on’) :-X < 15, !.

action(X,’switch-off’) :-X > 30, !.

action(X,’don’t do anything’).?- thermostat(X).Possible actions: switch on, switch off, don’t do anythingWithout cut the possible instructions would be like this:

switch on, don’t do anything, switch off, don’t do anything, don’t do anything, …

Page 31: Lecture 10

“if, then, else“

action(X,’switch-on’) :-X < 15.

action(X,’swithch-off’) :-X > 30.

action(X,’noting’) :-

not(X < 15), not(X > 30). Less effective; we keep testing the condition

Page 32: Lecture 10

Exceptions, errorstest(X) :-

X = error, !, fail.test(X) :-

write(‘valid:’, X). If there is an error then the cut lets fail be applied;

the test fails. However, backtracking to the second clause is blocked. The execution returns to the clause preceding the first test.

Equivalent, less effective but more comprehensible program:

test(X) :-not(X = error), write(‘valid:’, X).

Page 33: Lecture 10

Data structure list List is a potentially infinite ordered n-tuple.

[fish, tortoise, crab, octopus, …] Notation: [Head|Body], where Head is an element Head is an element

of the listof the list and Body is again a listBody is again a list. Empty list [ ].

Procedure member (mostly built-in) tests whether the first argument is an element of the list

member(X,[X|_]). X is an element if it is the headmember(X,[_|Y]) :- member(X,Y). else check body

Procedure append (two lists)

append([ ],L,L).append([H,T],L,[H,T1]) :- append(T,L,T1).