Loops 结果后的Prolog循环

Loops 结果后的Prolog循环,loops,prolog,declarative,failure-slice,declarative-programming,Loops,Prolog,Declarative,Failure Slice,Declarative Programming,所以我写这个谓词是为了找到列表中所有可能的子集+置换。 我得到了正确的输出,但由于某种原因,程序在给出所有(正确的)结果后继续循环 我做错了什么 % Gets all subsets of a list aSubset([], []). aSubset([E|Tail], [E|NTail]):- aSubset(Tail, NTail). aSubset([_|Tail], NTail):- aSubset(Tail, NTail). % gets all subsets and permu

所以我写这个谓词是为了找到列表中所有可能的子集+置换。 我得到了正确的输出,但由于某种原因,程序在给出所有(正确的)结果后继续循环

我做错了什么

% Gets all subsets of a list
aSubset([], []).
aSubset([E|Tail], [E|NTail]):- aSubset(Tail, NTail).
aSubset([_|Tail], NTail):- aSubset(Tail, NTail).

% gets all subsets and permutates them
allSubsets([],[]).
allSubsets(X, Res) :- permutation(S, Res), aSubset(X, S).
我得到的所有子集([1,2,3],X)的结果是:

我必须在最后两行中止循环

提前感谢。

不仅
所有子集([1,2,3],X)
循环,而且更短的
所有子集([],X)

以下程序片段()已循环。因此,无需进一步研究

allSubsets([],[]) :- false. allSubsets(X, Res) :- permutation(S, Res), false, aSubset(X, S). 所有子集([],[]):-false。 所有子集(X,Res):- 排列(S,Res),假, aSubset(X,S)。
要改进这一点,您需要更改可见部分中的某些内容。目前,只有Arg2(
Res
)可以影响目标
置换(S,Res)
,Arg1(
X
)只发生在第二个目标中,此时影响第一个目标的(通用)终止已经太晚了。

实现这一目标的一种方法是稍微修改当前代码:

% Gets all subsets of a list
aSubset([], []).
aSubset([E|Tail], [E|NTail]):- aSubset(Tail, NTail).
aSubset([_|Tail], NTail):- aSubset(Tail, NTail).

% gets all subsets and permutates them
allSubsets([],[]).
allSubsets(X, Res) :- aSubset(X, S), permutation(S, Res).
因此,与其先进行无界置换,不如先生成已知列表的子集(有限数量的解),然后置换已知子集(也是有限数量的解)。回溯将在所有子集的所有排列中执行此操作:

| ?- allSubsets([1,2,3], L).

L = [1,2,3] ? a

L = [1,3,2]

L = [2,1,3]

L = [2,3,1]

L = [3,1,2]

L = [3,2,1]

L = [1,2]

L = [2,1]

L = [1,3]

L = [3,1]

L = [1]

L = [2,3]

L = [3,2]

L = [2]

L = [3]

L = []

(2 ms) no
| ?-

由于我是prolog新手,我不太确定什么是解决方案。。我也不太明白我的想法中“错误”的部分是什么。@ValentijnSpruyt以另一种方式陈述:你对
permutation(S,Res)
的查询太“开放”。这两个参数都是可变的。回溯时,它将继续生成并尝试无限排列,元素数量不断增加。你需要约束它。@潜伏者:发布一个终止“尽可能好”的版本怎么样?让我们看看我们能走多远@瓦伦蒂恩斯普鲁伊特:你读过标签上的其他答案吗?哪个系统给你这个结果?我的意思是,在不同的
L
之间是否真的没有分号(
)?啊,可能是Prolog GNU。对吗?@falseYes,如果我在GNU中按“a”,它不会显示分号。它只是列出了所有的结果。
| ?- allSubsets([1,2,3], L).

L = [1,2,3] ? a

L = [1,3,2]

L = [2,1,3]

L = [2,3,1]

L = [3,1,2]

L = [3,2,1]

L = [1,2]

L = [2,1]

L = [1,3]

L = [3,1]

L = [1]

L = [2,3]

L = [3,2]

L = [2]

L = [3]

L = []

(2 ms) no
| ?-