diff --git a/boolean-normal-forms.cabal b/boolean-normal-forms.cabal
--- a/boolean-normal-forms.cabal
+++ b/boolean-normal-forms.cabal
@@ -1,5 +1,5 @@
 name:                boolean-normal-forms
-version:             0.0.0.1
+version:             0.0.0.2
 synopsis:            Boolean normal form: NNF, DNF & CNF
 description:         The provided types that might be useful in symbolic manipulation of propositional logic expressions.
 license:             MIT
@@ -9,10 +9,20 @@
 copyright:           © Oleg Grenrus 2014
 category:            Data
 build-type:          Simple
-cabal-version:       >=1.10
+cabal-version:       >=1.18
 extra-source-files:  README.md
 extra-doc-files:      doc-formulae/*.svg
+tested-with:
+  GHC==7.6.3,
+  GHC==7.8.4,
+  GHC==7.10.3,
+  GHC==8.0.2,
+  GHC==8.2.2
 
+source-repository head
+  type: git
+  location: https://github.com/phadej/boolean-normal-forms.git
+
 library
   hs-source-dirs:      src
   exposed-modules:     Data.Algebra.Boolean.NormalForm,
@@ -33,16 +43,11 @@
                        ConstraintKinds,
                        TypeFamilies,
                        ScopedTypeVariables
-  build-depends:       base >=4.6 && <4.8,
-                       containers >=0.5 && <0.6,
-                       cond >=0.4.1 && <0.5
+  build-depends:       base        >=4.6   && <4.11,
+                       containers  >=0.5   && <0.6,
+                       cond        >=0.4.1 && <0.5
   default-language:    Haskell2010
   ghc-options:         -Wall
-                       -O2
-                       -fwarn-tabs
-                       -fspec-constr-count=6
-                       -fmax-simplifier-iterations=10
-                       -fdicts-cheap
 
 test-suite test
   default-language:    Haskell2010
@@ -50,6 +55,7 @@
   hs-source-dirs:      tests
   main-is:             Main.hs
   other-modules:       BooleanLaws,
+                       BooleanModelLaws,
                        CNFList,
                        CNFSet,
                        DNFList,
@@ -60,11 +66,11 @@
                        NNFSet,
                        NNFTree,
                        SimplifyLaws
-  ghc-options:         -Wall -O2 -fno-warn-orphans
-  build-depends:       base >=4.6 && <4.8,
-                       containers >= 0.5 && <0.6,
-                       cond >=0.4.1 && <0.5,
-                       tasty >=0.8,
-                       tasty-quickcheck >=0.8.0.3,
-                       QuickCheck >=2.7 && <=2.8,
+  ghc-options:         -Wall -fno-warn-orphans
+  build-depends:       base,
+                       containers,
+                       cond,
+                       tasty                >=0.8,
+                       tasty-quickcheck     >=0.8.0.3,
+                       QuickCheck           >=2.10 && <2.11,
                        boolean-normal-forms
diff --git a/src/Data/Algebra/Boolean/CNF/List.hs b/src/Data/Algebra/Boolean/CNF/List.hs
--- a/src/Data/Algebra/Boolean/CNF/List.hs
+++ b/src/Data/Algebra/Boolean/CNF/List.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -21,7 +22,8 @@
 import Prelude hiding ((||),(&&),not,any,all,and,or)
 import Data.Monoid
 import Data.Either (partitionEithers)
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 import Data.Algebra.Boolean.NormalForm
 import Data.Algebra.Boolean.Negable hiding (not)
@@ -35,7 +37,7 @@
 --
 -- <<doc-formulae/cnf.svg>>
 newtype CNF a = CNF { unCNF :: [[a]] }
-  deriving (Eq, Ord, Show, Read, Functor, Typeable)
+  deriving (Eq, Ord, Show, Read, Functor, Foldable, Typeable)
 
 instance CoBoolean1 CNF where
   toBooleanWith f = all (any f) . unCNF
diff --git a/src/Data/Algebra/Boolean/CNF/Set.hs b/src/Data/Algebra/Boolean/CNF/Set.hs
--- a/src/Data/Algebra/Boolean/CNF/Set.hs
+++ b/src/Data/Algebra/Boolean/CNF/Set.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -19,7 +20,8 @@
 
 import Prelude hiding ((||),(&&),not,and,or,any,all)
 import Data.Monoid
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 import Data.Set (Set)
 import qualified Data.Set as Set
@@ -39,7 +41,7 @@
 --
 -- <<doc-formulae/cnf.svg>>
 newtype CNF a = CNF { unCNF :: Set (Set a) }
-  deriving (Eq, Ord, Show, Read, Typeable)
+  deriving (Eq, Ord, Show, Read, Foldable, Typeable)
 
 instance CoBoolean1 CNF where
   toBooleanWith f = all (any f) . unCNF
diff --git a/src/Data/Algebra/Boolean/DNF/List.hs b/src/Data/Algebra/Boolean/DNF/List.hs
--- a/src/Data/Algebra/Boolean/DNF/List.hs
+++ b/src/Data/Algebra/Boolean/DNF/List.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -21,7 +22,8 @@
 import Prelude hiding ((||),(&&),not,any,all,and,or)
 import Data.Monoid
 import Data.Either (partitionEithers)
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 import Data.Algebra.Boolean.NormalForm
 import Data.Algebra.Boolean.Negable hiding (not)
@@ -35,7 +37,7 @@
 --
 -- <<doc-formulae/dnf.svg>>
 newtype DNF a = DNF { unDNF :: [[a]] }
-  deriving (Eq, Ord, Show, Read, Functor, Typeable)
+  deriving (Eq, Ord, Show, Read, Functor, Foldable, Typeable)
 
 instance CoBoolean1 DNF where
   toBooleanWith f = any (all f) . unDNF
diff --git a/src/Data/Algebra/Boolean/DNF/Set.hs b/src/Data/Algebra/Boolean/DNF/Set.hs
--- a/src/Data/Algebra/Boolean/DNF/Set.hs
+++ b/src/Data/Algebra/Boolean/DNF/Set.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -19,7 +20,8 @@
 
 import Prelude hiding ((||),(&&),not,and,or,any,all)
 import Data.Monoid
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 import Data.Set (Set)
 import qualified Data.Set as Set
@@ -39,7 +41,7 @@
 --
 -- <<doc-formulae/dnf.svg>>
 newtype DNF a = DNF { unDNF :: Set (Set a) }
-  deriving (Eq, Ord, Show, Read, Typeable)
+  deriving (Eq, Ord, Show, Read, Foldable, Typeable)
 
 instance CoBoolean1 DNF where
   toBooleanWith f = any (all f) . unDNF
diff --git a/src/Data/Algebra/Boolean/FreeBoolean.hs b/src/Data/Algebra/Boolean/FreeBoolean.hs
--- a/src/Data/Algebra/Boolean/FreeBoolean.hs
+++ b/src/Data/Algebra/Boolean/FreeBoolean.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 --------------------------------------------------------------------
 -- |
@@ -14,7 +15,8 @@
   module Data.Algebra.Boolean.CoBoolean
 ) where
 
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 import Data.Algebra.Boolean.CoBoolean
 import Data.Algebra.Boolean.Negable hiding (not)
@@ -32,7 +34,7 @@
                    | FBNot (FreeBoolean a)
                    | FBAnd (FreeBoolean a) (FreeBoolean a)
                    | FBOr (FreeBoolean a) (FreeBoolean a)
-  deriving (Eq, Ord, Show, Read, Functor, Typeable)
+  deriving (Eq, Ord, Show, Read, Functor, Foldable, Typeable)
 
 instance CoBoolean1 FreeBoolean where
   toBooleanWith f (FBValue x)  = f x
diff --git a/src/Data/Algebra/Boolean/NNF/Set.hs b/src/Data/Algebra/Boolean/NNF/Set.hs
--- a/src/Data/Algebra/Boolean/NNF/Set.hs
+++ b/src/Data/Algebra/Boolean/NNF/Set.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -24,7 +25,8 @@
 import Prelude hiding ((||),(&&),not,any,all)
 import Data.Algebra.Boolean
 
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 -- | Boolean formula in Negation Normal Form
 --
@@ -36,7 +38,7 @@
            | NNFValue a
            | NNFOr (Set (NNF a))
            | NNFAnd (Set (NNF a))
-  deriving (Eq, Ord, Show, Read, Typeable)
+  deriving (Eq, Ord, Show, Read, Foldable, Typeable)
 
 instance CoBoolean a => CoBoolean (NNF a) where
   toBoolean = toBooleanWith toBoolean
diff --git a/src/Data/Algebra/Boolean/NNF/Tree.hs b/src/Data/Algebra/Boolean/NNF/Tree.hs
--- a/src/Data/Algebra/Boolean/NNF/Tree.hs
+++ b/src/Data/Algebra/Boolean/NNF/Tree.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveFoldable #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE TypeFamilies #-}
 --------------------------------------------------------------------
@@ -23,7 +24,8 @@
 
 import Data.Algebra.Boolean
 
-import Data.Typeable
+import Data.Typeable (Typeable)
+import Data.Foldable (Foldable)
 
 -- | Boolean formula in Negation Normal Form
 --
@@ -35,7 +37,7 @@
            | NNFValue a
            | NNFOr (NNF a) (NNF a)
            | NNFAnd (NNF a) (NNF a)
-  deriving (Eq, Ord, Show, Read, Functor, Typeable)
+  deriving (Eq, Ord, Show, Read, Functor, Foldable, Typeable)
 
 instance CoBoolean a => CoBoolean (NNF a) where
   toBoolean = toBooleanWith toBoolean
diff --git a/tests/BooleanModelLaws.hs b/tests/BooleanModelLaws.hs
new file mode 100644
--- /dev/null
+++ b/tests/BooleanModelLaws.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE ConstraintKinds #-}
+module BooleanModelLaws (booleanModelLaws) where
+
+import Test.Tasty
+import Test.Tasty.QuickCheck as QC
+
+import FreeBoolean
+
+import Data.Algebra.Boolean.NormalForm
+
+modelProperty :: (CoBoolean a, NormalForm nf, NFConstraint nf a) => nf a -> FreeBoolean a-> Property
+modelProperty t b = collect (freeBooleanHeight b) $
+  toBoolWith toBool b == toBoolWith toBool (fromFreeBoolean b `asTypeOf` t)
+
+booleanModelLaws :: (Arbitrary a, Show a, CoBoolean a, NormalForm nf, NFConstraint nf a) => nf a -> TestTree
+booleanModelLaws t = QC.testProperty "Boolean model" $ modelProperty t
diff --git a/tests/CNFSet.hs b/tests/CNFSet.hs
--- a/tests/CNFSet.hs
+++ b/tests/CNFSet.hs
@@ -18,9 +18,6 @@
 import Data.Algebra.Boolean.Negable (Negable)
 import Data.Algebra.Boolean.CNF.Set
 
-instance Arbitrary a => Arbitrary (Sum a) where
-  arbitrary = Sum <$> arbitrary
-
 instance (Ord a, Negable a, Arbitrary a) => Arbitrary (CNF a) where
   arbitrary = fromFreeBoolean <$> arbitrary
 
diff --git a/tests/DNFSet.hs b/tests/DNFSet.hs
--- a/tests/DNFSet.hs
+++ b/tests/DNFSet.hs
@@ -18,9 +18,6 @@
 import Data.Algebra.Boolean.Negable (Negable)
 import Data.Algebra.Boolean.DNF.Set
 
-instance Arbitrary a => Arbitrary (Sum a) where
-  arbitrary = Sum <$> arbitrary
-
 instance (Ord a, Negable a, Arbitrary a) => Arbitrary (DNF a) where
   arbitrary = fromFreeBoolean <$> arbitrary
 
diff --git a/tests/NNFSet.hs b/tests/NNFSet.hs
--- a/tests/NNFSet.hs
+++ b/tests/NNFSet.hs
@@ -18,9 +18,6 @@
 import Data.Algebra.Boolean.Negable (Negable)
 import Data.Algebra.Boolean.NNF.Set
 
-instance Arbitrary a => Arbitrary (Sum a) where
-  arbitrary = Sum <$> arbitrary
-
 instance (Ord a, Negable a, Arbitrary a) => Arbitrary (NNF a) where
   arbitrary = fromFreeBoolean <$> arbitrary
 
