过滤器关联表prolog

过滤器关联表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/3谓词,该谓词使用给定谓词(第一个参数)过滤关联数组(第二个参数),并将结果写入第三个参数。谓词的作用应该类似于include/3。筛选器谓词应使用键值对作为参数

在筛选之前,我无法将表更改为列表。 我怎么做

我的代码

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代码中有其他变量名称,但现在我引入了一些更改,看起来它正在工作