如何验证涉及dif / 2约束的交换性?

时间:2016-06-27 22:55:58

标签: prolog prolog-dif clp

围绕dif / 2约束存在很多炒作,特别是作为对(\ =)/ 2和(\ ==)/ 2的某些非声明性的拯救。这种非声明性通常被描述为非单调性,并且给出了非交际性的​​例子。

但是测试涉及dif / 2的测试用例是否可交换的方法是什么。以下是我想要做的元解释:

  

我进行了交换性测试,我想探究这两种变体   给出相同的结果:

?- A, B.
-- versus --
?- B, A.

通常你可以用(==)/ 2内置谓词检查单调性,如果它归结为检查交换性。由于此谓词遵循实例化变量。

但是,如果您正在测试产生约束的案例,请调用call_with_residue / 2 还不够,你还需要有相等的约束。哪个行 很棘手,如下例所示:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.23)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam

?- dif(f(X,X),f(a(U,g(T)),a(g(Z),U))), X=a(g(Z),U).
X = a(g(Z), U),
dif(f(a(g(Z), U), U, Z, U, T), f(a(U, g(T)), g(Z), T, g(Z), Z)).

?- X=a(g(Z),U), dif(f(X,X),f(a(U,g(T)),a(g(Z),U))).
X = a(g(Z), U),
dif(f(U, T), f(g(Z), Z)).

任何想法如何进行?

免责声明,它是一个陷阱:
我并不赞同将交换性测试作为一种好的测试方法,在这种方法中,您可以将好的和坏的谓词与规范分开。因为通常好的和坏的谓词都可能没有交换性问题。

我正在使用交换性测试作为一种工具来找出有关dif / 2约束相等的方法。然后,可以在更传统的测试用例中将此等式用作验证点。

1 个答案:

答案 0 :(得分:4)

有几种方法。在这种情况下,最简单的方法是简单地重新发布收集的剩余约束。

在这个例子中,我们得到:

?- X = a(g(Z), U),
   dif(f(a(g(Z), U), U, Z, U, T), f(a(U, g(T)), g(Z), T, g(Z), Z)).
X = a(g(Z), U),
dif(f(U, T), f(g(Z), Z)).

目标现在变得更加简单了!

您可以使用copy_term/3call_residue_vars/2收集剩余目标。