Prolog:过滤列表?

发布于 2024-07-08 21:16:47 字数 622 浏览 5 评论 0原文

我目前正在 Prolog 上开发一个非常短的项目,并且在尝试将我创建的“过滤器”应用到列表时陷入困境。 我已经准备好了你所说的过滤器,但我无法应用它。 如果我说明一下会更好:

filter(A, B) 

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

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

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

我已经准备好“过滤器”函数,但现在我需要将其应用到第二个示例中所示的列表,排除在应用第一个参数时过滤器返回 true 的所有元素。

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

我在该函数的基本结构方面遇到了麻烦,因此如果有人可以提供此类函数的基本轮廓,那将会有很大的帮助。 我已经尽可能地简化了我的情况,这样我就可以利用您可能提供的任何内容,并根据我的需要进行修改。

提前致谢!

I'm currently working on a very short project on Prolog, and just got stuck trying to apply a "filter" I have created to a list. I have what you could call the filter ready, but I can't apply it. It'd be better if I illustrate:

filter(A, B) 

...outputs 'true' if certain conditions are met.

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

...outputs a list which includes all elements from the second argument that make the filter output false. (So if filter(A, X) is true, the output is [Y, Z] ).

I have the "filter" function ready, but now I need to apply it to a list as shown on the second example, excluding all elements for which the filter returns true when applied with the first argument.

So, if the filter is a simple A == B, the function is supposed to receive A [A,B,A,C,D,A] and output [B,C,D], having removed all the elements for which the filter applies, obviously.

I'm having trouble with the basic structure of the function, so if anyone could supply a basic outline for a function such as this it would be of great help. I've simplified my situation as much as possible so I can take whatever you may be able to provide and modify it for my needs.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

在你怀里撒娇 2024-07-15 21:16:47

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].

SWI-Prolog offers exclude/3 and other such meta-predicates. Your original problem can be coded like this:

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

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

Usage example:

?- filterList(A, [A, B, A, C, D, A], Out).
Out = [B, C, D].
倥絔 2024-07-15 21:16:47

如果您正在 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 阶逻辑成为可能。

If you are searching for higher-order functions in Prolog, you should definetly consult Naish (1995), a very good resource on this.

His definition of filter/3 is the following (he uses difference-list notation, therefore escapes having to define filter/4):


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

I you have questions about this predicate, please ask me in the comment. Reading the paper is also highly recommended, it also definess map, foldr and compose! Note that many of the limitations he mentions (like, for example a missing call/3 or a higher-order apply do not apply anymore. SWI-Prolog has the =.. operator, which addresses all of his concerns and makes arbitrary n-order logic possible.

天涯离梦残月幽梦 2024-07-15 21:16:47

以谓词的成功或失败作为过滤标准的过滤函数存在一个固有的问题:生成的程序不再是纯粹的单调程序。 因此,它失去了所有的声明性属性——唯一剩下的意义是程序性的逐步解释。 这是使用 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).
   X = A, B = X, Xs = [X,X]
;  X = A, Xs = [X], dif(X,B)
;  X = B, Xs = [X], dif(X,A)
;  Xs = [], dif(X,A), dif(X,B).

有四种可能性可以通过等于 X 的标准来过滤两个元素的列表。 每个元素可能相同也可能不同。

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

There is an inherent problem with filter functions that take the success or failure of a predicate as criterion for filtering: The resulting program is no longer a pure monotonic program. It therefore loses all its declarative properties — the only meaning that remains is a procedural step-by-step interpretation. Here is a pure, reified version of filtering using 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).

The first argument is thus a closure/continuation that will receive two further arguments: The element and the resulting truth value.

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

Now, results remain precise:

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

There are four possibilities how a list of two elements can be filtered by the criterion of being equal to X. Each element might be equal or might be different.

The downside of this approach is that one has to provide reified versions of all criteria.

苏佲洛 2024-07-15 21:16:47

好吧,你知道什么,我刚刚想通了。 因此,我在这里提交了我自己问题的答案,正如预期的那样,一个非常短的函数完成了这项工作:

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.
   ).

Well what'd you know I just figured it out. So, here's me submitting an answer to my own question, as expected a really short function did the job:

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.
   ).
数理化全能战士 2024-07-15 21:16:47

我得到一个国家的成年人 // 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)

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

I get the adults of a country // 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)

This is a filter in prolog // Asi es un filter en prolog

以往的大感动 2024-07-15 21:16:47
filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文