180 likes | 271 Views
LING 388: Language and Computers. Sandiway Fong Lecture 4: 9/1. Homework 1 given out in the lab class last Wednesday reminder: due tonight ( midnight in my mailbox ) We’ll go through the solution to the homework next time Homework 2 to be given out today
E N D
LING 388: Language and Computers Sandiway Fong Lecture 4: 9/1
Homework 1 given out in the lab class last Wednesday reminder: due tonight (midnight in my mailbox) We’ll go through the solution to the homework next time Homework 2 to be given out today Due by next Wednesday midnight Reminder Next Monday is Labor Day (no class) Administrivia
Last Time • Prolog lists: • comma-separated notation[1,2,3,4,5] • head-tail notation [1,2|[3]] • Recursion: • defining something in terms of itself • but reducing the problem on each iteration • example: • lastinlist/2 finding the last element of a list • Today: • more on recursion...
SWI-Prolog Built-in Predicates • Actually… last/2 is a built-in in SWI-Prolog http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%27F.1%27%2cswi%28%27%2fdoc%2fManual%2fpredsummary.html%27%29%29
Definition lastinlist([X],X). (base case) lastinlist([X|L],Y) :- lastinlist(L,Y). (recursive case) Notes: There are two cases We use the head/tail notation in the recursive case we list the base case first and the recursive case last because Prolog accesses its database in first-to-last order Captures intuition Base Case: i.e. simplest case last element of a list containing just one element Recursive Case: we define last element of a nontrivial list in terms of the last element of its tail captures idea that last [1,2,3] = last tail [1,2,3] tail [1,2,3] = [2,3] last [2,3] = last tail [2,3] tail [2,3] = [3] last [3] is 3 (by the case case) so last [1,2,3] is 3 Re-cap of lastinlist/2 Definition
Simple Procedure Given a query, e.g. ?- q(A1,A2). match query against the database in first-to-last order Fact a fact matches the query q(B1,B2). only if the predicate names match (here: q) the number of arguments (arity) match (here: 2) and each corresponding argument matches (here: A1 must match B1, and A2 must match B2) Rule a rule matches the query if the head of the rule matches the query q(C1,C2) :- p(C1), r(C2). if the head of the rule matches the query (like Fact-matching) ?- q(A1,A2). q(C1,C2) :- p(C1), r(C2). the body of the rule creates new sub-queries that must all be true in Prolog’s world for the entire rule to be true ?- p(C1). ?- r(C2). Prolog Computation Summary
Prolog Lists lastinlist([X],X). (base case) lastinlist([X|L],Y) :-lastinlist(L,Y).(recursive case) • Query ?- lastinlist([1,2,3],Z). Z=3 • Computation procedure • ?- lastinlist([1,2,3],Z). • match factlastinlist([X],X). NO • match head of rulelastinlist([X|L],Y) :-lastinlist(L,Y).YES • match names:lastinlist • match arity: 2 • match corresponding 1st arguments: [1,2,3] = [X|L] • X=1 L=[2,3] • match corresponding 2nd arguments: • Y=Z • create new sub-query: • ?- lastinlist([2,3],Y).
Prolog Lists lastinlist([X],X). (base case) lastinlist([X|L],Y) :-lastinlist(L,Y).(recursive case) • Sub-Query ?- lastinlist([2,3],Y). • Computation procedure (2nd time around) • ?- lastinlist([2,3],Y). • match factlastinlist([X],X). NO • match head of rulelastinlist([X’|L’],Y’) :-lastinlist(L’,Y’).YES • match names:lastinlist • match arity: 2 • match corresponding 1st arguments: [2,3] = [X’|L’] • X’=2 L’=[3] • match corresponding 2nd arguments: • Y=Y’ • create new sub-query: • ?- lastinlist([3],Y’).
Prolog Lists lastinlist([X],X). (base case) lastinlist([X|L],Y) :-lastinlist(L,Y).(recursive case) • Sub-Query ?- lastinlist([3],Y’). • Computation procedure (3rd time around) • ?- lastinlist([3],Y’). • match factlastinlist([X”],X”). YES • match names:lastinlist • match arity: 2 • match corresponding 1st arguments: [3] = [X”] • X”=3 • match corresponding 2nd arguments: • X”=Y’ • no new sub-query • We’re done! • X”=3, X”=Y’, Y=Y’, Y=Z • Original query was ?- lastinlist([1,2,3],Z). Z=3 YES
commands ?- trace. switch tracing on [trace] ?- prompt ?- notrace. switch tracing off in trace mode [return] creep (one step forward) trace mode display Call <query> about to evaluate <query> Exit <query> <query> succeeded Redo <query> see if query can be satisfied another way Fail <query> <query> can’t be matched Let’s run through our example using the SWI-Prolog trace mechanism Prolog tracing
Prolog Lists lastinlist([X],X). (base case) lastinlist([X|L],Y) :-lastinlist(L,Y).(recursive case) • Query ?-lastinlist([],Z). No • Computation tree • ?-lastinlist([],Z). (Neither case matches!) • No
Prolog Lists lastinlist([X],X). (base case) lastinlist([X|L],Y) :-lastinlist(L,Y).(recursive case) • What happens to the computation tree for this query? • ?-lastinlist(W,3). W=[3] (base case) W=[X] X=3 • ; • ?- lastinlist(W,3). (recursive case)W=[X|L] Y=3 • ?- lastinlist(L,3). (base case) L=[3] • W = [X,3] • ; • ?- lastinlist(L,3). (recursive case)L=[X’|L’] Y’=3 • ?- lastinlist(L’,3). (base case) L’=[3] • W = [X, X’,3] • ;and so on… all lists with last element = 3 [3] [ _ ,3] [ _ , _ ,3] [ _ , _ , _ ,3] and so on...
Computation tree • Definition • lastinlist([X],X). (base case) • lastinlist([X|L],Y) :-lastinlist(L,Y). (recursive case) • Query • ?-lastinlist([mary,likes,john],Y). View of recursive matching procedure as a computation tree lastinlist([mary,likes,john],Y). lastinlist([X],X). [X] ≠ [mary,likes,john] [X|L] = [mary,likes,john] Y = Y’ Y = john lastinlist([likes,john],Y). lastinlist([X’],X’). [X’] ≠ [likes,john] [X’|L’] = [likes,john] lastinlist([john],Y’). X” = Y’ Y’ = john lastinlist([X”],X”). [X”] = [john] X” = john
Computation tree • Definition • lastinlist([X],X). (base case) • lastinlist([X|L],Y) :-lastinlist(L,Y). (recursive case) Answer: Y = john did we completely explore the search space? NO Ask for more answers (;) what happens? lastinlist([mary,likes,john],Y). lastinlist([X],X). [X] ≠ [mary,likes,john] [X|L] = [mary,likes,john] lastinlist([likes,john],Y). lastinlist([X’],X’). [X’] ≠ [likes,john] [X’|L’] = [likes,john] lastinlist([john],Y’). lastinlist([X”|L”],Y”). lastinlist([X”],X”). [X”] = [john] [X”|L”] = [john] lastinlist([],Y”’). X” = john no match
Length of a List • Usage • ?- len(L,N). • L a list, N the length of L • Definition • len([],0). (base case) • len([X|L],N) :- len(L,M), N is M+1. (recursive case) • Notes • recursive definition (similar in style to lastinlist/2) • Prolog builtin predicate is/2 evaluates arithmetic expressions on the right-hand-side (RHS) • Examples • ?-len([john,[saw,mary]],X). X=2 • ?-len([john,saw,mary], 4). No
Length of a List • Usage • ?- len(L,N). • L a list, N the length of L • Definition • len([],0). (base case) • len([X|L],N) :- len(L,M), N is M+1. (recursive case)
Length of a List • Usage • ?- len(L,N). • L a list, N the length of L • Definition • len([],0). (base case) • len([X|L],N) :- len(L,M), N is M+1. (recursive case) • Example • ?- len(L,3). what happens? First answer: [ _ , _ , _ ] what happens after you hit semicolon ? (try it for yourself in Prolog and see)
Homework 2 • Submit your programs and examples in one file! • Exercise 1 (4pts): • write a recursive definition lastbut1/2 to find the 2nd last element of a list • e.g. ?- lastbut1([a,b,c,d,e],X). X=d • Exercise 2 (6pts): • Write a recursive definition midlist/2 to pick out the middle element of a list • (if there is no middle element, it should fail to return an answer) • e.g. ?-midlist([a,b,c,d,e],X). X=c • ?-midlist([a,b,c,d],X). No