如何正确编写normalized(A,B)谓词解决clingo变量不安全报错
Clingo中normalized谓词编写问题解答
变量A不安全的原因
Clingo对安全变量的判定规则并非仅要求变量出现在规则体中,而是要求变量必须出现在规则体的正的、非内置比较操作的普通原子中。你编写的代码里,变量A仅出现在比较运算A != 0中,内置比较操作无法绑定变量的取值范围,Clingo无法确定A的可取值集合,因此会判定A为不安全变量。
如果Clingo允许该规则生效,理论上所有不等于0的整数都可以满足规则条件,确实会产生无限大的答案集,这也是Clingo抛出安全错误的核心原因,用于避免出现无限稳定模型的情况。
修改后代码仍报错的原因
你的修改版代码存在两个问题:
- 规则中的变量B仅出现在
B != 0的比较运算中,同样没有被普通原子绑定,仍然属于不安全变量 - 你定义的
normalized是二元谓词,但写的事实normalized(number(10)).是一元谓词,和规则签名不匹配,本身无法被规则匹配
正确的编写方式
核心思路是先显式限定需要做归一化的数值的取值范围,把变量绑定到有限的取值集合上,示例代码如下:
% 声明所有需要进行归一化处理的输入数值 input_num(0). input_num(10). % 可按需添加其他需要处理的数值,比如 input_num(-2), input_num(7) % 归一化规则 normalized(X, 0) :- input_num(X), X = 0. normalized(X, 1) :- input_num(X), X != 0.
运行上述代码后会得到预期结果:normalized(0,0)和normalized(10,1)。如果需要处理固定连续范围内的整数,也可以用内置范围限定简化取值绑定,比如要处理0到100之间的整数,可写作:
normalized(X, 0) :- X = 0. normalized(X, 1) :- X in 1..100.
内容的提问来源于stack exchange,提问作者Fabian Schneider
相关产品推荐
相关产品推荐

