2

我正在努力完成本页底部的练习,但我发现自己对第 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).

很容易确定是否可以在两个城市之间旅行。我只是这样做了:

connected(X, Y) :- byCar(X, Y); byTrain(X, Y); byPlane(X, Y).
travel(X, Y) :- connected(X, Y).
travel(X, Z) :- connected(Y, Z), travel(X, Y).

但是,当我必须用变量实际统一路径时,我完全糊涂了!

我写了这个:

connected(X, Y) :- byCar(X, Y); byTrain(X, Y); byPlane(X, Y).
connected(Y, Z, Out) :- connected(Y, Z).
travel(X, Y, Out) :- connected(X, Y).
travel(A, Z, Out) :- connected(Y, Z),travel(A, Y, connected(Y, Z, Out)).

并叫travel(valmont, losAngeles,X).

除了最后的匿名变量之外,在跟踪过程中有一个点会显示正确的路径:

travel(valmont, metz, connected(metz, paris, connected(paris, losAngeles, _17)))

但我实际上不知道如何将它与变量统一起来X

我实在是想不通这个。谁能给我一个提示只是为了把我推向正确的方向?我只是缺少一个终止条件还是什么?

编辑:

我现在有:

connected(X,Y) :- byCar(X,Y);byTrain(X,Y);byPlane(X,Y).

go(X,Y) :- connected(X,Y).

travel(X,Y,go(X,Y)) :- connected(X,Y).
travel(A,Z,Path) :- travel(Y,Z,Path),go(A,Y,Path).

go(A,Y,Path) :- travel(A,Y,Path).

但它会像这样卡住:

4    4  Exit: byPlane(paris,losAngeles) ? 
3    3  Exit: connected(paris,losAngeles) ? 
2    2  Exit: travel(paris,losAngeles,go(paris,losAngeles)) ? 
5    2  Call: go(metz,paris,go(paris,losAngeles)) ? 
6    3  Call: travel(metz,paris,go(paris,losAngeles)) ? 
7    4  Call: travel(_217,paris,go(paris,losAngeles)) ? 
8    5  Call: travel(_242,paris,go(paris,losAngeles)) ? 
9    6  Call: travel(_267,paris,go(paris,losAngeles)) ? 
10    7  Call: travel(_292,paris,go(paris,losAngeles)) ? 

我玩过它,但我无法让它来构建整个go(a,b,go(b,c))等等......

4

2 回答 2

2

我会给你递归的基本情况:

travel(X, Y, go(X, Y)) :- connected(X, Y).

递归的情况看起来非常相似,除了go/3您正在构建的术语必须将位置作为其前两个参数,并将路径(另一个go/2go/3术语)作为其第二个参数。

于 2012-04-19T15:57:43.410 回答
1

我让一位病理学家通过以下方式向我解释了这一点:

您的目标是获得 X = go(valmont,metz,go(metz,paris,go(paris,losAngeles))) 以响应查询 travel(valmont,losAngeles,X)。

为了解决这个问题,你的 travel/3 谓词需要有 From、To 和 Path,但它必须以没有 Path 的简单 go(From, To) 结尾。简单的 go(From, To) 是你的 travel/3 的基本条件,所以:

travel(X, Y, go(X, Y)) :- connected(X, Y).

这正是 larsmans 所说的。

现在,您需要创建递归 travel/3 谓词:

travel(X, Y, go(X, Z, Path)) :-
 connected(X, Z),
 travel(Z, Y, Path).

你的 go/2 谓词是多余的,而且有点令人困惑,因为 travel/3 谓词看起来像一个 go 谓词。通过删除 go/2 谓词,代码更易于阅读和理解。

于 2014-05-13T13:34:02.343 回答