周锡令经过几十年的全球性的努力,以机器翻译为代表的计算机自然语言处理工作始终没有达到人们预想的境界。
于是我们竟不住要问:为什么电脑处理起“编程语言”来那样轻松自如,可以作好多非常复杂的事情;而在一句普通的自然语言面前却显得像一个大笨蛋呢?自然语言和编程语言的本质区别到底在哪里?自然语言和编程语言显然有很多地方不同。
但是作为“语言”,两者都面临语言使用这所需要的一些要求:(1)有强大的表达能力(能够把事情说清楚)(2)结构化。
人的短时记忆容量不多,信息如果不分层次,无论听说还是阅读都会造成困难。
(3)具有简洁、浓缩表达的机制(使听说双方都不觉得罗嗦)。
在这两种要求的驱动下,两种语言都会发展出一些机制,这些机制在两种语言中的表现可能大不相同,但是会存在某种对应关系。
在文科领域有所谓“比较文学”的行当。
考虑到不同民族,不同文化发源地发展出来的文学作品既有各自的特色,又有互通的共性,可以对它们的异同加以比较。
事实证明,从这种比较中,可以得到许多有益的启示。
“比较”既然是观察和分析事物的有效方法,把自然形成的语言和人工设计的语言(计算机编程语言就是应用最为广泛的一种人工语言)进行一番比较也许能给我们一些工作上的启示。
语言的设计者自然语言是在无数多人群之间的碰撞和交流之间产生、发展、筛选、淘汰之后形成的,好比是“市场经济”的产物。
计算机编程语言(以下简称“编程语言”)则是“计划经济”的产物。
它所使用的词汇、规则都是事先由一位“上帝”(语言的设计者)策划好的。
词汇及其分类“词”是自然语言中的基石,它们是具有语义的最小独立单位。
在编程语言中对应的东西就是token。
Token是编译程序中的术语,它包括外形像英语单词的Word,以及“=, +, -, *, /, ==,>, <, (, ), ……” 之类的符号。
从信息处理的角度来看,“词”和token都是“符号(Symbol)”,它们可以被我们“用来”映射到各种实体或者概念上去。
根据一个符号所映射到各种实体或者概念的性质来把它们进行分类。
语言学家把自然语言中的词划分为许多类:名词、动词、形容词、副词、数词、连接词、感叹词、………。
我们应该注意到,它们不是在同一级别上的。
名词和动词:是最重要的。
它们直接反映了我们对世界上形形色色的事物以及这些事物之间的相互作用。
形容词、副词、数词、则是第二级的。
它们只对事物以及这些事物之间的相互作用起修饰作用。
剩下来的连接词、感叹词、………则是第三级的。
它们主要起语法的作用。
(用来提示语句内部的结构性信息,起连接作用、用来表述“词”与“词”之间的关系)与之对应,在编程语言中,可以把token划分为:l 命令:运算符、子程序名。
它们对应于自然语言中的动词。
动词的“价”则相当于编程语言中的命令、运算符、子程序所需要的“变元(arguments)”的个数。
在编程语言中,有时某些“变元”可以省略不写,而用预先规定的“缺省值”代替。
在自然语言中,也有类似的情况,但是缺省的东西要根据上下文来补充。
自然语言中存在一些“泛义动词”,例如汉语中的“打”,“搞”,“干”……,英语中的“get”,“take”等。
它们的进一步的具体含义要由这些动词所涉及的对象来确定。
例如:“打毛衣”中的“打”应理解为“编织”,“打篮球”中的“打”应理解为“玩”,“打开水”中的“打”应理解为“取得”,等等。
l 在面向对象的编程语言中,也有类似的“动态绑定(Dynamic Binding)”机制:一个函数名或者子程序名字的具体含义要在“运行时”依据所涉及对象在当时的指的类型来决定。
l 数据:常数、变量名。
它们对应于自然语言中的名词。
l 其他:起连接作用、用来表述token 之间的关系的符号,例如if, then等等。
它们对应于自然语言中的连接词、感叹词等等。
动词和名词之间的互换性在自然语言中,有一个引人瞩目的现象,那就是“名词和动词之间的呼唤性”。
这是因为,“词”或者token 是用来表达“概念”的,而一个概念往往有多种侧面。
所以自然语言中常常出现用同一个“符号”来表达不同的侧面的现象。
举例来说:“钉”本来是名词,但是可以转化,作为动词来使用:我把画钉在墙上。
“锁”本来是名词,但是可以转化,作为动词来使用:我用锁把门锁上。
古汉语中这样的例子更多。
“叔”可以转化为“认……为叔叔”,“尘”可以当作“弄脏”,“污染”的意义来使用。
反过来,动词也往往可以转化为名词使用。
比如,“偷”是动词。
但是在“偷是不对的。
”这句话中的“偷”却是一个名词,因为这句话也可以说成:“偷这种行为是不对的”在计算机编程语言中,也有类似情况。
在declaration(声明)中,函数、子程序名表现为“名词”,但是在执行语句中,他们就成了动词。
例如在C语言中:double x,y;double sqrt(double); /* sqrt 在这里以名词的面貌出现*/…………….x = sqrt(y); /* sqrt 在这里以动词的面貌出现*/词类的判断从语法分析的角度看,对词或token 进行分类的依据是它的语法功能。
从语言使用者的角度看,则是他们的使用方式。
因此如何对词或token所属类别进行判断乃是一件至关重要的事情。
不管在自然语言中,还是在编程语言中,判断一个词或者token 的类别的办法基本上是两种:词典和词本身所携带的形态标志。
词典中提供的信息在编程语言中,为判断一个token 的类别而提供的“词典”有两种:1. 一种是语言中“先验地”规定好了的外部词典。
例如关键字和一些保留字。
2. 另外一种是编程人员(用户)临时定义的内部词典,这就是程序中的declaration.在自然语言中,基本上只使用外部词典。
(在某些文件[特别是有关技术标准的文件] 中,有时也在文件的开头部分定义一个“术语”集合,但是很少涉及词性的问题)。
例如中,市面上提供的英语词典对其中所收罗的词的词性都给出了说明。
与编程语言不同的地方是:有相当一部分词具有多种词性。
例如:字符串“increase” 既可以当作名词来使用,又可以当作动词来使用。
奇怪的是,汉语词典基本上都没有给出词性方面的信息。
其主要原因大概是由于汉语中大部分的词都允许以多种方式使用,也就是说具有不止一种词性。
这种现象在古汉语中标显得尤为明显。
汉语中的这种“传统”的来源可能如下:汉语是象形文字,最方便给有形的对象起名字。
所以至少在汉语中“名词”最优先地得到发展。
在古汉语中,由于为抽象的动作设计象形字比较困难,所以往往就把名词直截了当地转化为动词使用:“老”指老年人,老年人应予以“尊重”,所以就把它当作现代汉语中的“尊重”这一动词来使用。
“幼”指婴幼儿,婴幼儿需要“爱护”,所以就把它当作现代汉语中的“爱护”这一动词来使用。
于是就出现了“老吾老以及人之老,幼吾幼以及人之幼”以及与之类似的“君君臣臣父父子子”这类令现代人费解的句子。
词类划分的形式标志如果能够从词或token的外形(形式上的)特征就能判断出他是属于哪一类,那么无论从“书写者撰写”的角度,还是从“阅读者理解”的角度,都能够大大减少出错的机会。
在某些编程语言(例如Visual Basic)中,如果一个变量没有在任何地方加以声明,也可以从变量名字的外形上看出它的类型。
例如:名字以%结尾的变量是‘整数’,名字以&结尾的变量是‘字符串’,名字以&结尾的变量是‘浮点数’等等。
英语中,在某种程度上也有类似的机制,例如:以tion, ing 结尾的基本上是名词。
以-lize 结尾的基本上是名词。
以-ful 结尾的基本上是形容词。
以-ly 结尾的大概是副词。
汉语使用方块字,没有办法添加尾缀,所以没有这样的形态标志。
因此大家认为,这一现象给汉语的计算机处理增加了困难。
不过话不能说得太绝对。
在某些情况下,汉语还是有“形态标志”的。
例如,在名词的前面加“很”“还”之类一般用来修饰形容词的副词,就是在“形态”上指出:后面的这个名词已经转化为“形容词”了。
例子如:“同学们说我穿这条裙子很青春。
”,“我们排演的这套节目还是很生活的。
”,“他比林彪还林彪。
”。
作用域编程语言的名字都有“作用域(scope)”问题。
这一点在语言设计中都作了明确、毫不含糊的规定。
程序被划分为模块、分程序,它们是作用域的天然边界。
自然语言中当然有类似要求。
章节、段落的划分,引号(“”,‘’)的使用也是名字的作用域的天然边界。
但是与编程语言相比,并没有硬性的规定,读者往往要利用生活常识依据“语义合理性”来进行判断。
指针自然语言中的指代词(你、我、他、它等等)好比编程语言中的“指针(point)”。
但是自然语言中从不明显地交待:从现在起,“他”表示“张三”,直到遇见新的声明为止。
每一个具体的代词指向何方要根据句子域句子之间的前后语义来联系来判断。
在为了处理自然语言而为计算机编制词典的时候,一个十分重要的问题是:我们把自然语言中的“词”看成是一个“概念(concept)”还是只看成一个“符号(symbol)”。
字面上的一个词可以对应多个概念,例如“编辑”既可以指一种工作、职业,又可以指以这种工作为职业的“人”。
目前这方面似乎仍存在不同的看法,但是从计算机处理的角度看,当然是看成一个“符号”为宜。
这样就出现了如何判断某一个“词(符号)”指向何种概念的问题。
自然语言中使用最多、最具有生命力的词大多具有多个“义项”。
从这个观点看,多义项词更接近于编程语言中的指针。
语句类型动作语句自然语言中,像:税收人员向大家宣传税收政策。
”我吃了一块蛋糕。
”都表示某一主体采取了某种动作,因而改变了世界。
这种句子围绕着中心动词“宣传”,“吃”而展开。
这种“动作语句”显然对应于编程语言中的“命令语句”(赋值语句,子程序调用,带有副作用的函数调用等。
)如果使用编程语言中的形式来书写上述两个句子,结果就是:宣传(税收人员,大家,税收政策)吃(我,一块蛋糕)子程序“宣传”有三个变元,所以“宣传”是三价动词。
子程序“吃”有两个变元,所以“吃”是二价动词。
描述语句自然语言中,描述句以静态的方式描写周围的世界,某种事物的存在,或者它的属性。
在汉语中,最常见的是以“是”为中心谓词的描写句,例如:她是近视眼。
(健康)他是小孩。
(年龄)他是高个子。
(身材)他是工程师。
(职业)……可见,中心谓词“是”把句子分成左右两个部分。
右边部分叙述了左边部分的某种属性。
至于具体是什么属性,完全要依靠读者的知识来判断。
也许把“是”称为“系动词”就是因为它的功能只不过是把左右两部分联系起来,或者说,只是指出左右两部分有联系,至于什么样的联系,则语焉不详。
由于系动词只起“语法上分割、语义上联系”的作用,因此它往往可以被省略(这时可以认为中心谓词是“Φ” )。