在ISO Prolog中,一致性仅针对那些不受出现检查限制的情况(NSTO)进行定义。其背后的思想是覆盖程序中大多数使用的一致性情况,并且所有Prolog系统都实际支持这些情况。更具体地,ISO/IEC 13211-1:1995如下所述:
7.3.3 受出现检查(STO)和不受出现检查(NSTO)的主题
如果存在通过Herbrand算法步骤进行处理的方式,则一组方程(或两个术语)是“受到出现检查”(STO)。发生7.3.2 g。
如果不存在通过Herbrand算法步骤进行处理的方式,则一组方程(或两个术语)为“不受出现检查”(NSTO),使7.3.2 g无法发生。
...
此步骤7.3.2 g如下所述:
如果有形如X = t的方程,其中X是一个变量,而t是包含该变量的非变量项,则以失败(不可统一,正出现检查)退出。完整算法称为Herbrand算法,通常被称为Martelli-Montanari统一算法 - 其本质上通过非确定性方式重写一组方程。请注意,新方程式引入方式如下:如果存在等式f(a1,a2, ...aN) = f(b1,b2, ...bN),则用ai = bi替换它。
这意味着具有相同功能符但不同维度的两个复合术语永远不会对STO-ness产生贡献。
这种非确定性是使STO测试难以实现的原因。毕竟,仅仅测试是否需要进行出现检查是不够的,而是要证明在执行算法的所有可能方式中,这种情况永远不会发生。
以下是一个案例来说明这种情况:
这是一个简单的开始步骤:所有成功的情况都由
7.3.3 受出现检查(STO)和不受出现检查(NSTO)的主题
如果存在通过Herbrand算法步骤进行处理的方式,则一组方程(或两个术语)是“受到出现检查”(STO)。发生7.3.2 g。
如果不存在通过Herbrand算法步骤进行处理的方式,则一组方程(或两个术语)为“不受出现检查”(NSTO),使7.3.2 g无法发生。
...
此步骤7.3.2 g如下所述:
如果有形如X = t的方程,其中X是一个变量,而t是包含该变量的非变量项,则以失败(不可统一,正出现检查)退出。完整算法称为Herbrand算法,通常被称为Martelli-Montanari统一算法 - 其本质上通过非确定性方式重写一组方程。请注意,新方程式引入方式如下:如果存在等式f(a1,a2, ...aN) = f(b1,b2, ...bN),则用ai = bi替换它。
这意味着具有相同功能符但不同维度的两个复合术语永远不会对STO-ness产生贡献。
这种非确定性是使STO测试难以实现的原因。毕竟,仅仅测试是否需要进行出现检查是不够的,而是要证明在执行算法的所有可能方式中,这种情况永远不会发生。
以下是一个案例来说明这种情况:
?- A/B+C*D = 1/2+3*4.
统一可能从A = 1
开始,也可以是其他任意一对,并以任何顺序继续。为确保NSTO属性,必须确保不存在可能产生STO情况的路径。考虑一个对当前实现没有问题但仍然存在STO情况的案例:
?- 1+A = 2+s(A).
Prolog系统会将此方程式重写为:
?- 1 = 2, A = s(A).
现在,它们选择以下之一:
1 = 2
,这会使算法失败退出;或者A = s(A)
,其中应用了步骤g并检测到STO-ness。
我的问题有两个方面。首先是关于ISO Prolog实现unify_sto(X,Y)
的问题(仅使用第1部分的已定义的内建函数),满足以下条件:
如果统一是STO,则
unify_sto(X,Y)
会产生错误,否则如果
unify_sto(X,Y)
成功,则X = Y
也成功如果
unify_sto(X,Y)
失败,则X = Y
也失败
我的第二个问题与此情况下出现的特定错误有关。请参见ISO的错误分类。
这是一个简单的开始步骤:所有成功的情况都由
unify_with_occurs_check(X,Y)
的成功涵盖。还需要区分NSTO失败和STO错误的情况。这就是事情开始变得困难的地方...
A = s(A)
这样的情况,A = B
是未定义的,而unify_with_occurs_check(A, s(A))
是明确定义的:它会失败。我不清楚你对unify_sto/2
的定义是什么。有太多未被定义。 - false