How do you create a property that checks that all solutions provided are valid solutions, I need it to output as a Property, but I'm unsure how to do that, I only understand how to do Bool outputs for quickCheck properties. See below for my attempt, and the general idea of how I want it to function:
solve :: Sudoku -> Maybe Sudoku
solve s = solve' (blanks s) s
solve' :: [Pos] -> Sudoku -> Maybe Sudoku
solve' blankl s
| not (isOkay s) = Nothing
| isFilled s = Just s
| otherwise = listToMaybe [fromJust sol | n <- [1..9],
let sol = solve' (tail blankl) (update s (head blankl) (Just n)),
sol /= Nothing]
isSolutionOf :: Sudoku -> Sudoku -> Bool
isSolutionOf s1 s2 =
isOkay s1
&& isFilled s1
&& and [ a == b || b == Nothing |
(a,b) <- zip (concat (rows s1)) (concat (rows s2)) ]
prop_SolveSound :: Sudoku -> Property
prop_SolveSound s
| solution == Nothing = True
| otherwise = isSolutionOf (fromJust solution) s where
solution = solve s
Any help is much appreciated, I guess what I'm asking is how can you convert the - quite clearly - Bool
output from prop_SolveSound
to a Property
output?
At the very simplest, you can use property
method to convert e.g. Bool
to Property
. I suggest to look at the instances of Testable
class, and try to understand what each of them does, and how it can be used.
Or you can be more sophisticated and use some other functions returning Property
, e.g. ===
. That might be tricky in your example.
One quite useful function, is counterexample
. It allows you to print additional output, when property doesn't hold. For example, it's used to implement ===
:
(===) :: (Eq a, Show a) => a -> a -> Property
x === y =
counterexample (show x ++ interpret res ++ show y) res
where
res = x == y
interpret True = " == "
interpret False = " /= "
As this is an assignment, I'm not giving you any more hints.