Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

程序求助

浏览上一个主题 浏览下一个主题 向下  留言 [第1页/共1页]

1 程序求助 于 周五 五月 18, 2012 5:45 pm

如下是一个解决下列问题的程序:

假设三角形ABC中,b物体在A点,a物体在B点,C点为空。
规定物体可以沿着三角形的边由一个顶点运动到另一个顶点。

问题是:将ab交换位置,所需要的步骤。

以下是我的程序:


:- dynamic(been/1). %been can be modified when running
location(b, a, nul, 0, []). % nul means the point is empty
% N is the number of steps
% the last para stores the path

% nul is in C, others are the same

location(nul, B, C, N, Path):-
not(been([nul, B, C])), assert(been([nul, B, C])),
location(B, nul, C, Temp, Path1)| % swap B with nul, which means moving the obj in B to A
location(C, B, nul, Temp, Path1),
N is Temp+1, Path is [[nul, B, C]|Path1].

location(A, nul, C, N, Path):-
not(been([A, nul, C])), assert(been([A, nul, C])),
location(nul, A, C, Temp, Path1)|
location(A, C, nul, Temp, Path1),
N is Temp+1, Path is [[A, nul, C]|Path1].

location(A, B, nul, N, Path):-
not(been([A, B, nul])), assert(been([A, B, nul])),
location(nul, B, A, Temp, Path1)|
location(A, nul, B, Temp, Path1),
N is Temp+1, Path is [[A, B, nul]|Path1].

在swipl-5.10.4上运行“location(a, b, nul, X, Y)”,
结果直接溢出了。
求解答。

查阅用户资料

2 回复: 程序求助 于 周六 五月 19, 2012 4:17 pm

ZDKING 写道::如下是一个解决下列问题的程序:

假设三角形ABC中,b物体在A点,a物体在B点,C点为空。
规定物体可以沿着三角形的边由一个顶点运动到另一个顶点。

问题是:将ab交换位置,所需要的步骤。

以下是我的程序:


:- dynamic(been/1). %been can be modified when running
location(b, a, nul, 0, []). % nul means the point is empty
% N is the number of steps
% the last para stores the path

% nul is in C, others are the same

location(nul, B, C, N, Path):-
not(been([nul, B, C])), assert(been([nul, B, C])),
location(B, nul, C, Temp, Path1)| % swap B with nul, which means moving the obj in B to A
location(C, B, nul, Temp, Path1),
N is Temp+1, Path is [[nul, B, C]|Path1].

location(A, nul, C, N, Path):-
not(been([A, nul, C])), assert(been([A, nul, C])),
location(nul, A, C, Temp, Path1)|
location(A, C, nul, Temp, Path1),
N is Temp+1, Path is [[A, nul, C]|Path1].

location(A, B, nul, N, Path):-
not(been([A, B, nul])), assert(been([A, B, nul])),
location(nul, B, A, Temp, Path1)|
location(A, nul, B, Temp, Path1),
N is Temp+1, Path is [[A, B, nul]|Path1].

在swipl-5.10.4上运行“location(a, b, nul, X, Y)”,
结果直接溢出了。
求解答。

有几点疑问:

1.
你的查询是否应用location(b, a, nul, X, Y)才对,
因为我读你程序码的意思,你的location的参数应该要是"原先位置",
而每个location的代码里,分别列了2个location,中间以"|"隔开,
表示的是你"将怎么移动(有2种可能选项)",
既然是这样,查询时的参数应该用我写的这样,逻辑才是一致的,
表示的是初始时刻A位置摆放的是b,B位置摆放的是a,
然后去做查询,匹配看看如何移动能得出我们想要的结果。

2.
要设定一个终止条件,判断移动的位置是否已是我们想要的,
如果是则直接开始计算步数和路径而不需要再调用location,不然会无限循环的。

3.
两个location要用括号括起来,也就是"……, (location1 | location2), ……"的形式,
原因在于,如果你不加,
prolog是先运算and,再运算or,
那么当前面的not(), assert()语句为假时,prolog仍会去执行location2,
但这显然不是我们想要的,我们想要的是前面为否的话,直接传回否。


