你是非常接近一个解决方案!
要完全解决这个问题,考虑有轻微概括member/2
:我们在这种情况下使用的积木是很多像member/2
,但具有下列扭曲:我们让第三 参数表示什么剩余列表 是,我的意思是列表没有 “member”。
传统上,这个谓词被称为select/3
,这是一个非常糟糕的名字,因为它表明我们只能在一个方向上使用谓词。这是势在必行。
我会用一个更具描述性的,声明名和调用这个selection/3
。
想想这关系这样的:
selection(E, [E|Ls], Ls).
selection(E, [L|Ls], [L|Rest]) :-
selection(E, Ls, Rest).
你能想到的member/2
作为selection/3
一个特例,因为我们可以在selection/3
来定义member/2
,不关心剩余 列表:
member(E, Ls) :- selection(E, Ls, _).
使用selection/3
,我们可以这样写:
list_cover([], _).
list_cover([L|Ls], Cs0) :-
selection(L, Cs0, Cs),
list_cover(Ls, Cs).
我们可以读取第二条款如下:
如果L
是Cs0
的成员,并且是Cs
剩余列表(即,Cs0
无 L
)和Cs
覆盖 Ls
,然后Cs0
覆盖 [L|Ls]
。
请注意命名约定,它理想地表明每个参数代表什么。在我们的 的情况下,第二个的说法是覆盖 列表。简单地调用cover/2
不会使 明确哪个参数实际上表示 封面。
样品答问:
?- list_cover([a,e,i,o], [m,o,n,k,e,y,b,r,a,i,n]).
true .
?- list_cover([a,a,a], [a,a]).
false.
?- list_cover([a,a,a], [a,a,b,a]).
true .
并进一步:
?- list_cover(Ls, Cs).
Ls = [] ;
Ls = [_1900],
Cs = [_1900|_1908] ;
Ls = [_1900, _1912],
Cs = [_1900, _1912|_1920].
很酷,不是吗?这是相当一般的!
多好的答案! – Enigmativity
绝对的辉煌,谢谢你我的男人。 – Hidden