DLV清单组成 [英] DLV list composition
问题描述
我想知道DLV中是否有一种方法可以创建包含规则中所有谓词的元素的列表.例如,如果我有以下谓词
I was wondering if there is a way in DLV for creating a list with the elements of all predicates that are true in a rule. For example, if I have the following predicates
foo(a, b).
foo(a, c).
foo(a, e).
foo(b, c).
我要查找的结果应该是新的谓词,其中第一个元素是foo
的第一个参数,第二个参数应包含一个列表,其中所有元素都与第一个参数相关联.凭经验:
The result I am looking for should be new predicates where the first element is the first parameter of foo
and the second parameter should contain a list with all the elements associated to the first parameter. Empirically:
bar(a, [b,c,e]).
bar(b, [c]).
我知道可以使用以下代码来获得这些结果(还有更多):
I know there is a way of getting these results (plus many more) with the following code:
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)防止丢弃所有不必要的谓词.
But I would like to know if there is a way of preventing the generation of all possible lists of size from 1 to N (being N the number of elements of the final list). I would like to do it for two reasons: (1) reduce computational cost (2) prevent discarding all unnecessary predicates.
如果不是计算成本问题(可能是这种情况),我正在考虑以下更改,以便仅保留具有最大列表的谓词:
If the computational cost was not a problem, which may be the case, I was thinking of the following changes in order to keep only the predicates with the largest lists:
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,_)的情况下才生成条形(A,P),但是我得到规则不安全".还尝试计算出现的次数,并出现类似的问题...
However, this starts to get complicated and is showing all of the lists of maximum size and not only one of them. How do I get rid of all but one? I tried generating bar(A,P) only in case their is no other bar(A, _) but I get "rule is not safe". Also tried counting the number of occurrences and similar problems appear...
最重要的是,没有那么多技巧,是否有可能一次获得我期望的结果?
Most importantly, is it possible to get the results I expect all at once without that many tricks?
感谢您的帮助,
谢谢!
推荐答案
显然,我发现了通过按特定顺序添加元素来解决该问题的方法.我要做的是仅在元素小于当前列表的最后一个元素时在列表的末尾添加元素.我是在处理名称而不是数字,所以虽然这是不可能的.
Apparently I found a solution to the problem by adding elements in a particular order. What I do is to add the element at the end of the list only if its smaller than the last element of the current list. I was dealing with names rather than numbers so I though this wasn't possible).
这是代码:
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.
希望它对以后的人有所帮助.
Hope it helps someone else in the future.
这篇关于DLV清单组成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!