Prolog 对列表元素进行 XOR

Prolog XOR on elements of list

我是 Prolog 的新手,我想对给定长度为 n 的列表的元素应用异或运算。如果列表的第一个 n-1 元素中包含一些假元素或最后一个元素为真,则谓词应 return 真。

到目前为止,我已经编写了以下代码,但它不能正常工作,例如查询 ?- function([true,false,false]) 谓词应该 return True 但它 return是错误的。

function([X|_]) :-  \ + X,!.
function([X]):-X,!.
function([_|XS]):- function(XS),!,helper(XS).

helper([X]):- X,!.
helper([_|YS]):- helper(YS),!.

如果你能帮助我,我将不胜感激。谢谢!

我手边没有 prolog 编译器,但这应该可以解决问题。

function([false|_]).

function([X]):- X.

function([_ | XS]) :- function(XS).

这又是你的规格:

The predicate should return True if list contains some false elements in the first n-1 element or if last element is True.

让我们像这样定义谓词 xor_check/1

xor_check(List) :-
   booleans(List),
   append(ButLast,[Last],List),
   xor_check__aux(Last,ButLast).

以上代码基于 xor_check__aux/2,后者又基于 memberd/2:

xor_check__aux(true,_).
xor_check__aux(false,ButLast) :-
   memberd(false,ButLast).

辅助谓词boolean/1booleans/1可以定义为:

boolean(true).
boolean(false).

booleans([]).
booleans([B|Bs]) :-
   boolean(B),
   booleans(Bs).

示例查询(使用 SICStus Prolog 4.3.2):

?- xor_check([true,false]).
no
?- xor_check([true,true,true]).
yes
?- xor_check([true,false,false]).
yes

如果 A 或 B 为真,则 A XOR B if 为真,但不能同时为真。这是它的真相 table:

  A   |   B   | A XOR B
------+------ |---------
false | false | false
false | true  | true
true  | false | true
true  | true  | false

将真理 table 写为 Prolog 谓词:

%      A       B   | A XOR B
%    -----   ----- | -------
xor( false , false , false   ) .
xor( false , true  , true    ) .
xor( true  , false , true    ) .
xor( true  , true  , false   ) .

那么它就是一个简单的递归遍历列表的问题。当列表折叠成单个元素时,它在 [true] 上成功,否则失败:

xor_list( [ A,B | T ] ) :- xor(A,B,C) , xor_list( [C|T] ) .
xor_list( [ true    ] ) .

这都可以折叠成一个稍微smaller/simpler谓词:

xor_list( [ false , false | T ] ) :- xor_list( [ false | T ] ) .
xor_list( [ false , true  | T ] ) :- xor_list( [ true  | T ] ) .
xor_list( [ true  , false | T ] ) :- xor_list( [ true  | T ] ) .
xor_list( [ true  , true  | T ] ) :- xor_list( [ false | T ] ) .
xor_list( [ true              ] ) .