Filtering elements from a list based on conditions in prolog
I have a list of routes
path(chicago,milwaukee).
path(milwaukee,detroit).
path(chicago,detroit).
path(detroit, newyork).
path(newyork, boston).
path(atlanta,boston).
I have a predicate routefrom which开发者_运维技巧 gives all the cities between start & end. For example:
?- routefrom(chicago,newyork,X).
X=[chicago,milwaukee,detroit,newyork]
To get all the routes I have
allroutes(Start,End,P) :- findall(X,pathfrom(Start,End,X),P).
Example:
?- allroutes(chicago,neywork,P).
X=[[chicago,milwaukee,detroit,newyork],[chicago,detroit,newyork]].
I have a predicate rule goodroute(M)
which returns true if the routes does not contain milwaukee and contains either chicago or newyork.
Example:
?- goodroute([chicago, milwaukee,detroit]).
false
?-goodroute([chicago,detroit,newyork,boston]).
true
Now, I need to filter out the routes which have milwaukee and get a list which has chicago or newyork from the result of allroutes. I tried
filerroute :- exclude(maplist(goodroute(findall(X,pathfrom(Start,End,X),P).
What I am trying to do is map the goodroute on the result of findall so that some of it would be true & some would be false and exclude would eliminate the false. I am not exactly sure how exclude works. How do I filter out the elements which are false according to the goodroute predicate and get a list of elements having only elements matching the true condition?
exclude
and include
(which you really want) take a predicate name as their first argument:
goodroutes(From, To, Routes) :-
allroutes(From, To, All),
include(goodroute, All, Routes).
Though it would be more efficient to filter out the bad routes during the call to findall
, since then you wouldn't have to build the set of all routes first:
goodroutes(From, To, Routes) :-
findall(Route, (pathfrom(From, To, Route), goodroute(Route)), Routes).
Note the ( , )
; we're giving findall
a conjunction of two goals as its second argument.
精彩评论