我正在尝试使用 LogicBlox 作为 Datalog 求解器的功能。我有性能问题,我认为我使用 LB 是错误的,因为它表现得好像它正在实现所有关系(具有例如魔术集的 Datalog 求解器不会这样做)。
正如我所说,我可能没有按预期使用 LB,但这是我的测试。我想创建一些二元关系 e(x,y) 的传递闭包 c(x,y)。出于测试的目的,我将 e 创建为一个简单的循环,即我将 e(i,(i+1)%1000) 添加到 LB 为 0 ≤ i < 1000。
当我只对 from0(x) <- c(0,x) 感兴趣时,不需要实际实现 c 并且魔法集方法将创建一个谓词 c_{bound,free}(x,y) 并计算 from0 (0) 然后从 0(1) 等推导出来。整个操作大约需要 1000 步。
如果我用程序做我的例子:
e(x,y) -> int(x), int(y).
// fill e with data
c(x,y) -> int(x), int(y).
c(x,y) <- e(x,y) ; c(x,z),e(z,y).
from0(x) <- c(0,x).
然后,显然,我正在生成 c 的物化版本,并且 c 将包含所有元素对;因此总操作大约需要 1000^2 的时间(当我运行查询时,我发现它实际上需要一些时间来计算)。
从文档中,LogicBlox 允许将谓词定义为“派生”,但对于 c 来说,它似乎不可能作为 c 自身递归。
现在,我还尝试在查询或 exec 块中使用“本地谓词”定义此传递闭包,但没有成功。我试过的例子:
query '
_c(x,y)->int(x),int(y).
_c(x,y) <- e(x,y) ; e(x,z),_c(z,y).
_(x) <- _c(0,x).'
显然,在这个例子中,我可以手动优化查询并定义一个块:
f0(x)->int(x).
f0(y)<- e(0,y) ; f0(x),e(x,y).
但如果我正确理解 LB,应该有办法将优化留给 LB。