如何在序言中实现列表的 AND 运算符?

How to implement AND operator of a list in prolog?

我正在制定时间表计划。给定 [t,t,t,f,t][f,f,t,f,f]。 我想要跟随功能

and(L,[t,t,t,f,t],[f,f,t,f,f]).
L = [f,f,t,f,f].

我知道如何实现 2 元素的 AND 运算符。但是不知道怎么实现list版本

这是我已经完成的:

available(Z,X,Y):- Z = t, X = t, Y = t. 
available(Z,X,Y):- Z = f, X = f. 
available(Z,X,Y):- Z = f, Y = f.

首先,让我们修复and/3以涵盖所有可能性。请注意,您可以在规则的 header 中与原子统一,而不是

xyz(X) := X=a;

你可以写

xyz(a).

并跳过 body。这是 and/3:

and(t, t, t).
and(t, f, f).
and(f, t, f).
and(f, f, f).

您可以将其缩减为两条规则,但这对于使列表起作用并不重要。

有几种方法可以使 and_list/3 带有 built-in 列表谓词,例如 maplist/4。但是,应该学习基本的递归写法,因为它有助于理解 Prolog 的其余部分:

and_list([], [], []).
and_list([H1|T1], [H2|T2], [R|RT]) :-
    and(H1, H2, R),
    and_list(T1, T2, RT).

第一个子句是基本子句。它告诉 Prolog 当列表为空时要做什么。第二个子句结合了 and_list/3 的递归调用和对两个列表头的 and/3 的调用。

Demo.

我首先定义二进制和 band/3 如下:

band(t,t,t).
band(t,f,f).
band(f,t,f).
band(f,f,f).

然后用maplist/3收集所有答案:

and(L, Left, Right):-
  maplist(band, Left, Right, L).

示例查询:

?- and(L,[t,f,t,f],[t,t,f,f]).
L = [t, f, f, f]

您应该遵循从其他答案中获得的指示。 但只是为了展示您当前的代码是如何工作的,请考虑

and(F,X,Y) :- maplist(available, F,X,Y), !.

产生

?- and(L,[t,t,t,f,t],[f,f,t,f,f]).
L = [f, f, t, f, f].