Setof每次返回列表,prolog

时间:2014-10-22 08:58:51

标签: prolog prolog-setof

我使用的谓词如下:

predicate(Country, X):-
    setof(Length, anotherPredicate(Country,Length), X).

我的问题是我的代码返回每个值的列表X.我想要的是返回一个包含所有数字的大清单,因为现在我得到了答案:

Country = adsfsadf;
X = [123];
Country = asfdsaf;
X = [312];

因此,每次我想要一个包含所有内容的大列表时,不要使用小列表。

编辑评论----------

predicate(Country, Length) :-
   setof(p(ML,C,L),
      ( anotherPredicate(C, L), ML is -L ),
      [p(_,Country, Length)|_]).

这就是我写的,它立即给我错误。

2 个答案:

答案 0 :(得分:3)

目前,您为Country的每个解决方案获得一个列表。就是这样,因为setof/3标识所有自由变量并为这些变量的每个不同实例化生成一个列表。

但你要问的是不一致的。一方面,您只想拥有一个列表。只要您可以轻松构建解决方案集,这很容易提供。

 setof(Length, Country^anotherPredicate(Country,Length), X).

另一方面,您仍然希望Country变量作为predicate/2的第一个参数出现!这没有任何意义。只不过坚持认为局部变量存在于外部环境中。不幸的是,Prolog没有直接检测到这样的错误。适用于

predicate(Country, X):-
    setof(Length, Country^anotherPredicate(Country,Length), X).

?- predicate(C, L).
L = [length_of_1, length_of_2].

?- C = c1, predicate(C, L).
C = c1,
L = [length_of_1].

也就是说,通过专门化目标(通过添加C = c1),可以找到不同的L

但有一点需要注意:如果有两个长度相同的国家,比如23,结果应该是什么?您想要一个元素[23]还是两个[23,23]?从您的描述中不清楚这一点。

如果你想要两个,你必须先确定:

setof(Country-Length, anotherPredicate(Country, Length), CL),
keys_values(CL, Lengths),
...

编辑:回复您的评论:

biggestcountry_val(Country, Length) :-
   setof(p(ML,C,L),
      ( anotherPredicate(C, L), ML is -L ),
      [p(_,Country, Length)|_]).

答案 1 :(得分:1)

如果没有一些样本数据和预期/期望的结果,就很难说出你需要什么。但是......检查谓词中的参数状态可能会为您提供所需的内容。

例如,鉴于此数据:

foo( albania ,  1 ) .
foo( albania ,  2 ) .
foo( albania ,  3 ) .
foo( albania ,  4 ) .
foo( albania ,  5 ) .
foo( albania ,  6 ) .
foo( iceland ,  4 ) .
foo( iceland ,  5 ) .
foo( iceland ,  6 ) .
foo( iceland ,  7 ) .
foo( iceland ,  8 ) .
foo( iceland ,  9 ) .
foo( france  ,  7 ) .
foo( france  ,  8 ) .
foo( france  ,  9 ) .
foo( france  , 10 ) .
foo( france  , 11 ) .
foo( france  , 12 ) .

您对问题中显示的内容的初步裁减

predicate(Country, X):-
  setof(Length, foo(Country,Length), X).
Country作为未绑定变量调用时,

返回这些多个结果:

?- predicate(Country,X).
Country = albania , X = [1, 2, 3, 4, 5, 6] ;
Country = france  , X = [7, 8, 9, 10, 11, 12] ;
Country = iceland , X = [4, 5, 6, 7, 8, 9] .

如果在Country被绑定到有效国家/地区iceland的情况下调用此单一结果,则在这种情况下:

?- predicate(iceland,X).
X = [4, 5, 6, 7, 8, 9].

但是,如果您这样做,

predicate( C , Xs ) :- var(C)    , setof( X , C^foo(C,X) , Xs ) .
predicate( C , Xs ) :- nonvar(C) , setof( X ,   foo(C,X) , Xs ) .

当参数未绑定时,您将获得此解决方案:

?- try_this(C,Xs).
Xs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ;
false.

您会注意到C仍未绑定。

当参数绑定时,你会得到这个结果:

?- try_this(iceland,Xs).
Xs = [4, 5, 6, 7, 8, 9].