diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013-2014, Omari Norman
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Omari Norman nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/current-versions.txt b/current-versions.txt
new file mode 100644
--- /dev/null
+++ b/current-versions.txt
@@ -0,0 +1,51 @@
+This package was tested to work with these dependency
+versions and compiler version.
+These are the default versions fetched by cabal install.
+Tested as of: 2014-07-13 16:28:45.229908 UTC
+Path to compiler: ghc-7.8.2
+Compiler description: 7.8.2
+
+/opt/ghc/7.8.2/lib/ghc-7.8.2/package.conf.d:
+    Cabal-1.18.1.3
+    array-0.5.0.0
+    base-4.7.0.0
+    bin-package-db-0.0.0.0
+    binary-0.7.1.0
+    rts-1.0
+    bytestring-0.10.4.0
+    containers-0.5.5.1
+    deepseq-1.3.0.2
+    directory-1.2.1.0
+    filepath-1.3.0.2
+    (ghc-7.8.2)
+    ghc-prim-0.3.1.0
+    (haskell2010-1.1.2.0)
+    (haskell98-2.0.0.3)
+    hoopl-3.10.0.1
+    hpc-0.6.0.1
+    integer-gmp-0.5.1.0
+    old-locale-1.0.0.6
+    old-time-1.1.0.2
+    pretty-1.1.1.1
+    process-1.2.0.0
+    template-haskell-2.9.0.0
+    time-1.4.2
+    transformers-0.3.0.0
+    unix-2.7.0.1
+
+/home/massysett/prednote/tests/sunlight-29186/db:
+    QuickCheck-2.7.5
+    contravariant-0.6
+    prednote-0.24.0.0
+    prednote-test-0.24.0.0
+    primitive-0.5.3.0
+    quickpull-0.2.0.0
+    rainbow-0.14.0.2
+    rainbow-tests-0.14.0.2
+    random-1.0.1.1
+    split-0.2.2
+    terminfo-0.4.0.0
+    text-1.1.1.3
+    tf-random-0.5
+    transformers-compat-0.3.3.4
+
diff --git a/exe/Decrees.hs b/exe/Decrees.hs
new file mode 100644
--- /dev/null
+++ b/exe/Decrees.hs
@@ -0,0 +1,115 @@
+-- | This module generated by the Quickpull package.
+-- Quickpull is available at:
+-- <http://www.github.com/massysett/quickpull>
+
+module Decrees where
+
+import Quickpull
+import qualified Prednote.Comparisons.Properties
+import qualified Prednote.Core.Properties
+import qualified Prednote.Prebuilt.Properties
+
+decrees :: [Decree]
+decrees =
+
+  [ Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 13, qName = "prop_compareBy"} ) ( Single Prednote.Comparisons.Properties.prop_compareBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 28, qName = "prop_compare"} ) ( Single Prednote.Comparisons.Properties.prop_compare )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 39, qName = "prop_equalBy"} ) ( Single Prednote.Comparisons.Properties.prop_equalBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 54, qName = "prop_equal"} ) ( Single Prednote.Comparisons.Properties.prop_equal )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 63, qName = "prop_compareByMaybe"} ) ( Single Prednote.Comparisons.Properties.prop_compareByMaybe )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 92, qName = "prop_greater"} ) ( Single Prednote.Comparisons.Properties.prop_greater )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 93, qName = "prop_less"} ) ( Single Prednote.Comparisons.Properties.prop_less )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 94, qName = "prop_greaterEq"} ) ( Single Prednote.Comparisons.Properties.prop_greaterEq )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 95, qName = "prop_lessEq"} ) ( Single Prednote.Comparisons.Properties.prop_lessEq )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 96, qName = "prop_notEq"} ) ( Single Prednote.Comparisons.Properties.prop_notEq )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 116, qName = "prop_greaterBy"} ) ( Single Prednote.Comparisons.Properties.prop_greaterBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 117, qName = "prop_lessBy"} ) ( Single Prednote.Comparisons.Properties.prop_lessBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 118, qName = "prop_greaterEqBy"} ) ( Single Prednote.Comparisons.Properties.prop_greaterEqBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 119, qName = "prop_lessEqBy"} ) ( Single Prednote.Comparisons.Properties.prop_lessEqBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 121, qName = "prop_notEqBy"} ) ( Single Prednote.Comparisons.Properties.prop_notEqBy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 150, qName = "prop_textEQ1"} ) ( Single Prednote.Comparisons.Properties.prop_textEQ1 )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 151, qName = "prop_textEQ2"} ) ( Single Prednote.Comparisons.Properties.prop_textEQ2 )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 152, qName = "prop_textG"} ) ( Single Prednote.Comparisons.Properties.prop_textG )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 153, qName = "prop_textL"} ) ( Single Prednote.Comparisons.Properties.prop_textL )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 154, qName = "prop_textGE"} ) ( Single Prednote.Comparisons.Properties.prop_textGE )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 155, qName = "prop_textLE"} ) ( Single Prednote.Comparisons.Properties.prop_textLE )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 156, qName = "prop_textNE1"} ) ( Single Prednote.Comparisons.Properties.prop_textNE1 )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Comparisons/Properties.hs", modName = ["Prednote","Comparisons","Properties"]}, linenum = 157, qName = "prop_textNE2"} ) ( Single Prednote.Comparisons.Properties.prop_textNE2 )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 17, qName = "prop_shown"} ) ( Single Prednote.Core.Properties.prop_shown )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 20, qName = "prop_hidden"} ) ( Single Prednote.Core.Properties.prop_hidden )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 23, qName = "prop_allEmpty"} ) ( Single Prednote.Core.Properties.prop_allEmpty )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 30, qName = "prop_allTrues"} ) ( Single Prednote.Core.Properties.prop_allTrues )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 36, qName = "prop_allOneFalse"} ) ( Single Prednote.Core.Properties.prop_allOneFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 43, qName = "prop_allNoShortTrue"} ) ( Single Prednote.Core.Properties.prop_allNoShortTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 50, qName = "prop_allNoShortLastFalse"} ) ( Single Prednote.Core.Properties.prop_allNoShortLastFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 58, qName = "prop_allShortNotLastFalse"} ) ( Single Prednote.Core.Properties.prop_allShortNotLastFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 67, qName = "prop_allShortCirLength"} ) ( Single Prednote.Core.Properties.prop_allShortCirLength )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 76, qName = "prop_allAllTrueLength"} ) ( Single Prednote.Core.Properties.prop_allAllTrueLength )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 84, qName = "prop_allOneFalseLength"} ) ( Single Prednote.Core.Properties.prop_allOneFalseLength )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 92, qName = "prop_allResultSpan"} ) ( Single Prednote.Core.Properties.prop_allResultSpan )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 101, qName = "prop_anyEmptyFalse"} ) ( Single Prednote.Core.Properties.prop_anyEmptyFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 106, qName = "prop_anyAllFalsesIsFalse"} ) ( Single Prednote.Core.Properties.prop_anyAllFalsesIsFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 112, qName = "prop_anyTrueOneTrue"} ) ( Single Prednote.Core.Properties.prop_anyTrueOneTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 119, qName = "prop_anyNoShortFalse"} ) ( Single Prednote.Core.Properties.prop_anyNoShortFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 126, qName = "prop_anyNoShortLastTrue"} ) ( Single Prednote.Core.Properties.prop_anyNoShortLastTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 133, qName = "prop_anyShortsNotLastTrue"} ) ( Single Prednote.Core.Properties.prop_anyShortsNotLastTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 141, qName = "prop_anyShortCircuitLastChild"} ) ( Single Prednote.Core.Properties.prop_anyShortCircuitLastChild )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 150, qName = "prop_anyResultSpan"} ) ( Single Prednote.Core.Properties.prop_anyResultSpan )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 160, qName = "prop_notOneChild"} ) ( Single Prednote.Core.Properties.prop_notOneChild )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 167, qName = "prop_notNeverShort"} ) ( Single Prednote.Core.Properties.prop_notNeverShort )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 174, qName = "prop_notIsOpposite"} ) ( Single Prednote.Core.Properties.prop_notIsOpposite )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 186, qName = "prop_fanSucceedOnUndefined"} ) ( Single Prednote.Core.Properties.prop_fanSucceedOnUndefined )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 197, qName = "prop_fanAlwaysShortsOnNonPositive"} ) ( Single Prednote.Core.Properties.prop_fanAlwaysShortsOnNonPositive )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 209, qName = "prop_fanNoShortCircuit"} ) ( Single Prednote.Core.Properties.prop_fanNoShortCircuit )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 223, qName = "prop_fanShortCircuitIntLessThan"} ) ( Single Prednote.Core.Properties.prop_fanShortCircuitIntLessThan )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 236, qName = "prop_fanNoShortCircuitOnNothing"} ) ( Single Prednote.Core.Properties.prop_fanNoShortCircuitOnNothing )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 247, qName = "prop_fanResult"} ) ( Single Prednote.Core.Properties.prop_fanResult )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 259, qName = "prop_fanVisibility"} ) ( Single Prednote.Core.Properties.prop_fanVisibility )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 272, qName = "prop_fanNumberOfChildren"} ) ( Single Prednote.Core.Properties.prop_fanNumberOfChildren )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 289, qName = "prop_fanAllTrueOnEmptyList"} ) ( Single Prednote.Core.Properties.prop_fanAllTrueOnEmptyList )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 294, qName = "prop_fanAllTrueAllItemsTrue"} ) ( Single Prednote.Core.Properties.prop_fanAllTrueAllItemsTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 299, qName = "prop_fanAllFalseOneItemFalse"} ) ( Single Prednote.Core.Properties.prop_fanAllFalseOneItemFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 305, qName = "prop_fanAllNoShortCircuitTrue"} ) ( Single Prednote.Core.Properties.prop_fanAllNoShortCircuitTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 311, qName = "prop_fanAllNoShortCircuitLastFalse"} ) ( Single Prednote.Core.Properties.prop_fanAllNoShortCircuitLastFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 318, qName = "prop_fanAllShortCircuitFalseNotLast"} ) ( Single Prednote.Core.Properties.prop_fanAllShortCircuitFalseNotLast )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 327, qName = "prop_fanAllShortCircuitLength"} ) ( Single Prednote.Core.Properties.prop_fanAllShortCircuitLength )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 337, qName = "prop_fanAnyFalseOnEmptyList"} ) ( Single Prednote.Core.Properties.prop_fanAnyFalseOnEmptyList )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 342, qName = "prop_fanAnyFalseAllItemsFalse"} ) ( Single Prednote.Core.Properties.prop_fanAnyFalseAllItemsFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 347, qName = "prop_fanAnyFalseOneItemFalse"} ) ( Single Prednote.Core.Properties.prop_fanAnyFalseOneItemFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 353, qName = "prop_fanAnyNoShortCircuitFalse"} ) ( Single Prednote.Core.Properties.prop_fanAnyNoShortCircuitFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 359, qName = "prop_fanAnyNoShortCircuitLastTrue"} ) ( Single Prednote.Core.Properties.prop_fanAnyNoShortCircuitLastTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 366, qName = "prop_fanAnyShortCircuitFalseNotLast"} ) ( Single Prednote.Core.Properties.prop_fanAnyShortCircuitFalseNotLast )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 375, qName = "prop_fanAnyShortCircuitLength"} ) ( Single Prednote.Core.Properties.prop_fanAnyShortCircuitLength )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 384, qName = "prop_fanAtLeastLTEQZero"} ) ( Single Prednote.Core.Properties.prop_fanAtLeastLTEQZero )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 401, qName = "prop_fanAtLeastTrue"} ) ( Single Prednote.Core.Properties.prop_fanAtLeastTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 410, qName = "prop_fanAtLeastShortFewer"} ) ( Single Prednote.Core.Properties.prop_fanAtLeastShortFewer )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 419, qName = "prop_fanAtLeastFalse"} ) ( Single Prednote.Core.Properties.prop_fanAtLeastFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 426, qName = "prop_fanAtLeastShortMoreAreAfter"} ) ( Single Prednote.Core.Properties.prop_fanAtLeastShortMoreAreAfter )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 437, qName = "prop_testIsEvaluation"} ) ( Single Prednote.Core.Properties.prop_testIsEvaluation )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 444, qName = "prop_testVSameAsTest"} ) ( Single Prednote.Core.Properties.prop_testVSameAsTest )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 451, qName = "prop_testVSameAsReport"} ) ( Single Prednote.Core.Properties.prop_testVSameAsReport )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 460, qName = "prop_filter"} ) ( Single Prednote.Core.Properties.prop_filter )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 473, qName = "prop_filterVFst"} ) ( Single Prednote.Core.Properties.prop_filterVFst )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 479, qName = "prop_filterVSnd"} ) ( Single Prednote.Core.Properties.prop_filterVSnd )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 489, qName = "prop_shorter"} ) ( Single Prednote.Core.Properties.prop_shorter )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Core/Properties.hs", modName = ["Prednote","Core","Properties"]}, linenum = 496, qName = "prop_shorterLazy"} ) ( Single Prednote.Core.Properties.prop_shorterLazy )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 31, qName = "prop_predicate"} ) ( Single Prednote.Prebuilt.Properties.prop_predicate )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 39, qName = "prop_predicateVisible"} ) ( Single Prednote.Prebuilt.Properties.prop_predicateVisible )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 47, qName = "prop_true"} ) ( Single Prednote.Prebuilt.Properties.prop_true )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 51, qName = "prop_trueShown"} ) ( Single Prednote.Prebuilt.Properties.prop_trueShown )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 54, qName = "prop_false"} ) ( Single Prednote.Prebuilt.Properties.prop_false )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 58, qName = "prop_falseShown"} ) ( Single Prednote.Prebuilt.Properties.prop_falseShown )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 62, qName = "prop_visibility"} ) ( Single Prednote.Prebuilt.Properties.prop_visibility )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 69, qName = "prop_reveal"} ) ( Single Prednote.Prebuilt.Properties.prop_reveal )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 73, qName = "prop_hidden"} ) ( Single Prednote.Prebuilt.Properties.prop_hidden )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 77, qName = "prop_showTrue"} ) ( Single Prednote.Prebuilt.Properties.prop_showTrue )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 84, qName = "prop_showFalse"} ) ( Single Prednote.Prebuilt.Properties.prop_showFalse )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 104, qName = "prop_allSame"} ) ( Single Prednote.Prebuilt.Properties.prop_allSame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 108, qName = "prop_allOpSame"} ) ( Single Prednote.Prebuilt.Properties.prop_allOpSame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 113, qName = "prop_anySame"} ) ( Single Prednote.Prebuilt.Properties.prop_anySame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 117, qName = "prop_anyOpSame"} ) ( Single Prednote.Prebuilt.Properties.prop_anyOpSame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 122, qName = "prop_notSame"} ) ( Single Prednote.Prebuilt.Properties.prop_notSame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 126, qName = "prop_fanAllSame"} ) ( Single Prednote.Prebuilt.Properties.prop_fanAllSame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 130, qName = "prop_fanAnySame"} ) ( Single Prednote.Prebuilt.Properties.prop_fanAnySame )
+  , Decree ( Meta {modDesc = ModDesc {modPath = "exe/Prednote/Prebuilt/Properties.hs", modName = ["Prednote","Prebuilt","Properties"]}, linenum = 134, qName = "prop_fanAtLeastSame"} ) ( Single Prednote.Prebuilt.Properties.prop_fanAtLeastSame )
+  ]
diff --git a/exe/Prednote/Comparisons/Properties.hs b/exe/Prednote/Comparisons/Properties.hs
new file mode 100644
--- /dev/null
+++ b/exe/Prednote/Comparisons/Properties.hs
@@ -0,0 +1,157 @@
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Prednote.Comparisons.Properties where
+
+import Data.Text.Generators
+import Test.QuickCheck
+import Data.Text (Text)
+import qualified Prednote.Comparisons as M
+import qualified Prednote.Core as C
+import Prednote.Tests.Util
+
+-- | compareBy is same as compare
+prop_compareBy =
+  forAll (text arbitrary) $ \t1 ->
+  forAll (text arbitrary) $ \t2 ->
+  forAll (fmap Blind $ function1 coarbitrary (text arbitrary))
+    $ \(Blind fTxt) ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  forAll arbitrary $ \ord ->
+  forAll (fmap Blind $ function2 coarbitrary coarbitrary arbitrary)
+    $ \(Blind fCmp) ->
+  C.test (M.compareBy t1 t2 fTxt (`fCmp` iRight) ord) iLeft
+    == (fCmp iLeft iRight == ord)
+
+-- | compare behaves like Prelude.compare
+prop_compare =
+  forAll (text arbitrary) $ \t1 ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  forAll arbitrary $ \ord ->
+  C.test (M.compare t1 iRight ord) iLeft
+    == (compare iLeft iRight == ord)
+
+-- | equalBy works as expected
+
+prop_equalBy =
+  forAll (text arbitrary) $ \t1 ->
+  forAll (text arbitrary) $ \t2 ->
+  forAll (fmap Blind $ function1 coarbitrary (text arbitrary))
+    $ \(Blind fTxt) ->
+  forAll (fmap Blind $ function2 coarbitrary coarbitrary arbitrary)
+    $ \(Blind p) ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  C.test (M.equalBy t1 t2 fTxt (`p` iRight)) iLeft
+    == (p iLeft iRight)
+
+-- | equal works as expected
+
+prop_equal =
+  forAll (text arbitrary) $ \t1 ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  C.test (M.equal t1 iRight) iLeft
+    == (iLeft == iRight)
+
+-- | compareByMaybe works as it should
+prop_compareByMaybe =
+  forAll (text arbitrary) $ \t1 ->
+  forAll (text arbitrary) $ \t2 ->
+  forAll (fmap Blind $ function1 coarbitrary (text arbitrary))
+    $ \(Blind fTxt) ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  forAll arbitrary $ \ord ->
+  forAll (fmap Blind $ function2 coarbitrary coarbitrary arbitrary)
+    $ \(Blind fCmp) ->
+  let rPred = C.test (M.compareByMaybe t1 t2 fTxt (`fCmp` iRight) ord)
+        iLeft
+      rCmp = fCmp iLeft iRight
+      r = case rCmp of
+        Nothing -> False
+        Just o -> o == ord
+  in rPred == r
+
+testOverloadedFn
+  :: (Text -> Int -> C.Pred Int)
+  -> (Int -> Int -> Bool)
+  -> Property
+testOverloadedFn f fb =
+  forAll (text arbitrary) $ \txt ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  C.test (f txt iRight) iLeft == fb iLeft iRight
+
+prop_greater = testOverloadedFn M.greater (>)
+prop_less = testOverloadedFn M.less (<)
+prop_greaterEq = testOverloadedFn M.greaterEq (>=)
+prop_lessEq = testOverloadedFn M.lessEq (<=)
+prop_notEq = testOverloadedFn M.notEq (/=)
+
+type ByFn
+  = Text
+  -> Text
+  -> (Int -> Text)
+  -> (Int -> Ordering)
+  -> C.Pred Int
+
+testByFn :: ByFn -> (Int -> Int -> Bool) -> Property
+testByFn f fb =
+  forAll (text arbitrary) $ \t1 ->
+  forAll (text arbitrary) $ \t2 ->
+  forAll (fmap Blind $ function1 coarbitrary (text arbitrary))
+    $ \(Blind fTxt) ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  C.test (f t1 t2 fTxt (`compare` iRight)) iLeft
+    == fb iLeft iRight
+
+prop_greaterBy = testByFn M.greaterBy (>)
+prop_lessBy = testByFn M.lessBy (<)
+prop_greaterEqBy = testByFn M.greaterEqBy (>=)
+prop_lessEqBy = testByFn M.lessEqBy (<=)
+
+prop_notEqBy =
+  forAll (text arbitrary) $ \t1 ->
+  forAll (text arbitrary) $ \t2 ->
+  forAll (fmap Blind $ function1 coarbitrary (text arbitrary))
+    $ \(Blind fTxt) ->
+  forAll (fmap Blind $ function2 coarbitrary coarbitrary arbitrary)
+    $ \(Blind fBool) ->
+  forAll arbitrary $ \iLeft ->
+  forAll arbitrary $ \iRight ->
+  let _types = (iLeft, iRight) :: (Int, Int) in
+  C.test (M.notEqBy t1 t2 fTxt (`fBool` iRight)) iLeft
+    == (not $ fBool iLeft iRight)
+
+
+testParseComparer
+  :: Text
+  -- ^ Comparer text to parse
+  -> (Text -> Int -> C.Pred Int)
+  -- ^ The comparer that should actually be returned
+  -> Property
+testParseComparer x p =
+  forAll (text arbitrary) $ \txt ->
+  forAll arbitrary $ \rhs ->
+  let get = M.compare txt rhs in
+  case M.parseComparer x get of
+    Nothing -> property False
+    Just p' -> forAll arbitrary $ \lhs ->
+      C.test (p txt rhs) lhs == C.test p' lhs
+
+prop_textEQ1 = testParseComparer "=" M.equal
+prop_textEQ2 = testParseComparer "==" M.equal
+prop_textG = testParseComparer ">" M.greater
+prop_textL = testParseComparer "<" M.less
+prop_textGE = testParseComparer ">=" M.greaterEq
+prop_textLE = testParseComparer "<=" M.lessEq
+prop_textNE1 = testParseComparer "/=" M.notEq
+prop_textNE2 = testParseComparer "!=" M.notEq
diff --git a/exe/Prednote/Core/Properties.hs b/exe/Prednote/Core/Properties.hs
new file mode 100644
--- /dev/null
+++ b/exe/Prednote/Core/Properties.hs
@@ -0,0 +1,500 @@
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+module Prednote.Core.Properties where
+
+import Prednote.Core.Generators
+import qualified Prednote.Core as C
+import qualified Prednote.Prebuilt as P
+import qualified Data.Tree as E
+import Test.QuickCheck
+import Prednote.Tests.Util
+import Prelude hiding (pred)
+import Control.Monad
+import Test.QuickCheck.Poly (A(..))
+import Data.Maybe
+import Data.List (intersperse)
+
+-- | Shown values are True
+prop_shown = C.unVisible C.shown
+
+-- | Hidden values are False
+prop_hidden = not $ C.unVisible C.hidden
+
+-- | empty list returns True for all
+prop_allEmpty =
+  forAll arbitrary $ \(A i) ->
+  C.test (C.all []) i
+
+-- # all
+
+-- | list of all True preds for all returns True
+prop_allTrues =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf1 (return P.true)) $ \ls ->
+  C.test (C.all ls) i
+
+-- | all list with at least one False pred returns False
+prop_allOneFalse =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls1 ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls2 ->
+  not $ C.test (C.all (ls1 ++ [P.false] ++ ls2)) i
+
+-- | all does not short circuit on True results
+prop_allNoShortTrue =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.true)) $ \ls ->
+  isNothing . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.all ls
+
+-- | all does not short circuit when only the last result is False
+prop_allNoShortLastFalse =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.true)) $ \ls ->
+  isNothing . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.all (ls ++ [P.false])
+
+-- | all short circuits when a result that is not the last result is
+-- False
+prop_allShortNotLastFalse =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls1 ->
+  forAll (listOf1 (elements [P.true, P.false])) $ \ls2 ->
+  isJust . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.all (ls1 ++ [P.false] ++ ls2)
+
+-- | when all short circuits, the number of children is equal to the
+-- leading number of True predicates plus one
+prop_allShortCirLength =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.true)) $ \ls1 ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls2 ->
+  (== (length ls1 + 1)) . length . E.subForest . ($ i) . C.evaluate
+    $ C.all (ls1 ++ [P.false] ++ ls2)
+
+-- | When all does not short circuit, the number of children is equal
+-- to the number of inputs
+prop_allAllTrueLength =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.true)) $ \ls1 ->
+  (== (length ls1)) . length . E.subForest . ($ i) . C.evaluate
+    $ C.all ls1
+
+-- | When all does not short circuit, the number of children is equal
+-- to the number of inputs
+prop_allOneFalseLength =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.true)) $ \ls1 ->
+  (== (length ls1 + 1)) . length . E.subForest . ($ i) . C.evaluate
+    $ C.all (ls1 ++ [P.false])
+
+-- | children of result of all is always a list of True followed by,
+-- at most, one False.
+prop_allResultSpan =
+  forAll arbitrary $ \i ->
+  forAll (listOf pred) $ \ls ->
+  (< 2) . length . dropWhile (C.result . E.rootLabel) . E.subForest
+    $ C.evaluate (C.all ls) i
+
+-- # any
+
+-- | any is false on an empty list
+prop_anyEmptyFalse =
+  forAll arbitrary $ \(A i) ->
+  not $ C.test (C.any []) i
+
+-- | any is False on list of all False
+prop_anyAllFalsesIsFalse =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf1 (return P.false)) $ \ls ->
+  not $ C.test (C.any ls) i
+
+-- | any is True if at least one Pred is True
+prop_anyTrueOneTrue =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls1 ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls2 ->
+  C.test (C.any (ls1 ++ [P.true] ++ ls2)) i
+
+-- | any does not short circuit on False results
+prop_anyNoShortFalse =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.false)) $ \ls ->
+  isNothing . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.any ls
+
+-- | any does not short circuit if only the last result is True
+prop_anyNoShortLastTrue =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (return P.false)) $ \ls ->
+  isNothing . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.any (ls ++ [P.true])
+
+-- | any short circuits if any result before the last result is True
+prop_anyShortsNotLastTrue =
+  forAll arbitrary $ \(A i) ->
+  forAll (listOf (elements [P.true, P.false])) $ \ls1 ->
+  forAll (listOf1 (elements [P.true, P.false])) $ \ls2 ->
+  isJust . C.short . E.rootLabel . ($ i) . C.evaluate
+    $ C.any (ls1 ++ [P.true] ++ ls2)
+
+-- | If there is a short circuit, last element of children is True
+prop_anyShortCircuitLastChild =
+  forAll arbitrary $ \i ->
+  forAll (listOf pred) $ \ps ->
+  let r = C.evaluate (C.any ps) i
+  in isJust (C.short . E.rootLabel $ r)
+     ==> last (map (C.result . E.rootLabel) . E.subForest $ r)
+
+-- | children of result of any is always a list of False followed by,
+-- at most, one True.
+prop_anyResultSpan =
+  forAll arbitrary $ \i ->
+  forAll (listOf pred) $ \ls ->
+  (< 2) . length . dropWhile (not . C.result . E.rootLabel) . E.subForest
+    $ C.evaluate (C.any ls) i
+
+-- # not
+
+-- | not always has exactly one child
+
+prop_notOneChild =
+  forAll arbitrary $ \i ->
+  forAll pred $ \p ->
+  (== 1) . length . E.subForest $ C.evaluate (C.not p) i
+
+-- | not never short circuits
+
+prop_notNeverShort =
+  forAll arbitrary $ \i ->
+  forAll pred $ \p ->
+  isNothing . C.short . E.rootLabel $ C.evaluate (C.not p) i
+
+-- | Result of not is always opposite child
+
+prop_notIsOpposite =
+  forAll arbitrary $ \i ->
+  forAll pred $ \p ->
+  let r = C.evaluate (C.not p) i
+  in (C.result . E.rootLabel $ r) ==
+      (not . C.result . E.rootLabel . head . E.subForest $ r)
+
+-- # fan
+
+-- | fan does not fail on an undefined list if the analyzer does not
+-- look at the list
+
+prop_fanSucceedOnUndefined =
+  forAll (return (undefined :: [Int])) $ \ls ->
+  forAll (elements [P.true, P.false]) $ \p ->
+  let genTup = liftM3 (,,) arbitrary visible arbitrary in
+  forAll genTup $ \tup ->
+  (C.result . E.rootLabel $
+        C.evaluate (C.fan (const tup) id p) ls) `seq` True
+
+-- | fan always short circuits if analyzer returns a Just Int with an
+-- Int less than zero
+
+prop_fanAlwaysShortsOnNonPositive =
+  forAll (listOf (return ())) $ \ls ->
+  forAll (elements [P.true, P.false]) $ \p ->
+  let genInt = arbitrarySizedIntegral `suchThat` (< 0)
+      genTup = liftM3 (,,) arbitrary visible (fmap Just genInt) in
+  forAll genTup $ \tup ->
+  isJust . C.short . E.rootLabel $
+    C.evaluate (C.fan (const tup) id p) ls
+
+-- | fan does not short circuit if analyzer returns a Just Int that is
+-- greater than or equal to the length of the list.
+
+prop_fanNoShortCircuit =
+  forAll (listOf (return ())) $ \ls ->
+  forAll (elements [P.true, P.false]) $ \p ->
+  let genInt = oneof [ return (length ls),
+                       choose (length ls, maxBound)]
+      genTup = liftM3 (,,) arbitrary visible (fmap Just genInt)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  isNothing . C.short . E.rootLabel $
+    C.evaluate (C.fan fn id p) ls
+
+-- | fan short circuits if analyzer returns a Just Int that is less
+-- than the length of the list
+
+prop_fanShortCircuitIntLessThan =
+  forAll (listOf (return ())) $ \ls ->
+  forAll (elements [P.true, P.false]) $ \p ->
+  let genInt = oneof [ return (length ls - 1),
+                       choose (minBound, length ls - 1) ]
+      genTup = liftM3 (,,) arbitrary visible (fmap Just genInt)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  isJust . C.short . E.rootLabel
+    $ C.evaluate (C.fan fn id p) ls
+
+-- | fan never short circuits if analyzer returns Nothing
+
+prop_fanNoShortCircuitOnNothing =
+  forAll (listOf (return ())) $ \ls ->
+  forAll (elements [P.true, P.false]) $ \p ->
+  let genTup = liftM3 (,,) arbitrary visible (return Nothing)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  isNothing . C.short . E.rootLabel
+    $ C.evaluate (C.fan fn id p) ls
+
+-- | fan result is as expected
+
+prop_fanResult =
+  forAll (listOf arbitrary) $ \ls ->
+  forAll pred $ \p ->
+  let genTup = liftM3 (,,) arbitrary visible (return Nothing)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  let bs = map (C.test p) ls
+      r = C.test (C.fan fn id p) ls
+      (rFn, _, _) = fn bs
+  in r === rFn
+
+-- | fan visibility is as expected
+prop_fanVisibility =
+  forAll (listOf arbitrary) $ \ls ->
+  forAll pred $ \p ->
+  let genTup = liftM3 (,,) arbitrary visible (return Nothing)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  let bs = map (C.test p) ls
+      r = C.visible . E.rootLabel $ C.evaluate (C.fan fn id p) ls
+      (_, rFn, _) = fn bs
+  in r === rFn
+
+-- | number of fan children is either the number of fanout items or
+-- the number indicated by the short circuit, whichever is less
+prop_fanNumberOfChildren =
+  forAll (listOf arbitrary) $ \ls ->
+  forAll pred $ \p ->
+  let genTup = liftM3 (,,) arbitrary visible (return Nothing)
+      genFn = fmap Blind $ function1 coarbitrary genTup in
+  forAll genFn $ \(Blind fn) ->
+  let bs = map (C.test p) ls
+      r = E.subForest $ C.evaluate (C.fan fn id p) ls
+      (_, _, may) = fn bs in
+  case may of
+    Nothing -> length r == length ls
+    Just i -> length r == (max 0 (min i (length ls)))
+
+-- # fanAll
+
+-- | fanAll is True on empty list
+
+prop_fanAllTrueOnEmptyList =
+  forAll pred $ \p ->
+  C.test (C.fanAll (const []) p) []
+
+-- | fanAll is True if all children are True
+prop_fanAllTrueAllItemsTrue =
+  forAll (listOf1 (return True)) $ \ls ->
+  C.test (C.fanAll id P.same) ls
+
+-- | fanAll is False if at least one value is False
+prop_fanAllFalseOneItemFalse =
+  forAll (listOf arbitrary) $ \ls1 ->
+  forAll (listOf arbitrary) $ \ls2 ->
+  not $ C.test (C.fanAll id P.same) (ls1 ++ [False] ++ ls2)
+
+-- | fanAll does not short circuit if result is True
+prop_fanAllNoShortCircuitTrue =
+  forAll (listOf (return True)) $ \ls ->
+  isNothing . C.short . E.rootLabel $
+    C.evaluate (C.fanAll id P.same) ls
+
+-- | fanAll does not short circuit if only the last value is False
+prop_fanAllNoShortCircuitLastFalse =
+  forAll (listOf (return True)) $ \ls ->
+  isNothing . C.short . E.rootLabel $
+    C.evaluate (C.fanAll id P.same) (ls ++ [False])
+
+-- | fanAll does short circuit if there is a False before the last
+-- value
+prop_fanAllShortCircuitFalseNotLast =
+  forAll (listOf arbitrary) $ \ls1 ->
+  forAll (listOf1 arbitrary) $ \ls2 ->
+  isJust . C.short . E.rootLabel $
+    C.evaluate (C.fanAll id P.same) (ls1 ++ [False] ++ ls2)
+
+-- | In short circuit, length of resulting items is length of list up
+-- to first False
+
+prop_fanAllShortCircuitLength =
+  forAll (listOf (return True)) $ \ls1 ->
+  forAll (listOf1 arbitrary) $ \ls2 ->
+  (== (length ls1 + 1)) . length . E.subForest $
+    C.evaluate (C.fanAll id P.same) (ls1 ++ [False] ++ ls2)
+
+-- # fanAny
+
+-- | fanAny is False on empty list
+
+prop_fanAnyFalseOnEmptyList =
+  forAll pred $ \p ->
+  not $ C.test (C.fanAny (const []) p) []
+
+-- | fanAny is False if all children are False
+prop_fanAnyFalseAllItemsFalse =
+  forAll (listOf1 (return False)) $ \ls ->
+  not $ C.test (C.fanAny id P.same) ls
+
+-- | fanAny is True if at least one value is True
+prop_fanAnyFalseOneItemFalse =
+  forAll (listOf arbitrary) $ \ls1 ->
+  forAll (listOf arbitrary) $ \ls2 ->
+  C.test (C.fanAny id P.same) (ls1 ++ [True] ++ ls2)
+
+-- | fanAny does not short circuit if result is False
+prop_fanAnyNoShortCircuitFalse =
+  forAll (listOf (return False)) $ \ls ->
+  isNothing . C.short . E.rootLabel $
+    C.evaluate (C.fanAny id P.same) ls
+
+-- | fanAny does not short circuit if only the last value is True
+prop_fanAnyNoShortCircuitLastTrue =
+  forAll (listOf (return False)) $ \ls ->
+  isNothing . C.short . E.rootLabel $
+    C.evaluate (C.fanAny id P.same) (ls ++ [True])
+
+-- | fanAny does short circuit if there is a True before the last
+-- value
+prop_fanAnyShortCircuitFalseNotLast =
+  forAll (listOf arbitrary) $ \ls1 ->
+  forAll (listOf1 arbitrary) $ \ls2 ->
+  isJust . C.short . E.rootLabel $
+    C.evaluate (C.fanAny id P.same) (ls1 ++ [True] ++ ls2)
+
+-- | In short circuit, length of resulting items is length of list up
+-- to first True
+
+prop_fanAnyShortCircuitLength =
+  forAll (listOf (return False)) $ \ls1 ->
+  forAll (listOf1 arbitrary) $ \ls2 ->
+  (== (length ls1 + 1)) . length . E.subForest $
+    C.evaluate (C.fanAny id P.same) (ls1 ++ [True] ++ ls2)
+
+-- # fanAtLeast
+
+-- | Always returns True if argument is less than or equal to zero.
+prop_fanAtLeastLTEQZero =
+  forAll pred $ \p ->
+  forAll (fmap (negate . abs) arbitrary) $ \i ->
+  forAll (listOf arbitrary) $ \ls ->
+  C.test (C.fanAtLeast i id p) ls
+
+surround :: a -> [a] -> [a]
+surround a = (a :) . intersperse a . (++ [a])
+
+-- | Generates a list of the given number of True items, surrounded by
+-- a random number of False items.
+listOfTrue :: Int -> Gen [Bool]
+listOfTrue i = fmap concat . sequence $ surround (listOf (return False))
+  (replicate i (return [True]))
+
+-- | Returns True if requisite number of items is found.
+
+prop_fanAtLeastTrue =
+  forAll (fmap getPositive arbitrary) $ \i ->
+  forAll (listOfTrue i) $ \ls ->
+  forAll (oneof [return i, choose (0, i)]) $ \n ->
+  C.test (C.fanAtLeast n id P.same) ls
+
+-- | Short circuits if fewer matching items are requested than are
+-- present.
+
+prop_fanAtLeastShortFewer =
+  forAll (fmap getPositive arbitrary) $ \i ->
+  forAll (listOfTrue i) $ \ls ->
+  forAll (oneof [return (i - 1), choose (0, i - 1)]) $ \n ->
+  isJust . C.short . E.rootLabel $
+    C.evaluate (C.fanAtLeast n id P.same) ls
+
+-- | Returns False if given number of items is not present.
+
+prop_fanAtLeastFalse =
+  forAll (fmap getNonNegative arbitrary) $ \i ->
+  forAll (listOfTrue i) $ \ls ->
+  forAll (oneof [return (i + 1), choose (i + 1, maxBound)]) $ \n ->
+  not $ C.test (C.fanAtLeast n id P.same) ls
+
+-- | Short circuits if additional items are after number of found items.
+prop_fanAtLeastShortMoreAreAfter =
+  forAll (fmap getPositive arbitrary) $ \i ->
+  forAll (listOfTrue i) $ \ls ->
+  forAll (listOf1 arbitrary) $ \more ->
+  forAll (choose (0, i)) $ \n ->
+  isJust . C.short . E.rootLabel
+    $ C.evaluate (C.fanAtLeast n id P.same) (ls ++ more)
+
+-- # report, plan - tested visually
+
+-- | test is same as evaluation
+prop_testIsEvaluation =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  C.test p i == C.result (E.rootLabel $ C.evaluate p i)
+
+-- | fst . testV is the same as test
+
+prop_testVSameAsTest =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  fst (C.testV p i) == C.result (E.rootLabel $ C.evaluate p i)
+
+-- | snd . testV is same as report
+
+prop_testVSameAsReport =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  snd (C.testV p i) == C.report 0 (C.evaluate p i)
+
+-- # filter
+
+-- | filter is the same as filter
+
+prop_filter =
+  forAll (fmap Blind $ function1 coarbitrary arbitrary) $ \(Blind fn) ->
+  forAll visible $ \v ->
+  forAll (fmap Blind $ (frequency [ (3, fmap Just chunker),
+                      (1, return Nothing)])) $ \(Blind mayCkr) ->
+  forAll (fmap Blind chunker) $ \(Blind ckr) ->
+  forAll (listOf arbitrary) $ \ls ->
+  let p = C.Pred (E.Node (const []) [])
+        (\a -> E.Node (C.Output (fn (a :: Int)) v mayCkr ckr) []) in
+  C.filter p ls === filter fn ls
+
+-- | fst . filterV is the same as filter
+
+prop_filterVFst =
+  forAll pred $ \p ->
+  forAll arbitrary $ \ls ->
+  fst (C.filterV p ls) === C.filter p ls
+
+-- | snd . filterV is the same as reporting on each item
+prop_filterVSnd =
+  forAll pred $ \p ->
+  forAll arbitrary $ \ls ->
+  snd (C.filterV p ls) ===
+    concat (map snd . map (C.testV p) $ ls)
+
+-- # shorter
+
+-- | shorter does what it should
+
+prop_shorter =
+  forAll (listOf (return ())) $ \ls1 ->
+  forAll (listOf (return ())) $ \ls2 ->
+  ls1 `C.shorter` ls2 === (length ls1 < length ls2)
+
+-- | shorter is OK with longer list that is undefined
+
+prop_shorterLazy =
+  forAll (listOf (return ())) $ \ls1 ->
+  let ls2 = ls1 ++ (() : undefined)
+  in ls1 `C.shorter` ls2
+  
diff --git a/exe/Prednote/Prebuilt/Properties.hs b/exe/Prednote/Prebuilt/Properties.hs
new file mode 100644
--- /dev/null
+++ b/exe/Prednote/Prebuilt/Properties.hs
@@ -0,0 +1,137 @@
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+module Prednote.Prebuilt.Properties where
+
+import Prednote.Core.Generators
+import Prednote.Tests.Util
+import Test.QuickCheck
+import Test.QuickCheck.Poly (A(..))
+import Data.Text.Generators
+import qualified Prednote.Prebuilt as P
+import qualified Prednote.Core as C
+import Prednote.Prebuilt ((&&&), (|||))
+import qualified Data.Tree as E
+import Prednote.Core (Pred)
+import Prelude hiding (pred)
+import Data.Maybe
+
+-- # tests for visibility
+isShown :: Pred Int -> Property
+isShown p =
+  forAll arbitrary $ \i ->
+  (== C.shown) . C.visible . E.rootLabel . C.evaluate p $ i
+
+isHidden :: Pred Int -> Property
+isHidden p =
+  forAll arbitrary $ \i ->
+  not . (== C.shown) . C.visible . E.rootLabel . C.evaluate p $ i
+
+-- # predicate
+
+-- | Predicate is same as running bare function
+prop_predicate =
+  forAll (text arbitrary) $ \x ->
+  forAll ( fmap Blind $
+           function1 coarbitrary (text arbitrary)) $ \(Blind dyn) ->
+  forAll (fmap Blind $ function1 coarbitrary arbitrary) $ \(Blind p) ->
+  forAll arbitrary $ \(A i) ->
+  C.test (P.predicate x dyn p) i === p i
+
+prop_predicateVisible =
+  forAll (text arbitrary) $ \x ->
+  forAll ( fmap Blind $
+           function1 coarbitrary (text arbitrary)) $ \(Blind dyn) ->
+  forAll (fmap Blind $ function1 coarbitrary arbitrary) $ \(Blind p) ->
+  isShown (P.predicate x dyn p)
+
+-- # true
+prop_true =
+  forAll arbitrary $ \(A i) ->
+  C.test P.true i
+
+prop_trueShown = isShown P.true
+
+-- # false
+prop_false =
+  forAll arbitrary $ \(A i) ->
+  not $ C.test P.false i
+
+prop_falseShown = isShown P.false
+
+-- # visibility
+
+prop_visibility =
+  forAll pred $ \p ->
+  forAll (fmap Blind $ function1 coarbitrary visible) $ \(Blind f) ->
+  forAll arbitrary $ \i ->
+  let r = E.rootLabel . ($ i) . C.evaluate . P.visibility f $ p in
+  C.visible r === f (C.result r)
+
+prop_reveal =
+  forAll pred $ \p ->
+  isShown (P.reveal p)
+
+prop_hidden =
+  forAll pred $ \p ->
+  isHidden (P.hide p)
+
+prop_showTrue =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  let r = E.rootLabel . ($ i) . C.evaluate . P.showTrue $ p in
+  if C.result r then C.visible r == C.shown
+    else C.visible r == C.hidden
+
+prop_showFalse =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  let r = E.rootLabel . ($ i) . C.evaluate . P.showFalse $ p in
+  if C.result r then C.visible r == C.hidden
+    else C.visible r == C.shown
+
+samePredGen :: Show a => Gen a -> Pred a -> Pred a -> Property
+samePredGen g x y =
+  forAll g $ \i ->
+  let getR = fmap (\(C.Output r v s _) -> (r, v, isNothing s))
+        . ($ i) . C.evaluate in
+  getR x === getR y
+  
+samePred :: Pred Int -> Pred Int -> Property
+samePred = samePredGen arbitrary
+
+samePredList :: Pred [Int] -> Pred [Int] -> Property
+samePredList = samePredGen (listOf arbitrary)
+
+prop_allSame =
+  forAll (listOf pred) $ \ps ->
+  samePred (C.all ps) (P.all ps)
+
+prop_allOpSame =
+  forAll pred $ \p1 ->
+  forAll pred $ \p2 ->
+  samePred (P.all [p1, p2]) (p1 &&& p2)
+
+prop_anySame =
+  forAll (listOf pred) $ \ps ->
+  samePred (C.any ps) (P.any ps)
+
+prop_anyOpSame =
+  forAll pred $ \p1 ->
+  forAll pred $ \p2 ->
+  samePred (P.any [p1, p2]) (p1 ||| p2)
+
+prop_notSame =
+  forAll pred $ \p ->
+  samePred (P.not p) (C.not p)
+
+prop_fanAllSame =
+  forAll pred $ \p ->
+  samePredList (P.fanAll id p) (C.fanAll id p)
+
+prop_fanAnySame =
+  forAll pred $ \p ->
+  samePredList (P.fanAny id p) (C.fanAny id p)
+
+prop_fanAtLeastSame =
+  forAll pred $ \p ->
+  forAll arbitrary $ \i ->
+  samePredList (P.fanAtLeast i id p) (C.fanAtLeast i id p)
diff --git a/exe/prednote-test.hs b/exe/prednote-test.hs
new file mode 100644
--- /dev/null
+++ b/exe/prednote-test.hs
@@ -0,0 +1,11 @@
+module Main where
+
+import Decrees
+import Quickpull
+import Test.QuickCheck
+
+args :: Args
+args = stdArgs { maxSize = 50 }
+
+main :: IO ()
+main = defaultMainWith args decrees
diff --git a/genCabal.hs b/genCabal.hs
new file mode 100644
--- /dev/null
+++ b/genCabal.hs
@@ -0,0 +1,95 @@
+-- Generates the Cabal file for prednote-test.
+-- Written to use version 0.10.0.2 of the Cartel
+-- library.
+
+module Main (main) where
+
+import CabalCommon
+import qualified Cartel as C
+
+prednote :: C.Package
+prednote = C.exactly "prednote" versionInts
+
+quickcheck :: C.Package
+quickcheck = C.closedOpen "QuickCheck" [2,7,5] [2,8]
+
+quickpull :: C.Package
+quickpull = C.closedOpen "quickpull" [0,2,0,0] [0,3]
+
+properties :: C.Properties
+properties = commonProperties
+  { C.prName = "prednote-test"
+  , C.prSynopsis = "Tests and QuickCheck generators to accompany prednote."
+  , C.prDescription =
+    [ "These are packaged separately so other packages may depend"
+    , "on them."
+    ]
+  , C.prExtraSourceFiles =
+    [ "genCabal.hs"
+    , "sunlight-test.hs"
+    , "current-versions.txt"
+    , "minimum-versions.txt"
+    ]
+  }
+
+depends :: [C.Package]
+depends =
+  [ base
+  , rainbow
+  , rainbow_tests
+  , text
+  , prednote
+  , quickcheck
+  , containers
+  , quickpull
+  ]
+
+library
+  :: [String]
+  -- ^ Library modules
+  -> C.Library
+library ms = C.Library
+  [ C.LibExposedModules ms
+  , C.buildDepends depends
+  , C.hsSourceDirs ["lib"]
+  , C.ghcOptions ghcOptions
+  , C.defaultLanguage C.Haskell2010
+  ]
+
+executable :: [String] -> C.Executable
+executable ms = C.Executable "prednote-test"
+  [ C.hsSourceDirs ["lib", "exe"]
+  , C.otherModules ms
+  , C.ExeMainIs "prednote-test.hs"
+  , C.ghcOptions ghcOptions
+  , C.defaultLanguage C.Haskell2010
+  , C.buildDepends depends
+  ]
+
+visual :: C.Executable
+visual = C.Executable "prednote-visual-test"
+  [ C.hsSourceDirs ["lib", "visual"]
+  , C.ExeMainIs "prednote-visual-test.hs"
+  , C.ghcOptions ghcOptions
+  , C.defaultLanguage C.Haskell2010
+  , C.buildDepends depends
+  ]
+
+cabal
+  :: [String]
+  -- ^ Modules for library
+  -> [String]
+  -- ^ Modules for the executable
+  -> C.Cabal
+cabal msLib msExe = C.empty
+  { C.cProperties = properties
+  , C.cRepositories = [repo]
+  , C.cLibrary = Just $ library msLib
+  , C.cExecutables = [executable (msLib ++ msExe), visual]
+  }
+
+main :: IO ()
+main = do
+  mods <- C.modules "lib"
+  modsExe <- C.modules "exe"
+  C.render "genCabal.hs" $ cabal mods modsExe
diff --git a/lib/Data/Tree/Generators.hs b/lib/Data/Tree/Generators.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Tree/Generators.hs
@@ -0,0 +1,13 @@
+module Data.Tree.Generators where
+
+import Data.Tree
+import Test.QuickCheck
+import Control.Monad
+
+tree :: Gen a -> Gen (Tree a)
+tree g = sized h
+  where
+    h s = liftM2 Node g cs
+      where
+        cs | s <= 0 = return []
+           | otherwise = resize (s `div` 8) (listOf (tree g))
diff --git a/lib/Prednote/Core/Generators.hs b/lib/Prednote/Core/Generators.hs
new file mode 100644
--- /dev/null
+++ b/lib/Prednote/Core/Generators.hs
@@ -0,0 +1,26 @@
+module Prednote.Core.Generators where
+
+import Test.QuickCheck hiding (output)
+import qualified Prednote.Core as C
+import Prednote.Tests.Util
+import System.Console.Rainbow.Types.Generators
+import Control.Monad
+import Prelude hiding (pred)
+import Data.Tree.Generators
+
+chunker :: Gen C.Chunker
+chunker = function1 variant (listOf chunk)
+
+visible :: Gen C.Visible
+visible = fmap C.Visible arbitrary
+
+output :: Gen C.Output
+output = liftM4 C.Output arbitrary visible
+  (frequency [(3, fmap Just chunker), (1, return Nothing)])
+  chunker
+
+pred :: Gen (C.Pred Int)
+pred = liftM2 C.Pred (tree chunker) (function1 variant (tree output))
+
+dynamicLabel :: Gen (Bool -> Int -> C.Chunker)
+dynamicLabel = function2 coarbitrary coarbitrary chunker
diff --git a/lib/Prednote/Tests/Util.hs b/lib/Prednote/Tests/Util.hs
new file mode 100644
--- /dev/null
+++ b/lib/Prednote/Tests/Util.hs
@@ -0,0 +1,31 @@
+module Prednote.Tests.Util where
+
+import Test.QuickCheck
+import Test.QuickCheck.Gen.Unsafe
+
+function1
+  :: (a -> Gen b -> Gen b)
+  -> Gen b
+  -> Gen (a -> b)
+function1 perturb gen = promote (`perturb` gen)
+
+function2
+  :: (a -> Gen r -> Gen r)
+  -> (b -> Gen r -> Gen r)
+  -> Gen r
+  -> Gen (a -> b -> r)
+function2 p1 p2 = fmap f . function1 p'
+  where
+    p' (a, b) = p1 a . p2 b
+    f g = \a b -> g (a, b)
+
+function3
+  :: (a -> Gen r -> Gen r)
+  -> (b -> Gen r -> Gen r)
+  -> (c -> Gen r -> Gen r)
+  -> Gen r
+  -> Gen (a -> b -> c -> r)
+function3 p1 p2 p3 = fmap f . function1 p'
+  where
+    p' (a, b, c) = p1 a . p2 b . p3 c
+    f g = \a b c -> g (a, b, c)
diff --git a/minimum-versions.txt b/minimum-versions.txt
new file mode 100644
--- /dev/null
+++ b/minimum-versions.txt
@@ -0,0 +1,53 @@
+This package was tested to work with these dependency
+versions and compiler version.
+These are the minimum versions given in the .cabal file.
+Tested as of: 2014-07-13 16:28:45.229908 UTC
+Path to compiler: ghc-7.4.1
+Compiler description: 7.4.1
+
+/opt/ghc/7.4.1/lib/ghc-7.4.1/package.conf.d:
+    Cabal-1.14.0
+    array-0.4.0.0
+    base-4.5.0.0
+    bin-package-db-0.0.0.0
+    binary-0.5.1.0
+    bytestring-0.9.2.1
+    containers-0.4.2.1
+    deepseq-1.3.0.0
+    directory-1.1.0.2
+    extensible-exceptions-0.1.1.4
+    filepath-1.3.0.0
+    (ghc-7.4.1)
+    ghc-prim-0.2.0.0
+    (haskell2010-1.1.0.1)
+    (haskell98-2.0.0.1)
+    hoopl-3.8.7.3
+    hpc-0.5.1.1
+    integer-gmp-0.4.0.0
+    old-locale-1.0.0.4
+    old-time-1.1.0.0
+    pretty-1.1.1.0
+    process-1.1.0.1
+    rts-1.0
+    template-haskell-2.7.0.0
+    time-1.4
+    unix-2.5.1.0
+
+/home/massysett/prednote/tests/sunlight-29186/db:
+    QuickCheck-2.7.5
+    contravariant-0.6
+    prednote-0.24.0.0
+    prednote-test-0.24.0.0
+    primitive-0.5.3.0
+    quickpull-0.2.0.0
+    rainbow-0.14.0.2
+    rainbow-tests-0.14.0.2
+    random-1.0.1.1
+    split-0.2.2
+    tagged-0.7.2
+    terminfo-0.4.0.0
+    text-0.11.2.0
+    tf-random-0.5
+    transformers-0.4.1.0
+    transformers-compat-0.3.3.4
+
diff --git a/prednote-test.cabal b/prednote-test.cabal
new file mode 100644
--- /dev/null
+++ b/prednote-test.cabal
@@ -0,0 +1,98 @@
+-- This Cabal file generated using the Cartel library.
+-- Cartel is available at:
+-- http://www.github.com/massysett/cartel
+--
+-- Script name used to generate: genCabal.hs
+-- Generated on: 2014-07-13 12:28:43.16095 EDT
+-- Cartel library version: 0.10.0.2
+name: prednote-test
+version: 0.24.0.0
+cabal-version: >= 1.14
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+copyright: Copyright 2013-2014 Omari Norman
+author: Omari Norman
+maintainer: omari@smileystation.com
+stability: Experimental
+homepage: http://www.github.com/massysett/prednote
+bug-reports: http://www.github.com/massysett/prednote/issues
+synopsis: Tests and QuickCheck generators to accompany prednote.
+description:
+  These are packaged separately so other packages may depend
+  on them.
+category: Data
+extra-source-files:
+    genCabal.hs
+  , sunlight-test.hs
+  , current-versions.txt
+  , minimum-versions.txt
+
+source-repository head
+  type: git
+  location: git://github.com/massysett/prednote.git
+  branch: master
+
+Library
+  exposed-modules:
+      Data.Tree.Generators
+    , Prednote.Core.Generators
+    , Prednote.Tests.Util
+  build-depends:
+      base ((> 4.5.0.0 || == 4.5.0.0) && < 5)
+    , rainbow ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , rainbow-tests ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , text ((> 0.11.2.0 || == 0.11.2.0) && < 1.2)
+    , prednote == 0.24.0.0
+    , QuickCheck ((> 2.7.5 || == 2.7.5) && < 2.8)
+    , containers ((> 0.4.2.1 || == 0.4.2.1) && < 0.6)
+    , quickpull ((> 0.2.0.0 || == 0.2.0.0) && < 0.3)
+  hs-source-dirs:
+      lib
+  ghc-options:
+      -Wall
+  default-language: Haskell2010
+
+Executable prednote-test
+  hs-source-dirs:
+      lib
+    , exe
+  other-modules:
+      Data.Tree.Generators
+    , Prednote.Core.Generators
+    , Prednote.Tests.Util
+    , Decrees
+    , Prednote.Comparisons.Properties
+    , Prednote.Core.Properties
+    , Prednote.Prebuilt.Properties
+  main-is: prednote-test.hs
+  ghc-options:
+      -Wall
+  default-language: Haskell2010
+  build-depends:
+      base ((> 4.5.0.0 || == 4.5.0.0) && < 5)
+    , rainbow ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , rainbow-tests ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , text ((> 0.11.2.0 || == 0.11.2.0) && < 1.2)
+    , prednote == 0.24.0.0
+    , QuickCheck ((> 2.7.5 || == 2.7.5) && < 2.8)
+    , containers ((> 0.4.2.1 || == 0.4.2.1) && < 0.6)
+    , quickpull ((> 0.2.0.0 || == 0.2.0.0) && < 0.3)
+
+Executable prednote-visual-test
+  hs-source-dirs:
+      lib
+    , visual
+  main-is: prednote-visual-test.hs
+  ghc-options:
+      -Wall
+  default-language: Haskell2010
+  build-depends:
+      base ((> 4.5.0.0 || == 4.5.0.0) && < 5)
+    , rainbow ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , rainbow-tests ((> 0.14.0.2 || == 0.14.0.2) && < 0.15)
+    , text ((> 0.11.2.0 || == 0.11.2.0) && < 1.2)
+    , prednote == 0.24.0.0
+    , QuickCheck ((> 2.7.5 || == 2.7.5) && < 2.8)
+    , containers ((> 0.4.2.1 || == 0.4.2.1) && < 0.6)
+    , quickpull ((> 0.2.0.0 || == 0.2.0.0) && < 0.3)
diff --git a/sunlight-test.hs b/sunlight-test.hs
new file mode 100644
--- /dev/null
+++ b/sunlight-test.hs
@@ -0,0 +1,15 @@
+module Main where
+
+import Test.Sunlight
+
+inputs = TestInputs
+  { tiDescription = Nothing
+  , tiCabal = "cabal"
+  , tiLowest = ("7.4.1", "ghc-7.4.1", "ghc-pkg-7.4.1")
+  , tiDefault = [ ("7.4.1", "ghc-7.4.1", "ghc-pkg-7.4.1")
+                , ("7.6.3", "ghc-7.6.3", "ghc-pkg-7.6.3")
+                , ("7.8.2", "ghc-7.8.2", "ghc-pkg-7.8.2") ]
+  , tiTest = [("dist/build/prednote-test/prednote-test", [])]
+  }
+
+main = runTests inputs
diff --git a/visual/prednote-visual-test.hs b/visual/prednote-visual-test.hs
new file mode 100644
--- /dev/null
+++ b/visual/prednote-visual-test.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Main where
+
+import Prednote
+import qualified Prednote as P
+import Prednote.Comparisons
+import Prednote.Format
+import qualified Data.Text as X
+import System.Console.Rainbow
+
+singleInt :: Pred Int
+singleInt = P.any
+  [ equal "integer" 5
+  , greaterEq "integer" 20
+  , lessEq "integer" 10
+  ]
+
+listInt :: Pred [Int]
+listInt = P.any
+  [ let l = "length is greater than 4"
+        dyn ls = (X.pack . show $ ls) <+> l
+    in predicate l dyn ((> 4) . length)
+
+  , let l = "is even"
+        dyn i = (X.pack . show $ i) <+> l
+        p = predicate l dyn even
+    in fanAll id p
+
+  , fanAny id (equal "integer" 5)
+  ]
+
+intList :: [Int]
+intList = [1,12,13,2,3,25,20,5,8,11]
+
+intLists :: [[Int]]
+intLists =
+  [ [4,2,1,9,20]
+  , [2,4,6]
+  , [6,7,9,5]
+  , [-1,4,11,19,20]
+  , [2,11]
+  ]
+
+main :: IO ()
+main = do
+  t <- termFromEnv
+  putStrLn $ "intList: " ++ show intList
+  putStrLn $ "intLists: " ++ show intLists
+  putStrLn "singleInt plan:"
+  putChunks t (plan singleInt)
+  putStrLn ""
+  putStrLn "listInt plan:"
+  putChunks t (plan listInt)
+  putStrLn ""
+  let (as, cks) = filterV singleInt intList
+  putStrLn "result from filtering int list:"
+  putStrLn $ show as
+  putStrLn ""
+  putChunks t cks
+  putStrLn ""
+  let (as', cks') = filterV listInt intLists
+  putStrLn "result from filtering int lists:"
+  putStrLn ""
+  putStrLn $ show as'
+  putStrLn ""
+  putChunks t cks'
+        
