Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], [])....
-
Upload
michael-cork -
Category
Documents
-
view
251 -
download
0
Transcript of Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], [])....
![Page 1: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/1.jpg)
Prolog Programming(Volume 3)
Dr W.F. Clocksin
![Page 2: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/2.jpg)
Mapping: The Full Map
sqlist( , )
sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L).
List of numbers
List of squares of numbers
![Page 3: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/3.jpg)
Mapping: The Full Map (cont’d)
Here is an exercise in compound terms. Map each list element (a number) to a term s(A,B) where A is the number and B is its square.Input: [1, 9, 15]
Output: [s(1,1), s(9, 81), s(15, 225)]
sqterm([], []). sqterm([X|T], [s(X,Y)|L]) :-
Y is X * X,sqterm(T, L).
![Page 4: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/4.jpg)
General Scheme for Full Map
/* fullmap(In, Out) */
fullmap([], []). fullmap([X|T], [Y|L]) :-
transform(X,Y), fullmap(T, L).
Here is a typical transformation table…
![Page 5: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/5.jpg)
Simple Transformation
transform(cat, gatto).
transform(dog, cane).
transform(hamster, criceto).
transform(X, X).
?- fullmap([cat, dog, goat], Z).
Z = [gatto, cane, goat]
A ‘catchall’ rule
![Page 6: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/6.jpg)
Worksheet 11: Multiple Choices
Sometimes the map needs to be sensitive to the input data:Input: [1, 3, w, 5, goat]
Output: [1, 9, w, 25, goat]
squint([], []). squint([X|T], [Y|L]) :-
integer(X),Y is X * X, squint(T, L).
squint([X|T], [X|L]) :- squint(T,L).
Just use a separate clause for each choice
![Page 7: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/7.jpg)
Multiple Choices
Using the infix binary compound term *, it is easy enough to give some mathematical reality to the map:Input: [1, 3, w, 5, goat]
Output: [1, 9, w*w, 25, goat*goat]
squint([], []). squint([X|T], [Y|L]) :-
integer(X),Y is X * X, squint(T, L).
squint([X|T], [X*X|L]) :- squint(T,L).
![Page 8: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/8.jpg)
Worksheet 12: Partial Maps
Given an input list, partially map it to an output list.
evens([], []).
evens([X|T], [X|L]) :- 0 is X mod 2, evens(T, L)
evens([X|T], L) :- 1 is X mod 2, evens(T, L).
?- evens([1, 2, 3, 4, 5, 6], Q),
Q = [2, 4, 6].
![Page 9: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/9.jpg)
General Scheme for Partial Maps
partial([], []).
partial([X|T], [X|L]) :- include(X), partial(T, L)
partial([X|T], L) :- partial(T, L).
For example,
include(X) :- X >= 0.
?- partial([-1, 0, 1, -2, 2], X),
X = [0, 1, 2].
![Page 10: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/10.jpg)
Partial Maps
Exercise: Write a program that ‘censors’ and input list, by making a new list in which certain prohibited words do not appear. To do this, define a predicate prohibit such that prohibit(X) succeeds if X is a censored word. For example,
prohibit(bother).
prohibit(blast).
prohibit(drat).
prohibit(fiddlesticks).
![Page 11: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/11.jpg)
Worked example
censor([], []).
censor([H|T], T1) :- prohibit(H), censor(T, T1).
censor([H|T], [H|T1]) :- censor(T, T1).
![Page 12: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/12.jpg)
Worksheet 13: Removing Duplicates
setify([], []).
setify([X|T], L) :- member(X,T), setify(T, L).
setify([X|T], [X|L]) :- setify(T, L).
![Page 13: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/13.jpg)
WS14: Partial Maps with a Parameter
Before, we saw how to prevent loops (when searching a graph) by keeping a ‘trail’ of the nodes visited so far. Here is another way to think about the problem.
Keep a list of all the visitable nodes. As each node is visited, strike it off the list and pass the reduced list to the recursive call. Backtracking restores the old list, so alternative paths can be searched.
![Page 14: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/14.jpg)
WS14: Partial Maps with a Parameter
First, a predicate to reduce the list.Goal reduce(L,X,M) succeeds for input list L, term X and output list M, when M contains the elements of L except for the first occurrence of X. Thus, X is a parameter that controls which element will be omitted from the output list.reduce([X|T], X, T).
reduce([H|T], X, [H|L]) :- reduce(T, X, L).
![Page 15: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/15.jpg)
Use this for searching as follows
path(X, X, L).
path(X, Y, L) :-
a(X, Z),
reduce(L, Z, L1),
path(Z, Y, L1).
Using the arc relation on Worksheet 9,
?- path(a, b, [a, b, c, d, e, f, g, h]).
yes.
![Page 16: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/16.jpg)
WS 15: Multiple Disjoint Partial Maps
Maps a list into several disjoint lists.Separating sheep from goats. Define the predicate herd, such that the goal herd(L, S, G) succeeds if S is a list of all the sheep in L and G is a list of all the goats in L.herd([], [], []).
herd([sheep|T], [sheep|S], G) :- herd(T, S, G).
herd([goat|T], S, [goat|G]) :- herd(T, S, G).
![Page 17: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/17.jpg)
What do the following goals do?
?- herd([sheep, goat, goat, sheep, goat], X, Y).
?- herd([goat, sheep, stone, goat, tree], X, Y).
?- herd(X, [sheep, sheep], [goat, goat]).
![Page 18: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/18.jpg)
How to deal with other objects?
?- herd([goat, sheep, stone, goat, tree], X, Y).
The above goal fails. Instead, we could ignore other objects by having a catchall:
herd([X|T], S, G) :- herd(T, S, G).
![Page 19: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/19.jpg)
Or, collect them in a list also
input sheep goats extras
herd([], [], [], []).
herd([sheep|T], [sheep|S], G, E) :- herd(T, S, G, E).
herd([goat|T], S, [goat|G], E) :- herd(T, S, G, E).
herd([X|T], S, G, [X|E]) :- herd(T, S, G, E).
![Page 20: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/20.jpg)
Example: Alternating a list
Maps an input list into a pair of lists, alternating the elements.alternate([a, b, c, d, e, f], [a, c, e], [b, d, f])
Alternating by index (which element of the input list it is):altx([], [], []).
altx([A, B | T], [A | T1], [B| T2]) :- altx(T, T1, T2).
![Page 21: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/21.jpg)
Or, alternating by value
Maps an input list into a pair of lists, alternating the elements.altv([1, 2, 3, 4], [2, 4], [1, 3])
altv([], [], []).
altv([A | T], [A | T1], B) :-
0 is A mod 2, altv(T, T1, B).
altv([B | T], A, [B | T2]) :-
1 is B mod 2, altv(T, A, T2).
See how this is the same as sheep and goats?
![Page 22: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/22.jpg)
WS 17: Full maps with state
/* mapsum(list of integers, cumulative sum) */
?- mapsum([1, 3, 2, 5, 4], X).
X = [1, 4, 6, 11, 15].0
![Page 23: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/23.jpg)
mapsum
Use an accumulator as a state variable that helps to determine the value of each element of the output list./* ms(input list, accumulator, output list) */
mapsum(A, B) :- ms(A, 0, B)
ms([], _, []).
ms([H|T], N, [C|L]) :- C is H + N, ms(T, C, L).
initialise accumulator
anonymous variable (don’t care aboutaccumulator if end of list)
![Page 24: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/24.jpg)
WS 18: Sequential Partial Map with State
Example: Run length encoding is a useful data representation and compression technique.
Represent sequential ‘runs’ of N identical terms T as the term N*T, for example
[12, 2, 2, w, 3, 3, s, s, s]
maps to[1*12, 2 * 2, 1 * w, 2 * 3, 3 * s].
![Page 25: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/25.jpg)
WS 18: Sequential Partial Map with State
[12, 2, 2, w, 3, 3, s, s, s] [1*12, 2 * 2, 1 * w, 2 * 3, 3 * s]
runcode(input, current term, current count, output)
runcode([], C, N, [N*C]).
runcode([H|T], H, N, Z) :-
N1 is N+1, runcode(T, H, N1, Z).
runcode([H|T], C, N, [N*C|Z]) :-
H \== C, runcode(T, H, 1, Z).
![Page 26: Prolog Programming (Volume 3) Dr W.F. Clocksin. Mapping: The Full Map sqlist(, ) sqlist([], []). sqlist([X|T], [Y|L]) :- Y is X * X, sqlist(T, L). List.](https://reader031.fdocuments.net/reader031/viewer/2022032516/56649c795503460f9492e37b/html5/thumbnails/26.jpg)
Sequential Partial Map with State
runcode([], C, N, [N*C]).
runcode([H|T], H, N, Z) :-
N1 is N+1, runcode(T, H, N1, Z).
runcode([H|T], C, N, [N*C|Z]) :-
H \== C, runcode(T, H, 1, Z).
End of list? Deal withleftover accumulator values
Have seen this before...
Otherwise, discharge the current run...
...and start a new run