Archive for May, 2011

Graphviz and the functional graph library

Sunday, May 29th, 2011

A friend of mine asked how to display a Haskell Functional Graph Library (FGL) graph using graphviz. Turns out it’s really straightforward. Martin Erwig (the author of FGL) considered this when writing the library

$ ghci
> let g=Data.Graph.Inductive.Example.dag4
Use one of the example graphs so that we can print it out.  Then
> import Data.Graph.Inductive.Graphviz
> graphviz g "Foo" (100.0, 100.0) (100, 100) Portrait

where the documentation for the graphviz function is here

Of course, you can do much more complex stuff with the graphviz package…but that’s for another day.

Further homage to QuickCheck

Friday, May 20th, 2011

Lets suppose you’ve got two similar recursive types that differ only in their “payload”. For example, you want a binary tree of boolean operations to store a Char and another similar tree to store a set of Char. Let’s call them Tree and STree. Something like in the following, non-working, code

data Tree = And Tree Tree
  | Or Tree Tree
  | Leaf Char

data STree = And STree STree
  | Or STree STree
  | Leaf (Set Char)

We’re repeating a lot of boiler plate here. It’d be great if I could parameterise the tree, which I can.

data MTree t = And (MTree t) (MTree t)
  | Or (MTree t) (MTree t)
  | Leaf t

This is great, it removes boilerplate, and gives me less code to test.

Take our Tree as defined above. It’s easy to create an Arbitrary Tree. The following code creates an arbitrary tree with a maximum branch depth (generally for efficiency reasons you don’t want test trees that are either (arbitrary :: Int) or infinitely deep)

import Test.QuickCheck
import Control.Monad

data Tree = And Tree Tree
  | Or Tree Tree
  | Leaf Char
  deriving Show

arbitraryTree :: Int -> Gen Tree
arbitraryTree 0        =
  do
    c <- arbitrary
    return (Leaf c)
arbitraryTree maxDepth =
  do
    t <- oneof [arbitraryTree 0,
                liftM2 And (arbitraryTree depth') (arbitraryTree depth'),
                liftM2 Or (arbitraryTree depth') (arbitraryTree depth')]
    return t
  where
    depth' = maxDepth -1

instance Arbitrary Tree where
  arbitrary = do
    maxDepth <- choose (1, 10)
    t <- arbitraryTree maxDepth
    return t

So how do you create an arbitrary MTree? The following code makes it all work.

import Test.QuickCheck
import Control.Monad

data MTree t = And (MTree t) (MTree t)
  | Or (MTree t) (MTree t)
  | Leaf t
  deriving Show

arbitraryMTree :: Arbitrary t => Int -> Gen (MTree t)
arbitraryMTree 0        =
  do
    c <- arbitrary
    return (Leaf c)
arbitraryMTree maxDepth =
  do
    tr <- oneof [arbitraryMTree 0,
                liftM2 And (arbitraryMTree depth') (arbitraryMTree depth'),
                liftM2 Or (arbitraryMTree depth') (arbitraryMTree depth')]
    return tr
  where
    depth' = maxDepth -1

instance Arbitrary t => Arbitrary (MTree t) where
  arbitrary = do
    maxDepth <- choose (1, 10)
    tr <- arbitraryMTree maxDepth
    return tr

This is remarkably neat. QuickCheck, for me, is the killer feature of functional programming!

Returning to the Squad example from the other day. We can create Arbitrary instances of Squad.

import Data.Set
import Data.List
import Test.QuickCheck
import Control.Monad

data Squad a = Squad { players :: (Set a), team :: a}

instance (Ord a, Arbitrary a) => Arbitrary (Squad a) where
  arbitrary =
    do
    ps <- listOf1 arbitrary
    t <- elements ps
    return (Squad (fromList ps) t)

But now I have a complication (and this is where the Squad metaphor breaks down, but please bare with me). Suppose I want a Squad of players where I can in some instances choose a subset of them to play, and in other instances only choose one of them to play. So the Squad still constains a set of players, but the team can sometimes be a subset of the players, and sometimes is a single player. We’ve got to allow instances of TypeSynonyms:

