如果 M 和 N 的差异大于 X,则序言中的谓词为真

Predicate in prolog which is true if M and N differ more than X

首先,我对 prolog 完全陌生,我正在尝试编写一个谓词 length(M,X,N),如果 M 与 N 的差异大于 X,则该谓词为真。

我编写了以下测试用例,如果 M(=dec.5) 和 N(=dec.2) 的差异大于 X(=dec.2),则该测试用例为真。在这种情况下也是如此,因为 5 和 2 的差值 3 大于 2:

?- length(s(s(s(s(s(0))))), s(s(0)), s(s(0))).
   true .

我知道 prolog 是递归工作的,所以我想知道我是否可以像在 C 语言中那样用条件(例如 <、>)构造这样的谓词,或者在 prolog 中是否有另一种方法可以做到这一点。很抱歉这个简单的问题,但我刚开始使用 prolog。

试试这个:

?- length(s(s(s(s(s(0))))), s(s(0)), s(s(0))).

length(s(_),0,0).
length(s(M),s(X),s(N)) :- length(M,X,N).

请记住,Prolog 的谓词不会 return 值 - 因此它们不会 return truefalse。他们要么成功,要么不成功。解释器只是告诉你你的程序是否成功。

您可以为 greater 或 less 构造谓词。例如:

greater_than(s(_), 0).
greater_than(s(X), s(Y)) :-
    greater_than(X, Y).

同样地:

less_than(0, s(_)).
less_than(s(X), s(Y)) :-
    less_than(X, Y).

如果你想找到绝对差异,你可以这样做:

abs_diff(0, 0, 0).
abs_diff(s(X), 0, s(X)).
abs_diff(0, s(X), s(X)).
abs_diff(s(X), s(Y), D) :-
    abs_diff(X, Y, D).

这些概念应该有助于启动一些关于如何解决其余问题的想法。

这个答案跟进了@lurker 的好答案,并通过利用提高了辅助谓词 abs_diff/3 的确定性 first argument clause indexing.

介绍x_y_dist/3

x_y_dist(0, Y, Y).
x_y_dist(s(X), Y, Z) :-
   y_sx_dist(Y, X, Z).

y_sx_dist(0, X, s(X)).
y_sx_dist(s(Y), X, Z) :-
   x_y_dist(X, Y, Z).

示例查询:

?- x_y_dist(X, Y, s(s(0))).                             % |X-Y| = 2
(  X =           0     , Y =         s(s(0))            % |0-2| = 2
;  X =       s(s(0))   , Y =             0              % |2-0| = 2
;  X =         s(0)    , Y =       s(s(s(0)))           % |1-3| = 2
;  X =     s(s(s(0)))  , Y =           s(0)             % |3-1| = 2
;  X =       s(s(0))   , Y =     s(s(s(s(0))))          % |2-4| = 2
;  X =   s(s(s(s(0)))) , Y =         s(s(0))            % |4-2| = 2
;  X =     s(s(s(0)))  , Y =   s(s(s(s(s(0)))))         % |3-5| = 2
;  X = s(s(s(s(s(0))))), Y =       s(s(s(0)))           % |5-3| = 2
;  X =   s(s(s(s(0)))) , Y = s(s(s(s(s(s(0))))))        % |4-6| = 2
;  .........
)