过滤器关联表prolog
我需要编写include_assoc/3谓词,该谓词使用给定谓词(第一个参数)过滤关联数组(第二个参数),并将结果写入第三个参数。谓词的作用应该类似于include/3。筛选器谓词应使用键值对作为参数 在筛选之前,我无法将表更改为列表。 我怎么做 我的代码过滤器关联表prolog,prolog,meta-predicate,Prolog,Meta Predicate,我需要编写include_assoc/3谓词,该谓词使用给定谓词(第一个参数)过滤关联数组(第二个参数),并将结果写入第三个参数。谓词的作用应该类似于include/3。筛选器谓词应使用键值对作为参数 在筛选之前,我无法将表更改为列表。 我怎么做 我的代码 include_assoc(_,X,_):- empty_assoc(X),!. include_assoc(Filtr,Tab,Result):- min_assoc(Tab,Key,Value), del_min_
include_assoc(_,X,_):-
empty_assoc(X),!.
include_assoc(Filtr,Tab,Result):-
min_assoc(Tab,Key,Value),
del_min_assoc(Tab,_,_,Tab1),
(call(Filtr,Key-Value) ->
(include_assoc(Filtr,Tab1,Result1),
put_assoc(Key,Result1,Value,Result));
include_assoc(Filtr,Tab1,Result1)).
最简单的解决方案是将其转换为列表,使用谓词过滤列表,然后构造一个新的assoc
:- use_module(library(assoc)).
:- use_module(library(apply)).
filter_assoc_l(Filter, In, Out) :-
assoc_to_list(In, List),
include(Filter, List, OutList),
list_to_assoc(OutList, Out).
你显然不能这样做。但是您仍然需要一种方法来迭代assoc的所有项,而不进入一个失败驱动的循环,该循环将在每次失败后撤消绑定gen_assoc
将为您提供所有密钥,但您要么必须使用findall/3
(与将其转换为列表相同),要么每次绑定后都必须失败(撤消工作)
这里的另一种方法是仅获取键列表,然后在值与筛选器不匹配时使用删除谓词来删除这些值。首先,我们需要获取键,然后调用一个助手谓词来遍历键列表:
filter_assoc_unlist(Filter, In, Out) :-
assoc_to_keys(In, Keys),
filter_assoc_keys(Filter, In, Keys, Out).
现在,我们可以检索当前键/值(键列表的头部),然后调用过滤器谓词来检查它。如果它过去了,我们只是重复;如果失败,我们将其删除,并将删除结果传递到递归步骤
filter_assoc_keys(Filter, In, [Key|Keys], Out) :-
min_assoc(In, Key, Value),
(call(Filter, Key-Value) ->
filter_assoc_keys(Filter, In, Keys, Out)
;
del_assoc(Key, In, _, Next),
filter_assoc_keys(Filter, Next, Keys, Out)
).
当我们用完键时,输入就是输出:
filter_assoc_keys(_, Out, [], Out).
我不知道这是否符合您的标准,但我希望它符合。请与我们分享您的尝试,我们将帮助您摆脱困境。@Daniel Lyons我粘贴了代码What's
Wynik
?@DanielLyons哦,对不起,我的oryginall代码中有其他变量名称,但现在我引入了一些更改,看起来它正在工作