如何使用PL-UNIT以任何顺序测试非确定性谓词


  • 我想单位测试一个非确定性谓词在Pl-unit中。

  • 我想"断言"我在测试中指定的解决方案是 predicate的唯一解决方案。

  • 不关心测试中指定每个解决方案的顺序

SWI-Promog手册说的是:

SWI-Prog手册具有一个很棒的部分,称为测试非确定性谓词...

2.2.3测试非确定性谓词

非确定性谓词成功零或更多次。他们的结果使用Findall/3或setof/3进行测试,然后使用值检查或使用全部或集合选项。以下是等效测试:

test(member) :-
        findall(X, member(X, [a,b,c]), Xs),
        Xs == [a,b,c].
test(member, all(X == [a,b,c])) :-
        member(X, [a,b,c]).

这几乎是正好我需要的东西。但是,要通过这些测试,必须按正确的顺序指定输出:[a, b, c]。我希望能够以任何订单来指定它,但仍具有测试通行证。

我正在尝试的例子:

假设我正在测试具有两个解决方案的(假设)谓词。

specialNumber(X) :-
    X is 2;
    X is 4.

我可以像这样写一个传递的单位测试...

% PASSES!
test(specialNumber, all(X == [2, 4])) :-
        specialNumber(X).

,但是如果我换了解决方案的顺序...

% FAILS!
test(specialNumber, all(X == [4, 2])) :-
        specialNumber(X).

无论找到解决方案的顺序如何?

如何进行测试。

考虑使用 setof/3 而不是 findall/3来收集和  sort

例如,给定对谓词的定义稍微重写:

Special_number(x): -         (x#= 2        ;x#= 4        )。

我们可以定义以下限制测试:

: -  begin_tests(all)。测试(解决方案, solutions = [2,4] ): -          setof (x,special_number(x),解决方案)。: -  end_tests(all)。

此测试用例如果您重写您的谓词例如:

Special_number(x): -         (x#= 4        ;x#= 2        )。

在这种情况下,我们有:

? -  findall(x,special_number(x),ls)。 ls = [4,2] 。? -  setof(x,special_number(x),ls)。 ls = [2,4] 

作为setof/3的替代方法,您可以使用:

  • findall/3
  • 然后用sort/2手动对解决方案进行排序。

相关主题供您阅读:

  • 术语的标准顺序
  • bagof/3
  • (@<)/2

我将添加必要的和在上面以ANBSP;练习为示例所必需的指令。

最新更新