Logic Programming - The University of Alabama in Huntsville

Download Report

Transcript Logic Programming - The University of Alabama in Huntsville

Programming Languages
2e Tucker and Noonan
Chapter 15 – part 2
Logic Programming
“Q: How many legs does a dog have if you call its
tail a leg?
A: Four. Calling a tail a leg doesn’t make it one.”
Abraham Lincoln
Review
• Prolog is a logic-based language
– Its syntax is based on Horn clauses, a predicate form
derived from the predicate calculus.
• It is also a declarative language
– Prolog programs describe goals and provide facts
and rules for the Prolog system to use in searching
for a goal solution.
– Compare to imperative languages, which describe
algorithms and specify the exact steps required to
achieve a goal.
Review
• Propositions: statements which are either
true or false; e.g., “my dog is black”
– Propositions can be represented by symbols,
combined with logical operators, and have truth
values based on the individual propositions; e.g.
p Λ q is true only if both p and q are true.
• Predicates: Propositions with variables,
and/or quantifiers: (for all) (there exists)
– x(dog(x) Λ black(x)); (x)(dog(x) → black(x))
Review: Basic Program Elements
• A Prolog program consists of terms:
– Atoms: literal strings or numbers
– Variables: consist of letters and underscores, must
start with an upper-case letter
• Atoms are distinguished from variables because atoms start
with a lower-case letter
• Prolog variables aren’t the same as variables in imperative
languages; they don’t represent values. They are temporarily
bound to objects/values during resolution.
– Structures: functor(parameters)
• Structures are predicates
Review: Facts and Rules
• Prolog facts are headless Horn clauses:
– student(jack, cs424).
– sweet(sugar).
• Prolog rules are headed Horn clauses:
– fattening(X) :- sweet(X).
– driversLicense(X) :- sixteen(X), passTest(X).
Review: Queries
• Prolog programs consist of facts and rules.
• Users describe goal states by posing
queries.
– Goals are described by assertions that state
the characteristics of the desired goal.
• Using the facts and rules in the program,
the Prolog system attempts to find a
solution to the query.
Review
• Prolog uses resolution theorem proving,
instantiation, and unification to find goal
states.
• The search process is a backtracking
approach: in case one goal cannot be
satisfied, back up to the nearest previous
goal state and try another approach.
Example
• Suppose a program has these facts & rules:
– mother(sue).
mother(jane).
female(X) :- mother(X).
•
•
•
•
To prove/disprove the goal female(jane).
First find the fact mother(sue). Reject.
Next find mother(jane). Matches on jane
“Unify” mother(X) in the rule and
mother(jane) in the fact (by instantiating X
with jane) to infer female(jane).
Breadth-first v Depth-first
Search
• Suppose a query has compound goals
(several propositions must be satisfied)
• Depth-first searches prove the first goal
before looking at the others.
• Breadth-first works on goals in parallel.
• Prolog uses the depth-first approach.
Backtracking
• When a compound goal is being proved, it
may be that a subgoal cannot be shown
true.
• In that case, Prolog will back up and try to
find another solution to a previous
subgoal.
*
A Partial Family Tree
Figure 15.3
A Small Family “Tree”
Figure 15.4
Processing Queries
• ?- father(X, sue)
The query is satisfied with the first
comparison. X is instantiated with john.
• ?- mother(sue, X)
Satisfied with X = nancy, X = jeff
• ?- mother(alice, ron)
Fails
?- grandparent(Who, ron).
• Instantiating grandparent rule from query:
Grandparent(Who,ron):parent(Who,X),parent(X,ron).
• First, find a fact that satisfies parent (Who,X)
– This entails finding a fact to satisfy either
father (Who, X) or mother(Who, X)
First try: father(john, sue) - “father” rule is first
• Next, find a fact that satisfies parent(sue,
ron)
– This does not succeed,
?- grandparent(Who, ron).
• Must satisfy both subgoals with same values
Grandparent(Who,ron):parent(Who,X),parent(X,ron).
• The first attempt, instantiating parent(Who, X) as
parent(john,sue), failed because the second
subgoal, parent(sue,ron), could not be proved.
• Backtrack to parent(Who, X) and use father(john,
bill) fact next.
• Instantiate Who=john, X=bill, and try to satisfy
second subgoal, parent(bill, ron).
– Success; because father(bill, ron) is a fact.
– Who = john, so grandparent(john, ron)
Prolog Lists
• The list is Prolog’s basic data structure
• Lists are a series of Prolog terms,
separated by commas
• Each list element can be a(n)
– atom
– variable
– sublist
– etc.
Examples of Lists
• The empty list:
[]
• List with embedded list: [girls, [like, boys]]
• List with variables:
[x, V1, y, V2, [A, B]]
– V1, V2, A, and B are variables that may be
instantiated with data at a later time.
• Multi-type lists:
• [A, _, Z]
[boy, [1, 2, 3], ran]
– The _ means “don’t care” – sometimes referred to as
an unbound variable.
Working with Lists
• [Head|Tail] notation simplifies processing:
– Head represents the first list element, Tail
represents everything else.
– Head can be any Prolog term (list, variable,
atom, predicate, etc.)
– If L = [a, b, c] then Head = a and Tail = [b,c]
– Tail is always another list.
• What is the head of [a]? The tail?
The append Function
• append is a built-in Prolog function that
concatenates two lists.
• append(A, B, L)
concatenates the lists A and B and returns
them as L.
• append([my, cat], [is, fat], L).
yields
L = [my, cat, is, fat]
The Append Function
• append(L1, L2, L3):
append([ ], X, X). %base case
append([Head|Tail], Y, [Head|Z])
:- append(Tail, Y, Z).
• This definition says:
– The empty list concatenated with any list (X)
returns an unchanged list (X again).
– If Tail is concatenated with Y to get Z, then a
list one element larger [Head | Tail] can be
concatenated with Y to get [Head | Z].
?- Append([english, russian], [spanish], L).
H=english, T=[russian], Y=[spanish], L=[english,Z]
1
and Z = [russian, spanish]
Append([russian],[spanish], [Z]).
H = russian, T=[ ], Y=[spanish], Z=[russian|Z1]
2
Append([ ], [spanish], [Z1]).
So Z1= [spanish]
X=[spanish], Z1=[spanish]
3
Append([ ], [spanish], [spanish]).
Recursion/ member
• The function returns ‘yes’ if x is a member
of a given list.
member(X, [X | _ ]).
member(X, [ _ | Y]) :- member(X, Y).
Member(X,Y)
• The test for membership succeeds if
either:
– X is the head of the list [X |_]
– X is not the head of the list [_| Y] , but X is a
member of the list Y.
• Notes: pattern matching governs tests for
equality.
• Don’t care entries (_) mark parts of a list
that aren’t important to the rule.
Using append
prefix(X, Z) :- append(X, Y, Z).
(finds all prefixes of a list Z)
suffix(Y, Z) :- append(X, Y, Z).
(finds all suffixes of Z)
Naming Lists
• Defining a set of lists:
a([single]).
a([a, b, c]).
a([cat, dog, sheep]).
• When a query such as a(L), prefix(X, L). Is
posed, all three lists will be processed.
• Other lists, such as b([red, yellow, green]),
would be ignored.
A Sample List Program
a([single]).
a([a, b, c]).
a([cat, dog, sheep]).
prefix(X, Z) :- append(X, _, Z).
suffix(Y, Z) :- append(_, Y, Z).
% To make queries about lists in the database:
% suffix(X, [the, cat, is, fat]).
% a(L), prefix(X, L).
Sample Output
?- a(L), prefix(X, L).
L = [single]
X = [] ;
Based on the program on
the previous slide:
a([single]).
a([a, b, c]).
a([cat, dog, sheep]).
prefix(X, Z) :- append(X, _, Z).
suffix(Y, Z) :- append(_, Y, Z).
L = [single]
X = [single] ;
L = [a, b, c]
X = [] ;
L = [a, b, c]
X = [a] ;
L = [a, b, c]
X = [a, b] ;
L = [a, b, c]
X = [a, b, c] ;
L = [cat, dog, sheep]
X = []
Sample Output
35 ?- a(L), append([cat], L, M).
L = [single]
M = [cat, single] ;
L = [a, b, c]
M = [cat, a, b, c] ;
L = [cat, dog, sheep]
M = [cat, cat, dog, sheep] ;
The Trace Function
To see the dynamics of a function call, use the trace
function. For example,given the following function:
factorial(0, 1).
factorial(N, Result):N > 0,
M is N-1,
factorial(M, SubRes),
Result is N * SubRes. %is ~ assignment
?- trace(factorial/2).
Tracing Output
•
•
•
•
•
•
•
•
•
•
•
?- factorial(4, X).
Call: ( 7) factorial(4, _G173)
Call: ( 8) factorial(3, _L131)
Call: ( 9) factorial(2, _L144)
Call: ( 10) factorial(1, _L157)
Call: ( 11) factorial(0, _L170)
Exit: ( 11) factorial(0, 1)
Exit: ( 10) factorial(1, 1)
Exit: ( 9) factorial(2, 2)
Exit: ( 8) factorial(3, 6)
Exit: ( 7) factorial(4, 24)
• X = 24
These are
temporary
variables
These are
levels in the
search tree
Logic Programming
15.2.2: Practical Aspects
15.3: Example Applications
Simple Arithmetic
• Integer “variables” and integer operations
are possible, but imperative language
“assignment statements” don’t exist.
6 ?- X = 3 + 6.
X = 3+6.
7 ?- X is 3 + 6.
X = 9.
8 ?- Y is X + 4.
ERROR: is/2: Arguments are not sufficiently
instantiated
Sample Program
•
•
•
•
speed(fred, 60).
speed(carol, 75).
time(fred, 20).
time(carol, 21).
• distance(X, Y) :- speed(X, Speed),
time(X, Time), Y is Speed * Time.
• area_square(S, A) :- A is S * S.
Prolog Operators
• is can be used to cause a variable to be
temporarily instantiated with a value.
• Does not have the same effect as an
assignment statement, because the effect
isn’t permanent.
• The not operator is used to indicate goal
failure. For example not(P) is true when
P is false.
Arithmetic
• Originally, used prefix notation +(7, X)
• Modern versions have infix notation
X is Y * C + 3.
• Qualification: Y and C must be instantiated, as in
the Speed program, but X cannot be (It’s not a
traditional assignment statement).
– X = X + Y is illegal.
– X is X + Y is illegal.
“Arguments are not sufficiently
instantiated”
More About Arithmetic
• Example of simple arithmetic
– ?- x is 3 + 7.
– x = 10
• Arithmetic operators: +, -, *, /, ^ (exponentiation)
• Relational operators: <, >, =, =<, >=, \=
Revisiting the Trace Function
• At the prompt, type “trace.”
• Then type the query.
• Prolog will show the rules it uses and the
instantiation of unbound constants.
Revisiting The Factorial Function
Evaluation of clauses is from left to right.
Note the use of is to temporarily assign
values to M and Result
Trace of Factorial (4)
Other Features
•
•
•
•
cut (!) – controls backtracking
not( ) – negation
assert(C) – add to database
retract(C) – removes from database
The cut & not Operators
• The cut (!) is used to control backtracking.
• It tells Prolog to stop at this point (if the
goals have succeeded once).
• Reasons: Faster execution, saves memory
• Not(P) will succeed when P fails.
– In some places it can replace the ! Operator.
Example: Revised Factorial
factorial(N, 1):- N < 1, !.
factorial(N, Result):- M is N – 1,
factorial(M, P),
Result is N * P.
factorial(N, 1):- N < 1.
factorial(N, Result):- not(N < 1),
M is N–1,
factorial(M, P),
Result is N * P.
When Cut Might Be Used
(Clocksin & Mellish)
•
To tell Prolog that it has found the right rule:
– “if you get this far, you have picked the correct rule for
this goal.”
•
To tell Prolog to fail a particular goal without trying
other solutions:
– “if you get to here, you should stop trying to satisfy the
goal.”
•
“if you get to here, you have found the only
solution to this problem and there is no point in
ever looking for alternatives.”
f(X, 0) :- X < 3, !.
f(X, 2) :- 3 =< X, X < 6, !.
f(X, 4) :- 6 =< X.
14 ?- consult('C:/Temp/prologProgs/cut_example.pl').
% C:/Temp/prologProgs/cut_example.pl compiled 0.00 sec, 8 bytes
Yes
15 ?- f(1, Y), 2 < Y.
No
16 ?- X = 4, f(X, Y), 2 < Y.
No
Since the three rules above are mutually exclusive, once one rule succeeds
there is no need to try another. In the first example, rule 1 succeeds ( X < 3).
If we try rules 2 and 3 they will fail.
In the second case (X = 4) the second rule succeeds.
The cut symbol prevents further attempts that will fail anyway.
Family Tree – Assert()
15 ?- child(jeff).
ERROR: Undefined procedure: child/1
16 ?- assert(child(jeff)).
Yes
17 ?- child(jeff).
Yes
Assert and Retract
• More sophisticated uses: assert can be
embedded in a function definition so
new facts and rules can be added to the
database in real time.
– Useful for learning programs, for example.
• Retract(C) deletes a clause that
matches C
Symbolic Differentiation Rules
Figure 15.9
Prolog Symbolic Differentiator
Figure 15.10
Search Tree for the Query d(x, 2*x+1, Ans)
Figure 15.11
Executing a Prolog Program
• Create a file containing facts and rules;
e.g., familytree.pl
• Under the file drop-down menu in
SWiplEdit select open to load the file into
the interpreter.
• From the Start menu select consult
• Type queries and the interpreter will try to
find answers:
– ?- talkswith(P1, P2).
SWIplEdit “compile” error
• If SWI-Prolog finds an error in the .pl file it
will give a message such as
ERROR:
c:/temp/prologprogs/remove.pl:
18:0: Syntax error: Illegal
start of term
(18 is the line number)
Runtime Error Message
• The function samelength was called with
one parameter when it needed 2:
21 ?- samelength(X).
ERROR:Undefined procedure:
samelength/1
ERROR:However, there are
definitions for: samelength/2
Runtime Errors
• Here, the error is an error of omission:
22 ?- samelength([a, b, c,],[a, b])
|
Queries must end with a period. If you hit
enter without typing a period SWIpl just
thinks you aren’t through.
Using SWI Prolog
• If there is an error that you can’t figure out
(for example you don’t get any answers,
you don’t get a prompt, typing a semicolon
doesn’t help) try “cancel” under the Start
button.
• If changes are made to the program, don’t
forget to “consult” again.
Test Review
•
•
•
•
Chapter 6.1 (Type Systems)
Chapter 7.1-7.5 (Semantics)
Chapter 12 (Imperative Programming)
Chapter 13: (Object Oriented
Programming)
• Chapter 15 (Logic Programming)
• Python & Scripting Languages (from the
notes).
Homework Questions I Might Have
Assigned
•
In C-like languages, when an expression
consists of two or more sub-expressions , such
as a + f(a) or x*y + x*y++ or x/3 – y +
4(x+y), the sub-expressions are evaluated
–
–
–
–
Left-to-right
Right-to-left
It depends on the precedence of the operators in
the sub-expression
It depends on the compiler.
Homework Questions I Might Have
Assigned - Functions
1 int a = 0;
…..
11 int newVal(int c)
12 {
…..
19 void main ( )
…..
24 return 0;
25
}
-----------------------------------------•
Show the stack of activation records as it would exist when line 8 has executed but
before line 9 executes. Your answer should follow the format in Figure 9.8
•
Show the stack again after the execution of line 23, but before the main function
terminates.
Homework Questions I Might Have
Assigned
Consider the following Horn clauses:
parent(X, Y):- father(X, Y).
grandparent(X,Z):- parent(X,Y), parent(Y,Z).
Use resolution, as in Prolog, to deduce a
new proposition from the two above
Homework Questions I Might Have
Assigned
Write a rule for the family tree data base that
defines a sister relation
For example – the sister of X has the same
father or mother.