@@ -33,53 +33,62 @@ module Constrained.Base (
3333 pattern (:>:) ,
3434 pattern Unary ,
3535
36- -- * Useful function symbols
36+ toCtx ,
37+ flipCtx ,
38+ fromListCtx ,
39+
40+ -- * Useful function symbols and patterns for building custom rewrite rules
3741 fromGeneric_ ,
3842 toGeneric_ ,
3943
40- -- * TODO: documentme
41- HasSpec (.. ),
42- propagateSpec ,
4344 pattern ToGeneric ,
4445 pattern FromGeneric ,
46+
47+ -- * Syntax for building specifications
4548 constrained ,
46- appFun ,
47- errorLikeMessage ,
48- isErrorLike ,
4949 notMemberSpec ,
5050 notEqualSpec ,
51+ typeSpec ,
5152 addToErrorSpec ,
52- memberSpecList ,
53- toCtx ,
54- flipCtx ,
55- BinaryShow (.. ),
56- name ,
53+ memberSpec ,
5754 fromSimpleRepSpec ,
5855 toSimpleRepSpec ,
59- toPred ,
60- forAllToList ,
6156 explainSpec ,
62- bind ,
57+
58+ -- * Instantiated types and helper patterns
6359 Term ,
6460 Specification ,
6561 Pred ,
66- IsPred ,
67- HintF (.. ),
6862 Binder ,
63+
64+ pattern TypeSpec ,
65+ pattern GenHint ,
66+
67+ -- * Constraints and classes
68+ HasSpec (.. ),
6969 HasGenHint (.. ),
7070 Forallable ,
71- pattern TypeSpec ,
72- typeSpec ,
71+ AppRequires ,
72+ GenericallyInstantiated ,
73+ GenericRequires ,
74+
75+ -- * TODO: documentme
76+ propagateSpec ,
77+ appFun ,
78+ errorLikeMessage ,
79+ isErrorLike ,
80+ BinaryShow (.. ),
81+ name ,
82+ toPred ,
83+ forAllToList ,
84+ bind ,
85+ IsPred ,
7386 equalSpec ,
7487 appTerm ,
75- GenericRequires ,
7688 HOLE (.. ),
77- AppRequires ,
7889 fromForAllSpec ,
7990 Fun (.. ),
80- GenericallyInstantiated ,
8191 BaseW (.. ),
82- fromListCtx ,
8392) where
8493
8594import Constrained.AbstractSyntax
@@ -129,22 +138,38 @@ instance Dependencies Deps where
129138
130139type Binder = BinderD Deps
131140
141+ -- | All the constraints needed for application in the first order term languge
132142type AppRequires t as b = AppRequiresD Deps t as b
133143
144+ -- | Predicates over `Term`s
134145type Pred = PredD Deps
135146
147+ -- | First-order language of variables, literals, and application
136148type Term = TermD Deps
137149
150+ -- | Specifications for generators instantiated with the `HasSpec` et al actual
151+ -- classes
138152type Specification = SpecificationD Deps
139153
154+ -- | Pattern match out a `TypeSpec` and the can't-"set" - avoids some tedious
155+ -- pitfalls related to the `Deps` and `Dependencies` trick
140156pattern TypeSpec :: () => HasSpec a => TypeSpec a -> [a ] -> Specification a
141157pattern TypeSpec ts cant = TypeSpecD (TypeSpecF ts) cant
142158
143159{-# COMPLETE ExplainSpec, MemberSpec, ErrorSpec, SuspendedSpec, TypeSpec, TrueSpec #-}
144160
161+ -- | Build a specifiation from just a `TypeSpec`, useful internal function when
162+ -- writing `Logic` instances
145163typeSpec :: HasSpec a => TypeSpec a -> Specification a
146164typeSpec ts = TypeSpec ts mempty
147165
166+ -- | Pattern match out a `Hint` and the `Term` it applies to - avoids some
167+ -- tedious pitfalls related to the `Deps` and `Dependencies` trick
168+ pattern GenHint :: () => HasGenHint a => Hint a -> Term a -> Pred
169+ pattern GenHint h t = GenHintD (HintF h) t
170+
171+ {-# COMPLETE ElemPred, Monitor, And, Exists, Subst, Let, Assert, Reifies, DependsOn, ForAll, Case, When, GenHint, TruePred, FalsePred, Explain #-}
172+
148173-- ====================================================================
149174
150175-- | A First-order typed logic has 4 components
@@ -735,7 +760,7 @@ bind bodyf = newv :-> bodyPred
735760 bound (Case _ cs) = getMax $ foldMapList (Max . boundBinder . thing) cs
736761 bound (When _ p) = bound p
737762 bound Reifies {} = - 1
738- bound GenHint {} = - 1
763+ bound GenHintD {} = - 1
739764 bound Assert {} = - 1
740765 bound DependsOn {} = - 1
741766 bound TruePred = - 1
@@ -793,27 +818,33 @@ instance IsPred (Term Bool) where
793818-- ============================================================
794819-- Simple Widely used operations on Specification
795820
796- -- | return a MemberSpec or ans ErrorSpec depending on if 'xs' the null list or not
797- memberSpecList :: [ a ] -> NE. NonEmpty String -> Specification a
798- memberSpecList xs messages =
821+ -- | return a MemberSpec or ans ErrorSpec depending on if 'xs' is null or not
822+ memberSpec :: Foldable f => f a -> NE. NonEmpty String -> Specification a
823+ memberSpec (toList -> xs) messages =
799824 case NE. nonEmpty xs of
800825 Nothing -> ErrorSpec messages
801826 Just ys -> MemberSpec ys
802827
828+ -- | Attach an explanation to a specification in order to track issues with satisfiability
803829explainSpec :: [String ] -> Specification a -> Specification a
804830explainSpec [] x = x
805831explainSpec es (ExplainSpec es' spec) = ExplainSpec (es ++ es') spec
806832explainSpec es spec = ExplainSpec es spec
807833
834+ -- | A "discrete" specification satisfied by exactly one element
808835equalSpec :: a -> Specification a
809836equalSpec = MemberSpec . pure
810837
838+ -- | Anything but this
811839notEqualSpec :: forall a . HasSpec a => a -> Specification a
812840notEqualSpec = TypeSpec (emptySpec @ a ) . pure
813841
842+ -- | Anything but these
814843notMemberSpec :: forall a f . (HasSpec a , Foldable f ) => f a -> Specification a
815844notMemberSpec = typeSpecOpt (emptySpec @ a ) . toList
816845
846+ -- | Build a `Specification` using predicates, e.g.
847+ -- > constrained $ \ x -> assert $ x `elem_` lit [1..10 :: Int]
817848constrained ::
818849 forall a p .
819850 (IsPred p , HasSpec a ) =>
@@ -823,6 +854,7 @@ constrained body =
823854 let x :-> p = bind body
824855 in SuspendedSpec x p
825856
857+ -- | Sound but not complete check for empty `Specification`s
826858isErrorLike :: forall a . Specification a -> Bool
827859isErrorLike (ExplainSpec _ s) = isErrorLike s
828860isErrorLike ErrorSpec {} = True
@@ -832,6 +864,7 @@ isErrorLike (TypeSpec x _) =
832864 Just _ -> True
833865isErrorLike _ = False
834866
867+ -- | Get the error message of an `isErrorLike` `Specification`
835868errorLikeMessage :: forall a . Specification a -> NE. NonEmpty String
836869errorLikeMessage (ErrorSpec es) = es
837870errorLikeMessage (TypeSpec x _) =
0 commit comments