鉴于两个已排序的列表Ys
和X
,如何确保Xs
中的Y
与{{1}中的任何Ys
之间的绝对差异至少是两个?
带有预期答案的示例查询:
?- different([1,2,4],[5,6]). % 5-4 < 2
false
?- different([1,4],[2,6]). % 2-1 < 2
false
?- different([1,2,6],[4,8]). % 4-2 >= 2 and 6-4 >= 2 and 8-6 >= 2
true
?- different([],[4]).
true
我怎样才能得到这个结果?有任何想法吗?谢谢!
修改:这是我现在的代码:
difference([], []).
difference([_|_], []).
difference([], [_|_]).
difference(L1, L2) :-
L1 = [X1|X2],
L2 = [Y1|_],
Dif is X1-Y1,
(-1>Dif|Dif>1),
difference(X2, L2).
答案 0 :(得分:1)
在这个答案中,我们使用clpfd来获得两者 通用性和最佳(线性)算术复杂度。
diff_to_mdist([], _, _).
diff_to_mdist([_|_], [], _).
diff_to_mdist([X|Xs], [Y|Ys], D) :-
( X #=< Y-D, diff_to_mdist(Xs, [Y|Ys], D)
; X #> Y-D, X #>= Y+D, diff_to_mdist([X|Xs], Ys, D)
).
diff_to_mdist([X0,X1|Xs], [Y0,Y1|Ys], D) :-
X0 #> Y0-D, X0 #< Y0+D,
( X0 #< Y0, X0 #=< Y0-D, X1 #>= Y0+D, diff_to_mdist([X0,X1|Xs], [Y1|Ys], D)
; X0 #> Y0, Y0 #=< X0-D, Y1 #>= X0+D, diff_to_mdist([X1|Xs], [Y0,Y1|Ys], D)
).
让我们使用gnu-prolog版本1.4.4并运行类似OP建议的查询!
| ?- diff_to_mdist([1,2,4], [5,6], 2).
no
| ?- diff_to_mdist([1,4], [2,6], 2).
no
| ?- diff_to_mdist([1,2,6], [4,8], 2).
true ? ;
no
| ?- diff_to_mdist([], [4], 2).
yes
答案 1 :(得分:0)
首先,您可以使您当前的代码更整洁,更容易阅读,如下所示:
different([], []).
different([_|_], []).
different([], [_|_]).
different([X|Xs], [Y|Ys]) :-
abs(X-Y) >= 2, % Prolog evaluates arithmetic expressions for compares
different(Xs, [Y|Ys]).
在这种情况下,你已经完成了我在评论中提到的递归的一个级别,因为它只检查第一个列表中的每个元素而不是第二个元素的第一个元素。它忽略了第二个列表中的所有其他元素。所以你需要进一步分解它。您可以创建一个帮助器谓词,将列表中的每个元素与单个值进行比较。然后让你的主谓词用另一个列表的每个元素调用这个辅助谓词。然后主要谓词如下:
different([], []).
different([], [_|_]).
different([X|Xs], L) :-
different_element(X, L),
different(Xs, L).
然后帮助器谓词是:
% This predicate succeeds if the first argument has the desired difference
% to each of the elements of the second argument (a list)
%
different_element(_, []).
different_element(X, [Y|Ys]) :-
abs(X-Y) >= 2,
different_element(X, Ys).