200 likes | 368 Views
Recall lists in Scheme: '(a b c) = (cons 'a (cons 'b (cons c '()))) ls = (cons (car ls) (cdr ls)) Want the same operations in Prolog: [a, b, c] = .(a, .(b, .(c, []))) car([X|Tail], X). cdr([X|Tail], Tail). cons(X, Tail, [X|Tail]). Prolog: Lists. lists.P. Prolog: Lists.
E N D
Recall lists in Scheme: • '(a b c) = (cons 'a (cons 'b (cons c '()))) • ls = (cons (car ls) (cdr ls)) • Want the same operations in Prolog: • [a, b, c] = .(a, .(b, .(c, []))) • car([X|Tail], X). • cdr([X|Tail], Tail). • cons(X, Tail, [X|Tail]). Prolog: Lists lists.P
Prolog: Lists Try it out: | ?- consult(lists). | ?- car([1,2,3], H). H = 1 | ?- cdr([1,2,3], T). T = [2,3] | ?- cons(1, [2,3], L). L = [1,2,3]
Prolog: Anonymous Variables • What really happens: • | ?- consult(lists). • ++Warning[XSB]: [Compiler] ./lists: Singleton • variable Tail in a clause of car/2 • ++Warning[XSB]: [Compiler] ./lists: Singleton variable X in a clause of cdr/2 • Problem: We're not using some variables: • car([X|Tail], X). % Tail unused • cdr([X|Tail], Tail). % X unused
Prolog: Anonymous Variables Solution: Anonymous variables car([X|_], X). % _ = whatever cdr([_|Tail], Tail).
Recall member? function (predicate) in Scheme: • (define member? • (lambda (a ls) • (cond ((null? ls) #f) • ((equal? a (car ls)) #t) • (else (member? a (cdr ls)))))) Prolog: Lists • Can also write it in ML: • fun member(a, nil) = false | • member(a, x::t) = • if a = x then true else member(a, t); • How about Prolog? • member(X, [X|_]). • member(X, [_|T]) :- member(X, T).
Recall family tree example: • parent(linda, simon). • parent(sam, simon). • parent(linda, sharon). • parent(sam, sharon). • female(sharon). • sister(S,X) :- parent(P,S), parent(P,X), • female(S). • | ?- sister(Who, simon). • Who = sharon; • Who = sharon Prolog: Backtracking and Cut • Look under the hood using trace:
| ?- trace. yes [trace] | ?- sister(Who, simon). (0) Call: sister(_h81,simon) ? % sister(S, X=simon) (1) Call: parent(_h148,_h81) ? % parent(P, S) (1) Exit: parent(linda,simon) ? % parent(P=linda, S=simon) (2) Call: parent(linda,simon) ? % parent(P=linda, X=simon) (2) Exit: parent(linda,simon) ? (3) Call: female(simon) ? % female(S=simon) (3) Fail: female(simon) ? (2) Redo: parent(linda,simon) ? % parent(P=linda, X=simon) (2) Fail: parent(linda,simon) ? % fail on redo (1) Redo: parent(linda,simon) ? % parent(P=linda, S=simon) (1) Exit: parent(linda,sharon) ? % parent(P=linda, S=sharon) (4) Call: parent(linda,simon) ? % parent(P=linda, X=simon) (4) Exit: parent(linda,simon) ? (5) Call: female(sharon) ? % female(S=sharon) (5) Exit: female(sharon) ? (0) Exit: sister(sharon,simon) ? % P=linda, X=simon, S=sharon Who = sharon; Prolog: Backtracking and Cut sister(S, X) :- parent(P,S), parent(P,X), female(S).
(0) Redo: sister(sharon,simon) ? (5) Redo: female(sharon) ? % female(S=sharon) (5) Fail: female(sharon) ? % fail on redo (4) Redo: parent(linda,simon) ? % parent(P=linda, X=simon) (4) Fail: parent(linda,simon) ? % fail on redo (1) Redo: parent(linda,sharon) ? % parent(P=linda, S=sharon) (1) Exit: parent(sam,simon) ? % parent(P=sam, S=simon) (6) Call: parent(sam,simon) ? % parent(P=sam, X=simon) (6) Exit: parent(sam,simon) ? (7) Call: female(simon) ? % female(S=simon) (7) Fail: female(simon) ? (6) Redo: parent(sam,simon) ? % parent(P=sam, X=simon) (6) Fail: parent(sam,simon) ? % fail on redo (1) Redo: parent(sam,simon) ? % parent(P=sam, S=simon) (1) Exit: parent(sam,sharon) ? % parent(P=sam, S=sharon) (8) Call: parent(sam,simon) ? % parent(P=sam, X=simon) (8) Exit: parent(sam,simon) ? (9) Call: female(sharon) ? % female(S=sharon) (9) Exit: female(sharon) ? (0) Exit: sister(sharon,simon) ? % P=sam, X=simon, S=sharon Prolog: Backtracking and Cut sister(S, X) :- parent(P,S), parent(P,X), female(S).
Prolog: Backtracking and Cut • We can view this process as a tree, where each branch represents a binding choice:
Prolog: Backtracking and Cut • We can view this process as a tree, where each branch represents a binding choice: X simon
Prolog: Backtracking and Cut X simon P linda S
Prolog: Backtracking and Cut X simon P linda S simon FAIL
Prolog: Backtracking and Cut Backtrack to most recent success: X simon P linda S
Prolog: Backtracking and Cut X simon P linda S sharon Succeed
Prolog: Backtracking and Cut User asks for more answers X simon P linda S sharon Succeed
Prolog: Backtracking and Cut Backtrack: no more choices for S X simon P linda S
Prolog: Backtracking and Cut Backtrack X simon P
Prolog: Backtracking and Cut X simon P sam S
Prolog: Backtracking and Cut X simon P sam S sharon Succeed
Cut (!) prevents backtracking: • sister(S,X) :- parent(P,S), parent(P,X), • female(S), !. % don't backtrack! • | ?- sister(Who, simon). • Who = sharon; • no Prolog: Backtracking and Cut • No longer a “pure” logic paradigm: we are exploiting sequential order.