因为我在你的代码上改动还不少,所以我直接把代码贴上来,
你看看有没什么问题。

代码:
:- dynamic(been/1). %been can be modified when running
% nul means the point is empty
% N is the number of steps
% the last para stores the path

% nul is in C, others are the same

location(nul, B, C, N, Path):- over_condition, N = 0, Path = [], !.
location(A, nul, C, N, Path):- over_condition, N = 0, Path = [], !.
location(A, B, nul, N, Path):- over_condition, N = 0, Path = [], !.

over_condition :- been([a, b, nul]).


location(nul, B, C, N, Path):-
not(been([nul, B, C])), assert(been([nul, B, C])),
(location(B, nul, C, Temp, Path1)| % swap B with nul, which means moving the obj in B to A
location(C, B, nul, Temp, Path1)),
N is Temp+1, Path = [[nul, B, C]|Path1].

location(A, nul, C, N, Path):-
not(been([A, nul, C])), assert(been([A, nul, C])),
(location(nul, A, C, Temp, Path1)|
location(A, C, nul, Temp, Path1)),
N is Temp+1, Path = [[A, nul, C]|Path1].

location(A, B, nul, N, Path):-
not(been([A, B, nul])), assert(been([A, B, nul])),
(location(nul, B, A, Temp, Path1)|
location(A, nul, B, Temp, Path1)),
N is Temp+1, Path = [[A, B, nul]|Path1].


4 ?- location(b,a,nul,X,Y).
X = 4,
Y = [[b, a, nul], [nul, a, b], [a, nul, b], [a, b, nul]] .

这里程序把原始状态也算为一步,如果你不想要的话,
只要简单做个处理(把最终的X减1,最终的Y第一项去掉)即可。

查阅用户资料 http://prolog.longluntan.net

3 回复 于 周日 五月 20, 2012 5:48 am


几个“疑问”我都看过了。

2,3的确是我没想明白,以及语法掌握不够。

第1问是这样:

已知初始状态为(b,a,nul),我想求的是如何得到(a,b,nul)。
所以,我将(b,a,nul)作为取值为真的谓词(不知这么说对不对),而查询的目标是location(a,b,nul,X,Y)。

这个问题困扰我好长时间了,但周围研究这个的也很少,一直没人解答。

谢谢啦。

查阅用户资料

4 回复: 程序求助 于 周日 五月 20, 2012 6:01 am

ZDKING 写道::
几个“疑问”我都看过了。

2,3的确是我没想明白,以及语法掌握不够。

第1问是这样:

已知初始状态为(b,a,nul),我想求的是如何得到(a,b,nul)。
所以,我将(b,a,nul)作为取值为真的谓词(不知这么说对不对),而查询的目标是location(a,b,nul,X,Y)。

这个问题困扰我好长时间了,但周围研究这个的也很少,一直没人解答。

谢谢啦。

是的,我看你写的"形式"确实是把location的参数当目标,
不过我前面的回答仍然猜测你是想把location的参数当成"原始状态"而非"目标",
这是因为你的注解里写了句"% swap B with nul, which means moving the obj in B to A"
location的代码实现上我感觉你其实是在把参数当"原先位置"而非"目标",
但事实上,从a-b-nul移成b-a-nul和从b-a-nul移成a-b-nul其实算出来的步数和路径形式都一样,
location的参数到底是目标还是初始不重要,只要定好初始和终止条件就可以,
初始和终止分别由查询或事实来给出,在我给你写的代码里,我的查询是初始,而over_condition定义了终止。
如果反过来用over_confition定义初始,应该就可以用你想要的location(a,b,nul,X,Y)来查询了。

查阅用户资料 http://prolog.longluntan.net

浏览上一个主题 浏览下一个主题 返回页首  留言 [第1页/共1页]

您在这个论坛的权限:
不能在这个论坛回复主题