如何创建一个从列表中获取特定种类原子的谓词?

时间:2013-12-02 20:41:34

标签: list integer prolog predicate

我想创建的谓词应该从列表中选取一种特定的原子, 例如整数。

prolog应该回答以下请求:

select_integers([1,g,5,k,8], X). 

X = [1,5,8].

这个谓词还应该能够选择两种不同的原子,例如:整数和字母。

select([1,g,5,k,8], X, Y).

X = [1,5,8]

Y = [g,k].

不幸的是,我创建谓词的尝试失败了......非常感谢!

2 个答案:

答案 0 :(得分:2)

您可以使用包含三个子句的单个规则来执行此操作:

  1. “base”子句表示从空列表中选取整数会产生一个空列表。
  2. 第二个子句说从以整数开始的列表中选取整数会产生列表,其head元素等于源列表的初始元素,而尾部则通过递归调用相同的规则生成
  3. 最后一句说明从 not 中以整数开始的列表中选择整数与从该列表的尾部选择整数相同。
  4. 以下是如何操作的示例:

    select_integers([],[]).
    select_integers([H|T], [H|R]) :- integer(H), select_integers(T, R).
    select_integers([H|T], R) :- \+ integer(H), select_integers(T, R).
    

    Demo on ideone

答案 1 :(得分:1)

如果您正在使用SWI-Prolog,则可以使用include/3为个别情况实现此目的:

?- include(integer, [1,a,2,z,3,b,b], S).
S = [1, 2, 3].

include/3在列表的每个元素上调用谓词integer/1,并在S中收集call(integer, X)为真的元素X(您可以使用{{1}自己编写此谓词}和解决方案的骨架提供了dasblinkenlight)。

有了这个谓词,我们可以轻松编写一个谓词,让我们多次在列表上调用call/1,每次使用不同的类型:

include/3

此谓词将类型列表作为其第一个参数,并将列表列表作为其第三个参数。后者中的每个列表都包含给定类型的select_type([], _, []). select_type([Type|Types], List, [S|Selected]) :- include(Type, List, S), select_type(Types, List, Selected). 中的元素。因此可以使用:

List

当然,这种谓词不一定局限于内置类型,但可以使用任何谓词列表,这些谓词有额外参数的空间。如,

?- select_type([integer, atom, var, float, is_list], [2.112,A,3.111,A,B,a,2,3,s,d], X).
X = [[2, 3], [a, s, d], [A, A, B], [2.112, 3.111], []].

因为?- select_type([plus(2,2)], [1,2,3,4,5,6], X). X = [[4]]. 是真的。


修改

要更直接地回答您的问题,并根据您在评论中的澄清,您可以编写一个类似于您提议的call(plus(2,2), 4)的谓词:

select/3

如您所见,这相当于连续两次调用select_int_atom(List, Int, Atom) :- include(integer, List, Int), include(atom, List, Atom). 。请注意,如mbratch所述,您不希望将include/3用于谓词,因为核心库中已有select