我正在通过http://www.learnprolognow.org学习Prolog,并且我在理解如何递归地建立一个带有来自另一个递归调用的结果的变量时遇到一些麻烦,根据实践会话3.4,问题3.最初的问题是直接的 - 前向递归调用以确定路由是否可行。但是后续问题要求您显示到达路径末端的实际路径。
我们获得以下旅游信息知识库:
byCar(auckland,hamilton).
byCar(hamilton,raglan).
byCar(valmont,saarbruecken).
byCar(valmont,metz).
byTrain(metz,frankfurt).
byTrain(saarbruecken,frankfurt).
byTrain(metz,paris).
byTrain(saarbruecken,paris).
byPlane(frankfurt,bangkok).
byPlane(frankfurt,singapore).
byPlane(paris,losAngeles).
byPlane(bangkok,auckland).
byPlane(singapore,auckland).
byPlane(losAngeles,auckland).
写一个谓词travel / 2,确定是否可以 通过将汽车,火车和火车链接在一起,从一个地方旅行到另一个地方 飞机旅行。例如,您的程序应该回答“是” 查询旅行(valmont,raglan)。
我使用以下代码解决了这个问题:
travel(From,To) :-
byCar(From,To).
travel(From,To) :-
byTrain(From,To).
travel(From,To) :-
byPlane(From,To).
travel(From,To) :-
byCar(From,NewTo),
travel(NewTo,To).
travel(From,To) :-
byTrain(From,NewTo),
travel(NewTo,To).
travel(From,To) :-
byPlane(From,NewTo),
travel(NewTo,To).
后续问题是:
因此,通过使用travel / 2查询上述数据库,您可以找到答案 有可能从Valmont到拉格伦。如果你在计划 这样的航程,这已经是有用的知识了,但你会的 可能更喜欢从Valmont到Raglan的精确路线。 写一个谓词旅行/ 3,告诉你何时采取的路线 从一个地方旅行到另一个地方。例如,程序应该 响应
X = go(valmont,metz,go(metz,paris,go(paris,losAngeles)))
到查询旅行(valmont,losAngeles,X)
我一直在努力用一系列go(From,To)填充X,展示旅程的连续步骤。它看起来像一个递归问题,但我不知道应该如何处理它。这种技术似乎是Prolog编程的基础,我对解决这个问题的思考过程很感兴趣,我期待着你能提供的任何见解。
答案 0 :(得分:3)
我去了。我对您的第一个解决方案进行了一处更改,只是为了删除一些冗余。我使用谓词connected/2
来概括by_car/2
,by_train/2
和by_plane/2
事实中出现的所有联系的共同关系:
connected(From, To) :- by_car(From, To).
connected(From, To) :- by_train(From, To).
connected(From, To) :- by_plane(From, To).
然后我将travel/2
定义为connected/2
的递归关系:
travel(From, To) :-
connected(From, To).
travel(From, To) :-
connected(From, Through),
travel(Through, To).
转到travel/3
,请注意嵌套go...
字词中的最终连接是结构go/2
,但其余的是go/3
s。因此,我们需要使用一系列以X
结尾的嵌套go/3
结构填充go/2
。这最后是我们的基本条件。然后,只需要重复travel/2
的第二个子句,但在第三个参数中包含一个go/3
,它将捕获每个实例化为From
和Through
的值。迭代:
travel(From, To, go(From, To)) :-
connected(From, To).
travel(From, To, go(From, Through, Route)) :-
connected(From, Through),
travel(Through, To, Route).