在Prolog中过滤列表

时间:2013-02-11 13:32:07

标签: prolog filtering

我正在开发一个用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 -let的说法 - “风格”的评论。

2 个答案:

答案 0 :(得分:7)

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

include(check_conditions,Lst, Success)

答案 1 :(得分:4)

你的基本递归应该写

filter([],[]).

你有一个错字

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

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