10. Logic Programming With Prolog |
Overview
|
Note: Study Section 11.3 of the textbook, excluding 11.3.2. |
Logic Programming
H :- B1, B2, ..., Bn. where H is the head term and Bi are the body terms |
Resolution
C :- A, B. D :- C. C :- A, B and then that D is true: D :- C D :- C the system then deduces that the sub-goal is C is true: C :- A, B Since the system could prove C it has proven D |
Prolog
|
Prolog Terms
functor(arg1, arg2, ..., argn) where functor is an atom and argi are terms |
Prolog Clauses
H :- B1, B2, ..., Bn. snowy(X) :- rainy(X), cold(X). Meaning "If X is rainy and X is cold then this implies that X is snowy" rainy(rochester). Meaning "Rochester is rainy." This fact is identical to the rule with true as the body predicate: rainy(rochester) :- true.
|
Queries and Goals
?- G1, G2, ..., Gn. where Gi are goals rainy(seattle). rainy(rochester). ?- rainy(C). C = seattle C = rochester no (no more solutions) |
Example
rainy(seattle). rainy(rochester). cold(rochester). snowy(X) :- rainy(X), cold(X). ?- snowy(rochester). yes ?- snowy(seattle). no ?- snowy(paris). no |
Example (cont'd)
rainy(seattle). rainy(rochester). cold(rochester). snowy(X) :- rainy(X), cold(X). C = rochester because rainy(rochester) and cold(rochester) are sub-goals that are both true facts in the database |
Backtracking
|
Example: Family Relationships
male(albert). male(edward). female(alice). female(victoria). parents(edward, victoria, albert). parents(alice, victoria, albert). sister(X,Y) :- female(X), parents(X,M,F), parents(Y,M,F). ?- sister(alice, X1). |
Example: Murder Mystery
murderer(X) :- hair(X, brown). % mr_holman
had a ring:
% mr_pope
had a watch:
% If
sir_raymond had tattered cuffs then mr_woodley had the pincenez:
% and
vice versa:
% A
person has tattered cuffs if he is in room 16:
% A
person has black hair if he is in room 14, etc:
% mr_holman
was in room 12, etc:
|
Example: Murder Mystery (cont'd)
murderer(X) hair(X, brown) attire(X, pincenez) X = mr_woodley attire(sir_raymond, tattered_cuffs) room(sir_raymond, 16) FAIL (no facts or rules) FAIL (no alternative rules) REDO (found one alternative rule) attire(X, pincenez) X = sir_raymond attire(mr_woodley, tattered_cuffs) room(mr_woodley, 16) SUCCESS SUCCESS: X = sir_raymond SUCCESS: X = sir_raymond SUCCESS: X = sir_raymond SUCCESS: X = sir_raymond |
Unification and Variables
|
Unification Examples
yes no no X = a yes X = a Y = foo(X,b) no |
Lists
[elt1,elt2, ..., eltn] where elti are terms [elt1,elt2, ..., eltn | tail] denotes a list whose tail list is tail T = [b,c] T = [c] T = [] |
List Membership
member(X, [X|T]). member(X, [H|T]) :- member(X, T). with X1 = b, H1 = a, and T1 = [b,c] with X2 = b and T2 = [c] |
Predicates are Relations
X = a ; % type ';' to try to find more solutions X = b ; % ... try to find more solutions X = c ; % ... try to find more solutions no Y = b L = [b|_G255] therefore, L is a list with b as head and _G255 as tail, where _G255 is a new variable append([H|T], A, [H|L]) :- append(T, A, L). X = [a,b,c,d,e] ?- append(Y, [d,e], [a,b,c,d,e]). Y = [a,b,c] ?- append([a,b,c], Z, [a,b,c,d,e]). Z = [d,e] |
Example: Bubble Sort
append(InitList, [B,A|Tail], List), A < B, append(InitList, [A,B|Tail], NewList), bubble(NewList, Sorted). bubble(List, List). append([], [2,3,1], [2,3,1]), 3 < 2, fails: backtrack append([2], [3,1], [2,3,1]), 1 < 3, append([2], [1,3], NewList1), this makes: NewList1=[2,1,3] bubble([2,1,3], L). append([], [2,1,3], [2,1,3]), 1 < 2, append([], [1,2,3], NewList2), this makes: NewList2=[1,2,3] bubble([1,2,3], L). append([], [1,2,3], [1,2,3]), 2 < 1, fails: backtrack append([1], [2,3], [1,2,3]), 3 < 2, fails: backtrack append([1,2], [3], [1,2,3]), does not unify: backtrack bubble([1,2,3], L). try second bubble-clause which makes L=[1,2,3] bubble([2,1,3], [1,2,3]). bubble([2,3,1], [1,2,3]). |
Imperative Control Flow
no yes if(Cond, Then, Else) :- Cond, !, Then. if(Cond, Then, Else) :- Else. X = a ; % type ';' to try to find more solutions no X = b ; % type ';' to try to find more solutions no no |
Example: Tic-Tac-Toe
ordered_line(1,2,3). ordered_line(4,5,6). ordered_line(7,8,9). ordered_line(1,4,7). ordered_line(2,5,8). ordered_line(3,6,9). ordered_line(1,5,9). ordered_line(3,5,7). |
Note: You can download the program from here (instructions are included in the source). |
Example: Tic-Tac-Toe (cont'd)
line(A,B,C) :- ordered_line(A,B,C). line(A,B,C) :- ordered_line(A,C,B). line(A,B,C) :- ordered_line(B,A,C). line(A,B,C) :- ordered_line(B,C,A). line(A,B,C) :- ordered_line(C,A,B). line(A,B,C) :- ordered_line(C,B,A). move(A) :- good(A), empty(A). empty(A) :- \+ full(A). full(A) :- x(A). full(A) :- o(A). good(A) :- win(A). % a cell where we win good(A) :- block_win(A). % a cell where we block the opponent from a win good(A) :- split(A). % a cell where we can make a split to win good(A) :- block_split(A). % a cell where we block the opponent from a split good(A) :- build(A). % choose a cell to get a line good(5). % choose a cell in a good location good(1). good(3). good(7). good(9). good(2). good(4). good(6). good(8). |
Example: Tic-Tac-Toe (cont'd)
win(A) :- x(B), x(C), line(A,B,C). block_win(A) :- o(B), o(C), line(A,B,C). split(A) :- x(B), x(C), \+ (B = C), line(A,B,D), line(A,C,E), empty(D), empty(E).
block_split(A) :- o(B), o(C), \+ (B = C), line(A,B,D), line(A,C,E), empty(D), empty(E). build(A) :- x(B), line(A,B,C), empty(C). |
Example: Tic-Tac-Toe (cont'd)
x(7). o(5). x(4). o(1). ?- move(A). A = 9 |
Arithmetic
X is 2*sin(1)+1 instantiates X with the results of 2*sin(1)+1 |
Arithmetic Examples
length([], 0). length([H|T], N) :- length(T, K), N is K + 1. where the first argument of length is a list and the second is the computed length ?- length([1,2,3], X). X = 3 gcd(A, A, A). gcd(A, B, G) :- A > B, N is A-B, gcd(N, B, G). gcd(A, B, G) :- A < B, N is B-A, gcd(A, N, G). |