我正在使用Triq(erlang quickcheck),但我无法为我的程序生成一组 nice 规则。
我想要生成的内容是这样的:
A -> B
我想提供A
和B
的大小,后者没有任何重复。
例如,如果我说用L.H.S生成规则。 [a]
和R.H.S.大小为4(即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 由什么构成并不重要 - 它可以是任何东西,只要它是独特的并且没有重复。
我的规格太乱了,不能在这里展示,所以我宁愿不这样做。
答案 0 :(得分: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])].