首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取Prolog的往返旅行结果?

如何获取Prolog的往返旅行结果?
EN

Stack Overflow用户
提问于 2013-12-13 09:07:57
回答 2查看 1.3K关注 0票数 1

我有这个Prolog问题,我想检查三件事。

  1. 可以从a到b,也可以从b到a
  2. 可以从a到b,也可以从b到a,它告诉我从a到b的路线。
  3. 与路线上的每一次旅行使用何种运输方式有关的第2号和补充信息相同。

目前,我设法得到了这个程序的第(1)部分,但当我运行,程序出来‘是’,即使它是一个错误的路线。不知道为什么。

代码语言:javascript
复制
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(losAngeles,auckland).

(1)

代码语言:javascript
复制
connect(X,Y):-byCar(X,Y);byCar(Y,X).
connect(X,Y):-byTrain(X,Y);byTrain(Y,X).
connect(X,Y):-byPlane(X,Y);byPlane(Y,X).

travel(X,Y):-travelLoop(X,Y,[]).
travelLoop(X,Y,_):-connect(X,Y).
travelLoop(X,Y,Passed):-connect(X,Thru),
    \+memberchk(Thru,Passed),
    travelLoop(Thru,Y,[Thru|Passed]),X\=Y.
travel(_,_):-write('Wrong travel input, please try again.'),nl.

(2)

代码语言:javascript
复制
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,W)):-travel(X,Z,go(X,Z)),travel(Z,Y,W).

(3)

代码语言:javascript
复制
travel1(X,Y,go(X,Y,car)):-byCar(X,Y).
travel1(X,Y,go(X,Y,train)):-byTrain(X,Y).
travel1(X,Y,go(X,Y,plane)):-byPlane(X,Y).
travel1(X,Y,go(X,Z,V,W)):-travel1(X,Z,go(X,Z,V)),travel1(Z,Y,W).

P.S. (2)和(3)不能想到来回谓词,只能得到一个方法。请帮帮忙。非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-13 10:21:07

首先,您的connect谓词忘记了传输模式。改为:

代码语言:javascript
复制
connect(X,Y,byCar):-   byCar(X,Y)   ; byCar(Y,X).
connect(X,Y,byTrain):- byTrain(X,Y) ; byTrain(Y,X).
connect(X,Y,byPlane):- byPlane(X,Y) ; byPlane(Y,X).

其次,在使用travelLoop的path参数时存在不一致之处:

代码语言:javascript
复制
travel(X,Y):-travelLoop(X,Y,[]).            %// -- start empty. Why not [X]?
travelLoop(X,Y,_):-connect(X,Y).            %// (1)
travelLoop(X,Y,Passed):-connect(X,Thru),
    \+memberchk(Thru,Passed),
    travelLoop(Thru,Y,[Thru|Passed]),       %// -- start from [Thru|...].
    X\=Y.                                   %// why here? should be at (1)

只有当第一个子句不成功时,travel的第二个子句才需要触发。为什么它是分离的?这两个子句在文件中应该是一个相邻的。

代码语言:javascript
复制
travel(_,_):-write('Wrong travel input, please try again.'),nl.
%// This says: succeed always, and tell the user it didn't. 
%// Need to join both clauses into one IF: (success -> true; wrong).

travelLoop的success子句缺失了:

代码语言:javascript
复制
travelLoop(X,Y, Path):- X=Y, %// report the Path to user: ... 
                        writeln( ... ).

至于返航,不是很简单吗?因此,将travelLoop重命名为travel_path,并将travel重写为

代码语言:javascript
复制
travel(X,Y):-   %// the to and fro loop
  travel_path(X,Y,[X]), travel_path(Y,X,[Y]) -> true ; wrong.

wrong:- writeln("Wrong input. Try again."), nl.
票数 1
EN

Stack Overflow用户

发布于 2013-12-14 06:41:43

实际上,下面是我的程序的一部分,我们需要写一个菜单形式,所以这是菜单的一部分。我插入了你为我修正的内容,我尝试过,因为我认为它是有效的,因为我认为选择的任何两个目的地都会有“是”的答案,因为有一个来回循环。但是,我认为这会影响(c)和(d)项。所以我不知道矛盾在哪里。

代码语言:javascript
复制
choice(3):- write('Select the way: '),nl,nl,
  write('a. Travel by using the same transportation.'),nl,
  write('b. Travel by chaining together car, train, and plane journeys.'),nl,
  write('c. How to travel from one place to another: cities.'),nl,
  write('d. How to travel from one place to another: cities and transportation.'),nl,
  read(Option),nl,nl,
  write('Enter the place start from: '),read(Start),
  write('Enter the place end at: '),read(End),
  option(Option,Start,End),nl,nl.

option(a,A,B):- travelSimple(A,B),nl,write('yes'),nl,nl,menu. 
option(b,A,B):- travel(A,B),nl,write('yes'),nl,nl,menu.
option(c,A,B):- findall(X,travel(A,B,X),List),nl,writelist(List),nl,nl,menu.    
option(d,A,B):- findall(Y,travel1(A,B,Y),List1),nl,writelist(List1),nl,nl,menu.
option(_,_,_):- write('Wrong option input, please try again.'),nl,nl,menu.

travel1(X,Y):-byCar(X,Y).
travel1(Y,X):-byCar(X,Y).
travel2(P,Q):-byTrain(P,Q).
travel2(Q,P):-byTrain(P,Q).
travel3(M,N):-byPlane(M,N).
travel3(N,M):-byPlane(M,N).

travelSimple(X,Y):-byCar(X,Z),travel1(Z,Y);byCar(X,Y).
travelSimple(Y,X):-byCar(X,Z),travel1(Z,Y);byCar(X,Y).
travelSimple(P,Q):-byTrain(P,R),travel2(R,Q);byTrain(P,Q).
travelSimple(Q,P):-byTrain(P,R),travel2(R,Q);byTrain(P,Q).
travelSimple(M,N):-byPlane(M,L),travel3(L,N);byPlane(M,N).
travelSimple(N,M):-byPlane(M,L),travel3(L,N);byPlane(M,N).
travelSimple(_,_):-write('Wrong travel simple input, please try again.'),nl.

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

travel(X,Y):-travelLoop(X,Y,[X]).          
travelLoop(X,Y,_):- connect(X,Y,byCar);
                    connect(X,Y,byTrain);
                    connect(X,Y,byPlane), X\=Y.           
travelLoop(X,Y,Passed):-connect(X,Thru,byCar);
                    connect(X,Thru,byTrain);
                    connect(X,Thru,byPlane);
                    \+memberchk(Thru,Passed),travelLoop([Thru|Passed],Y,Thru). 
travelLoop(X,Y,Path):- X=Y, writeln('Yes')-> true ; wrong.      
travel(X,Y):-travel_Path(X,Y,[X]), 
     travel_Path(Y,X,[Y]) -> true ; wrong. 
wrong:- writeln('Wrong travel input, please try again.'), nl.

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,W)):-travel(X,Z,go(X,Z)),travel(Z,Y,W).
travel1(X,Y,go(X,Y,car)):-byCar(X,Y).
travel1(X,Y,go(X,Y,train)):-byTrain(X,Y).
travel1(X,Y,go(X,Y,plane)):-byPlane(X,Y).
travel1(X,Y,go(X,Z,V,W)):-travel1(X,Z,go(X,Z,V)),travel1(Z,Y,W).

writelist([]).
writelist([L|Lt]):-write(L),nl,writelist(Lt).
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20562690

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档