如何创建从列表中提取特定种类原子的谓词



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

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].

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

您可以使用一个包含三个子句的规则:

  1. "base"子句表示,从空列表中挑选整数会生成一个空列表
  2. 第二个子句说,从一个以整数开头的列表中挑选整数会生成一个列表,该列表的head元素等于源列表的初始元素,tail元素由递归调用同一规则生成
  3. 最后一个子句说,从一个不以整数开头的列表中挑选整数与从该列表的尾部挑选整数相同

下面是一个如何做到这一点的例子:

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).

在ideone上演示。

如果您使用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(您可以使用call/1和提供的解决方案的框架dasblinkenlight自己编写此谓词)。

有了这个谓词,我们可以很容易地编写一个谓词,让我们多次调用列表上的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]].

因为CCD_ 8为真。


编辑:

为了更直接地回答你的问题,并根据你在评论中的澄清,你可以写一个类似于你提出的select/3的谓词:

select_int_atom(List, Int, Atom) :-
    include(integer, List, Int),
    include(atom, List, Atom).

正如您所看到的,这相当于连续两次调用include/3。请注意,正如mbratch所指出的,您不希望将select用于谓词,因为核心库中已经有一个select/3

最新更新