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

时间:2015-10-29 13:37:22

标签: 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运算符。但我不知道如何实现列表版本。

这就是我已经做过的事情:

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.

3 个答案:

答案 0 :(得分:3)

我首先要定义二进制和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]

答案 1 :(得分:1)

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

xyz(X) := X=a;

你可以写

xyz(a).

跳过身体。这是and/3

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

您可以将此缩小为两条规则,但这对于使列表无效非常重要。

有几种方法可以使and_list/3使用内置列表谓词,例如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.

答案 2 :(得分:0)

您应该按照其他答案中的指示进行操作。 但只是为了说明您当前的代码是如何工作的,请考虑

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].