Prolog:查找不满足目标的列表

标签 prolog depth-first-search goal-tracking

如果我有一个问题的边列表,例如“显示从一个被认为是危险的城市到一个被认为是安全的城市的路线”,那么......

dangerous(oakland).
safe(portland).

move(rome,plane,portland).
move(portland,plane,rome).
move(halifax,train,gatwick).
move(gatwick,car,rome).
move(portland,plane,newyork).
move(oakland,plane,rome).
move(oakland,plane,gatwick).
move(halifax,train,gatwick).
move(gatwick,plane,rome).
move(oakland,train,newyork).

我可以通过使用以下深度优先搜索(在SO上找到)来获取通往安全城市的路径列表...

dfs_start(Start, Goal, Path) :- phrase(dfs(Start, [], Goal), Path).

dfs(Node, _, Goal)   --> [Node], { call(Goal, Node) }.
dfs(Node0, Es, Goal) --> [Node0],
        { move(Node0,_,Node1), \+ member(Node1, Es) },
        dfs(Node1, [Node0|Es], Goal).

然而,我试图解决的问题是找到所有从危险城市不会通向安全城市的路径(在这种情况下只有一个奥克兰 -> 纽约。) 如果我用...调用上面的函数

dfs_start(oakland,safe,Path).

...我明白了

Path = [oakland, rome, portland] ;
Path = [oakland, gatwick, rome, portland] ;
Path = [oakland, gatwick, rome, portland] ;

...但我想做的是调用类似...

dfs_start(oakland,unsafe,Path).

...并得到...

Path = [oakland, newyork] ;

如有任何建议,我们将不胜感激!

最佳答案

问题描述不明确,也许这就是你怀疑的原因。 据我了解, unsafe(X). 显然是错误的,因为消除了每个过滤条件。你可以尝试这样简化规则(效率低下的规则我已经注释掉了,你可以删除):

% unsafe(X) :- findall(Y,safe(Y),SafeList), member(X,SafeList), !, fail.
unsafe(X) :- \+ safe(X).

编辑您与 Will Ness 交换的评论澄清了一点任务:当路径无法进一步延伸时,停止条件必须为真,并且任何安全城市都被禁止进入路径。我简化了一些代码,删除了不必要的功能,这样您就可以专注于逻辑:图是非循环的,因此不需要访问路径,并且不需要传递目标,只需使用所需的语句:

unsafe_path([Start|Path]) :-
    dangerous(Start),
    phrase(dfs(Start), Path).

dfs(Node) --> [Node1],
   {  move(Node, _, Node1),
      \+ lead_to_safe(Node1)
    } -> dfs(Node1) ; {true}.

lead_to_safe(Node) :- safe(Node).
lead_to_safe(Node) :-
    move(Node, _, Node1),
    lead_to_safe(Node1).

测试:

?- unsafe_path(P).
P = [oakland, newyork].

如果我们添加一个虚构的城市,路径就会延长:

?- assertz(move(newyork,train,turin)).

?- unsafe_path(P).
P = [oakland, newyork, turin].

如果我们让都灵成为通往安全城市的门户:

?- assertz(move(turin,train,portland)).

?- unsafe_path(P).
P = [oakland].

关于Prolog:查找不满足目标的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10964995/

相关文章:

prolog - WAM 的替代品

java - 图邻接表的实现

javascript - 如何在没有单独的感谢页面的情况下设置联系表单的 Google Analytics 目标跟踪?

list - Prolog:搜索长度>=3的子列表

list - 如何获取列表方案和序言的第一个、中间和最后一个元素?

list - Prolog IntList 定义

algorithm - 图上的随机路径 - 设置长度,无交叉,无死角

java - 一种迷宫生成方法的简单实现(随机DFS)

google-analytics - Google 分析向导中的目标 - 重复步骤

google-analytics - 从脚本设置动态目标值,无需电子商务跟踪