Prolog:基于逻辑的声明式编程 | AI生成和翻译

Home 2025.07

Prolog,全称为“逻辑编程”,是一种声明式编程语言,与 Python、Java 或 C++ 等命令式语言形成鲜明对比。它不是一步步告诉计算机如何解决问题,而是描述问题什么,然后 Prolog 利用其内置的推理引擎来寻找解决方案。

它特别适合涉及逻辑、符号推理和知识表示的问题,使其成为人工智能(AI)、自然语言处理和专家系统领域的基石。

Prolog 的核心概念:

  1. 事实: 事实是你提供给 Prolog 的关于世界的基本真理。它们代表无条件的断言。

    • 语法: 谓词(参数1, 参数2, ...).
    • 示例:
      • 男人(约翰). (约翰是男人)
      • 女人(玛丽). (玛丽是女人)
      • 父母(约翰, 玛丽). (约翰是玛丽的父母)
      • 首都(法国, 巴黎). (巴黎是法国的首都)
  2. 规则: 规则定义了事实之间的关系。它们声明,如果一个或多个其他事实(或条件)为真,则某个事实为真。

    • 语法: 头部 :- 主体. (读作“如果主体为真,则头部为真”)
      • 头部 是单个谓词。
      • 主体 是一个或多个谓词的合取,用逗号(,)分隔,表示“与”。
    • 示例:
      • 快乐(X) :- 喜欢(X, 披萨). (如果 X 喜欢披萨,则 X 快乐)
      • 父亲(X, Y) :- 父母(X, Y), 男性(X). (如果 X 是 Y 的父母 并且 X 是男性,则 X 是 Y 的父亲)
      • 祖父母(G, C) :- 父母(G, P), 父母(P, C). (如果 G 是 P 的父母 并且 P 是 C 的父母,则 G 是 C 的祖父母)
  3. 查询: 一旦你定义了事实和规则(你的“知识库”),你就可以向 Prolog 提问,称为查询,以检索信息或验证关系。

    • 语法: ?- 查询.
    • Prolog 尝试通过查找使查询为真的变量来满足查询,这是基于已建立的事实和规则。如果存在多个解,通常可以通过输入分号(;)来提示 Prolog 寻找更多解。
    • 示例:
      • ?- 男人(约翰). (约翰是男人吗?)
      • ?- 父母(约翰, X). (约翰是谁的父母? - X 是变量)
      • ?- 祖父母(伊丽莎白, 威廉). (伊丽莎白是威廉的祖父母吗?)
  4. 变量: Prolog 中的变量用于表示未知值。它们总是以大写字母或下划线(_)开头。与命令式语言中的变量不同,它们不是可以重新分配的内存位置;相反,它们是占位符,Prolog 尝试通过将值与它们统一来满足查询。

  5. 统一: 这是 Prolog 的核心机制。统一是一种模式匹配过程,它试图通过给变量赋值来使两个项相同。如果找到匹配,变量就被“绑定”到这些值。如果无法匹配,则统一失败。

  6. 回溯: 当 Prolog 尝试满足一个查询时,它以深度优先的方式遍历事实和规则。如果某条路径导致死胡同(目标无法满足),Prolog 会“回溯”到先前的选择点并尝试另一条路径。这种系统性的搜索使它能够找到查询的所有可能解。

Prolog 的工作原理(简化版):

  1. 你将一个 Prolog 程序(一组事实和规则)加载到解释器中。
  2. 你提出一个查询。
  3. Prolog 尝试通过将查询与其事实和规则的头部进行匹配来证明该查询。
  4. 如果某个规则的头部匹配,Prolog 然后尝试证明该规则主体中的条件(这些成为子目标)。
  5. 这个过程递归地继续,直到所有子目标都被事实或已成功证明的规则所满足。
  6. 如果找到一个解,Prolog 会呈现变量绑定。如果存在多个解,它可以回溯以找到它们。

Prolog 的优点:

Prolog 的缺点:


Prolog 代码示例:

要运行这些示例,你需要一个 Prolog 解释器(如 SWI-Prolog,它是免费且广泛使用的)。你通常将代码保存在扩展名为 .pl 的文件中(例如 family.pl),然后将其加载到解释器中。

示例 1:家庭关系

让我们定义一些基本的家庭关系。

family.pl:

% 事实:定义基本关系
男性(约翰).
男性(吉姆).
男性(乔治).
女性(玛丽).
女性(丽莎).
女性(苏珊).

父母(约翰, 丽莎).   % 约翰是丽莎的父母
父母(约翰, 吉姆).    % 约翰是吉姆的父母
父母(玛丽, 丽莎).   % 玛丽是丽莎的父母
父母(玛丽, 吉姆).    % 玛丽是吉姆的父母
父母(丽莎, 乔治). % 丽莎是乔治的父母
父母(吉姆, 苏珊).   % 吉姆是苏珊的父母

% 规则:定义衍生关系
父亲(X, Y) :- 父母(X, Y), 男性(X).         % X 是 Y 的父亲,如果 X 是 Y 的父母 并且 X 是男性。
母亲(X, Y) :- 父母(X, Y), 女性(X).        % X 是 Y 的母亲,如果 X 是 Y 的父母 并且 X 是女性。
孩子(X, Y) :- 父母(Y, X).                    % X 是 Y 的孩子,如果 Y 是 X 的父母。
祖父母(G, C) :- 父母(G, P), 父母(P, C). % G 是 C 的祖父母,如果 G 是 P 的父母 并且 P 是 C 的父母。
兄弟姐妹(X, Y) :- 父母(P, X), 父母(P, Y), X \= Y. % X 和 Y 是兄弟姐妹,如果他们共享父母 P,并且 X 与 Y 不同。

在 Prolog 解释器中运行(例如 SWI-Prolog):

?- consult('family.pl').
% family.pl compiled 0.00 sec, 7 clauses
true.

% 查询:

?- 男性(约翰).
true.

?- 女性(吉姆).
false.

?- 父母(约翰, 丽莎).
true.

?- 父母(X, 吉姆). % 谁是吉姆的父母?
X = 约翰 ;           % 输入 ';' 获取更多解
X = 玛丽.
false.

?- 父亲(约翰, 丽莎).
true.

?- 母亲(玛丽, 吉姆).
true.

?- 祖父母(约翰, 乔治).
true.

?- 祖父母(X, 苏珊). % 谁是苏珊的祖父母?
X = 约翰 ;
X = 玛丽.
false.

?- 兄弟姐妹(丽莎, 吉姆).
true.

?- 兄弟姐妹(丽莎, 乔治).
false. % 因为他们不共享*所有*父母

示例 2:简单的知识库(动物)

animals.pl:

% 关于动物及其属性的事实
动物().
动物().
动物().
动物().

有毛发().
有毛发().
会飞().
会游泳().

(, 骨头).
(, ).
(, 种子).
(, 浮游生物).

% 规则
是哺乳动物(X) :- 动物(X), 有毛发(X). % 哺乳动物是有毛发的动物。
会飞(X) :- 动物(X), 会飞(X).     % 某物会飞,如果它是动物并且会飞。

在 Prolog 解释器中运行:

?- consult('animals.pl').
% animals.pl compiled 0.00 sec, 10 clauses
true.

% 查询:

?- 动物().
true.

?- 有毛发().
true.

?- (, X). % 猫吃什么?
X = .

?- 是哺乳动物().
true.

?- 是哺乳动物().
false.

?- 会飞(X). % 什么动物会飞?
X = .
false.

这些示例阐释了 Prolog 的声明式特性:你定义关系和属性,系统则推断出你的查询的答案。


Back Donate