这可能是一个简单的问题,但我需要以不同的方式做到这一点。 问题是我必须在prolog中找到可能的航空路线。 我有这个知识库
from_to(fresno,seattle).
from_to(fresno,albany).
from_to(albany,dallas).
from_to(fresno,boston).
from_to(dallas,seattle).
from_to(dallas,albany).
from_to(seattle,dallas).
from_to(seattle,omaha).
from_to(atlanta,albany).
from_to(atlanta,dallas).
from_to(atlanta,boston).
from_to(omaha,atlanta).
from_to(omaha,albany).
from_to(albany,seattle).
我必须制作一个谓词路线(X,Y)来检查我们是否可以从X到Y. 我做的是这个:
route(X,Y):-from_to(X,Y).
route(X,Y):-from_to(X,Z), route(Z,Y).
但它不起作用,因为图表是循环的。我在互联网上搜索,每个人都说的唯一的事情是使用列表并检查访问过的路径。但我不能使用列表!我必须在不使用列表的情况下创建谓词路径(X,Y),如何在没有列表的情况下完成此操作? 谢谢
答案 0 :(得分:1)
route(X0,X) :-
from_to(X0,X1),
closure0(from_to,X1,X).
有关closure0/3
的定义,请参阅this question。
答案 1 :(得分:1)
如果您没有严格要求使用SWI-Prolog,您可以在具有表格支持的Prolog系统中轻松完成此操作。在B-Prolog中,我刚刚添加:- table route/2.
,现在它可以工作:
?- route(fresno, omaha).
yes
?- route(fresno, fresno).
no
?- route(atlanta, atlanta).
yes
?- route(atlanta, X).
X = albany ?;
X = dallas ?;
X = boston ?;
X = seattle ?;
X = omaha ?;
X = atlanta
yes
答案 2 :(得分:1)
所以你不能使用列表(我想知道为什么),但你可以使用计数器变量吗?尝试iteratively deepening search,首先深度为1,然后是2,深度优先搜索,依此类推。这将阻止循环的无限循环。
请记住搜索深度的上限,以避免在没有连接的情况下无限循环。
答案 3 :(得分:0)
我会尝试
:- dynamic visited/1.
route(X,Y) :- retractall(visited(_)), route_(X,Y).
route_(X,Y) :- from_to(X,Y).
route_(X,Y) :- from_to(X,Z), \+ visited(Z), asserta(visited(Z)), route_(Z,Y).
试验:
1 ?- route(fresno, omaha).
true ;
false.
2 ?- route(fresno, omaha).
true ;
false.
3 ?- route(fresno, fresno).
false.
4 ?- route(atlanta, atlanta).
true ;
false.
由于图表是在源代码中定义的,因此可以选择:
:- dynamic from_to/2.
route(X,Y):-retract(from_to(X,Y)).
route(X,Y):-retract(from_to(X,Z)), route(Z,Y).
但是在第一次调用之后,需要重新加载KB。