Lecture 9 - Nipissing University Word

Download Report

Transcript Lecture 9 - Nipissing University Word

COSC3306:
Programming Paradigms
Lecture 9: Declarative
Programming with Prolog
Haibin Zhu, Ph.D.
Computer Science
Nipissing University
(C) 2003
Contents
Prolog
Program structure
Logical variable
Syntax structure
Prolog facilities
Control structure
Resolution and unification
DFS
Backtracking
Deficiencies of Prolog
Cut Operator
Recursive Rules
Prolog
At the heart of the Prolog is a stored base of information
usually called a knowledge base or database, which
consists of facts and rules. The system is interactive in
which the user interacts with the system on a question
and answer basis. Answering a question involves
processing the data held in the knowledge base. A
general structure of Prolog is:
© 2003 Brooks/Cole Publishing / Thomson Learning™
Prolog
The basic features of Prolog include a powerful
pattern-matching facility, a backtracking strategy
that searches for proofs, uniform data structures
from which programs are built, and the general
interchangeability of input and output. Owing to
the lack of a standard definition, several dialects
of Prolog evolved, differing even in their basic
syntax. Fortunately, the Edinburg version in now
widely accepted as a standard.
Program Structure
A prolog program consists of three major
components stated as:
– Series of rules that define the problem
domain, which is the relation between objects;
– Series of facts that define the
interrelationships among the known objects;
and
– Logical statement known as goal or query that
is a question from the Prolog system to either
prove or disprove.
Program Structure
In general, the set of facts and rules is called assertions
or axioms and describes logical relationships among
objects and is the basis for the theorem-proving model of
Prolog system. Prolog programming language restricts
us to the logical statements (Horn clauses) of the form:
A :- A1, A2, … , An.
The symbol “:-” means if and the symbol “,” means and.
A is the head (goal) of the logical statement, A1, A2, …,
An forms the body (subgoals), and a period terminates
every Prolog axiom. Ai is called a literal, which is a
relationship between objects or the negation of a
relationship between objects.
Example
The following literals can express the
relationship between two objects, seyed and
mary.
x pet(x)  small(x)  apartment(x)
– likes(seyed, mary).
– father_of(seyed, mary).
x cat(x)  dog(x)  pet(x)
x poodle(x)  dog(x)  small(x)
poodle(fluffy)
apartment(X) :- pet(X), small(X).
(Logic)
pet(X):- cat(X).
pet(X):- dog(X).
dog(X):- poodle(X).
small(X) :- poodle(X).
poodle(fluffy)
(Prolog)
Query
Query is the given input to a program, which is treated as
a goal to be proved. In other words, the query is a
question asking about objects and their relationships. In
prolog, a query is just like a fact or rule, except that it is
started with a special symbol “ ?-”, a question mark and a
“-”, hyphen.
For example, in a query as the form:
?A1, A2, … , An.
In this case, we proceed by satisfying A1, and A2, and … ,
An separately as subgoals.
If all subgoals succeed, then we conclude that the goal
succeeds.
We use the convention that the names of all objects and
relationships start with a lowercase character and
variables start with an uppercase letter.
Logical Variable
The variable in imperative language is not the same
concept as a variable in logic programs:
– A program variable refers to a memory location that may have
changes in its contents; consider an assignment NN1.
– A variable in logic program simply stands for a value that, once
determined, will not change. For example, the equation X3Y11
and 2X3Y4 specify value for X and Y; namely X5 and Y2,
which will not be changed in this context. A variable in Prolog is
called a logical variable and acts in a manner differently.
Variables are strings of characters beginning with an uppercase
letter or an underscore.
– Once a logical variable is bound to a particular value, called an
instantiation of the variable, that binding cannot be altered
unless the pattern matching that caused the binding is undone
because of backtracking.
Logical Variable
The destructive assignment of imperative languages,
where a variable with a value binding is changed, cannot
be performed in logic programming.
Terms in a query change only by having variables filled in
for the first time, never by having a new value replace an
existing value.
An iterative accumulation of a value is obtained by having
each instance of a recursive rule take the values passed
to it and perform computations of values for new variables
that are then passed to another call.
Since a logical variable is bounded once, it is more like a
constant identifier with a dynamic defining expression as
in Ada than a variable in an imperative language.
Example
parent(seyed, mary).
parent(seyed,
mahsa).
parent(mary, leily).
parent(mahsa,
victoria).
Some queries:
? parent(seyed, mary).
yes
? parent(X, leily).
Xmary
yes
? parent(seyed, X).
Xmary;
 The user-typed
