使用带有内联谓词或“lambda”的“findall”的 Prolog 过滤列表

问题描述 投票:0回答:1

我有这个数据(数据是从 csv 读取的,它必须看起来像这样,又名术语列表,而不是数据库中定义的简单术语):

Rows = [row('A', 150), row('B', 300), row('C', 50)].

现在我希望按值过滤它们,我想做的就是这样(直接作为查询):

?- findall(Row, (member(row(Name, Value), Rows), Value > 50), Filtered).

但是这不起作用并给出:

?- Rows = [row('A', 150), row('B', 300), row('C', 50)], 
findall(Row, (member(row(Name, Value), Rows), Value > 50), Filtered). 
Rows = [row('A', 150), row('B', 300), row('C', 50)],
Filtered = [_, _].

目前唯一的方法是将它们放入文件中:

% Code.pl

% Have to provide this as a predicate
filter(Row, Rows) :-
    Row = row(_, Value),
    member(Row, Rows), 
    Value > 50.

% Also wanted to declare the following
% Neither works:
% data = [row('A', 150), row('B', 300), row('C', 50)].
% Rows = [row('A', 150), row('B', 300), row('C', 50)].

那么我可以做:

?- Rows = [row('A', 150), row('B', 300), row('C', 50)], findall(Row, filter(Row, data), Filtered).

# Or alternatively, wished to do:
?- findall(Row, filter(Row, data), Filtered).

另一方面,在起草这个例子时我遇到了这个问题:

% Wanted to put data directly inside code file, then query directly
% Neither works:
% data = [row('A', 150), row('B', 300), row('C', 50)].
% Rows = [row('A', 150), row('B', 300), row('C', 50)].

我有两个关于语法的问题:

  1. 如何将数据作为术语列表直接放入代码文件中(出于本示例的目的)?
  2. 对于查询,是否有办法实现我想要的,而不必将所有内容都放入脚本文件中? IE。
    Rows = [row('A', 150), row('B', 300), row('C', 50)], findall(Row, (member(row(Name, Value), Rows), Value > 50), Filtered).

备注:

syntax prolog swi-prolog
1个回答
0
投票

不需要辅助谓词或 lambda 表达式:

?- Rows = [row('A', 150), row('B', 300), row('C', 50)],
   findall(Row, (member(Row,Rows), Row = row(Name, Value), Value > 50), Filtered).
Rows = [row('A', 150), row('B', 300), row('C', 50)],
Filtered = [row('A', 150), row('B', 300)].
© www.soinside.com 2019 - 2024. All rights reserved.