我不熟悉 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])].