内部术语的序言映射表?

Prolog maplist on inner term?

如何在inner term上使用maplist?

假设知识库是:

gate(not(o), i). 
gate(not(i), o).

gate(and(o, i), o).
gate(and(i, o), o).
gate(and(B, B), B).

bits([i,o,o,i,i]).

以下无效: ?- bits(BITS), maplist(gate(not(X), Y), BITS, ANS)

我如何映射列表以便:

[i,o,o,i,i] -> [not(i), not(o), not(o), not(i), not(i)] ->[o,i,i,o,o]

这将在任何列表长度上完成:

:- bits([A,B,C,D,E]), gate(not(A), Anew), gate(not(B), Bnew), gate(not(C), Cnew), gate(not(D), Dnew), gate(not(E), Enew), ANS = [Anew, Bnew, Cnew, Dnew, Enew].

所以答案是:ANS = [o, i, i, o, o]

使用辅助谓词:

not(A, Z) :-
    gate(not(A), Z).

?- bits(BITS), maplist(not, BITS, ANS).

ANS  = [o, i, i, o, o],
BITS = [i, o, o, i, i]

但是如果你要添加两行helper,跳过gate()的东西直接写:

not(o, i).
not(i, o).

?- bits(BITS), maplist(not, BITS, ANS).

ANS  = [o, i, i, o, o],
BITS = [i, o, o, i, i]

如果您不想那样做,或者根本无法更改数据库,我知道的唯一方法是使用 yall in SWI Prolog, 等 lambda 库来编写:

?- bits(BITS), maplist([In, Out]>>gate(not(In), Out), BITS, ANS).

ANS  = [o, i, i, o, o],
BITS = [i, o, o, i, i]

(将其命名为 not 可能是一种错误的形式,但这是 not/2 并且内置的是 not/1 所以我认为它不会冲突)。