Sunday, November 16, 2014

如何写一个逻辑引擎?How to write a logic engine? (Chinese)

现试用最简单的方法,介绍如何写一个逻辑引擎。

即使是现时最尖端的人工智能,例如 OpenCog,它的内部仍然是很简单的。

逻辑推理 (deduction) 只需要两个算法:

  1. 命题推理
  2. 配对法 (unification) 
这两个算法只需要数行程式就能表达 !


逻辑是什么?


逻辑可以分解为两部分:
  1. 命题逻辑 (propositional logic)
  2. 命题内部的结构

命题逻辑

命题逻辑的意思是:  我们只关心命题的真假,而不看命题内部的结构。  所以「小明爱小娟」和「北京昨天下雨」都是同一类句子,只要我们知道它们的真值 (truth value)。

命题之间的关系用箭頭表示,例如:
  1. 吃了不洁食物 $\rightarrow$ 肚痛
  2. 下大雨,没带雨伞 $\rightarrow$ 变落汤鸡
但命题不一定非黑即白,关系也会有不确定因素,所以最严格是要用 fuzzy probability (模糊 机率) 来描述。

推理的算法,原理很简单:

所有命题的关系构成一个 graph,例如下图:


有些 nodes 的真值我们知道,有些不知道; 我们将真值由已知的 nodes「传播」到未知的 nodes 去。 这传播有其法则,例如 机率 要用机率论的法则计算,你甚至可以自创,甚至可以用机器学习那些法则,而不需我们伤脑筋去设计!

所以,你只要懂得怎样在电脑建立和处理 graph 结构,第一个问题便解决了。

谓词逻辑

现在来看看句子内部的结构。

最经典的做法是用谓词逻辑 (predicate logic),那是 Gottlob Frege 在 1879 年发明的。  罗素 (Bertrand Russell) 用它改写所有数学,使之发扬光大,然后 AI 之父 John McCarthy 把它应用在 AI 上,变成 classical AI。  但现在我们搞 strong AI 的人似乎都不太喜欢它,使用一些变奏,但基调一样。

谓词逻辑的做法就是将句子拆成 predicate 和 predicate 里面的 objects。
例如:
「小明爱小娟」 -->  爱(小明,小娟)
「北京下雨」-->  下雨(北京)
但对於较为复杂的句子结构例如「小明执迷不悟地爱着小娟」则视乎个别研究者的做法,没有统一的准则。  我们暂时不深究。

其实只要用某个方法把句子内部拆开就行,命题的推理方法完全没有变。

但句子拆开之后,我们可以在里面使用 variables (变量),那是很有用的。

例如,我们可以构造:
爱(小明,X)
那变量 X 可以是 小娟、美玲、等。

於是现在我们需要另一个算法,叫 unification (配对)。

Unification

Unify 的作用是:  给定两个句子 A 和 B,它们内部可以很复杂,也可以有 variables,而我们试图找一些 substitutions (代入),令那两句变成一样

例如:
爱(X,Y)

爱(小强,美玲)
这两句命题,只要代入{X = 小强,Y = 美玲},就可以变成同一句。

当然有些命题是无法 unify 的,例如:
爱(小明,小娟)
恨(小明,X)
那算法便会回覆 "fail"。

变量是很重要的发明,有了变量才可以表达 general rules (一般法则),例如:
「女人都说谎」换成逻辑就是:
女人(X) $\rightarrow$ 说谎(X)

有些人被女人骗过一次之后,便永远不信女人;  所以人脑的思想也是透过 generalization (一般化) 来学习的。  那是机器学习的範围,容后再谈。

Unify 所做的其实是 pattern matching。
例如:
    戴眼镜(X) 或 爱(小明,Y)
是一些模式,可以套到:
    戴眼镜(美玲) 或 爱(小明,小娟)
这些实例上。

人工智能就是一个很大的资料库,里面有很多用模式写成的 general rules,经过配对而产生新的推论。  例如 小娟是女人,所以用上面那条 general rule,得出小娟说谎的结论。 

No comments:

Post a Comment