删除回溯中的重复项

时间:2016-11-28 22:26:39

标签: prolog

我有一个谓词next,它基本上从列表中删除了数字,试图减少列表的整体大小。

例如,我有一个列表:

[3,2,1]

接下来将从列表中删除某些值,因此它会返回类似这样的内容

[3,2] or [3,1] or [3] or [2,1] etc 

我正在运行一个脚本来查找所有可能的动作:

findall(T, next([2,3], T), U). 

问题出在一个重复值的列表,如:

L = [1,1,1,1].

电话

findall(T, next([1,1,1,1], T), U). 

U[[1,1,1], [1,1,1], [1,1,1], [1,1,1]]

统一起来

有没有办法让Prolog明白它多次返回相同的输出?

next([_ | T], T).
next([H | Tin], [H | Tout]) :- 
     next(Tin, Tout).

1 个答案:

答案 0 :(得分:1)

它似乎适用于setof/3

setof(T, next([1,1,1,1], T), U)

---编辑---

OP说

  

这确实可以,但它有点像hacky修复,我正在寻找下一个谓词的改动

我不认为以下是一个很好的解决方案,我怀疑最好将setof/3与原next/2一起使用但是......

next(Lin, LLout) :-
  nextH(Lin, [], LLout).

nextH([], _, []).
nextH([H | Tin], Pre, LLout1) :-
  append(Pre, Tin, L),
  append(Pre, [H], Pre0),
  nextH(Tin, Pre0, LLout0),
  ( member(L, LLout0) 
    -> LLout1 = LLout0
    ;  LLout1 = [L | LLout0] ).

---编辑2 ---

OP问

  

你怎么能在下一个谓词中使用setof?

如果您使用生成单曲列表的原始next/2谓词(但我记得nextH,“下一位帮手”)

nextH([_ | T], T).
nextH([H | Tin], [H | Tout]) :-
  nextH(Tin, Tout).

返回唯一列表列表的next/2谓词变为简单(使用setof/3

next(Lin, LLout) :-
  setof(Lout, nextH(Lin, Lout), LLout).