Xmahsa;
semicolon asks the
no
system for more solutions
? parent(X, Y).
Xseyed
Ymary
System will list all of the parent
yes
pairs, one at a time if semicolons
are typed.
Prolog Syntax-Constants
– A Constant is one of:
Atom
Integer
Real Number
Atoms are made up of:
letters and digits: AB...Zab...z01...9 and _
(underscore)
symbol: any number of +, -, *, /,
Variables
Variables usually start with a capital letter. The
only interesting exception is the special
anonymous variable written _ and pronounced
``underscore''. In the rule process(X,Y):generate(_,Z),
test(_,Z),
evaluate(Z,Y).
the underscores refer to different unnamed
variables. For example, here are two versions of
member/2.
Compound Terms
A Compound Term is a functor with a (fixed) number
of arguments each of which may be a Prolog term.
happy(fred)
– principal functor = happy
– 1st argument = a constant (atom)
sum(5,X)
– principal functor = sum
– 1st argument = constant (integer)
– 2nd argument = variable
not(happy(woman))
– principal functor = not
– 1st argument = compound term
BNF Specification
Prolog Facilities-Arithmetic
?:- X is 3+4.
?:- X is 5-4.
?:- X is 3*4.
?:- X is 8/2.
?:- X is 5 mode 2.
Comparisons
X<Y.
X>Y.
X=<Y.
X>=Y.
X=\=Y.
X=:=Y.
List Operations
List is a sequence of elements that are separated commas,
shown between brackets, and have any length.
[H|T] expresses a list
– H matches the head of the list
– T matches the tail
List
Head
[a, b, c, d]
a
[]
none
[[the, man], human]
[the, man]
[the, [man, human]]
the
[the, [man, human], arm]
the
Tail
[b, c, d]
none
[human]
[[man, human]]
[[man, human], arm]
Examples
Last(X, [X]).
Last(X, [H|T]):-last(X,T)
?-Last(X, [a,b,c,d).
X=d
Member(X,[X|T]).
Member(X,[H|T]):-member(X,T).
?- member(a, [a,b,c,d])
Yes.
Examples
Concat([], L, L).
Concat([H|T], L, [H|M)):-concat(T, L, M).
?-Concat([a,b,c],[b,e],R).
R = [a,b,c,d,e].
?-append(….)
Input and Output
Read(X).
Average:-read(X), read(Y), Z is (X+Y)/2.
Write (variable).
?-X is 2*10, write (x).
Other examples:
– http://www.cs.dartmouth.edu/~jaa/CS118.99S/
Samples/Prolog/
– http://www.csci.csusb.edu/dick/cs320/lab/10.h
tml
To be Continued
Control Structure
Resolution
Unification
DFS
Control Structure
Because Prolog has been implemented with a
concern for efficiency, its control strategy acts
with a deterministic approach for discovering
proofs. The control system in Prolog can be
characterized by two criteria:
Goal order, meaning that the control system
chooses the first leftmost subgoal.
Rule order, meaning that the control system
selects the first logical statement.
Control Structure
This indicates that, the response to a query is affected
both by subgoal orders within the goal and by the logical
statements order within the knowledge base of facts and
rules.
There are two opposite methods in which goal can be
proved as: top-down approach which is similar to
recursion also called backward chaining and bottom-up
approach which is similar to iteration also called forward
chaining. There are various mixtures of top-down and
bottom-up that work from both the goal and the
hypotheses. It is worth noting that, bottom-up control
approach is more efficient than top-down approach,
since the bottom-up execution does not recompute the
subgoals.
Top-down Approach
In this approach, we start with the goal and
attempt to prove its correctness by finding a
sequence of matching logical statements that
lead to some set of original facts in the
knowledge base, meaning that all possible
resolution and unification could be performed
until the goal is proved. The top-down approach
execution of a logic program is similar to
recursive execution of a procedure.
The goal G is empty and True is reached.
No logical statement applies to the leftmost
subgoal of G.
Example
Assume a knowledge base contains the following fact
and rule.
mother(mary).
female(X)
:=
mother(X).
To trace the query female(mary), in top-down approach
the Prolog would be required to choose goal as starting
logical statement and use it to infer the truth of the goal.
In this example, a new logical statement mother(mary)
can be deduced by matching the goal female(mary) and
the second logical statement female(X) := mother(X) in
the knowledge base through instantiation of X to mary.
The goal can be inferred, because the new generated
logical statement mother(mary) is similar to the first
logical statement of the knowledge base.
Bottom-up Approach
In the bottom-up, we start with the hypotheses
which is the assumption that the goal is correct
and attempt to reach the goal. This indicates that
we start with the facts and rules of the
knowledge base and attempt to find a sequence
of matches that lead to the goal. In general
bottom-up approach works well when the
number of possibly correct answers is large. The
bottom-up control can stop in one of two cases:
The goal G is achieved and True is reached.
No logical statements can satisfy each other in
order to make a new logical statement.
Example
Assume a knowledge base contains the following fact
and rule.
mother(mary).
female(X)
:=
mother(X).
To trace the query female(mary), in bottom-up approach
the Prolog would be required to search through the
knowledge base in order to make a logical statement
correspond to the goal. In this example, the goal can be
deduced by matching the first fact mother(mary) with the
right side of the second rule female(X) := mother(X)
through instantiation of X to mary. A new generated
logical statement as female(mary) indicates that the goal
can be inferred, because it is similar to the goal.
Resolution and Unification
As an important practical application, resolution
theorem proving also known as the resolution
refutation system has made the current
generation of Prolog interpreter possible.
Unification is the search process of finding the
general substitution of variables that makes two
literally identical.
In general, when the interpreter tries to verify a
goal it searches the database of facts and rules
to find a matching fact or rule’s head. This is
corresponding to pattern matching and variable
binding.
Unification
Selects a fact if:
– The name is the same as that of the goal to be proven.
– The number of arguments is the same.
– For all corresponding arguments one of the following conditions holds:
They are exactly the same constant.
They are an unbound variable and a constant. In this case the variable
becomes bound to the constant.
They are both variables. In this case, if one is bound then the other becomes
bound to the same object. If both are bound, then both become bound to the
same object.
– If no matching fact or rule’s head can be found by unification, then the
goal fails.
This indicates that, the resolution and unification works by canceling
out matching literals that appear on different sides of the “:-” sign. If
we have two logical statements, any two matching (or unifiable)
literals, which appear both on the right of one of them and on the left
of the other, cancel each other out.
Example
Consider the following facts and rules translated
into Prolog clause form on the right.
–
–
–
–
–
–
–
(1)
(2)
(3)
(4)
(5)
(6)
(7)
:- a.
a :- b, c, d.
b :- e, f.
c :d :e :f :-
a
bcda
efb
c
d
e
f
The procedure of resolution for the
above example
The literal e in line 6 can be unified with the literal e in
line 3.
The literal f in line 7 cancels out the literal f in line 3.
The literal b in line 3 cancels out the literal b in line 2.
The literal c in line 4 can be resolved with the literal c in
line 2.
The literal d in line 5 cancels out the literal d in line 2.
After all the above, we are left with the literal a in line 2,
that can be canceled out with the original query, the
literal a in line 1.
Resolution by unification
However, two literals do not have to be identical to be resolved. For
example, in the following
parent_of(X, Y) :- father_of(X, Y), male(X).
father_of(john, mary).
male(john).
father_of(X, Y) literal appearing to the right of the first rule can be
unified with father_of(john, mary) in the second fact. These two
literals are unifiable when the variable X is instantiated to the
constant john, and the variable Y to the constant mary. Thus,
parent_of(X, Y) :- father_of(X, Y), male(X).
father_of(john, mary).
can be resolved to
parent_of(john, mary) :- male(john).
Resolution by refutation proofs
Resolution by refutation proofs requires that the axioms and
the negation of the goal be placed in clause form notation.
Clause form represents the logical statements as a set of
disjunction of literals.
The most common form of resolution is called binary
resolution, the basis for Prolog interpreter that is applied to
two clauses when one contains a literal and the other its
negation.
If these literals contain variables, the literals must be unified
to make them equivalent. In this case, a new clause is
produced consisting of the disjuncts of all the literals in the
two clauses excluded the literal and its negative instance,
which are said to have been resolved or cancelled out.
A Procedure of Refutation Proofs
The resulting clause receives the unification substitution under which
the literal and its negation are found as equivalent. In general, the
resolution refutation proofs can be stated as the following steps:
1.
2.
3.
Put the set of facts and rules into clause form notation.
Add the negation of what is to be proved (goal or query), in clause form to
the set of axioms.
Perform the following steps until there is no resolvable clause; if there is
no resolvable clause go to Step 4.
1)
2)
3)
4.
5.
Unify (resolve) these clauses together, making new clauses that logically
produced from them.
Produce a contradiction by generating an empty clause. If there is an empty
clause, stop and report the query is true.
The substitution used to produce the empty clause are those under which the
opposite of the negated goal is true.
Stop and report that the query is false; meaning that there is no solution
associated with this query.
It is worth noting that, the Step 3 is intended to produce an empty clause,
indicating that there is a solution associated with the goal.
Producing the Clause Form
In the following, we outline the process of conjunctive
normal form reduction through examples and give a brief
description for each step.
– We eliminate : “ if ” by using the equivalent form as:
b : a  a  b
– We eliminate  “ implies ” by using the equivalent form as:
a  b  a  b
– We reduce the scope of negation. This can be accomplished
using a number of the transformation rules. These include
a (a)  a
(a  b)  ab
(a  b)  ab
Producing the Clause Form (Cont’d)
We convert the expression to the conjunction of
disjunction of literals. This requires using the associative
and distributive properties of  and . These include
– a(b  c)  (ab) c
– a(b  c)  (ab) c
– a(b  c)  (ab)(ac)
It is important to mention that, the following logical
statement
– a(b  c)
is already in clause form notation, because  is not
distributed. Hence, it consists of the following two clauses:
– a
– (b  c)
Example
Example: We consider the following statements
translated into logical statements on the right
and we wish to prove that “Poddy will die”.
Statement
Logical Statement
All dogs are animals.
Poddy is a dog.
All animals will die.
Poddy will die.
 (X) dog(X)  animal(X).
