我想知道在DLV中是否有一种方法可以创建一个列表,其中包含规则中所有为真的谓词的元素。例如,如果我有以下谓词
foo(a, b).
foo(a, c).
foo(a, e).
foo(b, c).我正在寻找的结果应该是新的谓词,其中第一个元素是foo的第一个参数,第二个参数应该包含一个列表,其中所有元素都与第一个参数相关联。从经验上看:
bar(a, [b,c,e]).
bar(b, [c]).我知道有一种方法可以通过以下代码获得这些结果(以及更多):
bar(A, [X]) :- foo(A, X).
bar(A, P ) :- bar(A, P0),
foo(A, X),
not #member(X, P0),
#insLast(P0, X, P).但我想知道是否有一种方法可以防止生成大小从1到N(N是最终列表的元素数量)的所有可能的列表。我想这么做有两个原因:(1)减少计算成本(2)防止丢弃所有不必要的谓词。
如果计算成本不是问题(可能是这种情况),我正在考虑以下更改,以便只保留具有最大列表的谓词:
tmp_bar(A, [X], 1) :- foo(A, X).
tmp_bar(A, P, L) :- tmp_bar(A, P0, L0),
foo(A, X),
not #member(X, P0),
#insLast(P0, X, P),
L = L0 + 1.
bar(A, P) :- tmp_bar(A, P, L),
max_list(A, L).
max_list(A, L) :- foo(A, _),
#max{X: tmp_bar(A, P, X)} = L.然而,这开始变得复杂,并且显示了所有最大大小的列表,而不仅仅是其中的一个。除了一个,我怎么才能处理掉所有的?我尝试生成bar(A,P),但得到的结果是“规则不安全”。还尝试计算出现的次数和出现的类似问题...
最重要的是,有没有可能在没有那么多花招的情况下一下子得到我想要的结果?
任何帮助我们都很感激,
谢谢!
发布于 2016-09-23 18:15:12
显然,我通过按特定顺序添加元素找到了问题的解决方案。我所做的是,只有当元素小于当前列表的最后一个元素时,才将其添加到列表的末尾。我处理的是名字而不是数字,所以我认为这是不可能的)。
代码如下:
tmp_bar(A, [X], 1) :- foo(A, X).
tmp_bar(A, P, L) :- tmp_bar(A, P0, L0),
foo(A, X),
#last(P0, Y),
Y < X,
#insLast(P0, X, P),
L = L0 + 1.
bar(A, P) :- tmp_bar(A, P, L),
max_list(A, L).
max_list(A, L) :- foo(A, _),
#max{X: tmp_bar(A, P, X)} = L.希望将来能对其他人有所帮助。
https://stackoverflow.com/questions/39655922
复制相似问题