Prolog 算术:is 运算符
在 Prolog 中进行数值计算时,不能像其他编程语言那样直接用 X = 2 + 3 来求值。Prolog 默认将 + 视为一个结构(term),而不是运算指令。要真正执行加法、乘法等算术运算,必须使用 is 运算符。
理解 is 运算符的核心作用
使用 is 来强制 Prolog 对右侧的算术表达式求值,并将结果绑定到左侧变量。
关键规则:
is左侧必须是一个未绑定的变量(或能统一为数字的项)。is右侧必须是一个完全可计算的算术表达式,即所有变量都已绑定为具体数字。- 如果右侧包含未绑定变量,Prolog 会报错
Arguments are not sufficiently instantiated。
例如:
?- X is 2 + 3.
X = 5.
而以下写法无效:
?- X = 2 + 3.
X = 2+3. % X 是一个结构,不是数字 5
正确使用 is 的步骤
-
确保右侧表达式中的所有变量都有确定数值。
错误示例:?- X is Y + 2. ERROR: Arguments are not sufficiently instantiated因为
Y没有值,Prolog 无法计算。 -
先给变量赋值,再用 is 计算。
正确做法:?- Y = 4, X is Y + 2. X = 6, Y = 4. -
不要试图用 is 反向求解方程。
Prolog 的is不是等式,而是“求值并赋值”。
以下不会成功:?- 5 is X + 2. ERROR: Arguments are not sufficiently instantiated因为
X未绑定,右侧无法求值。 -
比较数值时,使用 =:= 而非 =。
=是结构统一(unification),不计算算术。=:=会先对两侧求值再比较数值是否相等。
示例:?- 2 + 3 =:= 5. true.
?- 2 + 3 = 5.
false. % 因为 2+3 是结构,5 是原子,两者不统一
常见错误与避坑指南
| 错误写法 | 问题原因 | 正确写法 |
|---|---|---|
X = 2 + 3 |
仅统一结构,未计算 | X is 2 + 3 |
5 is X + 2 |
右侧含未绑定变量 | 先设 X = 3,再 5 is X + 2 |
X is Y, Y = 5 |
is 执行时 Y 未绑定 |
Y = 5, X is Y |
X is 10 / 3 |
结果是浮点数(3.333...) | 若需整数除法,用 //:X is 10 // 3 |
注意:Prolog 中 / 总是返回浮点数,即使能整除。若需整数结果,应使用 //(整除)或 div(向零取整)。
在规则中使用 is
定义一个计算矩形面积的谓词:
area(Width, Height, Area) :-
Area is Width * Height.
调用时必须提供宽度和高度的具体数值:
?- area(4, 5, A).
A = 20.
?- area(W, 5, 20).
ERROR: Arguments are not sufficiently instantiated
因为 W 未绑定,Width * Height 无法求值。
如果需要反向求解(如已知面积和高,求宽),不能直接用 is,而应改用 CLP(FD) 库(约束逻辑编程),但那是更高级的主题。
支持的算术函数
Prolog 的 is 支持多种内置函数。右侧可包含:
- 基本运算:
+,-,*,/,//,mod,^ - 数学函数:
sin(X),cos(X),sqrt(X),abs(X),max(X,Y),min(X,Y) - 常量:
pi,e
示例:
?- X is sin(pi/2).
X = 1.0.
?- X is sqrt(16).
X = 4.0.
?- X is max(10, 20).
X = 20.
所有函数参数必须是已知数值。
性能与调试建议
始终在 is 之前绑定所有变量。这不仅避免错误,还能提升程序可读性。
调试技巧:若遇到 Arguments are not sufficiently instantiated 错误,检查 is 右侧的每个变量是否已在前序目标中被赋值。
例如,以下规则顺序错误:
bad_example(X, Y) :-
Z is X + Y, % 此时 X、Y 未绑定!
X = 2,
Y = 3.
应改为:
good_example(X, Y) :-
X = 2,
Y = 3,
Z is X + Y.
或者通过参数传入:
better_example(X, Y, Z) :-
Z is X + Y.
调用时:better_example(2, 3, Z).
与其他比较运算符配合使用
Prolog 提供多个用于数值比较的运算符,它们都会自动对两侧求值:
=:=:等于=\=:不等于<:小于>:大于=<:小于等于(注意是=<,不是<=)>=:大于等于
这些运算符内部隐含了“求值”行为,因此右侧可以包含表达式:
?- 5 =:= 2 + 3.
true.
?- X = 4, X < 2 * 3.
X = 4.
但同样要求所有变量已绑定。
记住:is 不是等号,而是“计算右边,赋给左边”。

暂无评论,快来抢沙发吧!