我正在尝试定义一个谓词<asp:TextBox runat="server" Text='<%# Bind("qty")%>'/>
,如果X和Y在列表中相邻,则为真。我的代码目前是这样的:
adjacent(X, Y, Zs)
它适用于adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
adjacent(X,Y, Tail).
的基本情况,但由于基本情况,每个其他情况也会返回true,我仍然坚持这一点。
另一个问题是,如果X不等于列表头部的第一部分,那么它会跳过X和Y并转到下一个'X';例如,如果 c 不等于 a ,那么它会跳过 a 和 b 并检查是否 c 等于 c 。例如,当列表是
时,这是有问题的adjacent(c, d, [a, b, c, d, e])
因为它最终永远不会检查 c (我相信)。
我很沮丧如何调和这两个问题,并将我对逻辑中的理解转化为代码。
编辑:感谢Christian Hujer的回答,我的基本案例错误已得到纠正,所以现在我只是坚持第二个问题。答案 0 :(得分:14)
在原始解决方案尝试中:
adjacent(_, _, []).
adjacent(X, Y, [X, Y|Tail]) :-
adjacent(X,Y, Tail).
正如@ChristianHujer所指出的那样,第一个条款不应该存在,因为它不是真的。空列表应该没有相邻的元素。
第二个条款也存在问题。它表明X
和Y
在列表中相邻,但随后递归并且不仅仅是成功。适当的条款应该是:
adjacent(X, Y, [X,Y|_]).
如果它们是列表中的前两个元素,那么X
和Y
在列表中是相邻的,无论尾部是什么。这也形成了一个合适的基础案例。然后你的一般递归条款应该处理其余的情况:
adjacent(X, Y, [_|Tail]) :-
adjacent(X, Y, Tail).
这表示X
和Y
在[_|Tail]
中相邻,如果它们在Tail
中相邻。这样可以解决您遇到的第二个问题。
因此,整个解决方案将是:
adjacent(X, Y, [X,Y|_]).
adjacent(X, Y, [_|Tail]) :-
adjacent(X, Y, Tail).
这将成功,X
和Y
按顺序一起出现在列表中。
append/3
的解决方案更简洁):
adjacent(X, Y) --> ..., [X, Y], ... .
... --> [] | [_], ... .
adjacent(X, Y, L) :- phrase(adjacent(X, Y), L).
| ?- adjacent(b, c, [a,b,c,d]).
true ? a
(1 ms) no
| ?-
答案 1 :(得分:7)
我认为你的基本情况是错误的。在您的情况下,您希望递归以假谓词终止,而不是使用真正的谓词。这是合乎逻辑的:在一个空列表中,没有相邻的元素。从不。
答案 2 :(得分:6)
在这个答案中,我们试图通过构建append/3
:
adjacent(E0, E1, Es) :- append(_, [E0,E1|_], Es).
示例查询:
?- adjacent(X, Y, [a,b,c,d,e]).
X = a, Y = b ;
X = b, Y = c ;
X = c, Y = d ;
X = d, Y = e ;
false.
答案 3 :(得分:6)
辅助谓词adjacent_/5
总是“落后”恰好两个(列表项):
adjacent(X0, X1, [E0,E1|Es]) :- adjacent_(Es, E0, E1, X0, X1). adjacent_([], E0, E1, E0, E1). adjacent_([E2|Es], E0, E1, X0, X1) :- if_(E0+E1 = X0+X1, true, adjacent_(Es, E1, E2, X0, X1)).
使用SWI-Prolog我们运行:
?- set_prolog_flag(double_quotes, chars). true. ?- adjacent(a, b, "abab"). true. ?- adjacent(b, c, "abcd"). true. ?- adjacent(X, Y, "abcd"). X = a, Y = b ; X = b, Y = c ; X = c, Y = d.
adjacent_/5
的更正定义也为以下查询提供了正确的答案:
?- adjacent(X, X, [A,B,C]). X = A, A = B ; X = B, B = C, dif(f(C,C),f(A,A)). ?- adjacent(a, X, "aab"). X = a ; X = b. ?- adjacent(a, b, "aab"). true.
答案 4 :(得分:4)
我认为这个定义在长期内比@ repeat的解决方案更可取:
adjacent(X0, X1, [E0,E1|Es]) :-
adjacent_(Es, E0, E1, X0, X1).
adjacent_([], E0, E1, E0, E1).
adjacent_([E2|Es], E0, E1, X0, X1) :-
if_(( E0 = X0, E1 = X1 ),
true,
adjacent_(Es, E1, E2, X0, X1)).
使用具体化的:
','(A_1, B_1, T) :-
if_(A_1, call(B_1, T), T = false).
;(A_1, B_1, T) :-
if_(A_1, T = true, call(B_1, T)).