我正在尝试解决chapter 6's excercises on LPN!中的以下问题:
编写一个谓词集(InList,OutList),该谓词集将任意列表作为输入,并返回一个列表,其中输入列表的每个元素仅出现一次。例如,查询
set([2,2,foo,1,foo, [],[]],X).
应该产生结果
X = [2,foo,1,[]].
我知道了:
set_([], [], []).
set_([H|Bag], [H|Set], Dups):-
set_(Bag, Set, Dups),
\+ member(H, Set),
\+ member(H, Dups).
set_([H|Bag], Set, [H|Dups]):-
set_(Bag, Set, Dups),
member(H, Set).
set(Bag, Set, Rest):-
reverse(BagR, Bag),
set_(BagR, SetR, RestR),
reverse(SetR, Set),
reverse(RestR, Rest).
set(Bag, Set):- set(Bag, Set, _).
但是我对这3个reverse/2
并没有什么印象。有人可以帮助我找到更优雅的解决方案吗?
我先尝试做一个右递归解决方案,但是试图证明问题可以“继续”会陷入困境。例如,如果我叫set_([1,2,1], L, R)
,则证明set(_, [1,2|_], [1|_]).
会卡住。如果您有关于如何避免这种情况的反馈,请告诉我!
foldl/4
:pushForward(X, [Set0, Rest], [Set, Rest]):-
\+ member(X, Set0),
append([Set0, [X]], Set).
pushForward(X, [Set, Rest0], [Set, Rest]):-
member(X, Set),
append([Rest0, [X]], Rest).
set(Bag, Set, Rest):- foldl(pushForward, Bag, [[],[]], [Set, Rest]).
set(Bag, Set):- set(Bag, Set, _).
由于您正在学习该语言,因此我不会显示完整的解决方案。