我想知道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.
然而,这开始变得复杂并且显示了所有最大尺寸的列表,而不仅仅是其中一个。除了一个以外我怎么摆脱?我尝试生成条形码(A,P),以防它们没有其他条形(A,_),但我得到“规则不安全”。还尝试计算出现次数和类似问题...
最重要的是,如果没有那么多技巧,是否有可能获得我期望的结果?
感谢任何帮助,
谢谢!
答案 0 :(得分:0)
显然,我通过按特定顺序添加元素找到了解决问题的方法。我所做的是只在小于当前列表的最后一个元素时才在列表末尾添加元素。我正在处理名字而不是数字,所以我虽然这不可能。)
以下是代码:
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.
希望将来帮助其他人。