1

我写了一个算法并尝试在Prolog中实现它,但我发现括号没有按预期工作:写入的内容并不是在退出括号之前全部完成。这是代码:

%1. If the first member of L1 is smaller than L2
%     A. If the first member of L1 is not equal to Last
%            Than: A.1 Add the first member of L1 to the first member of NL
%                  Begin recurssion on the resumption of L1, L2 resumption of NL
%                  and Last from L1.
%            Else: A.2  begin the recursion on resumption of L1, L2 with the
%                       first member and L3 with the first member.
%  2. If the first member in L1 is equal to the first member of L2,
%             Than: Start recursion on resumption of L1 and L2 (with its first
%                   member) and Last = *.
%  3. If the first member of L1 is bigger than the first membber of L2
%             Than: begin recursion on L1 with the first member, resumption of
%             L2 and Last = x. %(x != * only for debugging)
%  

                              */
make_list([X1|L1], [X2|L2], [X3|NewL], Last) :-
    (
        X1 < X2,
        (
            X1 \= Last,   %A
            X3=X1;
            make_list(L1, [X2|L2], NewL, X1) %B
        ),  %Why those parenthesis do not work as expected?

        ! %green cut
    );
    (
        X1=X2,
        make_list(L1, [X2|L2], [X3|NewL], *)
    ),
    !
    ;
    make_list([X1|L1], L2, [X3|NewL], *).

我的问题是如何让它按预期工作,为什么B一旦A完成就不起作用?毕竟它也在同一个括号中,例如:

?- make_list([6,6,10,20],[10,25,30],L, -).
L = [6|_G849]  % (should be [6,20]).

EDIT1:make_list 应该找到所有L1不在其中的成员L2并将它们放入NewL,同时Last存储最后一个L1被解析的成员。

EDIT2:不允许->(这是方法)。如果有人可以告诉我如何在序言中表达 if then else ,那就太好了。

4

2 回答 2

1

简而言之:!/0应用于谓词级别:在这里,您希望它应用于某些块级别,其中块将由(and分隔)。这种应用于块的切割概念在 Prolog 中不存在。剪切将删除所有遇到的选择点,直到它在谓词中的位置。

并且不要编写大量使用的代码,而是考虑引入新的子句,以提高可读性(正是因为我们不喜欢括号和(;)/2找出优先级):(;)/2(,)/2

c :- A; B.

可以写

c :- A.
c :- B.

这种方式通常会更好。更好地轻松生成代码,更好地维护、阅读和扩展代码。

我没有深入研究您的谓词或其他任何东西,只是想提一下这两件事。

于 2012-08-11T16:06:57.780 回答
1

我怀疑你的“绿色切割”根本不是绿色的;你有

( A ; B ), !

所以从第一次退出(A ; B)时,如果 A 成功,B将不再尝试 - 这就是 cut!在这里所说的:不要再尝试了。

如果你也想B被试,去掉切口!

If-then-else 是:

ifte(A,B,C):- A, B.
ifte(A,B,C):- \+A, C.

我们可以not通过使用 a来节省我们 a cut

ifte(A,B,C):- A, !, B.
ifte(A,B,C):- C.

关于您的代码:我们and then用逗号表示:A,B. 要输出 Last 最简单的方法是使用工作谓词,并带有附加参数“seen-last”;在基本情况下,最后一次看到并且输出将是统一的。

于 2012-08-11T15:02:33.270 回答