prolog - 无限递归错误和条件?
问题描述
我的数据库中有以下事实和规则。
above(b, a).
above(c, b).
above(d, c).
above(X,Y):-above(X,Z),above(Z,Y).
below(X,Y):- above(Y,X).
这适用于正面案例,因此如果我查询,
above(c,a).
返回值为真。但是,当我尝试下面的查询时期望为 False,
above(a,c).
我收到了消息,
Stack sizes: local: 0.2Gb, global: 16Kb, trail: 3Kb
Stack depth: 2,839,964, last-call: 0%, Choice points: 12
Probable infinite recursion (cycle):
[2,839,964] above(a, _1394)
[2,839,963] above(a, _1420)
我的理解是,由于没有与 关联的原子 X above(a,X).
,并且确实该查询返回 False,因此我的规则的第一个条件将不满足,这足以得出该查询为 False 的结论。情况似乎并非如此。我如何设置规则,以便它在返回 False 的同时仍按预期为阳性案例工作?
解决方案
因为above(a, X)
不匹配前三个子句(事实),所以进入第四个子句,above(X, Y) :- ...
. 之后你要做的第一件事就是above(X, Z)
,也就是说,above(a, Z)
。然后尝试前三个子句,但都失败了,然后above(X, Y)
再次尝试。这是你无限递归的来源。
解决方案是通过重命名其中之一来将您的规则与事实分开,例如:
is_above(b, a).
is_above(c, b).
is_above(d, c).
above(X,Y):- is_above(X,Z), above(Z,Y).
below(X,Y):- above(Y,X).
这样你就没有无限递归,above
必须在递归之前取得一些进展。
推荐阅读
- sql - 选择距当前日期最多两天的列 [SQLite3]
- objective-c - macOS:使用父窗口移动子窗口时出现问题
- amazon-rds - 如何解决创建 MySQL 5.5.53 只读副本时出现错误 InvalidParameterCombination、Status 400?
- flutter - 如何使曲线角像使用剪辑路径或任何其他小部件附加的文件一样颤动?
- laravel - findWhere() 函数在 laravel 查询中的作用
- lua - ROBLOX 战斗系统脚本 - 语法错误:预期 ')' 在第 7 行关闭 '('),得到 ','
- php - Homestead 没有按预期工作,忽略配置文件
- gps - 更新——传感器通过 Atlas Scientific 硬件串行端口扩展器 8:1 连接到 Arduino Uno 的问题
- c++ - 指向存储整数的堆内存位置的指针
- sql - 插入分组数据