SWI-Prolog Prolog 如何处理逻辑比较

发布于 2024-12-23 07:40:24 字数 909 浏览 1 评论 0原文

我在SWI-Prolog中编写了以下代码:

:- dynamic state_a/1 .
 :- dynamic state_b/1 .
 :- dynamic state_c/1 .
 state_a([1,2,3,4,5,0]).
 state_b([0]).
 chop(LIST,HEAD,TAIL) :- LIST=[HEAD|TAIL].
 move_ab :- !,state_a(X),
            chop(X,Ha,Ba),
            Ha>0,
            state_b(Y),
            chop(Y,Hb,Bb),!,
            (Ha<Hb ; Hb =:= 0),
            asserta(state_a(Ba)),asserta(state_b([Ha|Y])),
            retract(state_a(X)), retract(state_b(Y));
            write('Wrong Move.Choose Another').

我的代码中有2个OR(;)。当我第一次在 Prolog 中询问 move_ab 时,第二个 OR 之前的所有条件都为 true,因此我从 Prolog 中得到答案 true。 但当我第二次在 Prolog 中询问 move_ab 时,我得到的只是答案。 我不知道这是怎么发生的。第二个 OR 之前的一些条件不成立,因此 Prolog 应该检查第二个 OR 之后的条件并向我写消息Wrong Move.Choose Another.。 我尝试使用 () 对条件进行分组,但仍然收到相同的消息。 知道发生了什么吗?顺便说一句,我是 Prolog 的新手,两天前才开始:)

I have written the following code in SWI-Prolog:

:- dynamic state_a/1 .
 :- dynamic state_b/1 .
 :- dynamic state_c/1 .
 state_a([1,2,3,4,5,0]).
 state_b([0]).
 chop(LIST,HEAD,TAIL) :- LIST=[HEAD|TAIL].
 move_ab :- !,state_a(X),
            chop(X,Ha,Ba),
            Ha>0,
            state_b(Y),
            chop(Y,Hb,Bb),!,
            (Ha<Hb ; Hb =:= 0),
            asserta(state_a(Ba)),asserta(state_b([Ha|Y])),
            retract(state_a(X)), retract(state_b(Y));
            write('Wrong Move.Choose Another').

There are 2 OR(;) in my code. When I ask move_ab in Prolog for the first time all the conditions before the second OR are true so i get the answer true from Prolog.
But the second time I ask move_ab in Prolog I get just the answer false.
I don't know how this can happen. Some of the conditions before the second OR are not true so Prolog should check the condition after the second OR and write me the message Wrong Move.Choose Another..
I tried using () to group the conditions but I still get the same message.
Any idea about what is going on? By the way I am a newb in Prolog, just started 2 days ago :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浊酒尽余欢 2024-12-30 07:40:24

问题在于在正确测试条件之前使用 cut (!/0)。剪切删除选择点。这里,这意味着在您测试任何内容之前,这些选择就被删除了。因此,如果测试失败,一切都会失败!

顺便说一句,操作数据库可能不是最好的主意。为了表示状态,您可以使用全局变量,如下所示:

:- nb_setval(state_a, [1,2,3,4,5,0]).
:- nb_setval(state_b, [0]).

move_ab :-
    nb_getval(state_a, [Ha|Ta]),
    Ha > 0,
    nb_getval(state_b, [Hb|Tb]),
    (Ha < Hb ; Hb =:= 0),
    nb_setval(state_a, Ta),
    nb_setval(state_b, [Ha, Hb|Tb]),
    !
    ;
    write('Wrong Move.Choose Another').

给 prolog 初学者的一般建议是尽可能远离数据库操作,因为通常没有它就可以解决问题。虽然这可能是合理的,但全局变量会更快、更容易操作。

The problem lies in the use of cut (!/0) before the conditions are properly tested. Cut removes choice points. Here it means that the choices are removed before you even test anything. So if the tests fail, everything fails !

BTW, manipulating the database is maybe not the best idea there. To represent states, you could use global variables as follows :

:- nb_setval(state_a, [1,2,3,4,5,0]).
:- nb_setval(state_b, [0]).

move_ab :-
    nb_getval(state_a, [Ha|Ta]),
    Ha > 0,
    nb_getval(state_b, [Hb|Tb]),
    (Ha < Hb ; Hb =:= 0),
    nb_setval(state_a, Ta),
    nb_setval(state_b, [Ha, Hb|Tb]),
    !
    ;
    write('Wrong Move.Choose Another').

A general advice given to beginners in prolog is to stay away from database manipulation if possible, as often problems are solvable without it. Here though it could be justified, but global variables will be faster and easier to manipulate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文