【问题标题】:Filtering elements from a list based on conditions in prolog根据序言中的条件从列表中过滤元素
【发布时间】:2011-07-27 19:39:55
【问题描述】:

我有一个路线列表

path(chicago,milwaukee).
path(milwaukee,detroit).
path(chicago,detroit).
path(detroit, newyork).
path(newyork, boston).
path(atlanta,boston).

我有一个谓词路线,它给出了起点和终点之间的所有城市。 例如:

?- routefrom(chicago,newyork,X).
X=[chicago,milwaukee,detroit,newyork]

获取我拥有的所有路线

allroutes(Start,End,P) :- findall(X,pathfrom(Start,End,X),P).

例子:

?- allroutes(chicago,neywork,P).
X=[[chicago,milwaukee,detroit,newyork],[chicago,detroit,newyork]].

我有一个谓词规则goodroute(M),如果路线不包含密尔沃基并且包含芝加哥或纽约,则返回true。 示例:

?- goodroute([chicago, milwaukee,detroit]).
false

?-goodroute([chicago,detroit,newyork,boston]).
true

现在, 我需要过滤掉有 milwaukee 的路线,并从 allroutes 的结果中得到一个有 Chicago 或 newyork 的列表。 我试过了

filerroute :- exclude(maplist(goodroute(findall(X,pathfrom(Start,End,X),P).

我要做的是将goodroute映射到findall的结果上,这样其中一些是真的,一些是假的,而排除会消除错误。 我不确定 exclude 是如何工作的。 如何根据goodroute谓词过滤掉错误的元素,得到一个只有符合真实条件的元素的列表?

【问题讨论】:

    标签: list prolog


    【解决方案1】:

    excludeinclude(你真正想要的)将谓词名称作为它们的第一个参数:

    goodroutes(From, To, Routes) :-
        allroutes(From, To, All),
        include(goodroute, All, Routes).
    

    虽然在调用findall 期间过滤掉坏路由会更有效,但此后您不必先构建所有路由集:

    goodroutes(From, To, Routes) :-
        findall(Route, (pathfrom(From, To, Route), goodroute(Route)), Routes).
    

    注意( , );我们给findall 提供了两个目标的结合作为它的第二个参数。

    【讨论】:

    • 谢谢。使用 findall 的看起来比使用 include 的更有效。在findall(Route, (pathfrom(From, To, Route), goodroute(Route)), Routes). 中,我们可以使用尽可能多的目标来匹配它吗?如果我还有更多需要满足的条件,我就做findall(Route, (pathfrom(From, To, Route), goodroute(Route),another_condition), Routes).吧?
    • @RBK:没错,而且它也更便携。 include 如果你得到一个完整构建的列表作为输入,那很好,但尽早过滤最终可以节省 很多 时间。
    猜你喜欢
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2017-08-31
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多