Prolog 我怎样才能使它更具逻辑性?
我试图从以下方面解决以下问题: 编写一个谓词集(InList,OutList),它接受一个任意列表作为输入,并返回一个列表,其中输入列表的每个元素只出现一次。例如,查询Prolog 我怎样才能使它更具逻辑性?,prolog,Prolog,我试图从以下方面解决以下问题: 编写一个谓词集(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(
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个反向/2
并不感兴趣。有人能帮我想出一个更优雅的解决办法吗
我试图先做一个正确的递归解决方案,但它在试图证明问题可以“继续”时会陷入困境。例如,如果我调用set([1,2,1],L,R)
,它将无法证明set([1,2,2,1],[1,1])。
。如果您有关于如何避免这种情况的反馈,请告诉我
编辑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, _).
然而,这并没有真正触及问题的核心。我希望能够指定模型之间的关系,并询问“这些孔适合什么”。这个解决方案的作用正好相反——它接受一些值并将它们咀嚼,直到我们无事可做——这应该是Prolog的工作,而不是我的工作 在Prolog中,追求最简单的解决方案总是值得的,所以
- 使用简单的递归将元素从InList复制到累加器,前提是它们尚未存在
- 将生成的累加器反转为“超出显示”
由于您正在学习该语言,我将不展示完整的解决方案。名称不理想。使用
库(reif)
:
是的,这就是反面已经在做的事情。我试图避免更多的累加器,因为
Set
和Rest
感觉它们应该给我所有需要的记忆。在回顾中,我想我应该使用append/2
,而不是坚持在子句标题中加前缀。什么是“Onlus 1遍历”?很抱歉,输入错误,在单元格中,无法编辑注释。我的意思是“只有一个反面”。类似于set(L,S):-set(L,[],A),reverse(A,S)。
啊,我明白了,对不起!
list_nub([], []).
list_nub([E|Es], [E|Gs]) :-
tfilter(dif(E), Es, Fs),
list_nub(Fs, Gs).
?- Xs = [_,_,_], Ys = [_,_], list_nub(Xs, Ys).
Xs = [_A,_A,_B], Ys = [_A,_B], dif(_A,_B)
; Xs = [_A,_B,_A], Ys = [_A,_B], dif(_A,_B)
; Xs = [_A,_B,_B], Ys = [_A,_B], dif(_A,_B)
; false.
?- Xs = [_,_,_], Ys = [_], list_nub(Xs, Ys).
Xs = [_A,_A,_A], Ys = [_A]
; false.
?- Xs = [_,_,_], Ys = [_,_,_], list_nub(Xs, Ys).
Xs = [_A,_B,_C], Ys = [_A,_B,_C], dif(_A,_B), dif(_A,_C), dif(_B,_C).
?- dif(A,B), Xs = [A|_], Ys = [B|_], list_nub(Xs, Ys).
false.