我目前正在开发一个关于Prolog的非常短的项目,并且试图应用<!>“过滤器<!>我创建了一个列表。我有你可以称之为过滤器的东西,但我无法应用它。如果我说明一下会更好:

filter(A, B) 

...如果满足某些条件,则输出'true'。

filterList(A, [X, Y, Z])

...输出一个列表,其中包含第二个参数中的所有元素,这些元素使过滤器输出 false 。 (因此,如果过滤器(A,X)为真,则输出为[Y,Z])。

我有<!>“;过滤器<!>”;函数就绪,但现在我需要将它应用于第二个示例所示的列表,排除在应用第一个参数时过滤器返回true的所有元素。

所以,如果过滤器是一个简单的A == B,该函数应该接收A [A,B,A,C,D,A]并输出[B,C,D],已经删除了所有的显然,过滤器适用的元素。

我遇到了函数的基本结构问题,所以如果有人能为这样的函数提供基本的大纲,那将会有很大的帮助。我尽可能地简化了我的情况,所以我可以根据自己的需要采取任何你能提供的东西并进行修改。

提前致谢!

有帮助吗?

解决方案

如果您在Prolog中搜索高阶函数,您应该明确地参考 Naish(1995),这是一个非常好的资源。

他对filter/3的定义如下(他使用差异列表表示法,因此不必定义filter/4):


filter(_,[],[]).
filter(P, A0-As0, As) :-
    (
        call(P, A0) -> As = A0-As1
    ;
        As = As1
    )
    , filter(P, As0, As1).

我对这个谓词有疑问,请在评论中问我。也强烈推荐阅读论文,它也蔑视mapfoldrcompose!请注意,他提到的许多限制(例如,缺少的call/3或更高阶apply不再适用.SWI-Prolog有=..运算符,它解决了他所有的问题并且随意n阶逻辑可能。

其他提示

SWI-Prolog提供exclude/3和其他此类元谓词。您的原始问题可以这样编码:

are_identical(X, Y) :-
    X == Y.

filterList(A, In, Out) :-
    exclude(are_identical(A), In, Out).

用法示例:

?- filterList(A, [A, B, A, C, D, A], Out).
Out = [B, C, D].

过滤函数存在一个固有的问题,它将谓词的成功或失败作为过滤的标准:结果程序不再是纯粹的单调程序。因此它失去了所有声明属性<!>#8212;剩下的唯一含义是程序性的逐步解释。以下是使用 if_/3 过滤的纯粹,具体的过滤版本:

tfilter(_CT_2,    [], []).
tfilter(CT_2, [E|Es], Fs0) :-
   if_(call(CT_2,E), Fs0 = [E|Fs], Fs0 = Fs ),
   tfilter(CT_2, Es, Fs).

第一个参数因此是一个闭包/继续,它将接收另外两个参数:元素和结果真值。

=(X,X,true).
=(X,Y,false) :- dif(X,Y).

现在,结果仍然准确:

| ?- tfilter(=(X),[A,B],Xs).
B = A,
X = A,
Xs = [A,A] ? ;
X = A,
Xs = [A],
dif(A,B) ? ;
X = B,
Xs = [B],
dif(B,A) ? ;
Xs = [],
dif(X,A),
dif(X,B) ? ;
no

有两种可能性,如何通过等于X的标准来过滤两个元素的列表。每个元素可能相同或可能不同。

这种方法的缺点是必须提供所有标准的具体版本。

嗯,你知道我刚才弄清楚了。所以,我在这里提交了一个自己问题的答案,正如预期的那样,一个非常短的函数完成了这项工作:

filterList(_,[],R,R).           % Returns answer when the list is exhausted.
filterList(L,[A|List],Temp,Res) :-
   filterList(L,List,New,Res),  % Recursive call, New is either the same list
   (  filter(L,A),              % in case the filter outputs true, or the list
      New = Temp
   ;  New = [A|Temp]            % plus the current element otherwise.
   ).

我得到了一个国家的成年人// Obtengo los adultos de un pais,Country = Pais,People = Personas,Person = una sola Persona

habitants(USA, [juan, pedro, david])

adults(Adults, Country) :-
     findall(Person, (habitants(Country,People), member(People, Person), adult(Person)), Adults)

这是prolog中的过滤器// Asi es un filter en prolog

filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top