{-# LANGUAGE TypeSynonymInstances #-}
import Data.Set
import Data.List
import Test.QuickCheck
import Control.Monad

data Squad a b = Squad { players :: (Set a), team :: b}
type SetSquad = Squad Char (Set Char)
type SingleSquad = Squad Char Char

instance Arbitrary SetSquad where
  arbitrary =
    do
    ps <- listOf1 arbitrary
    t <- elements (subsequences ps)
    return (Squad (fromList ps) (fromList t))

instance Arbitrary SingleSquad where
  arbitrary =
    do
    ps <- listOf1 arbitrary
    t <- elements ps
    return (Squad (fromList ps) t)

Which is awesome.

Mad props to my homeboy Eric (I’ve been told that’s how one addresses a USian) for listening to my overtired ramblings last night, and for pointing me at numerous ways to implement what I wanted to.

Recursive types in QuickCheck

Wednesday, May 18th, 2011

I want to build arbitrary sized trees of Compound

data Compound = And Compound Compound
  | Or Compound Compound
  | Product Compound Compound
  | Not Compound
  | Leaf { diagram :: Unitary} deriving (Show, Eq)

However, I want to limit to a max depth, and I want to have each branch to be of an arbitrary depth.

mkBinary :: (Compound -> Compound -
> Compound) -> Int -> Gen Compound
mkBinary f depth =
  liftM2 f (mkCompound depth') (mkCompound depth')
  where
    depth' = depth -1

mkNot :: Int -> Gen Compound
mkNot depth =
  liftM Not (mkCompound (depth-1))

mkLeaf :: Gen Compound
mkLeaf = liftM Leaf arbitrary

mkCompound :: Int -> Gen Compound
mkCompound 0 = mkLeaf
mkCompound depth = oneof [mkLeaf, mkBinary And depth, mkBinary Or depth, mkBinary Product depth, mkNot depth]

instance Arbitrary Compound where
  arbitrary =
    do depth <- choose (0, 4)
       d <- mkCompound depth
       return d

QuickCheck can do it. It’s nice. Use it.

Creating Arbitrary Foo for QuickCheck

Tuesday, May 17th, 2011

I always write semi-automated tests, whatever language I’m using. In Haskell my preferred framework is QuickCheck, which goes beyond what an XUnit framework is capable of. I come to QuickCheck as a convert from the old religion of Object Oriented programming. However much I’ve adopted functional practices I find myself, in the darkest of times, falling back on idioms from a past life. Recently I’ve been testing code that looks like the following:

data Squad = Squad { players :: Set Char,
team :: Set Char }

So what I’ve got is some type which is composed of a set and some other set which is a subset of the original. I hope the Squad metaphor is reasonable. In many sports you’ll have a panel of players, called the squad, and then for any given game you’ll have a team which is a subset of the players in your squad. To simplify this problem, each player is identified by a single character rather than a name. Now, we don’t have a dependent type system here. Just plain old Haskell. So the constraint that “team is a subset of players” is not enforced by the type system.

Now I want to tell Haskell to create Arbitrary instances of Squad.

randSubset :: Ord a => Set a -> Gen (Set a)
randSubset xs = do {
mask <- vectorOf (Set.size xs) arbitrary;
return (Set.fromList [ e | (e,True) <- zip (Set.toList xs) mask ]) }

instance Arbitrary Squad where
arbitrary = do {
players <- listOf1 (arbitrary :: Gen Char);
team <- randSubset (Set.fromList players);
return (Squad (Set.fromList players) team))}

The smarts here is in randSubset, but listOf1 ensures that there’s at least one player in our squad. I was struggling when playing around with a random number generator, to try and pull out random elements from a Set. Such thinking is a false idol. With some guidance from the only person on the planet to be 90% Real Jedi I realised you can just use the common generator combinators as provided by QuickCheck.

So the fragment

do {
mask <- vectorOf (Set.size xs) arbitrary;
return (Set.fromList [ e | (e,True) <- zip (Set.toList xs) mask ])}

asks for an arbitrary list of boolean values where the list is the same length as the size of the input Set. Then where the ith element of the list is true, the ith element of the set is considered to be in the subset, or omitted otherwise. It’s a nice idiom, useful anywhere you’re playing with sets that aren’t quite arbitrary themselves, but are constrained to be a subset of another.

An issue with QuickCheck 2

Saturday, May 7th, 2011

I’ve been interested in functional programming for a while. I’ve hacked up a few things. Mira and Conferenceasaurus mainly. I’m not claiming that the code is great, I’d regard myself still as a n00b. I also have an interest in software testing, to this end the QuickCheck is both interesting and awesome. However, I’ve got one significant issue with my usage of it.

The types I’m playing with should probably be implemented using a dependent type system. For example, I’ve got a lot of

data Foo = Foo {bar::Set a, quux::Set a}

where quux should be a subset of bar. I’m not using a dependent type system, just regular Haskell, so the dependence is not enforced. However, I do want to generate instances of Arbitrary Foo where quux is a random subset of bar. Randomness is where my issues lie.

I could generate a random subset of a set

import Data.Set
import Data.Maybe
import Test.QuickCheck

randSubset :: Set a -> Gen (Set a)
randSubset xs = do {
mask <- vectorOf (size xs) (arbitrary::Gen Bool);
return (fromList (catMaybes [if b then (Just e) else Nothing | e <- l, b <- mask]))
}
where
l = toList xs

However, you’ll notice that the type signature is randSubset :: Set a -> Gen (Set a) and to create quux as a random subset of bar in an Arbitrary Foo I’d need this to return a Set a. I could unGen it, however this would require picking a seed which produces the same set of pseudo-random numbers each time, or generating a random seed, in which case I’d have to return an IO (Set a).

So, question time. Is it possible to generate arbitrary instances of Foo such that the property “quux is a subset of bar” is enforced in all arbitrary instances?

update:
As arbitrary :: Gen a then arbitrary = do x <- arbitrary; y <- randSubset x; return (Foo x y) is the solution.