Prolog
符号 AI 的编程范式与普通命令式编程貌似相似,但是存在显著区别。理解这种差异是掌握经典符号主义 AI 的关键,也能帮助我们看清现代神经网络方法与早期符号方法的根本分歧。
声明式与命令式
普通编程语言如 C、Python、Java 采用命令式范式,开发者描述"怎么做"——即执行步骤的序列。程序的控制流由开发者预先写好,计算机按指令机械执行。符号 AI 采用声明式范式,开发者只需描述"是什么"——即领域知识和逻辑规则,推理引擎负责自动推导结论。
这种差异在实践中表现明显。用 Python 写一个动物分类程序,开发者需要穷举所有可能的条件分支,程序只能按预设的代码路径执行,无法产生开发者未预料的新结论。用 Prolog 实现同样功能,只需声明事实和规则,引擎会自动搜索解空间,甚至能推导出开发者未曾显式编码的新知识。
知识与控制分离
符号 AI 的核心架构原则是知识库与推理引擎分离。知识库存储领域特定的事实和规则,推理引擎是通用的逻辑求解器。修改系统行为只需更新知识库,无需改动推理引擎。这种分离使得同一推理引擎可以应用于完全不同的领域,专家系统的开发成本大幅降低。
普通程序的知识与控制是交织在一起的。业务逻辑直接硬编码在控制流中,修改行为需要重写代码、重新编译部署。编译器将高级语言翻译成机器码,执行时仍然是固定的指令序列,不存在搜索、回溯或自动规则匹配。符号推理引擎更像一个通用定理证明器,在运行时根据当前事实集动态搜索规则空间,支持统一和回溯机制。
Prolog 语言基础
Prolog 程序由三种语句构成:事实、规则和查询。事实是无条件为真的原子命题,如 parent(john, mary) 表示 John 是 Mary 的父母。规则描述条件关系,头部分是结论,体部分是前提条件,如 grandparent(X, Y) :- parent(X, Z), parent(Z, Y) 表示 X 是 Y 的祖父母当且仅当存在 Z 使得 X 是 Z 的父母且 Z 是 Y 的父母。查询向系统提问,引擎通过搜索和回溯寻找答案。
Prolog 的执行机制基于归结原理和 SLD 分辨。查询触发规则匹配,变量通过统一操作绑定值,失败时自动回溯到最近的分支点。递归是 Prolog 的核心编程模式,列表处理、树遍历等操作都通过递归实现。切断操作用于剪枝搜索树,避免不必要的回溯,但使用不当会破坏程序完备性。
代码示例
以家谱关系为例展示 Prolog 的声明式编程特点。首先定义基本事实,然后编写递归规则推导更复杂的关系。
/* 事实:父母关系 */
parent(tom, bob).
parent(tom, liz).
parent(bob, pat).
parent(bob, jim).
parent(pat, tim).
/* 规则:祖先关系(递归定义) */
ancestor(X, Y) :- parent(X, Y). /* X 是 Y 的父母 */
ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y). /* X 是 Z 的父母,Z 是 Y 的祖先 */
/* 规则:后代关系 */
descendant(X, Y) :- ancestor(Y, X).
/* 查询示例 */
?- ancestor(tom, pat).
/* true. tom → bob → pat */
?- ancestor(tom, X).
/* X = bob ;
X = liz ;
X = pat ;
X = jim ;
X = tim. */
?- descendant(X, tom).
/* X = bob ;
X = liz ;
X = pat ;
X = jim ;
X = tim. */这个示例展示了符号 AI 的核心特点。开发者只需声明基本事实和推理规则,引擎自动完成所有搜索和推导工作。当我们查询 ancestor(tom, pat) 时,引擎自动搜索路径:tom 是 bob 的父母,bob 是 pat 的父母,因此 tom 是 pat 的祖先。整个推理过程无需显式编写循环或递归调用,完全由 Prolog 的搜索机制完成。
对比 Python 实现,开发者需要显式编写递归函数、管理遍历逻辑、处理边界条件。两种实现的功能相同,但 Prolog 版本更接近领域知识的自然表达。
Lisp 与符号操纵
Lisp 是早期 AI 的主流语言,从 1958 年起就成为符号 AI 的首选工具。代码即数据的设计使得程序可以像处理数据一样处理代码结构,元编程和递归处理符号表达式非常自然。Lisp 的符号表达式(S-expression)是树形结构,适合表示语法树、逻辑公式等复杂符号结构。
早期 AI 程序多用 Lisp 实现,包括逻辑理论家程序、通用问题求解器等。Lisp 的动态类型、垃圾回收、高阶函数等特性在当时的编程环境中是革命性的,这些特性后来影响了 Python、Ruby 等现代语言。
专家系统架构
典型专家系统由三个组件构成:知识库、推理引擎和用户界面。知识库存储规则和事实,推理引擎应用规则进行推理,用户界面接受查询并展示推理过程。MYCIN 用 Lisp 实现规则链,能够解释推理依据,这种可解释性是现代黑盒模型所缺乏的。DENDRAL 用符号匹配分析化学结构,展示了符号系统在科学发现中的潜力。
实现挑战
纯符号 AI 的编程虽然优雅,但在工程实践中面临严峻挑战。知识获取瓶颈意味着每条规则都需要专家与知识工程师紧密合作,专家的隐性知识难以显式化为规则。脆性问题是致命伤,规则只能覆盖预见到的情况,遇到边界场景就会崩溃。规模问题指规则数量随问题复杂度呈指数增长,几万条规则的系统难以维护。
正是这些挑战导致符号 AI 在 2012 年后让位于连接主义。但符号方法的价值并未消失,在法律推理、数学证明、安全关键系统等需要可解释性和精确推理的场景中仍然不可替代。现代神经符号融合试图结合两者的优势,这可能是通往更强大 AI 的必经之路。
编程对比
| 方面 | 符号 AI(如 Prolog) | 普通编程语言(如 Python) |
|---|---|---|
| 核心范式 | 声明式:描述"是什么" | 命令式:描述"怎么做" |
| 知识表示 | 知识库与推理引擎分离 | 逻辑硬编码在控制流中 |
| 执行机制 | 引擎自动搜索、匹配、演绎 | 按固定顺序或分支执行 |
| 灵活性 | 修改知识库即可改变行为 | 修改逻辑需重写代码 |
| 通用性 | 目标是通用推理能力 | 解决特定问题 |
| 解释性 | 推理过程可追溯 | 需要额外调试或日志 |