Search code examples
haskellquickcheck

Haskell Matrices testing using QuickCheck


I'm creating a Matrix module in Haskell and I want to use QuickCheck to test some properties of my code. Specifically I want to generate random matrices that have an associated inverse. The following is my attempt at creating a QuickCheck generator that generates such matrices.

invertibleMatrix :: (Num a, Arbitrary a) => Gen (Matrix a)
invertibleMatrix = do s <- choose (2,10)
                      a <- vectorOf s (vector s)
                      if (det (Matrix a) == 0) then
                        invertibleMatrix
                      else
                        return (Matrix a)

The code first creates a size between 2 and 10 and then a vector of vectors of this size. If the determinant is zero then the matrix is not invertible and so I call invertibleMatrix recursively. Otherwise I return the new matrix.

The trouble is, this code does not terminate when I put it in a property to test. (I think that it's constantly creating the same s x s matrix of zero elements which obviously doesn't have an inverse and so it goes into an infinite loop). What am I doing wrong? How do I fix this? Thanks.

Mark


Solution

  • squareMatrix :: (Num a, Arbitrary a) => Gen (Matrix a)
    squareMatrix = do s <- choose (2,6)
                      a <- vectorOf s (vector s)
                      return (Matrix a)
    
    invertibleMatrix :: (Num a, Arbitrary a) => Gen (Matrix a)
    invertibleMatrix = suchThat squareMatrix ((/=0) . det) 
    

    In case anyone wants to know, this is the solution.

    Mark