2016-11-28 70 views
1

我有一个谓词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

这似乎是一个作品setof/3

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

---编辑---

的OP说

这并做到这一点,但它是一个有点哈克修补程序,我正在寻找在下一个谓词的变化

我不认为这是一个很好的解决方案下面,我怀疑这是更好地利用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]). 

--- EDIT 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). 
+0

该做到的,但它是一个有点哈克修复,我期待在未来谓词 – user3667111

+0

的改变@ user3667111 - 如果你要求改变它,你应该告诉我们你的'下一个/ 2' – max66

+0

当然,我已经添加到编辑 – user3667111