我编写了一个算法并尝试在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
将最后一个成员存储在{ {1}}已解析。
EDIT2:不 - &gt;是允许的(这是如何工作)。如果有人能告诉我如何在prolog中表达,那可能会很棒。
答案 0 :(得分:1)
我怀疑&#34;绿色切割&#34;你的不是绿色的;你有
( A ; B ), !
所以第一次退出(A ; B)
时,如果A成功,B
再也不会被尝试 - 这就是!
在这里所说的内容:don&# 39;再试一次。
如果您也想尝试B
,请移除剪切!
。
If-then-else是:
ifte(A,B,C):- A, B.
ifte(A,B,C):- \+A, C.
我们可以使用not
,
cut
ifte(A,B,C):- A, !, B.
ifte(A,B,C):- C.
关于您的代码:我们使用逗号and then
表达A,B
。输出最后一个最容易使用工作谓词,附加参数,&#34; see-last&#34 ;;在最后看到的基础情况和输出将统一。
答案 1 :(得分:1)
简而言之:!/0
适用于谓词级别:此处您希望将其应用于某些块级别,其中块将由(
和)
分隔。 Prolog中不存在应用于块的切割概念。剪切将擦除所有遇到的选择点,直到它在谓词中的位置。
而不是使用大量(;)/2
用法编写代码,考虑引入新的子句,以提高可读性(正是因为我们不喜欢括号并找出(;)/2
和(,)/2
优先级):
c :- A; B.
可以写
c :- A.
c :- B.
这种方式通常会更好。最好是轻松生成代码,更好地维护代码,阅读代码并扩展代码。
我没有深入研究你的谓词或任何东西,只是想提到这两件事。