fatih university department of computer engineering programming style and technique notes for ch.8...
TRANSCRIPT
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Programming Style and Technique
Notes for Ch.8 of BratkoFor CENG421&553 Fall03
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Use
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Use of Recursion: maplist• Recursion is always used. maplist is an example of
a “higher-order function”: a function that applies to another function
• In the original LISP (McCarthy, 1960):• ((label maplist (lambda (x f) (cond ((null x) ‘( )) (‘t (cons (f (car x)) (maplist (cdr x) f))))))
• maplist( List, F, NewList) if NewList contains the result of applying F to each element of List, in order
• The function F the binary relation representing the function we want to apply
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
maplist II• Boundary (base) case: List = [ ]
– if List = [ ] then NewList = [ ]• General case: List = [ X|Tail]
– To transform a list of the form [ X|Tail], do• transform the item X by F, obtaining New X,
and• transform the list Tail obtaining NewTail• the whole transformed list if [ NewX|NewTail]
• See ch8_1.pl• Prolog recursion objects recursive
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
/* maplist( List,F,NewList) if NewList contains the result of applying
the function F (represented by a binary relation <domain,range>) to each
entry of NewList, in order. */
maplist( [],_,[]).
maplist( [ X|Tail],F,[ NewX|NewTail]) :- G =.. [ F,X,NewX], G, % some Prologs require call( G) instead of G maplist( Tail,F,NewTail).
/* Square function, for example query ?- maplist( [2,6,5],square,Squares) */square( X,Y) :- Y is X*X.
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Generalization• Generalization allows us to use recursion• Example: eight queens
• without generalization, no integer to recur on!
• Define nqueens( Pos,N)– if N queens are safe in position Pos
• Base case: N = 0: trivial• General case: N > 0
• achieve a safe configuration of N-1 queens• add the remaining queen so that it does
attack
• eightqueens( Pos) :- nqueens( Pos,8).
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Debugging
• Most Prolog interpreters and compilers use a four-port model for goals
foo/n
call succeed
retry fail
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Improving Efficiency
• Eight queens, again:• using a more informed initial ordering of
queen coordinate values helps, as described in the comments at the end of ex4_6.pl
• Map coloring– start with countries that have many
neighbors• Warnsdorff’s heuristic for the knight’s
tour
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
% Ex 4.6[B]
% Figure 4.7 Program 1 for the eight queens problem.
% solution( BoardPosition) if% BoardPosition is a list of non-attacking
queens
solution( [] ).
solution( [X/Y | Others] ) :- % First queen at X/Y, other queens at Others
solution( Others), member( Y,[1,2,3,4,5,6,7,8]), % Order of
alternatives defined here! noattack( X/Y, Others). % First queen
does not attack others
noattack( _, [] ). % Nothing to attack
noattack( X/Y, [X1/Y1 | Others] ) :- Y =\= Y1, % Different Y-
coordinates Y1-Y =\= X1-X, % Different
diagonals Y1-Y =\= X-X1, noattack( X/Y, Others).
% A solution template
template( [1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8] ).
solution1(S) :- template(S), solution(S).
% When computing all solutions, all orders are equivalent:
/* Original Order: member( Y,[1,2,3,4,5,6,7,8])
4 ?- time(setof(S,solution1(S),L)), length(L,N).% 171,051 inferences in 0.22 seconds (776387
Lips) *//* More informed order: member( Y,
[1,3,5,7,2,4,6,1])16 ?- time(setof(S,solution1(S),L)), length(L,N).% 171,051 inferences in 0.22 seconds (776387
Lips)*/
% When computing one solution, the informed order is much better:
/* More informed order: member( Y,[1,3,5,7,2,4,6,1])
18 ?- time(solution1(S)).% 368 inferences in 0.00 seconds (Infinite Lips)
*//* Original Order: member( Y,[1,2,3,4,5,6,7,8])19 ?- time(solution1(S)).% 9,382 inferences in 0.01 seconds (936851
Lips)*/
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
colors( []).colors( [ Country/Color|Rest]) :- colors( Rest), member( Color,[yellow,blue,red,green]), not( (member( Country1/Color,Rest),neighbor( Country,Country1)) ). % Note the extra parentheses, to make a single conjunctive goal of two
neighbor( Country,Country1) :- ngb( Country,Neighbors), member( Country1,Neighbors).
makelist( List) :- collect( [germany],[],List).
collect( [],Closed,Closed). % No more candidates for closedcollect( [ X|Open],Closed,List) :- member( X,Closed),!, % If X has already been collected, collect( Open,Closed,List). % discard itcollect( [X|Open],Closed,List) :- ngb( X,Ngbs), conc( Ngbs,Open,Open1), % built-in version of concat collect( Open1,[ X|Closed],List).
country( X) :- ngb( X,_). % Incomplete ngb relation below gives only six countries
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
% Neighbors for the 6 original EU countries (Treaty of Rome, 1957)% Andorra, Monaco, San Marino, and Vatican City are not considered% Only land (bridge and tunnel included) borders are considered/* Reorder the ngb relation so that the country that has the largest
amount of neighbour will be at the top. So start coloring from that, continue with its neighbours, then the neighbours of the neighbours etc.
*/ngb( germany,
[denmark,poland,czech,austria,switzerland,france,luxembourg,belgium,netherlands]).
ngb( netherlands, [germany,belgium,france]).ngb( belgium, [netherlands,germany,luxembourg,france]).ngb( france, [belgium,luxembourg,germany,switzerland,italy,spain]).ngb( luxembourg, [belgium,germany,france]).ngb( italy, [france,austria,slovenia]).
ngb( denmark, [germany]).ngb( poland, [germany]).ngb( czech, [germany]).ngb( austria, [germany, italy]).ngb( switzerland, [germany,italy,france]).ngb( spain, [france]).ngb( slovenia, [italy]).
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Difference Lists• The difference list L-E contains the
elements of L that occur before E. E is a suffix of L.
• E.g., [a,b,c,d] – [c,d] is [a,b]• Trick: [a,b,c,d|E] – E is [a,b,c,d]!
• Difference lists allow concatenation of lists in constant time, as in imperative languages.
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Concatenation and Difference Lists
• Difference lists can be concatenated in constant time by using conc_dl:
• ?conc_dl([a,b|A] – A, [c,d|C] – C, Result) unify with conc_dl(X – Y, Y – Z, X – Z):
• {X / [a,b|A]}• {Y / A} • {A / [c,d|C]}• {Z / C}• {Result / X – Z}, i.e. {Result / [a,b|A] –
C}, i.e.• {Result / [a,b,c,d|C} – C}
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Some Caveats
• While the result of conc_dl has an uninstatiated tail, the first argument does not.
– You cannot use it as an argument to conc_dl in the same clause.
• “Difference lists are powerful but counterintuitive. They appear most often in procedures that were first implemented with conventional lists and then carefully rewritten for efficiency” [Covington, p.183].
FATIH UNIVERSITYFATIH UNIVERSITYDepartment of Computer EngineeringDepartment of Computer Engineering
Improveing efficiency by asserting derived facts
• fib and fib2.• Execution trees• Page 204• More difficult but more efficient
one:forwardfib