我'我正在制定一个时间表计划。给定[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.
答案 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
的调用结合起来。
答案 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].