我想知道 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) 只有在它们不是其他 bar(A, _) 但我得到“规则不安全”的情况下。还尝试计算出现次数和出现类似问题...
最重要的是,是否有可能在没有那么多技巧的情况下一次获得我期望的结果?
任何帮助表示赞赏,
谢谢!