IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Haskell Discussion :

Aide avec QuickCheck


Sujet :

Haskell

  1. #1
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut Aide avec QuickCheck
    Salut,

    Pour ceux qui s'en souviennent, j'ai écrit une petite librairie pour calculer les points d'une main de cribbage. J'aimerais utiliser QuickCheck pour faire des vérifications, mais j'ai des petits ennuis dû en grande partie à ma "newbieness".

    Pour commencer, voici mes déclarations de types:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    data Suit = Clubs | Diamond | Heart | Spade
       deriving (Show, Eq)
     
    data Rank = Ace
              | Two
              | Three
              | Four
              | Five
              | Six
              | Seven
              | Eight
              | Nine
              | Ten
              | Jack
              | Queen
              | King
       deriving (Show, Eq, Enum)
     
    type Card    = (Rank, Suit)
    type Hand    = [Card]
    type Starter = Maybe Card
    Maintenant, voici mes déclarations d'instances d'Arbitrary:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    newtype CribbageHand = CribbageHand Hand
        deriving (Show)
     
    instance Arbitrary Suit where
        arbitrary = do
            suit <- oneof $ map return [Clubs, Diamond, Heart, Spade]
            return suit
     
    instance Arbitrary Rank where
        arbitrary = do
            n <- choose (0, 12)
            return (toEnum n)
     
    instance Arbitrary CribbageHand where
        arbitrary = do
            cards <- vector 5::Gen [Card]
            return $ CribbageHand cards
    Première chose, si vous voyez des problèmes avec ces déclarations, dites-le moi. Ces déclarations semble fonctionner, car j'ai pu écrire quelques propriétés et les exécuter. J'aimerais avoir un peu plus de contrôle sur la distribution des cartes:

    • Je voudrais pouvoir choisir que des cartes différentes
    • Pour tester la flush, j'aimerais pouvoir choisir la couleur des cartes
    • Pour tester le point avec le valet, j'aimerais pouvoir m'assurer qu'il y a un valet dans le jeu
    • Etc.


    Si vous pouviez me donner des indications sur comment arriver à ces buts, j'apprécierais énormément.

    Merci.

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Petite remarque d'abord :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    instance Arbitrary Suit where
        arbitrary = do
            suit <- oneof $ map return [Clubs, Diamond, Heart, Spade]
            return suit
    peut-être écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    instance Arbitrary Suit where
        arbitrary = elements [Clubs, Diamond, Heart, Spade]
    Egalement, il est peut-être plus élégant d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    instance Arbitrary Rank where
        arbitrary = liftM toEnum $ choose (0, 12)
    Pour ce qui est de la main, on voudrait effectivement plutôt que tous les éléments soient différents, ce que vector ne fait pas, il faut définir un nouveau générateur de listes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    differents n = aux_diff n []
        where 
          aux_diff 0 _ = return []
          aux_diff n seen = do
            x <- untilM (not . (`elem` seen)) arbitrary
            xs <- aux_diff (n-1) (x:seen)
            return (x:xs)
          untilM p act = do
            result <- act
            if p result then return result else untilM p act
    Ensuite tu remplaces vector par differents dans ton instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    instance Arbitrary CribbageHand where
        arbitrary = liftM CribbageHand $ differents 5
    (l'annotation de type n'est pas nécessaire, Haskell peut deviner tout seul)

    Pour tester la flush, j'aimerais pouvoir choisir la couleur des cartes
    Pour tester le point avec le valet, j'aimerais pouvoir m'assurer qu'il y a un valet dans le jeu
    Etc.
    Je suppose que le premier point je le ferais avec forAll et le second simplement avec ==>.
    Tu as bien lu le manuel ?

    --
    Jedaï

  3. #3
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut
    Lu, oui. Compris, plus ou moins :-/

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    module TestCribbage where
     
    import Test.QuickCheck
    import Cribbage
    import Control.Monad
     
    newtype CribbageHand = CH Hand
        deriving (Show)
     
    instance Arbitrary Suit where
        arbitrary = elements [Clubs, Diamond, Heart, Spade]
        coarbitrary = undefined
     
    instance Arbitrary Rank where
        arbitrary = liftM toEnum $ choose (0, 12)
        coarbitrary = undefined
     
    differents n = differents' n arbitrary
     
    differents' n g = aux_diff n []
        where 
          aux_diff 0 _ = return []
          aux_diff n seen = do
            x <- untilM (not . (`elem` seen)) g
            xs <- aux_diff (n-1) (x:seen)
            return (x:xs)
          untilM p act = do
            result <- act
            if p result then return result else untilM p act
     
    instance Arbitrary CribbageHand where
        arbitrary = liftM CH $ differents 4
        coarbitrary = undefined
     
    prop_Trivial (CH hand) starter isCrib = 
        count hand starter isCrib >= 0
     
    prop_Flush randSuit starter =
        forAll (differents 4) $ \ranks ->
            let hand = map (\r->(r,randSuit)) ranks
                score = countFlush hand starter False
            in score >= 4 && score <= 5
     
    prop_Jocker (CH hand) starter =
        let jacks = filter ((== Jack) . rank) hand
            starterSuit = liftM suit starter
        in not (null jacks) 
               && maybe False (\s -> any ((== s).suit) jacks) starterSuit
                      ==> countJack hand starter == 1
    (La dernière propriété est franchement tordue, mais comme je ne sais pas exactement ce que tu voulais ?)

    --
    Jedaï

Discussions similaires

  1. Besoin d'aide avec Regexp::Assemble
    Par mobscene dans le forum Modules
    Réponses: 5
    Dernier message: 11/04/2007, 12h39
  2. [ASA] J'ai besoin d'aide avec sybase et vb6 svp !!
    Par tibo830 dans le forum SQL Anywhere
    Réponses: 7
    Dernier message: 12/05/2006, 10h09
  3. Besoin d'aide avec TinyXML
    Par Clad3 dans le forum Bibliothèques
    Réponses: 5
    Dernier message: 15/08/2005, 18h20
  4. Réponses: 2
    Dernier message: 29/08/2003, 17h52
  5. Besoin d'aide avec postgresql sous windows NT
    Par Chihuahua dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/07/2003, 08h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo