More examples Today’s examples are related to coursework.
-
Upload
amy-bryant -
Category
Documents
-
view
212 -
download
0
Transcript of More examples Today’s examples are related to coursework.
More examples
Today’s examples are related to coursework
Once upon a time, an insect was crawling along a wire cube, ……
In the original program, the relation arrow(X,Y) represents a directed link from X to Y. The relation cango(X,Y) means that there is a path from X to Y
cango(X, Y):- arrow(X, Y).
cango(X, Y):- arrow(X, Z),cango(Z, Y).
f
g
a b
c
h
e
d
How does ‘cango’ program work?
cango(X, Y):- arrow(X, Y).cango(X, Y):- arrow(X, Z),
cango(Z, Y).
?- cango(a,h).
a
b c e
d f d g g f
h h h h h h
Prolog uses ‘cango’ with a depth first search.
‘cango’ is a general program not just for this given cube.
f
g
a b
c
h
e
d
Observation: change the order of arrow, then check if the order of solutions changes
Is ‘cango’ really a general program?
In the original program, the relation arrow(X,Y) only represents a link from X to Y, not Y to X.
How do we extend it to a bi-directional link?
Easy – using disjunction:
next(X, Y):- arrow(X, Y).
next(X, Y):- arrow(Y, X).
f
g
a b
c
h
e
d
cango(X, Y):- next(X, Y).cango(X, Y):- next(X, Z),
cango(Z, Y).
What happens after replacing ‘arrow’ by ‘next’?
Introduced circles into the map. There is a danger of being trapped in a circle!
?- cango(a,h).a
b c e
a d
b c
a a
f
g
a b
c
h
e
d
cango(X, Y):- next(X, Y).cango(X, Y):- next(X, Z),
cango(Z, Y).
Q: Is ‘cango’ a general program? A: It only works if no circle in the map.
We must add something to avoid being trapped in a circle.
Solution 1: using an extra list to store the path generated so far, only extend a new node which is not in the list
Solution 2: no u-turn. it is restricted to certain type of maps where circles are only created by u-turn.
f
g
a b
c
h
e
d
Q-block
Solution 2 (we will use this!)
• For some maps, there are no circles as long as u-turn is not allowed. In this case, the easy solution is to add an extra test to disallow u-turn.
next(a, b, north).next(b, a, south). ......
% PreDir is the direction before Xcango(X,Y, PreDir):- next(X,Y, Dir),
not_u_turn(PreDir, Dir).cango(X,Y, PreDir):- next(X,Z, Dir),
not_u_turn(PreDir, Dir),cango(Z , Y, Dir).
Two ways to define not_u_turn
• Define ‘u_turn’, then make use of \+ (not) : u_turn(south,north). u_turn(north,south).u_turn(west,east). u_turn(east, west).
not_u_turn(X,Y):- \+( u_turn(X,Y) ).
• Define ‘not_u_turn’ directly :not_u_turn(south, west).
not_u_turn(south, east)........not_u_turn(start, _).
Move to real program, more information needed in the ‘next’
% (From,To, Direction, WhichSide, Distance)
next('2q43', '2q49', south, right, 1).next('2q49', '2q43', north, left, 1).
next('2q49', 'area3', south, left, 1).next('area3', '2q49', north, left, 1).
next('area3', '2q46', south, left, 3).next('2q46', 'area3', north, right, 3).
next('2q46', '2q47', south, left, 2).next('2q47', '2q46', north, right, 2). .......
Your ‘cango’ program should have6 parameters
cango(X,Y,Path,Dir,Dist,PreDir)
Path and Dir are lists which are exactly same as cango4Dist is a list of distancesPreDir indicates previous direction. You need to use it to
compare with the next direction. no u-turn !
For example?- cango(‘2q43’, ‘2q47’, P, Dir, Dist, start).P = [2q43,2q49,area3,2q46,2q47]Dir = [south,south,south,south]Dist = [1,1,3,2]
Put them all together
:-[map]. % include the file map.pl
test(X, Y):-cango(X, Y, Path, Dir, Dist, start),cal_route(Dir, Dist, NewDir, NewDist),write(NewDir), nl,write(NewDist), nl.
A little help on ‘cal_route’ (week5’s task)
• The following program reduces a sequence of same items into to one item
reduce([X],[X]). % if only one item % nothing to reduce
reduce([X,X|T], R):- reduce( [X|T], R ).
reduce([X,Y|T], [X|R]):- X \== Y,reduce( [Y|T], R ).
?- reduce([a,a,b,b,b,c], R).produces R = [a,b,c]
Solution 1 - new cango program with circle detection (not used for our assignment !)
Need an extra list to storethe path generated so far:
cango(X,Y, CurrentPath):- next(X,Y), \+ member(Y,CurrentPath).
cango(X,Y, CurrentPath):- next(X,Z), \+ member(Z,CurrentPath), cango(Z,Y, [Z|
CurrentPath]).
(‘\+’ means ‘not’)
If we want to return a path,then add the 4th argument:
cango(X,Y, P, FinalPath):- next(X,Y),
\+ member(Y,P). FinalPath = [Y|P].
cango(X,Y, CP, FP):- next(X,Z), \+ member(Z,CP), cango(Z,Y, [Z|CP], FP).
When call this new cango, we must initialize the 3rd argument
Question: What is the CurrentPath initially?
Answer: it is the start point.
?- cango(a,h, [a], Path).
Path = [h,d,b,a],
… …
Why the returned Path is reversed?
In each recursion, the 3rd argument is added an element
at its front: [a], [b,a], [d,b,a], and finally [h,d,b,a]
This kind of list is called an accumulator
How to reverse a list another example of using accumulator
Naïve reverse
rev1([H|T], R):-
rev1(T, RT),
append(RT,[H], R).
append([], L, L).
append([H|T],X,[H|L]):-
append(T,X,L).
More efficient reverse – the
3rd arg. is an accumulator
rev2(L, RL):- % init accumulator
rev2(L, RL, []).
rev2([H|T], RL, CL):-
rev2(T, RL, [H|CL]).
rev2([], RL, CL):- % base
RL=CL.