“-"是什么意思?处理列表时,Prolog 中的符号是什么意思? [英] What does the "-" symbol mean in Prolog when dealing with lists?

查看:165
本文介绍了“-"是什么意思?处理列表时,Prolog 中的符号是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读这个的答案 问题,

p(X) :- read(A), q(A,X-[]).

q(end,X-X) :- !.    
q(A,[A|X]-Y) :- read(B), q(B,X-Y).

上面的代码使用语法List-List.我有点明白发生了什么,但我想知道-"符号/谓词在这里做了什么.另外,这个 SWI 是特定的吗?

The code above uses the syntax List-List. I somewhat understand what is going on, but I want to know what exactly what the "-" symbol/predicate does here. Also, is this SWI specific?

推荐答案

(-)/2 表示差异列表是一个相当不常见的约定.在旧书中,还使用了另一个运算符 (\)/2.

The (-)/2 to represent difference lists is a rather uncommon convention. In older books, another operator (\)/2 was used too.

许多人更喜欢使用两个单独的参数.与使用运算符相比,有几个优点:

Many prefer to use two separate arguments instead. There are several advantages compared to using an operator:

  1. 谓词不能意外地与参数的未实例化变量一起使用.考虑调用 q(A, X) 代替 q(A, X-[]).

使用两个参数时,执行效率甚至更高.许多系统,如 SWI,必须动态创建每个 (-)/2 结构.

Execution is even a bit more efficient when using two arguments. Many systems, like SWI, have to create each (-)/2 structure dynamically.

尽管如此,还有另一种使用差异列表的方法,这种方法通常不太容易出错:您可以使用 用于此目的.

Nevertheless, there is also another way to use difference lists, which is often less error-prone: You might use a dcg for this purpose.

其实程序有两个错误,一个是差异列表的处理方式造成的.另一个错误是程序不处理文件尾.最好使用 end_of_file 代替 end.但你迟早会发现这是肤浅的.

In fact, there are two errors in the program, one of which is caused by the way how difference list are handled. The other error is that the program does not handle end-of-file. It would be better to use end_of_file in place of end. But that's a superficial thing you would have found yourself sooner or later.

另一个更微妙的错误是由于差异列表和剪辑之间的相互作用.我不是裁员的忠实粉丝,但让我们看看这条规则.在执行完其左侧的所有内容后进行剪切.

The other, more subtle error is due to the interaction between difference lists and the cut. I am not a big fan of cuts, but let's look into that rule. A cut cuts after everything to its left-hand-side has been executed.

q(end_of_file,X-X) :- !.

第一个参数是原子end_of_file.由于我们使用 q/2 仅将 read/1 的结果作为第一个参数,所以这只能是一个比较.所以我们在文件(或流)的末尾.然而,还有一些事情必须坚持下去.只有当它们也成功时,才会执行切割:第二个参数必须是 (-)/2 (好吧,在所有地方都有一个减号).然后: (-)/2 的两个参数必须相同(必须统一).为什么?我们在文件的末尾,但如果这些参数不统一,将尝试其他规则.

The first argument is the atom end_of_file. Since we are using q/2 only with the result of read/1 as first argument, this can only be a comparison. So we are at the end of the file (or stream). Then, however, there are further things that must hold. And only if those succeed as well, will the cut be executed: The second argument must be a (-)/2 (ok, in all places there is a minus at its place). And then: The two arguments of (-)/2 must be the same (must unify). Why? We are at the end of the file, but if those arguments do not unify, the other rule will be tried.

这是什么时候发生的?这是一个令人讨厌的案例:

When does this happen? Here is such a nasty case:

p([X,Y,Z]).

只需输入一个常量,例如 my_constant.,然后按 Cntrl-dCntrl+z.在这种情况下 p/1 应该怎么做?理想情况下,它会在您完成输入后失败.但是,它将等待进一步的输入.

And simply enter a single constant, say my_constant. and then press Cntrl-d or Cntrl+z. What should p/1 do in such a case? Ideally, it would fail after you finished the input. However, it will wait for further input.

原因是切口放置不当.我们说p/1 并不坚定.这是 Prolog 程序中的常见错误.我只能建议减少切割的使用和 DCG 的采用.使用 DCG,这不会发生:

The reason is the inappropriate placing of the cut. We say that p/1 is not steadfast. This is a common error in Prolog programs. I can only recommend to reduce the usage of cuts and the adoption of DCGs. With DCGs, this cannot happen:

p2(X) :- read(A), phrase(q2(A),X).

q2(end_of_file) --> !.
q2(A) --> [A], {read(B)}, q2(B).

对于 DCG,无论 p/1 的参数如何,都会执行剪切.

With DCGs, the cut is executed regardless of the argument of p/1.

这篇关于“-"是什么意思?处理列表时,Prolog 中的符号是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