Dynamic 动态检查成员资格swi prolog

Dynamic 动态检查成员资格swi prolog,dynamic,prolog,membership,Dynamic,Prolog,Membership,给定一个自然数列表list我想检查每个子集的元素之和是否不同。最初我使用这个代码 distinctSubsetSums(List,Sums) :- findall(Sum,(subset(Sub,List),sum_list(Sub,Sum)),Sums), all_distinct(Sums). 但我认为存在一个更好的解决方案,因为在我的代码中,我找到了所有可能子集的所有和,然后检查它们是否不同。我认为有一种方法可以动态检查是否已经计算了一个和,然后返回false,而不搜索所有子集 有人能帮

给定一个自然数列表
list
我想检查每个子集的元素之和是否不同。最初我使用这个代码

distinctSubsetSums(List,Sums) :- findall(Sum,(subset(Sub,List),sum_list(Sub,Sum)),Sums), all_distinct(Sums).
但我认为存在一个更好的解决方案,因为在我的代码中,我找到了所有可能子集的所有和,然后检查它们是否不同。我认为有一种方法可以动态检查是否已经计算了一个和,然后返回
false
,而不搜索所有子集


有人能帮我吗?

您使用此代码得到了什么结果?它有用吗?当你说你认为有一个更好的解决方案时,你所说的“更好”是什么意思
all_distinct/1
仅在CLP(FD)`上下文中工作。检查文档。它建立了一个约束,即列表中的所有元素都是不同的。它不会通过或失败,这取决于列表中的元素是否不同。因此,如果您拥有的东西确实不起作用,请为列表编写您自己的
all_different/1
谓词。是的,我正在使用
clpfd
库,代码可以工作。使用
?-trace.
我试图查看此列表
[3,2,1]
的结果。计算总和的子集顺序为:
[3,2,1]
[3,2]
[3,1]
[3]
[2,1]
[2]
[1]
[]。只有这样,它才会检查此列表是否有不同的元素,因为它包含两个
3
。我想要的是在搜索时检查重复项,以便谓词在找到的第五个子集处失败(
[2,1]
将给出一个
3
的总和,就像
[3]
所做的那样)。您可以编写一个递归谓词,该谓词获取子集列表,以及迄今为止的总和列表。每次调用时,计算当前子集的和,并检查它是否不在列表中。最后是唯一和的列表。然后你可以看看交错求和和和检查子集的生成,这样你只有一个谓词。你说我必须在求和之前找到所有子集?我想要的是找到一个子集->计算总和->检查它是否重复->如果是,则失败。如果没有,请找到下一个子集并重新启动
subset_sums(List,Sums) :-
  sum_subset(List,[],[],Sums).

sum_subset([I|Is],Js,Sums0,Sums) :-
  sum_subset(Is,Js,Sums0,Sums1),
  sum_subset(Is,[I|Js],Sums1,Sums).
sum_subset([],Js,Sums0,Sums) :-
  sum_list(Js,Sum),
  \+ member(Sum,Sums0),
  Sums = [Sum|Sums0].