module GF2test (run) where import Data.Bits (xor) import Data.List (foldl') import Test.HUnit import LinearAlgebra.GF2 ( fromBools , gaussianEliminationAllMasks , maskToIndicesInt ) -- XOR of the rows selected by a mask xorSelected :: [Integer] -> [Int] -> Integer xorSelected rows idxs = foldl' xor 0 [ rows !! i | i <- idxs ] run :: IO () run = do putStrLn "GF2 Gaussian elimination test" -- one dependency: rows 0, 1 and 3 XOR to zero let rowsBits = map fromBools [ [True, False, True] , [False, True, True] , [True, True, True] , [True, True, False] ] masks = gaussianEliminationAllMasks rowsBits assertEqual "expected exactly one dependency" 1 (length masks) assertEqual "expected rows 0,1,3" [[0,1,3]] (map maskToIndicesInt masks) -- no dependency case: the three rows are independent let rowsBits2 = map fromBools [ [True, False, True] , [False, True, True] , [True, True, True] ] assertEqual "Expected no dependency" [] (gaussianEliminationAllMasks rowsBits2) -- several dependencies: 5 rows of rank 2 give a null space of dimension 3 let rowsBits3 = map fromBools [ [True, False, True] -- a , [False, True, True] -- b , [True, True, False] -- a xor b , [True, False, True] -- a again , [False, False, False] -- zero row ] masks3 = gaussianEliminationAllMasks rowsBits3 idxs3 = map maskToIndicesInt masks3 assertEqual "expected rows - rank = 3 dependencies" 3 (length masks3) assertBool "every dependency must XOR to zero" (all (\ix -> xorSelected rowsBits3 ix == 0) idxs3) assertBool "no dependency may be empty" (all (not . null) idxs3) assertBool "the zero row (index 4) must be a dependency on its own" ([4] `elem` idxs3) -- the dependencies must be linearly independent (distinct and non-zero masks) assertEqual "dependencies must be pairwise distinct" (length masks3) (length (dedup masks3)) -- a repeated row is a dependency of size two let rowsBits4 = map fromBools [ [True, False], [False, True], [True, False] ] assertEqual "duplicate row dependency" [[0,2]] (map maskToIndicesInt (gaussianEliminationAllMasks rowsBits4)) -- empty input assertEqual "no rows, no dependency" [] (gaussianEliminationAllMasks []) putStrLn "GF2 test done." where dedup [] = [] dedup (x : xs) = x : dedup (filter (/= x) xs)