旅行
经过中间站的旅行方式
答案
travel(X, Y,gobyCar(X,Y)) :- byCar(X, Y).
travel(X, Y,gobyTrain(X,Y)) :- byTrain(X, Y).
travel(X, Y,gobyPlane(X,Y)) :- byPlane(X, Y).
travel(X, Y,gobyCar(X,Z,Journey)) :-
byCar(X, Z),
travel(Z, Y,Journey).
travel(X, Y,gobyTrain(X,Z,Journey)) :-
byTrain(X, Z),
travel(Z, Y,Journey).
travel(X, Y,gobyPlane(X,Z,Journey)) :-
byPlane(X, Z),
travel(Z, Y,Journey).
验证
?- travel(valmont,losAngeles,X).
X =
gobyCar(
valmont,
saarbruecken,
gobyTrain(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
历程
两地间是否能到达
这是第二题。
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(X,Y):-
byCar(X,_),byCar(_,Y),
%write(X),write("byCar"),write(_), write(_),write("byCar"),write(Y).
travel(X,Y):-
byCar(X,_),byTrain(_,Y).
travel(X,Y):-
byCar(X,_),byPlane(_,Y).
travel(X,Y):-
byTrain(X,_),byCar(_,Y).
travel(X,Y):-
byTrain(X,_),byTrain(_,Y).
travel(X,Y):-
byTrain(X,_),byPlane(_,Y).
travel(X,Y):-
byPlane(X,_),byCar(_,Y).
travel(X,Y):-
byPlane(X,_),byTrain(_,Y).
travel(X,Y):-
byPlane(X,_),byPlane(_,Y).
"_"跟python一样表示忽略的意思,在前面文章里也用到了。命题写得有点多,效果还是达到了。这第三章是讲递归。有三种交通方式,一个中间站就是3x3=9种方式。
怎么到达
第三题。%write(X),write(“byCar”),write(), write(),write(“byCar”),write(Y). 可以看到上面代码里有这行注释。我尝试一般程序开发的打印了。失败是惨重的。
网上找到了答案
travel(X, Y,go(X,Y)) :- byCar(X, Y).
travel(X, Y,go(X,Y)) :- byTrain(X, Y).
travel(X, Y,go(X,Y)) :- byPlane(X, Y).
travel(X, Y,go(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
如此简洁。原来分号“;”是表示析取的意思。我默默地把自己前面的题也改了。
输出的结果是:
X =
go(
valmont,
saarbruecken,
go(saarbruecken,paris,go(paris,losAngeles))
)
网上没有答案
第四题要求回答旅行方式。只有自己来了。是不是把go的命题改成gobyCar、gobyTrain、gobyPlane三个命题。
travel(X, Y,gobyCar(X,Y)) :- byCar(X, Y).
travel(X, Y,gobyTrain(X,Y)) :- byTrain(X, Y).
travel(X, Y,gobyPlane(X,Y)) :- byPlane(X, Y).
travel(X, Y,go(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
回答里只有最后一步是飞机方式。
X =
go(
valmont,
saarbruecken,
go(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
递归
复杂命题先递归调用,到最后有直接答案了才走前面三个命题。可以把前面学到的析取加到递归调用travel(X, Y,go(X,Z,Journey)) 里面调用自己的那一步 travel(Z, Y,Journey)吗?改成 (gobyCar(X,Z,Journey),gobyTrain(X,Z,Journey),gobyPlane(X,Z,Journey)))
travel(X, Y,gobyCar(X,Y)) :- byCar(X, Y).
travel(X, Y,gobyTrain(X,Y)) :- byTrain(X, Y).
travel(X, Y,gobyPlane(X,Y)) :- byPlane(X, Y).
travel(X, Y,go(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
(gobyCar(X,Z,Journey),gobyTrain(X,Z,Journey),gobyPlane(X,Z,Journey))).
直接返回false.
?- travel(valmont,losAngeles,X).
false
命题参数
把析取加到命题的参数里呢?
travel(X, Y,gobyCar(X,Y)) :- byCar(X, Y).
travel(X, Y,gobyTrain(X,Y)) :- byTrain(X, Y).
travel(X, Y,gobyPlane(X,Y)) :- byPlane(X, Y).
travel(X, Y,(gobyCar(X,Z,Journey),gobyTrain(X,Z,Journey),gobyPlane(X,Z,Journey))) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
回答很奇怪,最后面一步都是重复的。
X =
gobyCar(
valmont,
saarbruecken,
gobyCar(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyTrain(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyPlane(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
;
gobyTrain(
valmont,
saarbruecken,
gobyCar(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyTrain(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyPlane(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
;
gobyPlane(
valmont,
saarbruecken,
gobyCar(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyTrain(saarbruecken,paris,gobyPlane(paris,losAngeles));
gobyPlane(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
找回自信
命题参数和递归调用地方两种修改方式都不行。是不是析取有问题?多写几行呢,反正是复制粘贴。定义了三个travel(X, Y,gobyCar(X,Z,Journey)) ,travel(X, Y,gobyTrain(X,Z,Journey)) ,travel(X, Y,gobyPlane(X,Z,Journey))复杂命题。析取改成一步一步走也可以的。
travel(X, Y,gobyCar(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
travel(X, Y,gobyTrain(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
travel(X, Y,gobyPlane(X,Z,Journey)) :-
(byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),
travel(Z, Y,Journey).
差点成功
X =
gobyCar(
valmont,
saarbruecken,
gobyCar(saarbruecken,paris,gobyPlane(paris,losAngeles))
)
前面的go也变了。就在准备发布文章的一刻,多看了一眼。前面两个地点之间都是开汽车吗?不是,这些英文字母真让人眼花缭乱。
调试
感觉成功就差着窗户纸了。是代码还不够简洁吗?又是一顿折腾改成了开头的代码。
扩展
CMG“中国红”走遍世界,从巴黎载誉而归。东风可以到华盛顿。
添加四个命题:
travel(paris, china,gobyCMG(paris,china)).
travel(china, washington,gobyDongfeng(china,washington)).
travel(X, Y,gobyCMG(X,Z,Journey)) :-
byCMG(X, Z),
travel(Z, Y,Journey).
travel(X, Y,gobyDongfeng(X,Z,Journey)) :-
byDongfeng(X, Z),
travel(Z, Y,Journey).
查询valmont到华盛顿的方案:
?- travel(valmont,washington,X).
X =
gobyCar(
valmont,
saarbruecken,
gobyTrain(
saarbruecken,
paris,
gobyCMG(paris,china,gobyDongfeng(china,washington))
)
)
X =
gobyCar(
valmont,
metz,
gobyTrain(
metz,
paris,
gobyCMG(paris,china,gobyDongfeng(china,washington))
)
)
有两种方案。