I have a list of data
city(portsmouth,london).
city(london,bristol).
city(portsmouth,plymouth).
city(plymouth,london).
city(london,plymouth).
city(london,birmingham).
city(birmingham,bristol).
I'm using a method which is
?-op(150,xfy,pathto).
?-op(150,xfy,avoid).
X pathto Y:- city(X,Y).
and not so sure can be use like
X pathto Y avoid Z:-
findall(Path,avoid_country(X,Y,Z,Path),Paths),write(Paths),nl.
avoid_path(Start, End, Avoid,[]) :-
country(Start, End).
avoid_path(Start,End,Avoid,[Path|Result]):-
city(Start,Path),
Path\== Avoid,
avoid_path(Path, End,Avoid, Result).
it actually works perfectly without the avoids thing as well as the Path\== Avoid,
the error result is
| ?- portsmouth to bristol avoid birmingham.
Error 1, Backtrack Stack Full, Trying city/2
it should be [[london],[plymouth,london]].
Ok, so : first you got a loop in your facts : (london, plymouth) and (plymouth, london). That means that any attempt of backtracking will never end.
Then I'm not sure that you can use 2 operators this way, but since I'm not sure, other people will be more insightful on the matter :)
I took this convention : portsmouth to bristol-[london, birmingham] means from portsmouth to bristol avoiding london and birmingham (I took this convention not to manage the operators question), here is a working code that keeps track of visited cities to avoid infinite possibilities :
city(portsmouth,london).
city(london,bristol).
city(portsmouth,plymouth).
city(plymouth,london).
city(london,plymouth).
city(london,birmingham).
city(birmingham,bristol).
:- op(150, xfy, to).
Start to End-Avoid :-
findall(Waypoint, get_waypoints(Start, End, [Start], Avoid, Waypoint), Waypoints),
!,
write(Waypoints).
Start to End :-
findall(Waypoint, get_waypoints(Start, End, [Start], [], Waypoint), Waypoints),
write(Waypoints).
get_waypoints(Start, End, _Visited, _Avoid, []) :-
city(Start, End).
get_waypoints(Start, End, Visited, Avoid, [Waypoint|Result]) :-
city(Start, Waypoint),
don't go through cities to avoid...
\+ member(Waypoint, Avoid),
this check allows us not to fall into loops. This way, backtracking ends.
\+ member(Waypoint, Visited),
get_waypoints(Waypoint, End, [Waypoint|Visited], Avoid, Result).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With