【问题标题】:Filter a list in Prolog在 Prolog 中过滤列表
【发布时间】:2013-02-11 13:32:07
【问题描述】:

我正在开发一个用 Prolog 编写的应用程序。我想过滤一个元素列表并删除那些不满足特定约束或条件的元素,保持原始列表顺序。我认为最好的方法是这样的:

filter([],Filtered).
filter([L|List],[F|Filtered]) :-
    /* Conditions are met: bypass the element to the filtered list */
    check_conditions(L),
    filter(List,Filtered).
filter([L|List],Filtered) :-
    /* Conditions are not met: do not include the element in the filtered list */
    filter_aborts(List,Filtered).

在接受它作为我的问题的解决方案之前,我想尝试一下(独立地),所以我编译并运行了我的代码(SWI-Prolog)并测试了一些情况。当我使用硬编码列表(或任何您想称呼它的名称)输入 Prolog 查询时,我得到如下内容:

?- filter([id01,id02,id03,id04,id05,id06],F).
F = [id03, id05, id06|_G1024] .

该列表肯定被过滤了,但我在它的末尾得到了这个实例名称“_G1024”。我知道发生这种情况是因为 F 没有实例化,但我不知道解决方案是什么。此外,如果我尝试做一些不同的事情,比如将列表作为实例化变量输入,我得到的就更奇怪了:

?- L=[id02,id03,id04,id05,id06].
L = [id02, id03, id04, id05, id06].

?- filter(L,F).
L = [] ;
L = [id01],
F = [id01|_G347] ;
L = [id01, id01],
F = [id01, id01|_G403] 
... and so on.

Prolog 变量不应该是一次赋值变量吗?我的程序是否真的改变了L 或者我没有正确理解它?其中的一部分,因为我是 Prolog 的新手,我会很感激任何关于我的 Prolog 的评论 - 比如说...... - “风格”。

【问题讨论】:

    标签: prolog filtering


    【解决方案1】:

    您使用 SWI-Prolog,因此您可以根据自己的条件编写成功或失败的谓词,然后使用 include(Predidate, Lst, Success) 。例如

    include(check_conditions,Lst, Success)
    

    【讨论】:

    • 你是对的 (+1) 呈现的谓词最好用 include/3 编写,但我最终自己编写了一个 filter/3 因为我想要(为了提高效率)能够更改接受的元素
    • 坦克@joel76!我不知道这个include/3 谓词。我将在这里使用它,因为它完全符合我的需求。
    【解决方案2】:

    你的基本递归应该写成

    filter([],[]).
    

    你有一个错字

    filter([L|List],[L|Filtered]) :-
    ...
    

    你有单例 F 而不是(第二个)L

    【讨论】:

    • 我正要评论我在阅读您的答案时发现了(愚蠢的)错误。非常感谢,这是错误的!即便如此,第二个错误的原因是什么?
    • 我在写下这个问题时想到了一个错字,因为编写的程序会输出一个未实例化变量的列表
    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    相关资源
    最近更新 更多