dog(poddy).
 (Y) animal(Y)  die(Y).
die(poddy).
Example 1
First, we convert the logical statements to the following
clause form notation.
Logical Statement Clause Form
1.  (X) dog(X)  animal(X)
2. dog(poddy)
3.  (Y) animal(Y)  die(Y)
 dog(X)  animal(X)
dog(poddy)
 animal(Y)  die(Y)
We negate the query that “Poddy will die”.
4. die(poddy)
 die(poddy)
Next, we resolve the clauses having opposite literals,
producing a new clause by resolution procedure and
continue until the empty clause is found.
On.pl
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.10 Resolution proof for Poddy will die
Example 2
Consider the following logical statements translated into Prolog clause form
on the right. We would like to know that “who does John like?” by issuing a
query as
?- likes(john, Somebody).
Logical Statement
Clause Form
1. likes(david, bert).
likes(david, bert)
2. likes(bert, john).
likes(bert, john)
3. likes(john, X) :- likes(X, bert).
 likes(X, bert)  likes(john, X)
4. ?- likes(john, Somebody).
 likes(john, Somebody)
It is worth noting that, we convert the rule likes(john, X) :- likes(X, bert) to
form likes(X, bert)  likes(john, X) in order to be converted into clause
form, meaning that if is changed to implies.
The empty clause indicates that, the query is true when the variable
Somebody is instantiated to the constant David.
Likes.pl
© 2003 Brooks/Cole Publishing / Thomson Learning™
Error!!, P374 Fig. 11.11
Figure 11.11 Resolution proof for ? –
likes (john, Somebody)
Example 3
Logical Statement
1.
2.
3.
4.
5.
on(b, a).
on(a, table).
above(X, Y):- on(X,Y).
above(X, Z):- above(X, Y), above(Y, Z).
?-above(b,table).
Clause Form
1. on(b, a).
2. on(a, table).
3.  on(X,Y) V above(X, Y).
4.  above(X, Y)   above(Y, Z)  above(X, Z).
5.  above(b,table).
On.pl
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.12 Resolution proof for ? - above (b, table)
Depth-First Search
Matching the fact and rule with the first
subgoal
Try the facts and rules in order
Adding the precondition of the rule at the
beginning of the goal after a match
Family.pl
Figure 11.13 Portion
of the Prolog depthfirst search tree
leading to success
© 2003 Brooks/Cole Publishing / Thomson Learning™
To be continued
Backtracking
Deficiencies of Prolog
Cut Operator
Recursive Rules
Backtracking
Prolog uses unification to match a goal to
the head of a clause, but if there are
several candidate clauses, which does
Prolog choose to try first? In most cases
Prolog looks through the clauses in the
order in which they are entered in the logic
base. This is not the case for a 'sorted'
predicate, which is, as the name implies,
stored in sorted order.
Backtracking
Prolog's backtracking top-to-bottom, left-to-right search is
simple and effective. Backtracking works as follows:
1. If Prolog cannot prove a sub-goal in the body of a clause,
then it looks at the sub-goal immediately to its left. If there
are any other clauses which can be used to re-prove this
goal, then any variable bindings which resulted from the
previous clause selection are discarded, and Prolog
continues with the new proof.
2. If the sub-goal which initially failed was the first goal in the
body of the clause, then the whole goal fails, and the
backtracking continues in the parent clause (the clause
containing the reference to the goal whose proof just
failed).
Backtracking
Backtracking is a very powerful tool since
it will try and generate a solution by
automated search.
Unfortunately it can sometimes be too
powerful, generating solutions that were
not wanted, and so we have to have some
way of controlling it.
Deficiencies of Prolog
Resolution order control
Semantics of Prolog
The closed world assumption
Resolution order control
In Prolog, statement order is meaningful.
The user can affect both efficiency and semantics by ordering the
statements in a Prolog program.
–
–
–
–
–
–
parent(bob, pat).
parent(tom, bob).
pred(X, Z) :- parent(X, Z).
pred(X, Z) :- parent(X, Y), pred(Y, Z).
?- pred(tom, pat).
Yes
If the rules are:
– pred(X, Z) :- pred(Y, Z), parent(X, Y).
– pred(X, Z) :- parent(X, Z).
– ?- pred(tom, pat)
Semantics of Prolog
Procedural semantics:
– how Prolog answers questions.
Declarative semantics:
– the logical meaning of Prolog program
Programs with the same declarative semantics may
have different Procedural xsemantics.
– Example:
P :- R, S.
P :- S, R.
Danger of indefinite looping
– Consider
– p :- p.
– ?- p.
The closed world assumption
Anything that cannot be proved to be
true is assumed to be false.
For Prolog, the only truths are those
that can be proved using the given
facts. Prolog cannot prove that a given
goal is false. Prolog adopts the closed
world assumption to assume that
anything that cannot be proved to be
true be false.
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.15 Tree structure of facts
Resorder.pl;
Resorder1.pl;
Resorder2.pl
Cut Operator
Denoted with a "!". !/0 is always true, so if a
clause containing a cut is read as a statement of
truth, it behaves as if there were no cut there.
But cut affects the way backtracking is
performed as follows:
– Once a cut is executed, the choice of the clause
which contains it is frozen as a proof step. Also any
choices made during the proof of the goals between
the head of the clause and the cut are frozen. Thus
cut acts like a fence. When backtracking passes over
the cut (heading left in a clause), then proof
reconsideration continues not with the goal to the left
of the !, but the goal to the left of the goal which
chose the clause containing the cut.
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.16 The effect of Cut in the first rule
Orcut.pl
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.17 The effect of a Cut in the second rule
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.18 The effect of Cut in conjunction with fail
"cut" problem
"cut" (!) is a goal that always succeeds immediately.
cut is used to avoid unnecessary backtracking.
Example:
member(X, [X|L]).
member(X, [Y|L]) :- member(X, L).
This is 'non-deterministic': if X occurs serveral times
then any occurrence can be found.
A deterministic member: use a cut to prevent
backtracking as soon as X is found.
member(X, [X|L]):-!.
member(X, [Y|L]) :- member(X, L).
"cut" problem
This will generate just one solution.
?- member(X, [a, b, c]).
X=a;
no
The use of cut is not recommended because it
destroys one of the important advantages of logic
programming, i.e., programs do not specify how
solutions are to be found.
Negation as failure
Example
– sibling(X, Y) :- parent(M, X), parent(M, Y),
not(X = Y).
Definition of negation in Prolog:
– not(P) :- P, !, fail; true.
Which can be read:
– If P succeeds, then not(P) fails, otherwise not(P) succeeds.
The negation problem
The Prolog not operator is not equivalent to a logical
NOT operator.
not(not(some_goal)).
is not always equivalent to some_goal.
?. not human(mary).
Yes
This means only that there is not enough information
in the program to prove that Mary is human. Prolog's
reasoning is based on the closed world assumption.
Recursive Rules
Let's look at a more interesting extension to the directed
graph program.
Suppose we aren't satisfied with a predicate which
distinguishes pairs of nodes linked by paths of length two.
Suppose we want a general predicate which is satisfied by
a pair of nodes just in case they are linked by a path in the
graph - a path of any (positive) length.
Thinking recursively, we can see that there is a path from
one node to another if there is an edge between them (a
base case), or if there is an edge to an intermediate node
from which there is a path to the final node.
The following two rules define the path relation for our
program.
Recursive Rules
path(Node1,Node2) :- edge(Node1,Node2).
path(Node1,Node2) :- edge(Node1,SomeNode),
path(SomeNode,Node2).
There are two important characteristics in this
example. First, the use of two rules (with the
same head) to define a predicate reflects the
use of the logical ``OR'' in a Prolog program.
Recursive Rules
We would read these two rules as:
path(Node1,Node2) is true if
edge(Node1,Node2) is true or if there is a node
SomeNode for which both
edge(Node1,SomeNode) and
path(SomeNode,Node2) are true. Second, the
predicate used in the head of the second rule
also appears in the body of that rule. The two
rules together show how a recursive definition
can be implemented in Prolog .
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.19 A train route between five cities
Travel.pl
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.20 The first stage of the journey
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.21 The program that corresponds to ?
– travel (boiling-springs, columbia)
© 2003 Brooks/Cole Publishing / Thomson Learning™
Figure 11.22 The program that corresponds to ? travel (boiling-springs, columbia) query
Summary
Prolog
Program structure
Logical variable
Syntax structure
Control structure
Resolution and unification
DFS
Backtracking
Deficiencies of Prolog
Cut Operator
Recursive Rules
Prolog facilities