diff --git a/HasCacBDD.cabal b/HasCacBDD.cabal
--- a/HasCacBDD.cabal
+++ b/HasCacBDD.cabal
@@ -1,5 +1,5 @@
 name:                HasCacBDD
-version:             0.1.0.2
+version:             0.1.0.3
 synopsis:            Haskell bindings for CacBDD
 homepage:            https://github.com/m4lvin/HasCacBDD
 license:             GPL-2
diff --git a/hs/Data/HasCacBDD.hs b/hs/Data/HasCacBDD.hs
--- a/hs/Data/HasCacBDD.hs
+++ b/hs/Data/HasCacBDD.hs
@@ -289,14 +289,14 @@
 sizeOf :: Bdd -> Int
 sizeOf = length.subsOf
 
--- FIXME: Should we print outermost brackets around non-constant BDDs?
 instance Show Bdd where
-  show b = show (unravel b)
+  show = show . unravel
 
--- TODO: add a Read instance and test that Show and Read are inverses of each other
+instance Read Bdd where
+  readsPrec k input = map (\(a,s) -> (ravel a, s)) (readsPrec k input)
 
 -- | A simple tree definition to show BDDs as text.
-data BddTree = Bot | Top | Var Int BddTree BddTree deriving (Show)
+data BddTree = Bot | Top | Var Int BddTree BddTree deriving (Eq,Read,Show)
 
 -- | Convert a BDD to a tree.
 unravel :: Bdd -> BddTree
diff --git a/hs/Data/HasCacBDD/Visuals.hs b/hs/Data/HasCacBDD/Visuals.hs
--- a/hs/Data/HasCacBDD/Visuals.hs
+++ b/hs/Data/HasCacBDD/Visuals.hs
@@ -7,10 +7,12 @@
   svgGraph
 ) where
 
-import Data.HasCacBDD
-import System.Process
+import System.Exit
 import System.IO
+import System.Process
 
+import Data.HasCacBDD
+
 -- | Generate a string which describes the BDD in the dot language.
 genGraph :: Bdd -> String
 genGraph = genGraphWith show
@@ -61,12 +63,7 @@
 -- | Generate SVG of a BDD with dot.
 svgGraph :: Bdd -> IO String
 svgGraph b = do
-  (inp,out,_,pid) <- runInteractiveProcess "/usr/bin/dot" ["-Tsvg" ] Nothing Nothing
-  hPutStr inp (genGraph b)
-  hSetBinaryMode inp False
-  hSetBinaryMode out False
-  hFlush inp
-  hClose inp
-  outstring <- hGetContents out
-  _ <- waitForProcess pid
-  return $ (unlines.tail.lines) outstring
+  (exitCode,out,err) <- readProcessWithExitCode "/usr/bin/dot" ["-Tsvg" ] (genGraph b)
+  case exitCode of
+    ExitSuccess -> return $ (unlines.tail.lines) out
+    ExitFailure n -> error $ "dot -Tsvg failed with exit code " ++ show n ++ " and error: " ++ err
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,3 +1,3 @@
-resolver: lts-12.9
+resolver: lts-16.1
 packages:
 - '.'
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -67,6 +67,8 @@
     it "show bot == \"Bot\"" $ show bot `shouldBe` "Bot"
   describe "QuickCheck Properties" $ do
     prop "selfEqual"      (\b -> (b::Bdd) == b)
+    prop "showReadEqual"  (\b -> read (show b) == (b::Bdd))
+    prop "showReadTreeEq" (\b -> (ravel . read . show . unravel $ b) == b)
     prop "idSymmetry"     (\a b -> ((a::Bdd) == (b::Bdd)) == (b == a))
     prop "singleNegation" (\b -> neg b /= b)
     prop "doubleNegation" (\b -> neg (neg b) == b)
@@ -93,6 +95,7 @@
     prop "deMorganTwoSet" (\as -> neg (disSet as) ==  conSet (map neg as))
     prop "conSetCommute"  (\a as -> conSet (a:as) == con (conSet as) a)
     prop "disSetCommute"  (\a as -> disSet (a:as) == dis (disSet as) a)
+    prop "xor-disSet"     ( (\as -> xorSet as `imp` disSet as == top) . (take 23) )
     prop "xorSetNeg3"     (\a b c -> xorSet [a,b,c] == xorSet [neg a, b, neg c])
     prop "xorSetCommute3" (\a b c -> xorSet [a,b,c] == xor (xorSet [a,b]) c)
     prop "xorSetCommute4" (\a b c d -> xorSet [a,b,c,d] == xor (xorSet [b,c,a]) d)
@@ -101,6 +104,7 @@
     prop "restrictLaw"    (\a b -> b `imp` equ (restrictLaw a b) a == top)
     prop "evaluate"       (\b -> all (\s -> evaluate b s == Just True) (allSatsWith (allVarsOf b) b))
     prop "evaluateFun"    (\b -> all (\s -> evaluateFun b (\n -> fromJust $ lookup n s)) (allSats b))
+    prop "evaluateFun F"  (\b -> all (\s -> not (evaluateFun bot (\n -> fromJust $ lookup n s))) (allSats b))
     prop "allSatsWith"    (\b -> all (\s -> restrictSet b s == top) (allSatsWith (allVarsOf b) b))
     prop "anySatWith"     (\b -> let vs = allVarsOf b in if b==bot then isNothing (anySatWith vs b) else restrictSet b (fromJust $ anySatWith vs b) == top)
     prop "satCountWith"   (\b -> let vs = allVarsOf b in length (allSatsWith vs b) == satCountWith vs b)
@@ -112,9 +116,11 @@
                                    in
                                       relabel gnippam (relabel mapping b) == b)
     prop "relabelFun"    (\a -> relabelFun (\x -> x-7) (relabelFun (+7) a) == a)
-    prop "substit"       (\b c -> substit 1 b c == ifthenelse b (restrict c (1,True)) (restrict c (1,False)))
-    prop "show"          (\a b -> (show (unravel a) == show (unravel b)) == (a == (b::Bdd)))
+    prop "substit"       (\b c -> substit 5 b c == ifthenelse b (restrict c (5,True)) (restrict c (5,False)))
+    prop "show"          (\a b -> (show a == show b) == (a == (b::Bdd)))
+    prop "read"          (\b -> read (show b) == (b :: Bdd))
     prop "showList"      (\a b -> (showList [unravel a] "" == showList [unravel b] "") == (a == (b::Bdd)))
+    prop "readList"      (\a b -> (readList (show [a,b]) == [([unravel a, unravel b] :: [BddTree], "")]))
   describe "QuickCheck Expected Failures" $ do
     prop "wrong deMorganOne" $
       expectFailure (\a b -> neg (a `con` b) === (neg a `con` neg b))
