1

我正在使用Triq (erlang quickcheck),我无法为我的程序生成一组好的规则。

我想要生成的是看起来像这样的东西:

A -> B

我想提供A的位置和大小B,后者没有任何重复项。

例如,如果我说用[a]大小为 4 的 LHS 和 RHS(即A = [a]size(B) = 4)生成我的规则,我想得到这样的东西:

{rule, [a], [1,2,4,5]}
{rule, [a], [a,d,c,e]}
{rule, [a], [q,d,3,4]}

请注意,我不希望B 中有任何重复项(这是我遇到问题的部分)。此外, B由什么组成并不重要——它可以是任何东西,只要它是不同的并且没有重复。

我的规格太乱了,无法在这里展示,所以我宁愿不展示。

4

1 回答 1

2

我不熟悉 Triq,但在 PropEr 和 Quviq 的 Qickcheck 中,您可以使用?SUCHTHAT过滤“坏”实例的条件。

如果生成的实例不满足 ?SUCHTHAT 约束,则将其丢弃且不计为有效测试。您可以使用此机制生成指定大小的列表(即 PropEr 所谓的“向量”),然后丢弃那些具有重复项的列表,但我认为随后会丢弃太多实例(另请参见链接)。

修补生成器通常更有效,以使所有实例都有效,在您的情况下,例如生成(3) X 倍的元素,删除重复项并根据需要保留尽可能多的元素。这仍然可能失败,并且会失败,因此您需要提防它。

这是您的案例的生成器,在 PropEr 中,以及一个虚拟属性:

-module(dummy).

-export([rule_prop/0]).

-include_lib("proper/include/proper.hrl").

-define(X, 5).

rule_prop() ->
  ?FORALL(_, rule_gen(integer(), 4, integer()), true).

rule_gen(A, SizeB, TypeB) ->
  ?LET(
     EnoughB,
     ?SUCHTHAT(
        NoDupB,
        ?LET(
           ManyB,
           vector(?X * SizeB, TypeB),
           no_dups(ManyB)
          ),
        length(NoDupB) >= SizeB
       ),
     begin
       B = lists:sublist(EnoughB, SizeB),
       {rule, A, B}
     end).

no_dups([]) ->
  [];
no_dups([A|B]) ->
  [A | no_dups([X || X <- B, X =/= A])].
于 2016-04-06T08:50:54.597 回答