2016-04-06 3 views
1

J'utilise Triq (erlang quickcheck) et je rencontre des problèmes pour générer un ensemble de règles nice pour mon programme.Génération d'une règle aléatoire pour le test basé sur la propriété

Ce que je veux générer sont des choses qui ressemble à ceci:

A -> B 

où je voudrais fournir A et la taille de B, avec celui-ci ne pas avoir de dupicates. Par exemple, si je dis générer des règles avec L.H.S. de [a] et R.H.S. de la taille 4 (.-à-dire A = [a] et size(B) = 4) Je voudrais obtenir quelque chose comme ceci:

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

Remarque, je ne veux pas tout dupicates en B (ce qui est la partie que je vais avoir du mal à). En outre, peu importe ce que contient B - cela peut être n'importe quoi tant qu'il est distinct et sans dupicates.

Ma spécification est beaucoup trop salissante pour montrer ici, donc je préfère ne pas.

Répondre

1

Je ne suis pas familier avec Triq, mais dans PropEr et Qickcheck de Quviq vous pouvez utiliser les conditions ?SUCHTHAT qui filtrent les 'mauvaises' instances.

Si une instance générée ne satisfait pas à une contrainte? SUCHTHAT, elle est ignorée et n'est pas comptée comme un test valide. Vous pouvez utiliser ce mécanisme pour générer des listes de la taille spécifiée (c'est-à-dire ce que PropEr appelle les «vecteurs»), puis rejeter ceux qui ont des doublons, mais je pense que trop d'instances seraient rejetées (voir aussi le lien).

Il est généralement plus efficace de bricoler avec le générateur de sorte que toutes les instances sont valides, dans votre cas par exemple. générer (3) X fois autant d'éléments, en supprimant les doublons et en gardant autant que vous le souhaitez. Cela peut toujours échouer, et il échouera, vous devez donc vous en prémunir.

est ici un générateur pour votre cas, CORRECTE, avec une propriété fictive:

-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])]. 
+0

Merci, juste une question: pourquoi avons-nous générons 3 fois plus? Le numéro trois est-il spécial, ou voulez-vous dire que nous devons simplement générer plus que nécessaire? – drozzy

+0

Non, il ne "garantit" pas qu'il restera assez d'éléments distincts après la suppression des doublons. – aronisstav

+0

Est-ce que ça va toujours générer quelque chose? – drozzy