{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Constrained.Generation where
import Constrained.AbstractSyntax
import Constrained.Base
import Constrained.Conformance (
checkPred,
checkPredsE,
conformsToSpec,
satisfies,
)
import Constrained.Core (
Evidence (..),
Value (..),
Var (..),
eqVar,
freshen,
unValue,
unionWithMaybe,
)
import Constrained.Env (
Env,
extendEnv,
findEnv,
lookupEnv,
singletonEnv,
)
import Constrained.FunctionSymbol
import Constrained.GenT
import Constrained.Generic
import Constrained.Graph (
Graph (..),
deleteNode,
topsort,
transitiveClosure,
)
import Constrained.List (
FunTy,
List (..),
ListCtx (..),
foldMapList,
lengthList,
mapList,
mapMList,
uncurryList_,
)
import Constrained.NumOrd
import Constrained.PrettyUtils
import Constrained.Syntax
import Control.Applicative
import Control.Monad
import Control.Monad.Writer (Writer, runWriter, tell)
import Data.Foldable
import Data.Int
import Data.Kind
import Data.List (partition)
import Data.List.NonEmpty (NonEmpty ((:|)))
import qualified Data.List.NonEmpty as NE
import Data.Maybe
import Data.Semigroup (Any (..), getSum)
import qualified Data.Semigroup as Semigroup
import Data.Set (Set)
import qualified Data.Set as Set
import Data.String
import Data.Typeable
import GHC.Stack
import GHC.TypeLits
import Prettyprinter hiding (cat)
import Test.QuickCheck hiding (Args, Fun, Witness, forAll, witness)
import Test.QuickCheck.Gen
import Test.QuickCheck.Random hiding (left, right)
import Prelude hiding (cycle, pred)
genFromSpecT ::
forall a m. (HasCallStack, HasSpec a, MonadGenError m) => Specification a -> GenT m a
genFromSpecT :: forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT (Specification a -> Specification a
forall a. HasSpec a => Specification a -> Specification a
simplifySpec -> Specification a
spec) = case Specification a
spec of
ExplainSpec [] Specification a
s -> Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
s
ExplainSpec [[Char]]
es Specification a
s -> [[Char]] -> GenT m a -> GenT m a
forall (m :: * -> *) a. MonadGenError m => [[Char]] -> m a -> m a
push [[Char]]
es (Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
s)
MemberSpec NonEmpty a
as -> [Char] -> GenT m a -> GenT m a
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain ([Char]
"genFromSpecT on spec" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
spec) (GenT m a -> GenT m a) -> GenT m a -> GenT m a
forall a b. (a -> b) -> a -> b
$ Gen a -> GenT m a
forall (m :: * -> *) a. Applicative m => Gen a -> GenT m a
pureGen ([a] -> Gen a
forall a. HasCallStack => [a] -> Gen a
elements (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty a
as))
Specification a
TrueSpec -> Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT (TypeSpec a -> Specification a
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec (TypeSpec a -> Specification a) -> TypeSpec a -> Specification a
forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => TypeSpec a
emptySpec @a)
SuspendedSpec Var a
x Pred
p
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x Name -> Pred -> Bool
forall a. HasVariables a => Name -> a -> Bool
`appearsIn` Pred
p -> do
!Env
_ <- Env -> Pred -> GenT m Env
forall (m :: * -> *). MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds Env
forall a. Monoid a => a
mempty Pred
p
Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
forall deps a. SpecificationD deps a
TrueSpec
| Bool
otherwise -> do
Env
env <- Env -> Pred -> GenT m Env
forall (m :: * -> *). MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds Env
forall a. Monoid a => a
mempty Pred
p
Env -> Var a -> GenT m a
forall a (m :: * -> *).
(Typeable a, MonadGenError m) =>
Env -> Var a -> m a
findEnv Env
env Var a
x
TypeSpec TypeSpec a
s [a]
cant -> do
GenMode
mode <- GenT m GenMode
forall (m :: * -> *). Applicative m => GenT m GenMode
getMode
NonEmpty [Char] -> GenT m a -> GenT m a
forall a. HasCallStack => NonEmpty [Char] -> GenT m a -> GenT m a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a -> m a
explainNE
( [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[ [Char]
"genFromSpecT on (TypeSpec tspec cant) at type " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ forall t. Typeable t => [Char]
forall {k} (t :: k). Typeable t => [Char]
showType @a
, [Char]
"tspec = "
, TypeSpec a -> [Char]
forall a. Show a => a -> [Char]
show TypeSpec a
s
, [Char]
"cant = " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Doc Any -> [Char]
forall a. Show a => a -> [Char]
show ([a] -> Doc Any
forall a x. (Show a, Typeable a) => [a] -> Doc x
short [a]
cant)
, [Char]
"with mode " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ GenMode -> [Char]
forall a. Show a => a -> [Char]
show GenMode
mode
]
)
(GenT m a -> GenT m a) -> GenT m a -> GenT m a
forall a b. (a -> b) -> a -> b
$
TypeSpec a -> GenT m a
forall a (m :: * -> *).
(HasSpec a, HasCallStack, MonadGenError m) =>
TypeSpec a -> GenT m a
forall (m :: * -> *).
(HasCallStack, MonadGenError m) =>
TypeSpec a -> GenT m a
genFromTypeSpec TypeSpec a
s GenT m a -> (a -> Bool) -> GenT m a
forall a (m :: * -> *).
(Typeable a, MonadGenError m) =>
GenT m a -> (a -> Bool) -> GenT m a
`suchThatT` (a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [a]
cant)
ErrorSpec NonEmpty [Char]
e -> NonEmpty [Char] -> GenT m a
forall a. HasCallStack => NonEmpty [Char] -> GenT m a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genErrorNE NonEmpty [Char]
e
simplifySpec :: HasSpec a => Specification a -> Specification a
simplifySpec :: forall a. HasSpec a => Specification a -> Specification a
simplifySpec Specification a
spec = case Specification a -> Specification a
forall a. Specification a -> Specification a
regularizeNames Specification a
spec of
SuspendedSpec Var a
x Pred
p ->
let optP :: Pred
optP = Pred -> Pred
optimisePred Pred
p
in GE (Specification a) -> Specification a
forall a. HasCallStack => GE (Specification a) -> Specification a
fromGESpec (GE (Specification a) -> Specification a)
-> GE (Specification a) -> Specification a
forall a b. (a -> b) -> a -> b
$
[Char] -> GE (Specification a) -> GE (Specification a)
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain
([Char]
"\nWhile calling simplifySpec on var " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Var a -> [Char]
forall a. Show a => a -> [Char]
show Var a
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\noptP=\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
optP [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\n")
(Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
optP)
MemberSpec NonEmpty a
xs -> NonEmpty a -> Specification a
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec NonEmpty a
xs
ErrorSpec NonEmpty [Char]
es -> NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec NonEmpty [Char]
es
TypeSpec TypeSpec a
ts [a]
cant -> TypeSpec a -> [a] -> Specification a
forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec TypeSpec a
ts [a]
cant
Specification a
TrueSpec -> Specification a
forall deps a. SpecificationD deps a
TrueSpec
ExplainSpec [[Char]]
es Specification a
s -> [[Char]] -> Specification a -> Specification a
forall a. [[Char]] -> Specification a -> Specification a
explainSpecOpt [[Char]]
es (Specification a -> Specification a
forall a. HasSpec a => Specification a -> Specification a
simplifySpec Specification a
s)
optimisePred :: Pred -> Pred
optimisePred :: Pred -> Pred
optimisePred Pred
p =
Pred -> Pred
simplifyPred
(Pred -> Pred) -> (Pred -> Pred) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
letSubexpressionElimination
(Pred -> Pred) -> (Pred -> Pred) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
letFloating
(Pred -> Pred) -> (Pred -> Pred) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
aggressiveInlining
(Pred -> Pred) -> (Pred -> Pred) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
simplifyPred
(Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Pred
p
aggressiveInlining :: Pred -> Pred
aggressiveInlining :: Pred -> Pred
aggressiveInlining Pred
pred
| Bool
inlined = Pred -> Pred
aggressiveInlining Pred
pInlined
| Bool
otherwise = Pred
pred
where
(Pred
pInlined, Any Bool
inlined) = Writer Any Pred -> (Pred, Any)
forall w a. Writer w a -> (a, w)
runWriter (Writer Any Pred -> (Pred, Any)) -> Writer Any Pred -> (Pred, Any)
forall a b. (a -> b) -> a -> b
$ FreeVars -> Subst -> Pred -> Writer Any Pred
go (Pred -> FreeVars
forall a. HasVariables a => a -> FreeVars
freeVars Pred
pred) [] Pred
pred
underBinder :: FreeVars -> Var a -> a -> FreeVars
underBinder FreeVars
fvs Var a
x a
p = FreeVars
fvs FreeVars -> [Name] -> FreeVars
forall (t :: * -> *). Foldable t => FreeVars -> t Name -> FreeVars
`without` [Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x] FreeVars -> FreeVars -> FreeVars
forall a. Semigroup a => a -> a -> a
<> Name -> Int -> FreeVars
singleton (Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x) (Name -> a -> Int
forall a. HasVariables a => Name -> a -> Int
countOf (Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x) a
p)
underBinderSub :: HasSpec a => Subst -> Var a -> Subst
underBinderSub :: forall a. HasSpec a => Subst -> Var a -> Subst
underBinderSub Subst
sub Var a
x =
[ Var a
x' Var a -> Term a -> SubstEntry
forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= Term a
t
| Var a
x' := Term a
t <- Subst
sub
, Maybe (a :~: a) -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe (a :~: a) -> Bool) -> Maybe (a :~: a) -> Bool
forall a b. (a -> b) -> a -> b
$ Var a -> Var a -> Maybe (a :~: a)
forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
x'
]
goBinder :: FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder :: forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub (Var a
x :-> Pred
p) = (Var a
x Var a -> Pred -> BinderD Deps a
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:->) (Pred -> BinderD Deps a)
-> Writer Any Pred -> WriterT Any Identity (BinderD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> Writer Any Pred
go (FreeVars -> Var a -> Pred -> FreeVars
forall {a} {a}.
(HasSpec a, HasVariables a) =>
FreeVars -> Var a -> a -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (Subst -> Var a -> Subst
forall a. HasSpec a => Subst -> Var a -> Subst
underBinderSub Subst
sub Var a
x) Pred
p
onlyUsedUniquely :: Name -> PredD deps -> Bool
onlyUsedUniquely Name
n PredD deps
p = case PredD deps
p of
Assert TermD deps Bool
t
| Name
n Name -> TermD deps Bool -> Bool
forall a. HasVariables a => Name -> a -> Bool
`appearsIn` TermD deps Bool
t -> Set Name -> Int
forall a. Set a -> Int
Set.size (TermD deps Bool -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet TermD deps Bool
t) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1
| Bool
otherwise -> Bool
True
And [PredD deps]
ps -> (PredD deps -> Bool) -> [PredD deps] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Name -> PredD deps -> Bool
onlyUsedUniquely Name
n) [PredD deps]
ps
PredD deps
_ -> Bool
False
go :: FreeVars -> Subst -> Pred -> Writer Any Pred
go FreeVars
fvs Subst
sub Pred
pred2 = case Pred
pred2 of
ElemPred Bool
bool TermD Deps a
t NonEmpty a
xs
| Bool -> Bool
not (TermD Deps a -> Bool
forall a. Term a -> Bool
isLit TermD Deps a
t)
, Lit a
a <- Subst -> TermD Deps a -> TermD Deps a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps a
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Bool -> TermD Deps a -> NonEmpty a -> Pred
forall deps a.
(HasSpecD deps a, Show a) =>
Bool -> TermD deps a -> NonEmpty a -> PredD deps
ElemPred Bool
bool (a -> TermD Deps a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit a
a) NonEmpty a
xs
| Bool
otherwise -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Bool -> TermD Deps a -> NonEmpty a -> Pred
forall deps a.
(HasSpecD deps a, Show a) =>
Bool -> TermD deps a -> NonEmpty a -> PredD deps
ElemPred Bool
bool TermD Deps a
t NonEmpty a
xs
Subst Var a
x TermD Deps a
t Pred
p -> FreeVars -> Subst -> Pred -> Writer Any Pred
go FreeVars
fvs Subst
sub (Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x TermD Deps a
t Pred
p)
Reifies TermD Deps b
t' TermD Deps a
t a -> b
f
| Bool -> Bool
not (TermD Deps a -> Bool
forall a. Term a -> Bool
isLit TermD Deps a
t)
, Lit a
a <- Subst -> TermD Deps a -> TermD Deps a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps a
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ TermD Deps b -> TermD Deps a -> (a -> b) -> Pred
forall deps a b.
(HasSpecD deps a, HasSpecD deps b, Show a, Show b) =>
TermD deps b -> TermD deps a -> (a -> b) -> PredD deps
Reifies TermD Deps b
t' (a -> TermD Deps a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit a
a) a -> b
f
| Bool
otherwise -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ TermD Deps b -> TermD Deps a -> (a -> b) -> Pred
forall deps a b.
(HasSpecD deps a, HasSpecD deps b, Show a, Show b) =>
TermD deps b -> TermD deps a -> (a -> b) -> PredD deps
Reifies TermD Deps b
t' TermD Deps a
t a -> b
f
ForAll TermD Deps t
set BinderD Deps e
b
| Bool -> Bool
not (TermD Deps t -> Bool
forall a. Term a -> Bool
isLit TermD Deps t
set)
, Lit t
a <- Subst -> TermD Deps t -> TermD Deps t
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps t
set -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ (e -> Pred) -> [e] -> Pred
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (e -> BinderD Deps e -> Pred
forall a. a -> Binder a -> Pred
`unBind` BinderD Deps e
b) (t -> [e]
forall t e. Forallable t e => t -> [e]
forAllToList t
a)
| Bool
otherwise -> TermD Deps t -> BinderD Deps e -> Pred
forall deps t e.
(ForallableD deps t e, HasSpecD deps t, HasSpecD deps e, Show t,
Show e) =>
TermD deps t -> BinderD deps e -> PredD deps
ForAll TermD Deps t
set (BinderD Deps e -> Pred)
-> WriterT Any Identity (BinderD Deps e) -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars
-> Subst -> BinderD Deps e -> WriterT Any Identity (BinderD Deps e)
forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub BinderD Deps e
b
Case TermD Deps (SumOver as)
t List (Weighted (BinderD Deps)) as
bs
| Bool -> Bool
not (TermD Deps (SumOver as) -> Bool
forall a. Term a -> Bool
isLit TermD Deps (SumOver as)
t)
, Lit SumOver as
a <- Subst -> TermD Deps (SumOver as) -> TermD Deps (SumOver as)
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps (SumOver as)
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ SumOver as
-> List (BinderD Deps) as
-> (forall {a}. (Typeable a, Show a) => Var a -> a -> Pred -> Pred)
-> Pred
forall (as :: [*]) r.
SumOver as
-> List (BinderD Deps) as
-> (forall a. (Typeable a, Show a) => Var a -> a -> Pred -> r)
-> r
runCaseOn SumOver as
a ((forall a. Weighted (BinderD Deps) a -> Binder a)
-> List (Weighted (BinderD Deps)) as -> List (BinderD Deps) as
forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList Weighted (BinderD Deps) a -> Binder a
forall a. Weighted (BinderD Deps) a -> Binder a
forall (f :: * -> *) a. Weighted f a -> f a
thing List (Weighted (BinderD Deps)) as
bs) ((forall {a}. (Typeable a, Show a) => Var a -> a -> Pred -> Pred)
-> Pred)
-> (forall {a}. (Typeable a, Show a) => Var a -> a -> Pred -> Pred)
-> Pred
forall a b. (a -> b) -> a -> b
$ \Var a
x a
v Pred
p -> Env -> Pred -> Pred
substPred (Var a -> a -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
v) Pred
p
| (Weighted Maybe Int
w (Var a
x :-> Pred
p) :> List (Weighted (BinderD Deps)) as1
Nil) <- List (Weighted (BinderD Deps)) as
bs -> do
let t' :: Term a
t' = Subst -> Term a -> Term a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
TermD Deps (SumOver as)
t
Pred
p' <- FreeVars -> Subst -> Pred -> Writer Any Pred
go (FreeVars -> Var a -> Pred -> FreeVars
forall {a} {a}.
(HasSpec a, HasVariables a) =>
FreeVars -> Var a -> a -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (Var a
x Var a -> Term a -> SubstEntry
forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= Term a
t' SubstEntry -> Subst -> Subst
forall a. a -> [a] -> [a]
: Subst
sub) Pred
p
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ TermD Deps (SumOver '[a])
-> List (Weighted (BinderD Deps)) '[a] -> Pred
forall deps (as :: [*]).
(HasSpecD deps (SumOver as), Show (SumOver as)) =>
TermD deps (SumOver as)
-> List (Weighted (BinderD deps)) as -> PredD deps
Case TermD Deps (SumOver as)
TermD Deps (SumOver '[a])
t (Maybe Int -> BinderD Deps a -> Weighted (BinderD Deps) a
forall (f :: * -> *) a. Maybe Int -> f a -> Weighted f a
Weighted Maybe Int
w (Var a
x Var a -> Pred -> BinderD Deps a
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
p') Weighted (BinderD Deps) a
-> List (Weighted (BinderD Deps)) '[]
-> List (Weighted (BinderD Deps)) '[a]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (Weighted (BinderD Deps)) '[]
forall {k} (f :: k -> *). List f '[]
Nil)
| Bool
otherwise -> TermD Deps (SumOver as)
-> List (Weighted (BinderD Deps)) as -> Pred
forall deps (as :: [*]).
(HasSpecD deps (SumOver as), Show (SumOver as)) =>
TermD deps (SumOver as)
-> List (Weighted (BinderD deps)) as -> PredD deps
Case TermD Deps (SumOver as)
t (List (Weighted (BinderD Deps)) as -> Pred)
-> WriterT Any Identity (List (Weighted (BinderD Deps)) as)
-> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a.
Weighted (BinderD Deps) a
-> WriterT Any Identity (Weighted (BinderD Deps) a))
-> List (Weighted (BinderD Deps)) as
-> WriterT Any Identity (List (Weighted (BinderD Deps)) as)
forall {k} (m :: * -> *) (f :: k -> *) (g :: k -> *) (as :: [k]).
Applicative m =>
(forall (a :: k). f a -> m (g a)) -> List f as -> m (List g as)
mapMList ((BinderD Deps a -> WriterT Any Identity (BinderD Deps a))
-> Weighted (BinderD Deps) a
-> WriterT Any Identity (Weighted (BinderD Deps) a)
forall (m :: * -> *) (f :: * -> *) a (g :: * -> *).
Applicative m =>
(f a -> m (g a)) -> Weighted f a -> m (Weighted g a)
traverseWeighted ((BinderD Deps a -> WriterT Any Identity (BinderD Deps a))
-> Weighted (BinderD Deps) a
-> WriterT Any Identity (Weighted (BinderD Deps) a))
-> (BinderD Deps a -> WriterT Any Identity (BinderD Deps a))
-> Weighted (BinderD Deps) a
-> WriterT Any Identity (Weighted (BinderD Deps) a)
forall a b. (a -> b) -> a -> b
$ FreeVars
-> Subst -> BinderD Deps a -> WriterT Any Identity (BinderD Deps a)
forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub) List (Weighted (BinderD Deps)) as
bs
When TermD Deps Bool
b Pred
tp
| Bool -> Bool
not (TermD Deps Bool -> Bool
forall a. Term a -> Bool
isLit TermD Deps Bool
b)
, Lit Bool
a <- Subst -> TermD Deps Bool -> TermD Deps Bool
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps Bool
b -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ if Bool
a then Pred
tp else Pred
forall deps. PredD deps
TruePred
| Bool
otherwise -> TermD Deps Bool -> Pred -> Pred
forall p. IsPred p => TermD Deps Bool -> p -> Pred
whenTrue TermD Deps Bool
b (Pred -> Pred) -> Writer Any Pred -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> Writer Any Pred
go FreeVars
fvs Subst
sub Pred
tp
Let TermD Deps a
t (Var a
x :-> Pred
p)
| (Name -> Bool) -> Set Name -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Name
n -> Name -> FreeVars -> Int
count Name
n FreeVars
fvs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
1) (TermD Deps a -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet TermD Deps a
t) -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x TermD Deps a
t Pred
p
| Name -> Pred -> Bool
forall {deps}.
HasVariables (TermD deps Bool) =>
Name -> PredD deps -> Bool
onlyUsedUniquely (Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x) Pred
p -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x TermD Deps a
t Pred
p
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x Name -> Pred -> Bool
forall a. HasVariables a => Name -> a -> Bool
`appearsIn` Pred
p -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
p
| Bool -> Bool
not (TermD Deps a -> Bool
forall a. Term a -> Bool
isLit TermD Deps a
t)
, Lit a
a <- Subst -> TermD Deps a -> TermD Deps a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps a
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ a -> BinderD Deps a -> Pred
forall a. a -> Binder a -> Pred
unBind a
a (Var a
x Var a -> Pred -> BinderD Deps a
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
p)
| Bool
otherwise -> TermD Deps a -> BinderD Deps a -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let TermD Deps a
t (BinderD Deps a -> Pred)
-> (Pred -> BinderD Deps a) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var a
x Var a -> Pred -> BinderD Deps a
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:->) (Pred -> Pred) -> Writer Any Pred -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> Writer Any Pred
go (FreeVars -> Var a -> Pred -> FreeVars
forall {a} {a}.
(HasSpec a, HasVariables a) =>
FreeVars -> Var a -> a -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (Var a
x Var a -> TermD Deps a -> SubstEntry
forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= TermD Deps a
t SubstEntry -> Subst -> Subst
forall a. a -> [a] -> [a]
: Subst
sub) Pred
p
Exists (forall b. TermD Deps b -> b) -> GE a
k BinderD Deps a
b -> ((forall b. TermD Deps b -> b) -> GE a) -> BinderD Deps a -> Pred
forall deps a.
((forall b. TermD deps b -> b) -> GE a)
-> BinderD deps a -> PredD deps
Exists (forall b. TermD Deps b -> b) -> GE a
k (BinderD Deps a -> Pred)
-> WriterT Any Identity (BinderD Deps a) -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars
-> Subst -> BinderD Deps a -> WriterT Any Identity (BinderD Deps a)
forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub BinderD Deps a
b
And [Pred]
ps -> [Pred] -> Pred
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([Pred] -> Pred) -> WriterT Any Identity [Pred] -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Pred -> Writer Any Pred) -> [Pred] -> WriterT Any Identity [Pred]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (FreeVars -> Subst -> Pred -> Writer Any Pred
go FreeVars
fvs Subst
sub) [Pred]
ps
Assert TermD Deps Bool
t
| Bool -> Bool
not (TermD Deps Bool -> Bool
forall a. Term a -> Bool
isLit TermD Deps Bool
t)
, Lit Bool
b <- Subst -> TermD Deps Bool -> TermD Deps Bool
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps Bool
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Bool -> Pred
forall p. IsPred p => p -> Pred
toPred Bool
b
| Bool
otherwise -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
GenHint HintD Deps a
_ TermD Deps a
t
| Bool -> Bool
not (TermD Deps a -> Bool
forall a. Term a -> Bool
isLit TermD Deps a
t)
, Lit {} <- Subst -> TermD Deps a -> TermD Deps a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps a
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
forall deps. PredD deps
TruePred
| Bool
otherwise -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
DependsOn TermD Deps a
t TermD Deps b
t'
| Bool -> Bool
not (TermD Deps a -> Bool
forall a. Term a -> Bool
isLit TermD Deps a
t)
, Lit {} <- Subst -> TermD Deps a -> TermD Deps a
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps a
t -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Pred
forall deps. PredD deps
TruePred
| Bool -> Bool
not (TermD Deps b -> Bool
forall a. Term a -> Bool
isLit TermD Deps b
t')
, Lit {} <- Subst -> TermD Deps b -> TermD Deps b
forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub TermD Deps b
t' -> do
Any -> WriterT Any Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Any -> WriterT Any Identity ()) -> Any -> WriterT Any Identity ()
forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pred -> Writer Any Pred) -> Pred -> Writer Any Pred
forall a b. (a -> b) -> a -> b
$ Pred
forall deps. PredD deps
TruePred
| Bool
otherwise -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Pred
TruePred -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
FalsePred {} -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Monitor {} -> Pred -> Writer Any Pred
forall a. a -> WriterT Any Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Explain NonEmpty [Char]
es Pred
p -> NonEmpty [Char] -> Pred -> Pred
forall deps. NonEmpty [Char] -> PredD deps -> PredD deps
Explain NonEmpty [Char]
es (Pred -> Pred) -> Writer Any Pred -> Writer Any Pred
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> Writer Any Pred
go FreeVars
fvs Subst
sub Pred
p
substituteAndSimplifyTerm :: Subst -> Term a -> Term a
substituteAndSimplifyTerm :: forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t =
case Writer Any (Term a) -> (Term a, Any)
forall w a. Writer w a -> (a, w)
runWriter (Writer Any (Term a) -> (Term a, Any))
-> Writer Any (Term a) -> (Term a, Any)
forall a b. (a -> b) -> a -> b
$ Subst -> Term a -> Writer Any (Term a)
forall a. Subst -> Term a -> Writer Any (Term a)
substituteTerm' Subst
sub Term a
t of
(Term a
t', Any Bool
b)
| Bool
b -> Term a -> Term a
forall a. Term a -> Term a
simplifyTerm Term a
t'
| Bool
otherwise -> Term a
t'
simplifyTerm :: forall a. Term a -> Term a
simplifyTerm :: forall a. Term a -> Term a
simplifyTerm = \case
V Var a
v -> Var a -> Term a
forall deps a.
(HasSpecD deps a, Typeable a) =>
Var a -> TermD deps a
V Var a
v
Lit a
l -> a -> Term a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit a
l
App (t dom a
f :: t bs a) ((forall a. Term a -> Term a)
-> List (TermD Deps) dom -> List (TermD Deps) dom
forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList Term a -> Term a
forall a. Term a -> Term a
simplifyTerm -> List (TermD Deps) dom
ts)
| Just List Value dom
vs <- List (TermD Deps) dom -> Maybe (List Value dom)
forall (as :: [*]). List (TermD Deps) as -> Maybe (List Value as)
fromLits List (TermD Deps) dom
ts -> a -> Term a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit (a -> Term a) -> a -> Term a
forall a b. (a -> b) -> a -> b
$ (forall a. Value a -> a) -> FunTy dom a -> List Value dom -> a
forall (ts :: [*]) (f :: * -> *) r.
TypeList ts =>
(forall a. f a -> a) -> FunTy ts r -> List f ts -> r
forall (f :: * -> *) r.
(forall a. f a -> a) -> FunTy dom r -> List f dom -> r
uncurryList_ Value a -> a
forall a. Value a -> a
unValue (t dom a -> FunTy dom a
forall (d :: [*]) r. t d r -> FunTy d r
forall (t :: [*] -> * -> *) (d :: [*]) r.
Semantics t =>
t d r -> FunTy d r
semantics t dom a
f) List Value dom
vs
| Just Term a
t <- t dom a
-> List (TermD Deps) dom
-> Evidence (AppRequiresD Deps t dom a)
-> Maybe (Term a)
forall (dom :: [*]) rng.
(TypeList dom, Typeable dom, HasSpec rng, All HasSpec dom) =>
t dom rng
-> List (TermD Deps) dom
-> Evidence (AppRequires t dom rng)
-> Maybe (Term rng)
forall (t :: [*] -> * -> *) (dom :: [*]) rng.
(Logic t, TypeList dom, Typeable dom, HasSpec rng,
All HasSpec dom) =>
t dom rng
-> List (TermD Deps) dom
-> Evidence (AppRequires t dom rng)
-> Maybe (Term rng)
rewriteRules t dom a
f List (TermD Deps) dom
ts (forall (c :: Constraint). c => Evidence c
Evidence @(AppRequires t bs a)) -> Term a -> Term a
forall a. Term a -> Term a
simplifyTerm Term a
t
| Bool
otherwise -> t dom a -> List (TermD Deps) dom -> Term a
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App t dom a
f List (TermD Deps) dom
ts
simplifyPred :: Pred -> Pred
simplifyPred :: Pred -> Pred
simplifyPred = \case
GenHint HintD Deps a
h TermD Deps a
t -> case TermD Deps a -> TermD Deps a
forall a. Term a -> Term a
simplifyTerm TermD Deps a
t of
Lit {} -> Pred
forall deps. PredD deps
TruePred
TermD Deps a
t' -> HintD Deps a -> TermD Deps a -> Pred
forall deps a.
(HasGenHintD deps a, Show a, Show (HintD deps a)) =>
HintD deps a -> TermD deps a -> PredD deps
GenHint HintD Deps a
h TermD Deps a
t'
p :: Pred
p@(ElemPred Bool
bool TermD Deps a
t NonEmpty a
xs) -> case TermD Deps a -> TermD Deps a
forall a. Term a -> Term a
simplifyTerm TermD Deps a
t of
Lit a
x -> case (a -> NonEmpty a -> Bool
forall a. Eq a => a -> NonEmpty a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem a
x NonEmpty a
xs, Bool
bool) of
(Bool
True, Bool
True) -> Pred
forall deps. PredD deps
TruePred
(Bool
True, Bool
False) -> NonEmpty [Char] -> Pred
forall deps. NonEmpty [Char] -> PredD deps
FalsePred ([Char]
"notElemPred reduces to True" [Char] -> [[Char]] -> NonEmpty [Char]
forall a. a -> [a] -> NonEmpty a
:| [Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
p])
(Bool
False, Bool
True) -> NonEmpty [Char] -> Pred
forall deps. NonEmpty [Char] -> PredD deps
FalsePred ([Char]
"elemPred reduces to False" [Char] -> [[Char]] -> NonEmpty [Char]
forall a. a -> [a] -> NonEmpty a
:| [Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
p])
(Bool
False, Bool
False) -> Pred
forall deps. PredD deps
TruePred
TermD Deps a
t' -> Bool -> TermD Deps a -> NonEmpty a -> Pred
forall deps a.
(HasSpecD deps a, Show a) =>
Bool -> TermD deps a -> NonEmpty a -> PredD deps
ElemPred Bool
bool TermD Deps a
t' NonEmpty a
xs
Subst Var a
x TermD Deps a
t Pred
p -> Pred -> Pred
simplifyPred (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x TermD Deps a
t Pred
p
Assert TermD Deps Bool
t -> TermD Deps Bool -> Pred
forall deps. TermD deps Bool -> PredD deps
Assert (TermD Deps Bool -> Pred) -> TermD Deps Bool -> Pred
forall a b. (a -> b) -> a -> b
$ TermD Deps Bool -> TermD Deps Bool
forall a. Term a -> Term a
simplifyTerm TermD Deps Bool
t
Reifies TermD Deps b
t' TermD Deps a
t a -> b
f -> case TermD Deps a -> TermD Deps a
forall a. Term a -> Term a
simplifyTerm TermD Deps a
t of
Lit a
a ->
Bool -> TermD Deps b -> NonEmpty b -> Pred
forall deps a.
(HasSpecD deps a, Show a) =>
Bool -> TermD deps a -> NonEmpty a -> PredD deps
ElemPred Bool
True (TermD Deps b -> TermD Deps b
forall a. Term a -> Term a
simplifyTerm TermD Deps b
t') (b -> NonEmpty b
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> b
f a
a))
TermD Deps a
t'' -> TermD Deps b -> TermD Deps a -> (a -> b) -> Pred
forall deps a b.
(HasSpecD deps a, HasSpecD deps b, Show a, Show b) =>
TermD deps b -> TermD deps a -> (a -> b) -> PredD deps
Reifies (TermD Deps b -> TermD Deps b
forall a. Term a -> Term a
simplifyTerm TermD Deps b
t') TermD Deps a
t'' a -> b
f
ForAll (Term t
ts :: Term t) (Binder e
b :: Binder a) -> case Term t -> Term t
forall a. Term a -> Term a
simplifyTerm Term t
ts of
Lit t
as -> (e -> Pred) -> [e] -> Pred
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (e -> Binder e -> Pred
forall a. a -> Binder a -> Pred
`unBind` Binder e
b) (t -> [e]
forall t e. Forallable t e => t -> [e]
forAllToList t
as)
Term t
set' -> case Binder e -> Binder e
forall a. Binder a -> Binder a
simplifyBinder Binder e
b of
Var e
_ :-> Pred
TruePred -> Pred
forall deps. PredD deps
TruePred
Binder e
b' -> Term t -> Binder e -> Pred
forall deps t e.
(ForallableD deps t e, HasSpecD deps t, HasSpecD deps e, Show t,
Show e) =>
TermD deps t -> BinderD deps e -> PredD deps
ForAll Term t
set' Binder e
b'
DependsOn TermD Deps a
_ Lit {} -> Pred
forall deps. PredD deps
TruePred
DependsOn Lit {} TermD Deps b
_ -> Pred
forall deps. PredD deps
TruePred
DependsOn TermD Deps a
x TermD Deps b
y -> TermD Deps a -> TermD Deps b -> Pred
forall deps a b.
(HasSpecD deps a, HasSpecD deps b, Show a, Show b) =>
TermD deps a -> TermD deps b -> PredD deps
DependsOn TermD Deps a
x TermD Deps b
y
Case TermD Deps (SumOver as)
t List (Weighted (BinderD Deps)) as
bs -> TermD Deps (SumOver as)
-> List (Weighted (BinderD Deps)) as -> Pred
forall (as :: [*]).
HasSpec (SumOver as) =>
Term (SumOver as) -> List (Weighted (BinderD Deps)) as -> Pred
mkCase (TermD Deps (SumOver as) -> TermD Deps (SumOver as)
forall a. Term a -> Term a
simplifyTerm TermD Deps (SumOver as)
t) ((forall a. Weighted (BinderD Deps) a -> Weighted (BinderD Deps) a)
-> List (Weighted (BinderD Deps)) as
-> List (Weighted (BinderD Deps)) as
forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList ((BinderD Deps a -> BinderD Deps a)
-> Weighted (BinderD Deps) a -> Weighted (BinderD Deps) a
forall (f :: * -> *) a (g :: * -> *) b.
(f a -> g b) -> Weighted f a -> Weighted g b
mapWeighted BinderD Deps a -> BinderD Deps a
forall a. Binder a -> Binder a
simplifyBinder) List (Weighted (BinderD Deps)) as
bs)
When TermD Deps Bool
b Pred
p -> TermD Deps Bool -> Pred -> Pred
forall p. IsPred p => TermD Deps Bool -> p -> Pred
whenTrue (TermD Deps Bool -> TermD Deps Bool
forall a. Term a -> Term a
simplifyTerm TermD Deps Bool
b) (Pred -> Pred
simplifyPred Pred
p)
Pred
TruePred -> Pred
forall deps. PredD deps
TruePred
FalsePred NonEmpty [Char]
es -> NonEmpty [Char] -> Pred
forall deps. NonEmpty [Char] -> PredD deps
FalsePred NonEmpty [Char]
es
And [Pred]
ps -> [Pred] -> Pred
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([Pred] -> [Pred]
simplifyPreds [Pred]
ps)
Let TermD Deps a
t BinderD Deps a
b -> case TermD Deps a -> TermD Deps a
forall a. Term a -> Term a
simplifyTerm TermD Deps a
t of
t' :: TermD Deps a
t'@App {} -> TermD Deps a -> BinderD Deps a -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let TermD Deps a
t' (BinderD Deps a -> BinderD Deps a
forall a. Binder a -> Binder a
simplifyBinder BinderD Deps a
b)
TermD Deps a
t' | Var a
x :-> Pred
p <- BinderD Deps a
b -> Pred -> Pred
simplifyPred (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x TermD Deps a
t' Pred
p
Exists (forall b. TermD Deps b -> b) -> GE a
k BinderD Deps a
b -> case BinderD Deps a -> BinderD Deps a
forall a. Binder a -> Binder a
simplifyBinder BinderD Deps a
b of
Var a
_ :-> Pred
TruePred -> Pred
forall deps. PredD deps
TruePred
Var a
x :-> Pred
p | Just Term a
t <- Var a -> Pred -> Maybe (Term a)
forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy Var a
x Pred
p -> Pred -> Pred
simplifyPred (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Var a -> Term a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p
BinderD Deps a
b' -> ((forall b. TermD Deps b -> b) -> GE a) -> BinderD Deps a -> Pred
forall deps a.
((forall b. TermD deps b -> b) -> GE a)
-> BinderD deps a -> PredD deps
Exists (forall b. TermD Deps b -> b) -> GE a
k BinderD Deps a
b'
Monitor {} -> Pred
forall deps. PredD deps
TruePred
Explain NonEmpty [Char]
es Pred
p -> NonEmpty [Char] -> Pred -> Pred
explanation NonEmpty [Char]
es (Pred -> Pred) -> Pred -> Pred
forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
p
simplifyPreds :: [Pred] -> [Pred]
simplifyPreds :: [Pred] -> [Pred]
simplifyPreds = [Pred] -> [Pred] -> [Pred]
forall {deps}. [PredD deps] -> [PredD deps] -> [PredD deps]
go [] ([Pred] -> [Pred]) -> ([Pred] -> [Pred]) -> [Pred] -> [Pred]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pred -> Pred) -> [Pred] -> [Pred]
forall a b. (a -> b) -> [a] -> [b]
map Pred -> Pred
simplifyPred
where
go :: [PredD deps] -> [PredD deps] -> [PredD deps]
go [PredD deps]
acc [] = [PredD deps] -> [PredD deps]
forall a. [a] -> [a]
reverse [PredD deps]
acc
go [PredD deps]
_ (FalsePred NonEmpty [Char]
err : [PredD deps]
_) = [NonEmpty [Char] -> PredD deps
forall deps. NonEmpty [Char] -> PredD deps
FalsePred NonEmpty [Char]
err]
go [PredD deps]
acc (PredD deps
TruePred : [PredD deps]
ps) = [PredD deps] -> [PredD deps] -> [PredD deps]
go [PredD deps]
acc [PredD deps]
ps
go [PredD deps]
acc (PredD deps
p : [PredD deps]
ps) = [PredD deps] -> [PredD deps] -> [PredD deps]
go (PredD deps
p PredD deps -> [PredD deps] -> [PredD deps]
forall a. a -> [a] -> [a]
: [PredD deps]
acc) [PredD deps]
ps
simplifyBinder :: Binder a -> Binder a
simplifyBinder :: forall a. Binder a -> Binder a
simplifyBinder (Var a
x :-> Pred
p) = Var a
x Var a -> Pred -> BinderD Deps a
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred -> Pred
simplifyPred Pred
p
computeSpecSimplified ::
forall a. (HasSpec a, HasCallStack) => Var a -> Pred -> GE (Specification a)
computeSpecSimplified :: forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
pred3 = GE (SpecificationD Deps a) -> GE (SpecificationD Deps a)
forall {deps} {a}.
GE (SpecificationD deps a) -> GE (SpecificationD deps a)
localGESpec (GE (SpecificationD Deps a) -> GE (SpecificationD Deps a))
-> GE (SpecificationD Deps a) -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ case Pred -> Pred
simplifyPred Pred
pred3 of
ElemPred Bool
True TermD Deps a
t NonEmpty a
xs -> Specification a -> Ctx a a -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (NonEmpty a -> Specification a
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec NonEmpty a
xs) (Ctx a a -> SpecificationD Deps a)
-> GE (Ctx a a) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps a -> GE (Ctx a a)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps a
t
ElemPred Bool
False (Term a
t :: Term b) NonEmpty a
xs -> Specification a -> Ctx a a -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec @b (forall a. HasSpec a => TypeSpec a
emptySpec @b) (NonEmpty a -> [a]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty a
xs)) (Ctx a a -> SpecificationD Deps a)
-> GE (Ctx a a) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> Term a -> GE (Ctx a a)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term a
t
Monitor {} -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
forall a. Monoid a => a
mempty
GenHint (HintF Hint a
h) TermD Deps a
t -> Specification a -> Ctx a a -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (Hint a -> Specification a
forall a. HasGenHint a => Hint a -> Specification a
giveHint Hint a
h) (Ctx a a -> SpecificationD Deps a)
-> GE (Ctx a a) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps a -> GE (Ctx a a)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps a
t
Subst Var a
x' TermD Deps a
t Pred
p' -> Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x (Var a -> TermD Deps a -> Pred -> Pred
forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x' TermD Deps a
t Pred
p')
Pred
TruePred -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
forall a. Monoid a => a
mempty
FalsePred NonEmpty [Char]
es -> NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a. HasCallStack => NonEmpty [Char] -> GE a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genErrorNE NonEmpty [Char]
es
And [Pred]
ps -> do
SpecificationD Deps a
spec <- [SpecificationD Deps a] -> SpecificationD Deps a
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([SpecificationD Deps a] -> SpecificationD Deps a)
-> GE [SpecificationD Deps a] -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Pred -> GE (SpecificationD Deps a))
-> [Pred] -> GE [SpecificationD Deps a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x) [Pred]
ps
case SpecificationD Deps a
spec of
ExplainSpec [[Char]]
es (SuspendedSpec Var a
y Pred
ps') -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> SpecificationD Deps a -> SpecificationD Deps a
forall a. [[Char]] -> Specification a -> Specification a
explainSpecOpt [[Char]]
es (Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
y (Pred -> SpecificationD Deps a) -> Pred -> SpecificationD Deps a
forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
ps')
SuspendedSpec Var a
y Pred
ps' -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
y (Pred -> SpecificationD Deps a) -> Pred -> SpecificationD Deps a
forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
ps'
SpecificationD Deps a
s -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
s
Let TermD Deps a
t BinderD Deps a
b -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
x (TermD Deps a -> BinderD Deps a -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let TermD Deps a
t BinderD Deps a
b)
Exists (forall b. TermD Deps b -> b) -> GE a
k BinderD Deps a
b -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
x (((forall b. TermD Deps b -> b) -> GE a) -> BinderD Deps a -> Pred
forall deps a.
((forall b. TermD deps b -> b) -> GE a)
-> BinderD deps a -> PredD deps
Exists (forall b. TermD Deps b -> b) -> GE a
k BinderD Deps a
b)
Assert (Lit Bool
True) -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
forall a. Monoid a => a
mempty
Assert (Lit Bool
False) -> [Char] -> GE (SpecificationD Deps a)
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
genError (Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
pred3)
Assert TermD Deps Bool
t -> Specification Bool -> Ctx a Bool -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (Bool -> Specification Bool
forall a. a -> Specification a
equalSpec Bool
True) (Ctx a Bool -> SpecificationD Deps a)
-> GE (Ctx a Bool) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps Bool -> GE (Ctx a Bool)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps Bool
t
ForAll (Lit t
s) BinderD Deps e
b -> [SpecificationD Deps a] -> SpecificationD Deps a
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([SpecificationD Deps a] -> SpecificationD Deps a)
-> GE [SpecificationD Deps a] -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (e -> GE (SpecificationD Deps a))
-> [e] -> GE [SpecificationD Deps a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\e
val -> Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x (Pred -> GE (SpecificationD Deps a))
-> Pred -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ e -> BinderD Deps e -> Pred
forall a. a -> Binder a -> Pred
unBind e
val BinderD Deps e
b) (t -> [e]
forall t e. Forallable t e => t -> [e]
forAllToList t
s)
ForAll TermD Deps t
t BinderD Deps e
b -> do
Specification e
bSpec <- BinderD Deps e -> GE (Specification e)
forall a. Binder a -> GE (Specification a)
computeSpecBinderSimplified BinderD Deps e
b
Specification t -> Ctx a t -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (Specification e -> Specification t
forall t e.
(Forallable t e, HasSpec t, HasSpec e) =>
Specification e -> Specification t
fromForAllSpec Specification e
bSpec) (Ctx a t -> SpecificationD Deps a)
-> GE (Ctx a t) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps t -> GE (Ctx a t)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps t
t
Case (Lit SumOver as
val) List (Weighted (BinderD Deps)) as
bs -> SumOver as
-> List (BinderD Deps) as
-> (forall {a}.
(Typeable a, Show a) =>
Var a -> a -> Pred -> GE (SpecificationD Deps a))
-> GE (SpecificationD Deps a)
forall (as :: [*]) r.
SumOver as
-> List (BinderD Deps) as
-> (forall a. (Typeable a, Show a) => Var a -> a -> Pred -> r)
-> r
runCaseOn SumOver as
val ((forall a. Weighted (BinderD Deps) a -> Binder a)
-> List (Weighted (BinderD Deps)) as -> List (BinderD Deps) as
forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList Weighted (BinderD Deps) a -> Binder a
forall a. Weighted (BinderD Deps) a -> Binder a
forall (f :: * -> *) a. Weighted f a -> f a
thing List (Weighted (BinderD Deps)) as
bs) ((forall {a}.
(Typeable a, Show a) =>
Var a -> a -> Pred -> GE (SpecificationD Deps a))
-> GE (SpecificationD Deps a))
-> (forall {a}.
(Typeable a, Show a) =>
Var a -> a -> Pred -> GE (SpecificationD Deps a))
-> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ \Var a
va a
vaVal Pred
psa -> Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x (Env -> Pred -> Pred
substPred (Var a -> a -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
va a
vaVal) Pred
psa)
Case TermD Deps (SumOver as)
t List (Weighted (BinderD Deps)) as
branches -> do
List (Weighted Specification) as
branchSpecs <- (forall a.
Weighted (BinderD Deps) a -> GE (Weighted Specification a))
-> List (Weighted (BinderD Deps)) as
-> GE (List (Weighted Specification) as)
forall {k} (m :: * -> *) (f :: k -> *) (g :: k -> *) (as :: [k]).
Applicative m =>
(forall (a :: k). f a -> m (g a)) -> List f as -> m (List g as)
mapMList ((BinderD Deps a -> GE (SpecificationD Deps a))
-> Weighted (BinderD Deps) a -> GE (Weighted Specification a)
forall (m :: * -> *) (f :: * -> *) a (g :: * -> *).
Applicative m =>
(f a -> m (g a)) -> Weighted f a -> m (Weighted g a)
traverseWeighted BinderD Deps a -> GE (SpecificationD Deps a)
forall a. Binder a -> GE (Specification a)
computeSpecBinderSimplified) List (Weighted (BinderD Deps)) as
branches
Specification (SumOver as)
-> Ctx a (SumOver as) -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
caseSpec ([Char] -> Maybe [Char]
forall a. a -> Maybe a
Just (forall t. Typeable t => [Char]
forall {k} (t :: k). Typeable t => [Char]
showType @a)) List (Weighted Specification) as
branchSpecs) (Ctx a (SumOver as) -> SpecificationD Deps a)
-> GE (Ctx a (SumOver as)) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps (SumOver as) -> GE (Ctx a (SumOver as))
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps (SumOver as)
t
When (Lit Bool
b) Pred
tp -> if Bool
b then Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
tp else SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
forall deps a. SpecificationD deps a
TrueSpec
When {} -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
x Pred
pred3
Reifies (Lit b
a) (Lit a
val) a -> b
f
| a -> b
f a
val b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
a -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SpecificationD Deps a
forall deps a. SpecificationD deps a
TrueSpec
| Bool
otherwise ->
SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$
NonEmpty [Char] -> SpecificationD Deps a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec ([[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList [[Char]
"Value does not reify to literal: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ a -> [Char]
forall a. Show a => a -> [Char]
show a
val [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" -/> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show b
a])
Reifies TermD Deps b
t' (Lit a
val) a -> b
f ->
Specification b -> Ctx a b -> SpecificationD Deps a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (b -> Specification b
forall a. a -> Specification a
equalSpec (a -> b
f a
val)) (Ctx a b -> SpecificationD Deps a)
-> GE (Ctx a b) -> GE (SpecificationD Deps a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var a -> TermD Deps b -> GE (Ctx a b)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x TermD Deps b
t'
Reifies Lit {} TermD Deps a
_ a -> b
_ ->
NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a. HasCallStack => NonEmpty [Char] -> GE a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalErrorNE (NonEmpty [Char] -> GE (SpecificationD Deps a))
-> NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList [[Char]
"Dependency error in computeSpec: Reifies", [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
pred3]
Explain NonEmpty [Char]
es Pred
p -> do
SpecificationD Deps a
s <- [[Char]]
-> GE (SpecificationD Deps a) -> GE (SpecificationD Deps a)
forall a. [[Char]] -> GE a -> GE a
pushGE (NonEmpty [Char] -> [[Char]]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty [Char]
es) (Var a -> Pred -> GE (SpecificationD Deps a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
p)
case SpecificationD Deps a
s of
SuspendedSpec Var a
x2 Pred
p2 -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> SpecificationD Deps a
forall deps a.
HasSpecD deps a =>
Var a -> PredD deps -> SpecificationD deps a
SuspendedSpec Var a
x2 (NonEmpty [Char] -> Pred -> Pred
explanation NonEmpty [Char]
es Pred
p2)
SpecificationD Deps a
_ -> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SpecificationD Deps a -> GE (SpecificationD Deps a))
-> SpecificationD Deps a -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$ NonEmpty [Char] -> SpecificationD Deps a -> SpecificationD Deps a
forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec NonEmpty [Char]
es SpecificationD Deps a
s
DependsOn {} ->
NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a. HasCallStack => NonEmpty [Char] -> GE a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalErrorNE (NonEmpty [Char] -> GE (SpecificationD Deps a))
-> NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$
[[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[ [Char]
"The impossible happened in computeSpec: DependsOn"
, [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Var a -> [Char]
forall a. Show a => a -> [Char]
show Var a
x
, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> Doc Any -> Doc Any
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Pred -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Pred -> Doc ann
pretty Pred
pred3)
]
Reifies {} ->
NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a. HasCallStack => NonEmpty [Char] -> GE a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalErrorNE (NonEmpty [Char] -> GE (SpecificationD Deps a))
-> NonEmpty [Char] -> GE (SpecificationD Deps a)
forall a b. (a -> b) -> a -> b
$
[[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[[Char]
"The impossible happened in computeSpec: Reifies", [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Var a -> [Char]
forall a. Show a => a -> [Char]
show Var a
x, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> Doc Any -> Doc Any
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Pred -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Pred -> Doc ann
pretty Pred
pred3)]
where
localGESpec :: GE (SpecificationD deps a) -> GE (SpecificationD deps a)
localGESpec GE (SpecificationD deps a)
ge = case GE (SpecificationD deps a)
ge of
(GenError NonEmpty (NonEmpty [Char])
xs) -> SpecificationD deps a -> GE (SpecificationD deps a)
forall a. a -> GE a
Result (SpecificationD deps a -> GE (SpecificationD deps a))
-> SpecificationD deps a -> GE (SpecificationD deps a)
forall a b. (a -> b) -> a -> b
$ NonEmpty [Char] -> SpecificationD deps a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec (NonEmpty (NonEmpty [Char]) -> NonEmpty [Char]
catMessageList NonEmpty (NonEmpty [Char])
xs)
(FatalError NonEmpty (NonEmpty [Char])
es) -> NonEmpty (NonEmpty [Char]) -> GE (SpecificationD deps a)
forall a. NonEmpty (NonEmpty [Char]) -> GE a
FatalError NonEmpty (NonEmpty [Char])
es
(Result SpecificationD deps a
v) -> SpecificationD deps a -> GE (SpecificationD deps a)
forall a. a -> GE a
Result SpecificationD deps a
v
computeSpec ::
forall a. (HasSpec a, HasCallStack) => Var a -> Pred -> GE (Specification a)
computeSpec :: forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x Pred
p = Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x (Pred -> Pred
simplifyPred Pred
p)
computeSpecBinder :: Binder a -> GE (Specification a)
computeSpecBinder :: forall a. Binder a -> GE (Specification a)
computeSpecBinder (Var a
x :-> Pred
p) = Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x Pred
p
computeSpecBinderSimplified :: Binder a -> GE (Specification a)
computeSpecBinderSimplified :: forall a. Binder a -> GE (Specification a)
computeSpecBinderSimplified (Var a
x :-> Pred
p) = Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
p
caseSpec ::
forall as.
HasSpec (SumOver as) =>
Maybe String ->
List (Weighted (Specification)) as ->
Specification (SumOver as)
caseSpec :: forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
caseSpec Maybe [Char]
tString List (Weighted Specification) as
ss
| List (Weighted Specification) as -> Bool
forall (as2 :: [*]). List (Weighted Specification) as2 -> Bool
allBranchesFail List (Weighted Specification) as
ss =
NonEmpty [Char] -> Specification (SumOver as)
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec
( [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[ [Char]
"When simplifying SumSpec, all branches in a caseOn" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tString [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" simplify to False."
, Specification (SumOver as) -> [Char]
forall a. Show a => a -> [Char]
show Specification (SumOver as)
spec
]
)
| Bool
True = Specification (SumOver as)
spec
where
spec :: Specification (SumOver as)
spec = Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
loop Maybe [Char]
tString List (Weighted Specification) as
ss
allBranchesFail :: forall as2. List (Weighted Specification) as2 -> Bool
allBranchesFail :: forall (as2 :: [*]). List (Weighted Specification) as2 -> Bool
allBranchesFail List (Weighted Specification) as2
Nil = [Char] -> Bool
forall a. HasCallStack => [Char] -> a
error [Char]
"The impossible happened in allBranchesFail"
allBranchesFail (Weighted Maybe Int
_ Specification a
s :> List (Weighted Specification) as1
Nil) = Specification a -> Bool
forall a. Specification a -> Bool
isErrorLike Specification a
s
allBranchesFail (Weighted Maybe Int
_ Specification a
s :> ss2 :: List (Weighted Specification) as1
ss2@(Weighted Specification a
_ :> List (Weighted Specification) as1
_)) = Specification a -> Bool
forall a. Specification a -> Bool
isErrorLike Specification a
s Bool -> Bool -> Bool
&& List (Weighted Specification) as1 -> Bool
forall (as2 :: [*]). List (Weighted Specification) as2 -> Bool
allBranchesFail List (Weighted Specification) as1
ss2
loop ::
forall as3.
HasSpec (SumOver as3) =>
Maybe String ->
List (Weighted Specification) as3 ->
Specification (SumOver as3)
loop :: forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
loop Maybe [Char]
_ List (Weighted Specification) as3
Nil = [Char] -> SpecificationD Deps (SumOver '[])
forall a. HasCallStack => [Char] -> a
error [Char]
"The impossible happened in caseSpec"
loop Maybe [Char]
_ (Weighted Specification a
s :> List (Weighted Specification) as1
Nil) = Weighted Specification a -> SpecificationD Deps a
forall (f :: * -> *) a. Weighted f a -> f a
thing Weighted Specification a
s
loop Maybe [Char]
mTypeString (Weighted Specification a
s :> ss1 :: List (Weighted Specification) as1
ss1@(Weighted Specification a
_ :> List (Weighted Specification) as1
_))
| Evidence (Prerequisites (SumOver as3))
Evidence <- forall a. HasSpec a => Evidence (Prerequisites a)
prerequisites @(SumOver as3) =
(TypeSpec (SumOver as3) -> SpecificationD Deps (SumOver as3)
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec (TypeSpec (SumOver as3) -> SpecificationD Deps (SumOver as3))
-> TypeSpec (SumOver as3) -> SpecificationD Deps (SumOver as3)
forall a b. (a -> b) -> a -> b
$ Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification (SumOver (a : as1))
-> SumSpec a (SumOver (a : as1))
forall a b.
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
SumSpecRaw Maybe [Char]
mTypeString Maybe (Int, Int)
theWeights (Weighted Specification a -> Specification a
forall (f :: * -> *) a. Weighted f a -> f a
thing Weighted Specification a
s) (Maybe [Char]
-> List (Weighted Specification) as1 -> Specification (SumOver as1)
forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
loop Maybe [Char]
forall a. Maybe a
Nothing List (Weighted Specification) as1
ss1))
where
theWeights :: Maybe (Int, Int)
theWeights =
case (Weighted Specification a -> Maybe Int
forall (f :: * -> *) a. Weighted f a -> Maybe Int
weight Weighted Specification a
s, List (Weighted Specification) as1 -> Maybe Int
forall (f :: * -> *) (as :: [*]). List (Weighted f) as -> Maybe Int
totalWeight List (Weighted Specification) as1
ss1) of
(Maybe Int
Nothing, Maybe Int
Nothing) -> Maybe (Int, Int)
forall a. Maybe a
Nothing
(Maybe Int
a, Maybe Int
b) -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
1 Maybe Int
a, Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (List (Weighted Specification) as1 -> Int
forall {k} (f :: k -> *) (as :: [k]). List f as -> Int
lengthList List (Weighted Specification) as1
ss1) Maybe Int
b)
data SumSpec a b
= SumSpecRaw
(Maybe String)
(Maybe (Int, Int))
(Specification a)
(Specification b)
pattern SumSpec ::
(Maybe (Int, Int)) -> (Specification a) -> (Specification b) -> SumSpec a b
pattern $mSumSpec :: forall {r} {a} {b}.
SumSpec a b
-> (Maybe (Int, Int) -> Specification a -> Specification b -> r)
-> ((# #) -> r)
-> r
$bSumSpec :: forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec a b c <- SumSpecRaw _ a b c
where
SumSpec Maybe (Int, Int)
a Specification a
b Specification b
c = Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
forall a b.
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
SumSpecRaw Maybe [Char]
forall a. Maybe a
Nothing Maybe (Int, Int)
a Specification a
b Specification b
c
{-# COMPLETE SumSpec #-}
sumType :: Maybe String -> String
sumType :: Maybe [Char] -> [Char]
sumType Maybe [Char]
Nothing = [Char]
""
sumType (Just [Char]
x) = [Char]
" type=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
x
totalWeight :: List (Weighted f) as -> Maybe Int
totalWeight :: forall (f :: * -> *) (as :: [*]). List (Weighted f) as -> Maybe Int
totalWeight = (Sum Int -> Int) -> Maybe (Sum Int) -> Maybe Int
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Sum Int -> Int
forall a. Sum a -> a
getSum (Maybe (Sum Int) -> Maybe Int)
-> (List (Weighted f) as -> Maybe (Sum Int))
-> List (Weighted f) as
-> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Weighted f a -> Maybe (Sum Int))
-> List (Weighted f) as -> Maybe (Sum Int)
forall {k} b (f :: k -> *) (as :: [k]).
Monoid b =>
(forall (a :: k). f a -> b) -> List f as -> b
foldMapList ((Int -> Sum Int) -> Maybe Int -> Maybe (Sum Int)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Sum Int
forall a. a -> Sum a
Semigroup.Sum (Maybe Int -> Maybe (Sum Int))
-> (Weighted f a -> Maybe Int) -> Weighted f a -> Maybe (Sum Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Weighted f a -> Maybe Int
forall (f :: * -> *) a. Weighted f a -> Maybe Int
weight)
genFromSpec :: forall a. (HasCallStack, HasSpec a) => Specification a -> Gen a
genFromSpec :: forall a. (HasCallStack, HasSpec a) => Specification a -> Gen a
genFromSpec Specification a
spec = do
Either (NonEmpty (NonEmpty [Char])) a
res <- GenT GE a -> Gen (Either (NonEmpty (NonEmpty [Char])) a)
forall a. GenT GE a -> Gen (Either (NonEmpty (NonEmpty [Char])) a)
catchGen (GenT GE a -> Gen (Either (NonEmpty (NonEmpty [Char])) a))
-> GenT GE a -> Gen (Either (NonEmpty (NonEmpty [Char])) a)
forall a b. (a -> b) -> a -> b
$ forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT @a @GE Specification a
spec
(NonEmpty (NonEmpty [Char]) -> Gen a)
-> (a -> Gen a) -> Either (NonEmpty (NonEmpty [Char])) a -> Gen a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([Char] -> Gen a
forall a. HasCallStack => [Char] -> a
error ([Char] -> Gen a)
-> (NonEmpty (NonEmpty [Char]) -> [Char])
-> NonEmpty (NonEmpty [Char])
-> Gen a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
'\n' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:) ([Char] -> [Char])
-> (NonEmpty (NonEmpty [Char]) -> [Char])
-> NonEmpty (NonEmpty [Char])
-> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (NonEmpty [Char]) -> [Char]
catMessages) a -> Gen a
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either (NonEmpty (NonEmpty [Char])) a
res
genFromSpecWithSeed ::
forall a. (HasCallStack, HasSpec a) => Int -> Int -> Specification a -> a
genFromSpecWithSeed :: forall a.
(HasCallStack, HasSpec a) =>
Int -> Int -> Specification a -> a
genFromSpecWithSeed Int
seed Int
size Specification a
spec = Gen a -> QCGen -> Int -> a
forall a. Gen a -> QCGen -> Int -> a
unGen (Specification a -> Gen a
forall a. (HasCallStack, HasSpec a) => Specification a -> Gen a
genFromSpec Specification a
spec) (Int -> QCGen
mkQCGen Int
seed) Int
size
debugSpec :: forall a. HasSpec a => Specification a -> IO ()
debugSpec :: forall a. HasSpec a => Specification a -> IO ()
debugSpec Specification a
spec = do
GE a
ans <- Gen (GE a) -> IO (GE a)
forall a. Gen a -> IO a
generate (Gen (GE a) -> IO (GE a)) -> Gen (GE a) -> IO (GE a)
forall a b. (a -> b) -> a -> b
$ GenT GE (GE a) -> Gen (GE a)
forall a. GenT GE a -> Gen a
genFromGenT (GenT GE (GE a) -> Gen (GE a)) -> GenT GE (GE a) -> Gen (GE a)
forall a b. (a -> b) -> a -> b
$ GenT GE a -> GenT GE (GE a)
forall (m :: * -> *) x.
MonadGenError m =>
GenT GE x -> GenT m (GE x)
inspect (Specification a -> GenT GE a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
spec)
let f :: NonEmpty [Char] -> IO ()
f NonEmpty [Char]
x = [Char] -> IO ()
putStrLn ([[Char]] -> [Char]
unlines (NonEmpty [Char] -> [[Char]]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty [Char]
x))
ok :: a -> IO ()
ok a
x =
if a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec a
x Specification a
spec
then [Char] -> IO ()
putStrLn [Char]
"True"
else [Char] -> IO ()
putStrLn [Char]
"False, perhaps there is an unsafeExists in the spec?"
case GE a
ans of
FatalError NonEmpty (NonEmpty [Char])
xs -> (NonEmpty [Char] -> IO ()) -> NonEmpty (NonEmpty [Char]) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ NonEmpty [Char] -> IO ()
f NonEmpty (NonEmpty [Char])
xs
GenError NonEmpty (NonEmpty [Char])
xs -> (NonEmpty [Char] -> IO ()) -> NonEmpty (NonEmpty [Char]) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ NonEmpty [Char] -> IO ()
f NonEmpty (NonEmpty [Char])
xs
Result a
x -> Specification a -> IO ()
forall a. Show a => a -> IO ()
print Specification a
spec IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> IO ()
forall a. Show a => a -> IO ()
print a
x IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> IO ()
ok a
x
shrinkWithSpec :: forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec :: forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec (Specification a -> Specification a
forall a. HasSpec a => Specification a -> Specification a
simplifySpec -> Specification a
spec) a
a = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ case Specification a
spec of
ExplainSpec [[Char]]
_ Specification a
s -> Specification a -> a -> [a]
forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
s a
a
TypeSpec TypeSpec a
s [a]
_ -> TypeSpec a -> a -> [a]
forall a. HasSpec a => TypeSpec a -> a -> [a]
shrinkWithTypeSpec TypeSpec a
s a
a
SuspendedSpec {} -> a -> [a]
shr a
a
MemberSpec {} -> a -> [a]
shr a
a
Specification a
TrueSpec -> a -> [a]
shr a
a
ErrorSpec {} -> []
where
shr :: a -> [a]
shr = TypeSpec a -> a -> [a]
forall a. HasSpec a => TypeSpec a -> a -> [a]
shrinkWithTypeSpec (forall a. HasSpec a => TypeSpec a
emptySpec @a)
shrinkFromPreds :: HasSpec a => Pred -> Var a -> a -> [a]
shrinkFromPreds :: forall a. HasSpec a => Pred -> Var a -> a -> [a]
shrinkFromPreds Pred
p
| Result SolverPlan
plan <- Pred -> GE SolverPlan
prepareLinearization Pred
p = \Var a
x a
a -> GE [a] -> [a]
forall a. GE [a] -> [a]
listFromGE (GE [a] -> [a]) -> GE [a] -> [a]
forall a b. (a -> b) -> a -> b
$ do
Bool
xaGood <- Env -> Pred -> GE Bool
forall (m :: * -> *). MonadGenError m => Env -> Pred -> m Bool
checkPred (Var a -> a -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
a) Pred
p
Bool -> GE () -> GE ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
xaGood (GE () -> GE ()) -> GE () -> GE ()
forall a b. (a -> b) -> a -> b
$
[Char] -> GE ()
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
fatalError [Char]
"Trying to shrink a bad value, don't do that!"
Env
initialEnv <- Env -> Pred -> GE Env
envFromPred (Var a -> a -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
a) Pred
p
[a] -> GE [a]
forall a. a -> GE a
forall (m :: * -> *) a. Monad m => a -> m a
return
[ a
a'
|
Env
env' <- Env -> SolverPlan -> [Env]
shrinkEnvFromPlan Env
initialEnv SolverPlan
plan
,
Just a
a' <- [Env -> Var a -> Maybe a
forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
env' Var a
x]
,
a
a' a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
a
]
| Bool
otherwise = [Char] -> Var a -> a -> [a]
forall a. HasCallStack => [Char] -> a
error [Char]
"Bad pred"
shrinkEnvFromPlan :: Env -> SolverPlan -> [Env]
shrinkEnvFromPlan :: Env -> SolverPlan -> [Env]
shrinkEnvFromPlan Env
initialEnv SolverPlan {[SolverStage]
Graph Name
solverPlan :: [SolverStage]
solverDependencies :: Graph Name
solverPlan :: SolverPlan -> [SolverStage]
solverDependencies :: SolverPlan -> Graph Name
..} = Env -> [SolverStage] -> [Env]
go Env
forall a. Monoid a => a
mempty [SolverStage]
solverPlan
where
go :: Env -> [SolverStage] -> [Env]
go :: Env -> [SolverStage] -> [Env]
go Env
_ [] = []
go Env
env ((Env -> SolverStage -> SolverStage
substStage Env
env -> SolverStage {[Pred]
Var a
Specification a
stageVar :: Var a
stagePreds :: [Pred]
stageSpec :: Specification a
stageVar :: ()
stagePreds :: SolverStage -> [Pred]
stageSpec :: ()
..}) : [SolverStage]
plan) = do
Just a
a <- [Env -> Var a -> Maybe a
forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
initialEnv Var a
stageVar]
[ Env
env' Env -> Env -> Env
forall a. Semigroup a => a -> a -> a
<> Env
fixedEnv
| a
a' <- Specification a -> a -> [a]
forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
stageSpec a
a
, let env' :: Env
env' = Var a -> a -> Env -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env -> Env
extendEnv Var a
stageVar a
a' Env
env
, Just Env
fixedEnv <- [Env -> [SolverStage] -> Maybe Env
fixupPlan Env
env' [SolverStage]
plan]
]
[Env] -> [Env] -> [Env]
forall a. [a] -> [a] -> [a]
++ Env -> [SolverStage] -> [Env]
go (Var a -> a -> Env -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env -> Env
extendEnv Var a
stageVar a
a Env
env) [SolverStage]
plan
fixupPlan :: Env -> [SolverStage] -> Maybe Env
fixupPlan :: Env -> [SolverStage] -> Maybe Env
fixupPlan Env
env [] = Env -> Maybe Env
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Env
env
fixupPlan Env
env ((Env -> SolverStage -> SolverStage
substStage Env
env -> SolverStage {[Pred]
Var a
Specification a
stageVar :: ()
stagePreds :: SolverStage -> [Pred]
stageSpec :: ()
stageVar :: Var a
stagePreds :: [Pred]
stageSpec :: Specification a
..}) : [SolverStage]
plan) =
case Env -> Var a -> Maybe a
forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
initialEnv Var a
stageVar Maybe a -> (a -> Maybe a) -> Maybe a
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Specification a -> a -> Maybe a
forall a. HasSpec a => Specification a -> a -> Maybe a
fixupWithSpec Specification a
stageSpec of
Maybe a
Nothing -> Maybe Env
forall a. Maybe a
Nothing
Just a
a -> Env -> [SolverStage] -> Maybe Env
fixupPlan (Var a -> a -> Env -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env -> Env
extendEnv Var a
stageVar a
a Env
env) [SolverStage]
plan
substStage :: Env -> SolverStage -> SolverStage
substStage :: Env -> SolverStage -> SolverStage
substStage Env
env (SolverStage Var a
y [Pred]
ps Specification a
spec) = SolverStage -> SolverStage
normalizeSolverStage (SolverStage -> SolverStage) -> SolverStage -> SolverStage
forall a b. (a -> b) -> a -> b
$ Var a -> [Pred] -> Specification a -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage Var a
y (Env -> Pred -> Pred
substPred Env
env (Pred -> Pred) -> [Pred] -> [Pred]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Pred]
ps) Specification a
spec
normalizeSolverStage :: SolverStage -> SolverStage
normalizeSolverStage :: SolverStage -> SolverStage
normalizeSolverStage (SolverStage Var a
x [Pred]
ps Specification a
spec) = Var a -> [Pred] -> Specification a -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage Var a
x [Pred]
ps'' (Specification a
spec Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> Specification a
spec')
where
([Pred]
ps', [Pred]
ps'') = (Pred -> Bool) -> [Pred] -> ([Pred], [Pred])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==) (Int -> Bool) -> (Pred -> Int) -> Pred -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set Name -> Int
forall a. Set a -> Int
Set.size (Set Name -> Int) -> (Pred -> Set Name) -> Pred -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet) [Pred]
ps
spec' :: Specification a
spec' = GE (Specification a) -> Specification a
forall a. HasCallStack => GE (Specification a) -> Specification a
fromGESpec (GE (Specification a) -> Specification a)
-> GE (Specification a) -> Specification a
forall a b. (a -> b) -> a -> b
$ Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x ([Pred] -> Pred
forall deps. [PredD deps] -> PredD deps
And [Pred]
ps')
fixupWithSpec :: forall a. HasSpec a => Specification a -> a -> Maybe a
fixupWithSpec :: forall a. HasSpec a => Specification a -> a -> Maybe a
fixupWithSpec Specification a
spec a
a
| a
a a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec = a -> Maybe a
forall a. a -> Maybe a
Just a
a
| Bool
otherwise = case Specification a
spec of
MemberSpec (a
x :| [a]
_) -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
Specification a
_ -> [a] -> Maybe a
forall a. [a] -> Maybe a
listToMaybe ([a] -> Maybe a) -> [a] -> Maybe a
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec) (Specification a -> a -> [a]
forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
forall deps a. SpecificationD deps a
TrueSpec a
a)
computeHints :: [Pred] -> Hints
computeHints :: [Pred] -> Graph Name
computeHints [Pred]
ps =
Graph Name -> Graph Name
forall node. Ord node => Graph node -> Graph node
transitiveClosure (Graph Name -> Graph Name) -> Graph Name -> Graph Name
forall a b. (a -> b) -> a -> b
$ [Graph Name] -> Graph Name
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [TermD Deps a
x TermD Deps a -> TermD Deps b -> Graph Name
forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> Graph Name
`irreflexiveDependencyOn` TermD Deps b
y | DependsOn TermD Deps a
x TermD Deps b
y <- [Pred]
ps]
prepareLinearization :: Pred -> GE SolverPlan
prepareLinearization :: Pred -> GE SolverPlan
prepareLinearization Pred
p = do
let preds :: [Pred]
preds = (Pred -> [Pred]) -> [Pred] -> [Pred]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Pred -> [Pred]
saturatePred ([Pred] -> [Pred]) -> [Pred] -> [Pred]
forall a b. (a -> b) -> a -> b
$ Pred -> [Pred]
flattenPred Pred
p
hints :: Graph Name
hints = [Pred] -> Graph Name
computeHints [Pred]
preds
graph :: Graph Name
graph = Graph Name -> Graph Name
forall node. Ord node => Graph node -> Graph node
transitiveClosure (Graph Name -> Graph Name) -> Graph Name -> Graph Name
forall a b. (a -> b) -> a -> b
$ Graph Name
hints Graph Name -> Graph Name -> Graph Name
forall a. Semigroup a => a -> a -> a
<> Graph Name -> Graph Name -> Graph Name
respecting Graph Name
hints ((Pred -> Graph Name) -> [Pred] -> Graph Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pred -> Graph Name
computeDependencies [Pred]
preds)
[SolverStage]
plan <-
NonEmpty [Char] -> GE [SolverStage] -> GE [SolverStage]
forall a. HasCallStack => NonEmpty [Char] -> GE a -> GE a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a -> m a
explainNE
( [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[ [Char]
"Linearizing"
, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Doc Any
" preds: " Doc Any -> Doc Any -> Doc Any
forall a. Semigroup a => a -> a -> a
<> [Pred] -> Doc Any
forall ann. [Pred] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [Pred]
preds
, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Doc Any
" graph: " Doc Any -> Doc Any -> Doc Any
forall a. Semigroup a => a -> a -> a
<> Graph Name -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Graph Name -> Doc ann
pretty Graph Name
graph
]
)
(GE [SolverStage] -> GE [SolverStage])
-> GE [SolverStage] -> GE [SolverStage]
forall a b. (a -> b) -> a -> b
$ [Pred] -> Graph Name -> GE [SolverStage]
forall (m :: * -> *).
MonadGenError m =>
[Pred] -> Graph Name -> m [SolverStage]
linearize [Pred]
preds Graph Name
graph
SolverPlan -> GE SolverPlan
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SolverPlan -> GE SolverPlan) -> SolverPlan -> GE SolverPlan
forall a b. (a -> b) -> a -> b
$ SolverPlan -> SolverPlan
backPropagation (SolverPlan -> SolverPlan) -> SolverPlan -> SolverPlan
forall a b. (a -> b) -> a -> b
$ [SolverStage] -> Graph Name -> SolverPlan
SolverPlan [SolverStage]
plan Graph Name
graph
flattenPred :: Pred -> [Pred]
flattenPred :: Pred -> [Pred]
flattenPred Pred
pIn = Set Int -> [Pred] -> [Pred]
go (Pred -> Set Int
forall t. HasVariables t => t -> Set Int
freeVarNames Pred
pIn) [Pred
pIn]
where
go :: Set Int -> [Pred] -> [Pred]
go Set Int
_ [] = []
go Set Int
fvs (Pred
p : [Pred]
ps) = case Pred
p of
And [Pred]
ps' -> Set Int -> [Pred] -> [Pred]
go Set Int
fvs ([Pred]
ps' [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ [Pred]
ps)
Let TermD Deps a
t BinderD Deps a
b -> Set Int
-> BinderD Deps a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
forall a.
Set Int
-> Binder a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
goBinder Set Int
fvs BinderD Deps a
b [Pred]
ps (\Var a
x -> (TermD Deps Bool -> Pred
forall p. IsPred p => p -> Pred
assert (TermD Deps a
t TermD Deps a -> TermD Deps a -> TermD Deps Bool
forall a. HasSpec a => Term a -> Term a -> TermD Deps Bool
==. (Var a -> TermD Deps a
forall deps a.
(HasSpecD deps a, Typeable a) =>
Var a -> TermD deps a
V Var a
x)) Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
:))
Exists (forall b. TermD Deps b -> b) -> GE a
_ BinderD Deps a
b -> Set Int
-> BinderD Deps a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
forall a.
Set Int
-> Binder a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
goBinder Set Int
fvs BinderD Deps a
b [Pred]
ps (([Pred] -> [Pred]) -> Var a -> [Pred] -> [Pred]
forall a b. a -> b -> a
const [Pred] -> [Pred]
forall a. a -> a
id)
When TermD Deps Bool
b Pred
pp -> (Pred -> Pred) -> [Pred] -> [Pred]
forall a b. (a -> b) -> [a] -> [b]
map (TermD Deps Bool -> Pred -> Pred
forall deps. TermD deps Bool -> PredD deps -> PredD deps
When TermD Deps Bool
b) (Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred
pp]) [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred]
ps
Explain NonEmpty [Char]
es Pred
pp -> (Pred -> Pred) -> [Pred] -> [Pred]
forall a b. (a -> b) -> [a] -> [b]
map (NonEmpty [Char] -> Pred -> Pred
explanation NonEmpty [Char]
es) (Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred
pp]) [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred]
ps
Pred
_ -> Pred
p Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred]
ps
goBinder ::
Set Int ->
Binder a ->
[Pred] ->
(HasSpec a => Var a -> [Pred] -> [Pred]) ->
[Pred]
goBinder :: forall a.
Set Int
-> Binder a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
goBinder Set Int
fvs (Var a
x :-> Pred
p) [Pred]
ps HasSpec a => Var a -> [Pred] -> [Pred]
k = Var a -> [Pred] -> [Pred]
HasSpec a => Var a -> [Pred] -> [Pred]
k Var a
x' ([Pred] -> [Pred]) -> [Pred] -> [Pred]
forall a b. (a -> b) -> a -> b
$ Set Int -> [Pred] -> [Pred]
go (Int -> Set Int -> Set Int
forall a. Ord a => a -> Set a -> Set a
Set.insert (Var a -> Int
forall a. Var a -> Int
nameOf Var a
x') Set Int
fvs) (Pred
p' Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: [Pred]
ps)
where
(Var a
x', Pred
p') = Var a -> Pred -> Set Int -> (Var a, Pred)
forall a t.
(Typeable a, Rename t) =>
Var a -> t -> Set Int -> (Var a, t)
freshen Var a
x Pred
p Set Int
fvs
linearize ::
MonadGenError m => [Pred] -> DependGraph -> m [SolverStage]
linearize :: forall (m :: * -> *).
MonadGenError m =>
[Pred] -> Graph Name -> m [SolverStage]
linearize [Pred]
preds Graph Name
graph = do
[Name]
sorted <- case Graph Name -> Either [Name] [Name]
forall node. Ord node => Graph node -> Either [node] [node]
topsort Graph Name
graph of
Left [Name]
cycle ->
[Char] -> m [Name]
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
fatalError
( Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$
Doc Any
"linearize: Dependency cycle in graph:"
Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc Any] -> Doc Any
forall ann. [Doc ann] -> Doc ann
vsep'
[ Doc Any
"cycle:" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Name] -> Doc Any
forall ann. [Name] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty [Name]
cycle
, Doc Any
"graph:" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> Graph Name -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Graph Name -> Doc ann
pretty Graph Name
graph
]
)
Right [Name]
sorted -> [Name] -> m [Name]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Name]
sorted
[Name] -> [(Set Name, Pred)] -> m [SolverStage]
go [Name]
sorted [(Pred -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet Pred
ps, Pred
ps) | Pred
ps <- (Pred -> Bool) -> [Pred] -> [Pred]
forall a. (a -> Bool) -> [a] -> [a]
filter Pred -> Bool
forall {deps}. PredD deps -> Bool
isRelevantPred [Pred]
preds]
where
isRelevantPred :: PredD deps -> Bool
isRelevantPred PredD deps
TruePred = Bool
False
isRelevantPred DependsOn {} = Bool
False
isRelevantPred (Assert (Lit Bool
True)) = Bool
False
isRelevantPred PredD deps
_ = Bool
True
go :: [Name] -> [(Set Name, Pred)] -> m [SolverStage]
go [] [] = [SolverStage] -> m [SolverStage]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go [] [(Set Name, Pred)]
ps
| Set Name -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Set Name -> Bool) -> Set Name -> Bool
forall a b. (a -> b) -> a -> b
$ ((Set Name, Pred) -> Set Name) -> [(Set Name, Pred)] -> Set Name
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Set Name, Pred) -> Set Name
forall a b. (a, b) -> a
fst [(Set Name, Pred)]
ps =
case NonEmpty [Char] -> Env -> [Pred] -> Maybe (NonEmpty [Char])
checkPredsE ([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"Linearizing fails") Env
forall a. Monoid a => a
mempty (((Set Name, Pred) -> Pred) -> [(Set Name, Pred)] -> [Pred]
forall a b. (a -> b) -> [a] -> [b]
map (Set Name, Pred) -> Pred
forall a b. (a, b) -> b
snd [(Set Name, Pred)]
ps) of
Maybe (NonEmpty [Char])
Nothing -> [SolverStage] -> m [SolverStage]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Just NonEmpty [Char]
msgs -> NonEmpty [Char] -> m [SolverStage]
forall a. HasCallStack => NonEmpty [Char] -> m a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genErrorNE NonEmpty [Char]
msgs
| Bool
otherwise =
NonEmpty [Char] -> m [SolverStage]
forall a. HasCallStack => NonEmpty [Char] -> m a
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalErrorNE (NonEmpty [Char] -> m [SolverStage])
-> NonEmpty [Char] -> m [SolverStage]
forall a b. (a -> b) -> a -> b
$
[[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
[ [Char]
"Dependency error in `linearize`: "
, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Int -> Doc Any -> Doc Any
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Doc Any -> Doc Any) -> Doc Any -> Doc Any
forall a b. (a -> b) -> a -> b
$ Doc Any
"graph: " Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> Graph Name -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Graph Name -> Doc ann
pretty Graph Name
graph
, Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$
Int -> Doc Any -> Doc Any
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (Doc Any -> Doc Any) -> Doc Any -> Doc Any
forall a b. (a -> b) -> a -> b
$
Doc Any
"the following left-over constraints are not defining constraints for a unique variable:"
Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc Any] -> Doc Any
forall ann. [Doc ann] -> Doc ann
vsep' (((Set Name, Pred) -> Doc Any) -> [(Set Name, Pred)] -> [Doc Any]
forall a b. (a -> b) -> [a] -> [b]
map (Pred -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Pred -> Doc ann
pretty (Pred -> Doc Any)
-> ((Set Name, Pred) -> Pred) -> (Set Name, Pred) -> Doc Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set Name, Pred) -> Pred
forall a b. (a, b) -> b
snd) [(Set Name, Pred)]
ps)
]
go (n :: Name
n@(Name Var a
x) : [Name]
ns) [(Set Name, Pred)]
ps = do
let ([(Set Name, Pred)]
nps, [(Set Name, Pred)]
ops) = ((Set Name, Pred) -> Bool)
-> [(Set Name, Pred)] -> ([(Set Name, Pred)], [(Set Name, Pred)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (Name -> Set Name -> Bool
isLastVariable Name
n (Set Name -> Bool)
-> ((Set Name, Pred) -> Set Name) -> (Set Name, Pred) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set Name, Pred) -> Set Name
forall a b. (a, b) -> a
fst) [(Set Name, Pred)]
ps
(SolverStage -> SolverStage
normalizeSolverStage (Var a -> [Pred] -> Specification a -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage Var a
x (((Set Name, Pred) -> Pred) -> [(Set Name, Pred)] -> [Pred]
forall a b. (a -> b) -> [a] -> [b]
map (Set Name, Pred) -> Pred
forall a b. (a, b) -> b
snd [(Set Name, Pred)]
nps) Specification a
forall a. Monoid a => a
mempty) SolverStage -> [SolverStage] -> [SolverStage]
forall a. a -> [a] -> [a]
:) ([SolverStage] -> [SolverStage])
-> m [SolverStage] -> m [SolverStage]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name] -> [(Set Name, Pred)] -> m [SolverStage]
go [Name]
ns [(Set Name, Pred)]
ops
isLastVariable :: Name -> Set Name -> Bool
isLastVariable Name
n Set Name
set = Name
n Name -> Set Name -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Name
set Bool -> Bool -> Bool
&& Name -> Set Name -> Graph Name -> Bool
solvableFrom Name
n (Name -> Set Name -> Set Name
forall a. Ord a => a -> Set a -> Set a
Set.delete Name
n Set Name
set) Graph Name
graph
mergeSolverStage :: SolverStage -> [SolverStage] -> [SolverStage]
mergeSolverStage :: SolverStage -> [SolverStage] -> [SolverStage]
mergeSolverStage (SolverStage Var a
x [Pred]
ps Specification a
spec) [SolverStage]
plan =
[ case Var a -> Var a -> Maybe (a :~: a)
forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
y of
Just a :~: a
Refl ->
Var a -> [Pred] -> Specification a -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage
Var a
y
([Pred]
ps [Pred] -> [Pred] -> [Pred]
forall a. [a] -> [a] -> [a]
++ [Pred]
ps')
( NonEmpty [Char] -> Specification a -> Specification a
forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec
( [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
( [ [Char]
"Solving var " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Var a -> [Char]
forall a. Show a => a -> [Char]
show Var a
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" fails."
, [Char]
"Merging the Specs"
, [Char]
" 1. " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
spec
, [Char]
" 2. " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
spec'
]
)
)
(Specification a
Specification a
spec Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> Specification a
spec')
)
Maybe (a :~: a)
Nothing -> SolverStage
stage
| stage :: SolverStage
stage@(SolverStage Var a
y [Pred]
ps' Specification a
spec') <- [SolverStage]
plan
]
prettyPlan :: HasSpec a => Specification a -> Doc ann
prettyPlan :: forall a ann. HasSpec a => Specification a -> Doc ann
prettyPlan (Specification a -> Specification a
forall a. HasSpec a => Specification a -> Specification a
simplifySpec -> Specification a
spec)
| SuspendedSpec Var a
_ Pred
p <- Specification a
spec
, Result SolverPlan
plan <- Pred -> GE SolverPlan
prepareLinearization Pred
p =
[Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep'
[ Doc ann
"Simplified spec:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
/> Specification a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Specification a -> Doc ann
pretty Specification a
spec
, SolverPlan -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. SolverPlan -> Doc ann
pretty SolverPlan
plan
]
| Bool
otherwise = Doc ann
"Simplfied spec:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
/> Specification a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Specification a -> Doc ann
pretty Specification a
spec
printPlan :: HasSpec a => Specification a -> IO ()
printPlan :: forall a. HasSpec a => Specification a -> IO ()
printPlan = Doc Any -> IO ()
forall a. Show a => a -> IO ()
print (Doc Any -> IO ())
-> (Specification a -> Doc Any) -> Specification a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Specification a -> Doc Any
forall a ann. HasSpec a => Specification a -> Doc ann
prettyPlan
isEmptyPlan :: SolverPlan -> Bool
isEmptyPlan :: SolverPlan -> Bool
isEmptyPlan (SolverPlan [SolverStage]
plan Graph Name
_) = [SolverStage] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SolverStage]
plan
stepPlan :: MonadGenError m => Env -> SolverPlan -> GenT m (Env, SolverPlan)
stepPlan :: forall (m :: * -> *).
MonadGenError m =>
Env -> SolverPlan -> GenT m (Env, SolverPlan)
stepPlan Env
env plan :: SolverPlan
plan@(SolverPlan [] Graph Name
_) = (Env, SolverPlan) -> GenT m (Env, SolverPlan)
forall a. a -> GenT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Env
env, SolverPlan
plan)
stepPlan Env
env (SolverPlan (SolverStage Var a
x [Pred]
ps Specification a
spec : [SolverStage]
pl) Graph Name
gr) = do
(Specification a
spec', [Specification a]
specs) <- GE (Specification a, [Specification a])
-> GenT m (Specification a, [Specification a])
forall (m :: * -> *) r. MonadGenError m => GE r -> m r
runGE
(GE (Specification a, [Specification a])
-> GenT m (Specification a, [Specification a]))
-> GE (Specification a, [Specification a])
-> GenT m (Specification a, [Specification a])
forall a b. (a -> b) -> a -> b
$ [Char]
-> GE (Specification a, [Specification a])
-> GE (Specification a, [Specification a])
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain
( Doc Any -> [Char]
forall a. Show a => a -> [Char]
show
( Doc Any
"Computing specs for variable "
Doc Any -> Doc Any -> Doc Any
forall a. Semigroup a => a -> a -> a
<> Var a -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Var a -> Doc ann
pretty Var a
x
Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc Any] -> Doc Any
forall ann. [Doc ann] -> Doc ann
vsep' ((Pred -> Doc Any) -> [Pred] -> [Doc Any]
forall a b. (a -> b) -> [a] -> [b]
map Pred -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Pred -> Doc ann
pretty [Pred]
ps)
)
)
(GE (Specification a, [Specification a])
-> GE (Specification a, [Specification a]))
-> GE (Specification a, [Specification a])
-> GE (Specification a, [Specification a])
forall a b. (a -> b) -> a -> b
$ do
[Specification a]
ispecs <- (Pred -> GE (Specification a)) -> [Pred] -> GE [Specification a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Var a -> Pred -> GE (Specification a)
forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x) [Pred]
ps
(Specification a, [Specification a])
-> GE (Specification a, [Specification a])
forall a. a -> GE a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Specification a, [Specification a])
-> GE (Specification a, [Specification a]))
-> (Specification a, [Specification a])
-> GE (Specification a, [Specification a])
forall a b. (a -> b) -> a -> b
$ ([Specification a] -> Specification a
forall m. Monoid m => [m] -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [Specification a]
ispecs, [Specification a]
ispecs)
a
val <-
Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT
( NonEmpty [Char] -> Specification a -> Specification a
forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec
( [[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList
( ( [Char]
"\nStepPlan for variable: "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Var a -> [Char]
forall a. Show a => a -> [Char]
show Var a
x
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" fails to produce Specification, probably overconstrained."
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"PS = "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines ((Pred -> [Char]) -> [Pred] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Pred -> [Char]
forall a. Show a => a -> [Char]
show [Pred]
ps)
)
[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: ([Char]
"Original spec " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
spec)
[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char]
"Predicates"
[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: (Pred -> Specification a -> [Char])
-> [Pred] -> [Specification a] -> [[Char]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
(\Pred
pred Specification a
specx -> [Char]
" pred " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Pred -> [Char]
forall a. Show a => a -> [Char]
show Pred
pred [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" -> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
specx)
[Pred]
ps
[Specification a]
specs
)
)
(Specification a
spec Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> Specification a
spec')
)
let env1 :: Env
env1 = Var a -> a -> Env -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env -> Env
extendEnv Var a
x a
val Env
env
(Env, SolverPlan) -> GenT m (Env, SolverPlan)
forall a. a -> GenT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Env
env1, SolverPlan -> SolverPlan
backPropagation (SolverPlan -> SolverPlan) -> SolverPlan -> SolverPlan
forall a b. (a -> b) -> a -> b
$ [SolverStage] -> Graph Name -> SolverPlan
SolverPlan (Env -> SolverStage -> SolverStage
substStage Env
env1 (SolverStage -> SolverStage) -> [SolverStage] -> [SolverStage]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SolverStage]
pl) (Name -> Graph Name -> Graph Name
forall node. Ord node => node -> Graph node -> Graph node
deleteNode (Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x) Graph Name
gr))
genFromPreds :: forall m. MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds :: forall (m :: * -> *). MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds Env
env0 (Pred -> Pred
optimisePred (Pred -> Pred) -> (Pred -> Pred) -> Pred -> Pred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
optimisePred -> Pred
preds) =
do
SolverPlan
plan <- GE SolverPlan -> GenT m SolverPlan
forall (m :: * -> *) r. MonadGenError m => GE r -> m r
runGE (GE SolverPlan -> GenT m SolverPlan)
-> GE SolverPlan -> GenT m SolverPlan
forall a b. (a -> b) -> a -> b
$ Pred -> GE SolverPlan
prepareLinearization Pred
preds
Env -> SolverPlan -> GenT m Env
go Env
env0 SolverPlan
plan
where
go :: Env -> SolverPlan -> GenT m Env
go :: Env -> SolverPlan -> GenT m Env
go Env
env SolverPlan
plan | SolverPlan -> Bool
isEmptyPlan SolverPlan
plan = Env -> GenT m Env
forall a. a -> GenT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Env
env
go Env
env SolverPlan
plan = do
(Env
env', SolverPlan
plan') <-
[Char] -> GenT m (Env, SolverPlan) -> GenT m (Env, SolverPlan)
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain (Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Doc Any -> [Char]) -> Doc Any -> [Char]
forall a b. (a -> b) -> a -> b
$ Doc Any
"Stepping the plan:" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc Any] -> Doc Any
forall ann. [Doc ann] -> Doc ann
vsep [SolverPlan -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. SolverPlan -> Doc ann
pretty SolverPlan
plan, Env -> Doc Any
forall a ann. Pretty a => a -> Doc ann
forall ann. Env -> Doc ann
pretty Env
env]) (GenT m (Env, SolverPlan) -> GenT m (Env, SolverPlan))
-> GenT m (Env, SolverPlan) -> GenT m (Env, SolverPlan)
forall a b. (a -> b) -> a -> b
$ Env -> SolverPlan -> GenT m (Env, SolverPlan)
forall (m :: * -> *).
MonadGenError m =>
Env -> SolverPlan -> GenT m (Env, SolverPlan)
stepPlan Env
env SolverPlan
plan
Env -> SolverPlan -> GenT m Env
go Env
env' SolverPlan
plan'
backPropagation :: SolverPlan -> SolverPlan
backPropagation :: SolverPlan -> SolverPlan
backPropagation (SolverPlan [SolverStage]
initplan Graph Name
graph) = [SolverStage] -> Graph Name -> SolverPlan
SolverPlan ([SolverStage] -> [SolverStage] -> [SolverStage]
go [] ([SolverStage] -> [SolverStage]
forall a. [a] -> [a]
reverse [SolverStage]
initplan)) Graph Name
graph
where
go :: [SolverStage] -> [SolverStage] -> [SolverStage]
go :: [SolverStage] -> [SolverStage] -> [SolverStage]
go [SolverStage]
acc [] = [SolverStage]
acc
go [SolverStage]
acc (s :: SolverStage
s@(SolverStage (Var a
x :: Var a) [Pred]
ps Specification a
spec) : [SolverStage]
plan) = [SolverStage] -> [SolverStage] -> [SolverStage]
go (SolverStage
s SolverStage -> [SolverStage] -> [SolverStage]
forall a. a -> [a] -> [a]
: [SolverStage]
acc) [SolverStage]
plan'
where
newStages :: [SolverStage]
newStages = (Pred -> [SolverStage]) -> [Pred] -> [SolverStage]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Specification a -> Pred -> [SolverStage]
newStage Specification a
spec) [Pred]
ps
plan' :: [SolverStage]
plan' = (SolverStage -> [SolverStage] -> [SolverStage])
-> [SolverStage] -> [SolverStage] -> [SolverStage]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr SolverStage -> [SolverStage] -> [SolverStage]
mergeSolverStage [SolverStage]
plan [SolverStage]
newStages
newStage :: Specification a -> Pred -> [SolverStage]
newStage Specification a
specl (Assert (Equal (V Var a
x') TermD Deps a
t)) =
Specification a -> Var a -> TermD Deps a -> [SolverStage]
forall b.
HasSpec b =>
Specification a -> Var b -> Term b -> [SolverStage]
termVarEqCases Specification a
specl Var a
x' TermD Deps a
t
newStage Specification a
specr (Assert (Equal Term a
t (V Var a
x'))) =
Specification a -> Var a -> Term a -> [SolverStage]
forall b.
HasSpec b =>
Specification a -> Var b -> Term b -> [SolverStage]
termVarEqCases Specification a
specr Var a
x' Term a
t
newStage Specification a
_ Pred
_ = []
termVarEqCases :: HasSpec b => Specification a -> Var b -> Term b -> [SolverStage]
termVarEqCases :: forall b.
HasSpec b =>
Specification a -> Var b -> Term b -> [SolverStage]
termVarEqCases (MemberSpec NonEmpty a
vs) Var b
x' Term b
t
| Name -> Set Name
forall a. a -> Set a
Set.singleton (Var a -> Name
forall a. HasSpec a => Var a -> Name
Name Var a
x) Set Name -> Set Name -> Bool
forall a. Eq a => a -> a -> Bool
== Term b -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet Term b
t =
[Var b -> [Pred] -> Specification b -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage Var b
x' [] (Specification b -> SolverStage) -> Specification b -> SolverStage
forall a b. (a -> b) -> a -> b
$ NonEmpty b -> Specification b
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (NonEmpty b -> NonEmpty b
forall a. Eq a => NonEmpty a -> NonEmpty a
NE.nub ((a -> b) -> NonEmpty a -> NonEmpty b
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
v -> GE b -> b
forall a. GE a -> a
errorGE (GE b -> b) -> GE b -> b
forall a b. (a -> b) -> a -> b
$ Env -> Term b -> GE b
forall (m :: * -> *) deps a.
MonadGenError m =>
Env -> TermD deps a -> m a
runTerm (Var a -> a -> Env
forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
v) Term b
t) NonEmpty a
vs))]
termVarEqCases Specification a
specx Var b
x' Term b
t
| Just a :~: b
Refl <- Var a -> Var b -> Maybe (a :~: b)
forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var b
x'
, [Name Var a
y] <- Set Name -> [Name]
forall a. Set a -> [a]
Set.toList (Set Name -> [Name]) -> Set Name -> [Name]
forall a b. (a -> b) -> a -> b
$ Term b -> Set Name
forall a. HasVariables a => a -> Set Name
freeVarSet Term b
t
, Result Ctx a b
ctx <- Var a -> Term b -> GE (Ctx a b)
forall (m :: * -> *) v a.
(Typeable v, Show v, MonadGenError m, HasCallStack) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
y Term b
t =
[Var a -> [Pred] -> Specification a -> SolverStage
forall b.
HasSpec b =>
Var b -> [Pred] -> Specification b -> SolverStage
SolverStage Var a
y [] (Specification a -> Ctx a a -> Specification a
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec Specification a
specx Ctx a a
Ctx a b
ctx)]
termVarEqCases Specification a
_ Var b
_ Term b
_ = []
data EqW :: [Type] -> Type -> Type where
EqualW :: (Eq a, HasSpec a) => EqW '[a, a] Bool
deriving instance Eq (EqW dom rng)
instance Show (EqW d r) where
show :: EqW d r -> [Char]
show EqW d r
EqualW = [Char]
"==."
instance Syntax EqW where
isInfix :: forall (dom :: [*]) rng. EqW dom rng -> Bool
isInfix EqW dom rng
EqualW = Bool
True
instance Semantics EqW where
semantics :: forall (d :: [*]) r. EqW d r -> FunTy d r
semantics EqW d r
EqualW = FunTy d r
a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)
instance Logic EqW where
propagate :: forall (as :: [*]) b a.
(AppRequires EqW as b, HasSpec a) =>
EqW as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
propagate EqW as b
f ListCtx Value as (HOLE a)
ctxt (ExplainSpec [[Char]]
es SpecificationD Deps b
s) = [[Char]] -> Specification a -> Specification a
forall a. [[Char]] -> Specification a -> Specification a
explainSpec [[Char]]
es (Specification a -> Specification a)
-> Specification a -> Specification a
forall a b. (a -> b) -> a -> b
$ EqW as b
-> ListCtx Value as (HOLE a)
-> SpecificationD Deps b
-> Specification a
forall (as :: [*]) b a.
(AppRequires EqW as b, HasSpec a) =>
EqW as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
forall (t :: [*] -> * -> *) (as :: [*]) b a.
(Logic t, AppRequires t as b, HasSpec a) =>
t as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
propagate EqW as b
f ListCtx Value as (HOLE a)
ctxt SpecificationD Deps b
s
propagate EqW as b
_ ListCtx Value as (HOLE a)
_ SpecificationD Deps b
TrueSpec = Specification a
forall deps a. SpecificationD deps a
TrueSpec
propagate EqW as b
_ ListCtx Value as (HOLE a)
_ (ErrorSpec NonEmpty [Char]
msgs) = NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec NonEmpty [Char]
msgs
propagate EqW as b
EqualW (HOLE a a
HOLE :? Value a
x :> List Value as1
Nil) (SuspendedSpec Var b
v Pred
ps) =
(Term a -> Pred) -> Specification a
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term a -> Pred) -> Specification a)
-> (Term a -> Pred) -> Specification a
forall a b. (a -> b) -> a -> b
$ \Term a
v' -> TermD Deps Bool -> BinderD Deps Bool -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let (EqW '[a, a] Bool -> List (TermD Deps) '[a, a] -> TermD Deps Bool
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App EqW '[a, a] Bool
forall b. (Eq b, HasSpec b) => EqW '[b, b] Bool
EqualW (Term a
v' Term a -> List (TermD Deps) '[a] -> List (TermD Deps) '[a, a]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> a -> Term a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit a
a
x Term a -> List (TermD Deps) '[] -> List (TermD Deps) '[a]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (TermD Deps) '[]
forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
Var Bool
v Var Bool -> Pred -> BinderD Deps Bool
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
ps)
propagate EqW as b
EqualW (Value a
x :! Unary HOLE a a
HOLE) (SuspendedSpec Var b
v Pred
ps) =
(Term a -> Pred) -> Specification a
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term a -> Pred) -> Specification a)
-> (Term a -> Pred) -> Specification a
forall a b. (a -> b) -> a -> b
$ \Term a
v' -> TermD Deps Bool -> BinderD Deps Bool -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let (EqW '[a, a] Bool -> List (TermD Deps) '[a, a] -> TermD Deps Bool
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App EqW '[a, a] Bool
forall b. (Eq b, HasSpec b) => EqW '[b, b] Bool
EqualW (a -> TermD Deps a
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit a
x TermD Deps a -> List (TermD Deps) '[a] -> List (TermD Deps) '[a, a]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term a
TermD Deps a
v' TermD Deps a -> List (TermD Deps) '[] -> List (TermD Deps) '[a]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (TermD Deps) '[]
forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
Var Bool
v Var Bool -> Pred -> BinderD Deps Bool
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
ps)
propagate EqW as b
EqualW (HOLE a a
HOLE :? Value a
s :> List Value as1
Nil) SpecificationD Deps b
spec =
Specification Bool -> (Bool -> Specification a) -> Specification a
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec SpecificationD Deps b
Specification Bool
spec ((Bool -> Specification a) -> Specification a)
-> (Bool -> Specification a) -> Specification a
forall a b. (a -> b) -> a -> b
$ \case
Bool
True -> a -> Specification a
forall a. a -> Specification a
equalSpec a
a
s
Bool
False -> a -> Specification a
forall a. HasSpec a => a -> Specification a
notEqualSpec a
a
s
propagate EqW as b
EqualW (Value a
s :! Unary HOLE a a
HOLE) SpecificationD Deps b
spec =
Specification Bool -> (Bool -> Specification a) -> Specification a
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec SpecificationD Deps b
Specification Bool
spec ((Bool -> Specification a) -> Specification a)
-> (Bool -> Specification a) -> Specification a
forall a b. (a -> b) -> a -> b
$ \case
Bool
True -> a -> Specification a
forall a. a -> Specification a
equalSpec a
a
s
Bool
False -> a -> Specification a
forall a. HasSpec a => a -> Specification a
notEqualSpec a
a
s
rewriteRules :: forall (dom :: [*]) rng.
(TypeList dom, Typeable dom, HasSpec rng, All HasSpec dom) =>
EqW dom rng
-> List (TermD Deps) dom
-> Evidence (AppRequires EqW dom rng)
-> Maybe (Term rng)
rewriteRules EqW dom rng
EqualW (Term a
t :> Term a
t' :> List (TermD Deps) as1
Nil) Evidence (AppRequires EqW dom rng)
Evidence
| Term a
t Term a -> Term a -> Bool
forall a. Eq a => a -> a -> Bool
== Term a
Term a
t' = Term rng -> Maybe (Term rng)
forall a. a -> Maybe a
Just (Term rng -> Maybe (Term rng)) -> Term rng -> Maybe (Term rng)
forall a b. (a -> b) -> a -> b
$ rng -> Term rng
forall a. HasSpec a => a -> Term a
lit rng
Bool
True
| Bool
otherwise = Maybe (Term rng)
forall a. Maybe a
Nothing
saturate :: forall (dom :: [*]).
EqW dom Bool -> List (TermD Deps) dom -> [Pred]
saturate EqW dom Bool
EqualW (FromGeneric (InjLeft Term a
_) :> Term a
t :> List (TermD Deps) as1
Nil) = [Term a -> TypeSpec a -> Pred
forall a. HasSpec a => Term a -> TypeSpec a -> Pred
toPreds Term a
t (Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
forall a. Maybe a
Nothing Specification a
forall deps a. SpecificationD deps a
TrueSpec (NonEmpty [Char] -> Specification b
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec ([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"saturatePred")))]
saturate EqW dom Bool
EqualW (FromGeneric (InjRight Term b
_) :> Term a
t :> List (TermD Deps) as1
Nil) = [Term a -> TypeSpec a -> Pred
forall a. HasSpec a => Term a -> TypeSpec a -> Pred
toPreds Term a
t (Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
forall a. Maybe a
Nothing (NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec ([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"saturatePred")) Specification b
forall deps a. SpecificationD deps a
TrueSpec)]
saturate EqW dom Bool
_ List (TermD Deps) dom
_ = []
infix 4 ==.
(==.) :: HasSpec a => Term a -> Term a -> Term Bool
==. :: forall a. HasSpec a => Term a -> Term a -> TermD Deps Bool
(==.) = EqW '[a, a] Bool
-> FunTy (MapList (TermD Deps) '[a, a]) (TermD Deps Bool)
forall (t :: [*] -> * -> *) (ds :: [*]) r.
AppRequires t ds r =>
t ds r -> FunTy (MapList (TermD Deps) ds) (Term r)
appTerm EqW '[a, a] Bool
forall b. (Eq b, HasSpec b) => EqW '[b, b] Bool
EqualW
pattern Equal ::
forall b.
() =>
forall a.
(b ~ Bool, Eq a, HasSpec a) =>
Term a ->
Term a ->
Term b
pattern $mEqual :: forall {r} {b}.
Term b
-> (forall {a}.
(b ~ Bool, Eq a, HasSpec a) =>
Term a -> Term a -> r)
-> ((# #) -> r)
-> r
Equal x y <-
( App
(getWitness -> Just EqualW)
(x :> y :> Nil)
)
whenTrue :: forall p. IsPred p => Term Bool -> p -> Pred
whenTrue :: forall p. IsPred p => TermD Deps Bool -> p -> Pred
whenTrue (Lit Bool
True) (p -> Pred
forall p. IsPred p => p -> Pred
toPred -> Pred
p) = Pred
p
whenTrue (Lit Bool
False) p
_ = Pred
forall deps. PredD deps
TruePred
whenTrue TermD Deps Bool
b (p -> Pred
forall p. IsPred p => p -> Pred
toPred -> FalsePred {}) = TermD Deps Bool -> Pred
forall p. IsPred p => p -> Pred
assert (TermD Deps Bool -> TermD Deps Bool
not_ TermD Deps Bool
b)
whenTrue TermD Deps Bool
_ (p -> Pred
forall p. IsPred p => p -> Pred
toPred -> Pred
TruePred) = Pred
forall deps. PredD deps
TruePred
whenTrue TermD Deps Bool
b (p -> Pred
forall p. IsPred p => p -> Pred
toPred -> Pred
p) = TermD Deps Bool -> Pred -> Pred
forall deps. TermD deps Bool -> PredD deps -> PredD deps
When TermD Deps Bool
b Pred
p
pinnedBy :: forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy :: forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy Var a
x (Assert (Equal Term a
t Term a
t'))
| V Var a
x' <- Term a
t, Just a :~: a
Refl <- Var a -> Var a -> Maybe (a :~: a)
forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
x' = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just Term a
Term a
t'
| V Var a
x' <- Term a
t', Just a :~: a
Refl <- Var a -> Var a -> Maybe (a :~: a)
forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
x' = Term a -> Maybe (Term a)
forall a. a -> Maybe a
Just Term a
Term a
t
pinnedBy Var a
x (And [Pred]
ps) = [Term a] -> Maybe (Term a)
forall a. [a] -> Maybe a
listToMaybe ([Term a] -> Maybe (Term a)) -> [Term a] -> Maybe (Term a)
forall a b. (a -> b) -> a -> b
$ [Maybe (Term a)] -> [Term a]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe (Term a)] -> [Term a]) -> [Maybe (Term a)] -> [Term a]
forall a b. (a -> b) -> a -> b
$ (Pred -> Maybe (Term a)) -> [Pred] -> [Maybe (Term a)]
forall a b. (a -> b) -> [a] -> [b]
map (Var a -> Pred -> Maybe (Term a)
forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy Var a
x) [Pred]
ps
pinnedBy Var a
_ Pred
_ = Maybe (Term a)
forall a. Maybe a
Nothing
saturatePred :: Pred -> [Pred]
saturatePred :: Pred -> [Pred]
saturatePred Pred
p =
Pred
p Pred -> [Pred] -> [Pred]
forall a. a -> [a] -> [a]
: case Pred
p of
Explain NonEmpty [Char]
_es Pred
x -> Pred -> [Pred]
saturatePred Pred
x
Assert (App t dom Bool
sym List (TermD Deps) dom
xs) -> t dom Bool -> List (TermD Deps) dom -> [Pred]
forall (dom :: [*]). t dom Bool -> List (TermD Deps) dom -> [Pred]
forall (t :: [*] -> * -> *) (dom :: [*]).
Logic t =>
t dom Bool -> List (TermD Deps) dom -> [Pred]
saturate t dom Bool
sym List (TermD Deps) dom
xs
Pred
_ -> []
guardSumSpec ::
forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
[String] ->
SumSpec a b ->
Specification (Sum a b)
guardSumSpec :: forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
[[Char]] -> SumSpec a b -> Specification (Sum a b)
guardSumSpec [[Char]]
msgs s :: SumSpec a b
s@(SumSpecRaw Maybe [Char]
tString Maybe (Int, Int)
_ Specification a
sa Specification b
sb)
| Specification a -> Bool
forall a. Specification a -> Bool
isErrorLike Specification a
sa
, Specification b -> Bool
forall a. Specification a -> Bool
isErrorLike Specification b
sb =
NonEmpty [Char] -> SpecificationD Deps (Sum a b)
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec (NonEmpty [Char] -> SpecificationD Deps (Sum a b))
-> NonEmpty [Char] -> SpecificationD Deps (Sum a b)
forall a b. (a -> b) -> a -> b
$
[[Char]] -> NonEmpty [Char]
forall a. HasCallStack => [a] -> NonEmpty a
NE.fromList ([[Char]] -> NonEmpty [Char]) -> [[Char]] -> NonEmpty [Char]
forall a b. (a -> b) -> a -> b
$
[[Char]]
msgs [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]
"All branches in a caseOn" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tString [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" simplify to False.", SumSpec a b -> [Char]
forall a. Show a => a -> [Char]
show SumSpec a b
s]
| Bool
otherwise = TypeSpec (Sum a b) -> SpecificationD Deps (Sum a b)
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec TypeSpec (Sum a b)
SumSpec a b
s
instance (KnownNat (CountCases b), HasSpec a, HasSpec b) => Show (SumSpec a b) where
show :: SumSpec a b -> [Char]
show sumspec :: SumSpec a b
sumspec@(SumSpecRaw Maybe [Char]
tstring Maybe (Int, Int)
hint Specification a
l Specification b
r) = case forall a. HasSpec a => TypeSpec a -> BinaryShow
alternateShow @(Sum a b) TypeSpec (Sum a b)
SumSpec a b
sumspec of
(BinaryShow [Char]
_ [Doc a]
ps) -> Doc a -> [Char]
forall a. Show a => a -> [Char]
show (Doc a -> [Char]) -> Doc a -> [Char]
forall a b. (a -> b) -> a -> b
$ Doc a -> Doc a
forall ann. Doc ann -> Doc ann
parens ([Char] -> Doc a
forall a. IsString a => [Char] -> a
fromString ([Char]
"SumSpec" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tstring) Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc a] -> Doc a
forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps)
BinaryShow
NonBinary ->
[Char]
"(SumSpec"
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tstring
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
hint)
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" ("
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification a -> [Char]
forall a. Show a => a -> [Char]
show Specification a
l
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
") "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Doc Any -> [Char]
forall a. Show a => a -> [Char]
show (Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
hint)
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" ("
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Specification b -> [Char]
forall a. Show a => a -> [Char]
show Specification b
r
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"))"
combTypeName :: Maybe String -> Maybe String -> Maybe String
combTypeName :: Maybe [Char] -> Maybe [Char] -> Maybe [Char]
combTypeName (Just [Char]
x) (Just [Char]
y) =
if [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
y then [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
x else [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" | " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
y [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")")
combTypeName (Just [Char]
x) Maybe [Char]
Nothing = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
x
combTypeName Maybe [Char]
Nothing (Just [Char]
x) = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
x
combTypeName Maybe [Char]
Nothing Maybe [Char]
Nothing = Maybe [Char]
forall a. Maybe a
Nothing
instance (HasSpec a, HasSpec b) => Semigroup (SumSpec a b) where
SumSpecRaw Maybe [Char]
t Maybe (Int, Int)
h Specification a
sa Specification b
sb <> :: SumSpec a b -> SumSpec a b -> SumSpec a b
<> SumSpecRaw Maybe [Char]
t' Maybe (Int, Int)
h' Specification a
sa' Specification b
sb' =
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
forall a b.
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
SumSpecRaw (Maybe [Char] -> Maybe [Char] -> Maybe [Char]
combTypeName Maybe [Char]
t Maybe [Char]
t') (((Int, Int) -> (Int, Int) -> (Int, Int))
-> Maybe (Int, Int) -> Maybe (Int, Int) -> Maybe (Int, Int)
forall a. (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
unionWithMaybe (Int, Int) -> (Int, Int) -> (Int, Int)
forall {a} {b}. (Num a, Num b) => (a, b) -> (a, b) -> (a, b)
mergeH Maybe (Int, Int)
h Maybe (Int, Int)
h') (Specification a
sa Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> Specification a
sa') (Specification b
sb Specification b -> Specification b -> Specification b
forall a. Semigroup a => a -> a -> a
<> Specification b
sb')
where
mergeH :: (a, b) -> (a, b) -> (a, b)
mergeH (a
fA, b
fB) (a
fA', b
fB') = (a
fA a -> a -> a
forall a. Num a => a -> a -> a
+ a
fA', b
fB b -> b -> b
forall a. Num a => a -> a -> a
+ b
fB')
instance forall a b. (HasSpec a, HasSpec b, KnownNat (CountCases b)) => Monoid (SumSpec a b) where
mempty :: SumSpec a b
mempty = Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
forall a. Maybe a
Nothing Specification a
forall a. Monoid a => a
mempty Specification b
forall a. Monoid a => a
mempty
type family CountCases a where
CountCases (Sum a b) = 1 + CountCases b
CountCases _ = 1
countCases :: forall a. KnownNat (CountCases a) => Int
countCases :: forall a. KnownNat (CountCases a) => Int
countCases = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal @(CountCases a) Proxy (CountCases a)
forall {k} (t :: k). Proxy t
Proxy)
instance (HasSpec a, HasSpec b, KnownNat (CountCases b)) => HasSpec (Sum a b) where
type TypeSpec (Sum a b) = SumSpec a b
type Prerequisites (Sum a b) = (HasSpec a, HasSpec b)
emptySpec :: TypeSpec (Sum a b)
emptySpec = TypeSpec (Sum a b)
SumSpec a b
forall a. Monoid a => a
mempty
combineSpec :: TypeSpec (Sum a b) -> TypeSpec (Sum a b) -> Specification (Sum a b)
combineSpec TypeSpec (Sum a b)
s TypeSpec (Sum a b)
s' = [[Char]] -> SumSpec a b -> Specification (Sum a b)
forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
[[Char]] -> SumSpec a b -> Specification (Sum a b)
guardSumSpec [[Char]
"When combining SumSpecs", [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ SumSpec a b -> [Char]
forall a. Show a => a -> [Char]
show TypeSpec (Sum a b)
SumSpec a b
s, [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ SumSpec a b -> [Char]
forall a. Show a => a -> [Char]
show TypeSpec (Sum a b)
SumSpec a b
s'] (TypeSpec (Sum a b)
SumSpec a b
s SumSpec a b -> SumSpec a b -> SumSpec a b
forall a. Semigroup a => a -> a -> a
<> TypeSpec (Sum a b)
SumSpec a b
s')
conformsTo :: HasCallStack => Sum a b -> TypeSpec (Sum a b) -> Bool
conformsTo (SumLeft a
a) (SumSpec Maybe (Int, Int)
_ Specification a
sa Specification b
_) = a -> Specification a -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec a
a Specification a
sa
conformsTo (SumRight b
b) (SumSpec Maybe (Int, Int)
_ Specification a
_ Specification b
sb) = b -> Specification b -> Bool
forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec b
b Specification b
sb
genFromTypeSpec :: forall (m :: * -> *).
(HasCallStack, MonadGenError m) =>
TypeSpec (Sum a b) -> GenT m (Sum a b)
genFromTypeSpec (SumSpec Maybe (Int, Int)
h Specification a
sa Specification b
sb)
| Bool
emptyA, Bool
emptyB = [Char] -> GenT m (Sum a b)
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
genError [Char]
"genFromTypeSpec @SumSpec: empty"
| Bool
emptyA = b -> Sum a b
forall a b. b -> Sum a b
SumRight (b -> Sum a b) -> GenT m b -> GenT m (Sum a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification b -> GenT m b
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification b
sb
| Bool
emptyB = a -> Sum a b
forall a b. a -> Sum a b
SumLeft (a -> Sum a b) -> GenT m a -> GenT m (Sum a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification a -> GenT m a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
sa
| Int
fA Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0, Int
fB Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = [Char] -> GenT m (Sum a b)
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
genError [Char]
"All frequencies 0"
| Bool
otherwise =
[(Int, GenT GE (Sum a b))] -> GenT m (Sum a b)
forall a (m :: * -> *).
(Typeable a, MonadGenError m) =>
[(Int, GenT GE a)] -> GenT m a
frequencyT
[ (Int
fA, a -> Sum a b
forall a b. a -> Sum a b
SumLeft (a -> Sum a b) -> GenT GE a -> GenT GE (Sum a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification a -> GenT GE a
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
sa)
, (Int
fB, b -> Sum a b
forall a b. b -> Sum a b
SumRight (b -> Sum a b) -> GenT GE b -> GenT GE (Sum a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification b -> GenT GE b
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification b
sb)
]
where
(Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 -> Int
fA, Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 -> Int
fB) = (Int, Int) -> Maybe (Int, Int) -> (Int, Int)
forall a. a -> Maybe a -> a
fromMaybe (Int
1, forall a. KnownNat (CountCases a) => Int
countCases @b) Maybe (Int, Int)
h
emptyA :: Bool
emptyA = Specification a -> Bool
forall a. Specification a -> Bool
isErrorLike Specification a
sa
emptyB :: Bool
emptyB = Specification b -> Bool
forall a. Specification a -> Bool
isErrorLike Specification b
sb
shrinkWithTypeSpec :: TypeSpec (Sum a b) -> Sum a b -> [Sum a b]
shrinkWithTypeSpec (SumSpec Maybe (Int, Int)
_ Specification a
sa Specification b
_) (SumLeft a
a) = a -> Sum a b
forall a b. a -> Sum a b
SumLeft (a -> Sum a b) -> [a] -> [Sum a b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification a -> a -> [a]
forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
sa a
a
shrinkWithTypeSpec (SumSpec Maybe (Int, Int)
_ Specification a
_ Specification b
sb) (SumRight b
b) = b -> Sum a b
forall a b. b -> Sum a b
SumRight (b -> Sum a b) -> [b] -> [Sum a b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Specification b -> b -> [b]
forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification b
sb b
b
toPreds :: Term (Sum a b) -> TypeSpec (Sum a b) -> Pred
toPreds Term (Sum a b)
ct (SumSpec Maybe (Int, Int)
h Specification a
sa Specification b
sb) =
TermD Deps (SumOver '[a, b])
-> List (Weighted (BinderD Deps)) '[a, b] -> Pred
forall deps (as :: [*]).
(HasSpecD deps (SumOver as), Show (SumOver as)) =>
TermD deps (SumOver as)
-> List (Weighted (BinderD deps)) as -> PredD deps
Case
TermD Deps (SumOver '[a, b])
Term (Sum a b)
ct
( (Maybe Int -> BinderD Deps a -> Weighted (BinderD Deps) a
forall (f :: * -> *) a. Maybe Int -> f a -> Weighted f a
Weighted ((Int, Int) -> Int
forall a b. (a, b) -> a
fst ((Int, Int) -> Int) -> Maybe (Int, Int) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Int, Int)
h) (BinderD Deps a -> Weighted (BinderD Deps) a)
-> BinderD Deps a -> Weighted (BinderD Deps) a
forall a b. (a -> b) -> a -> b
$ (Term a -> Pred) -> BinderD Deps a
forall a p. (HasSpec a, IsPred p) => (Term a -> p) -> Binder a
bind ((Term a -> Pred) -> BinderD Deps a)
-> (Term a -> Pred) -> BinderD Deps a
forall a b. (a -> b) -> a -> b
$ \Term a
a -> Term a -> Specification a -> Pred
forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies Term a
a Specification a
sa)
Weighted (BinderD Deps) a
-> List (Weighted (BinderD Deps)) '[b]
-> List (Weighted (BinderD Deps)) '[a, b]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> (Maybe Int -> BinderD Deps b -> Weighted (BinderD Deps) b
forall (f :: * -> *) a. Maybe Int -> f a -> Weighted f a
Weighted ((Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int) -> Maybe (Int, Int) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Int, Int)
h) (BinderD Deps b -> Weighted (BinderD Deps) b)
-> BinderD Deps b -> Weighted (BinderD Deps) b
forall a b. (a -> b) -> a -> b
$ (Term b -> Pred) -> BinderD Deps b
forall a p. (HasSpec a, IsPred p) => (Term a -> p) -> Binder a
bind ((Term b -> Pred) -> BinderD Deps b)
-> (Term b -> Pred) -> BinderD Deps b
forall a b. (a -> b) -> a -> b
$ \Term b
b -> Term b -> Specification b -> Pred
forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies Term b
b Specification b
sb)
Weighted (BinderD Deps) b
-> List (Weighted (BinderD Deps)) '[]
-> List (Weighted (BinderD Deps)) '[b]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (Weighted (BinderD Deps)) '[]
forall {k} (f :: k -> *). List f '[]
Nil
)
cardinalTypeSpec :: TypeSpec (Sum a b) -> Specification Integer
cardinalTypeSpec (SumSpec Maybe (Int, Int)
_ Specification a
leftspec Specification b
rightspec) = Specification Integer
-> Specification Integer -> Specification Integer
forall n.
Number n =>
Specification n -> Specification n -> Specification n
addSpecInt (Specification a -> Specification Integer
forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification a
leftspec) (Specification b -> Specification Integer
forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification b
rightspec)
typeSpecHasError :: TypeSpec (Sum a b) -> Maybe (NonEmpty [Char])
typeSpecHasError (SumSpec Maybe (Int, Int)
_ Specification a
x Specification b
y) =
case (Specification a -> Bool
forall a. Specification a -> Bool
isErrorLike Specification a
x, Specification b -> Bool
forall a. Specification a -> Bool
isErrorLike Specification b
y) of
(Bool
True, Bool
True) -> NonEmpty [Char] -> Maybe (NonEmpty [Char])
forall a. a -> Maybe a
Just (NonEmpty [Char] -> Maybe (NonEmpty [Char]))
-> NonEmpty [Char] -> Maybe (NonEmpty [Char])
forall a b. (a -> b) -> a -> b
$ (Specification a -> NonEmpty [Char]
forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification a
x NonEmpty [Char] -> NonEmpty [Char] -> NonEmpty [Char]
forall a. Semigroup a => a -> a -> a
<> Specification b -> NonEmpty [Char]
forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification b
y)
(Bool, Bool)
_ -> Maybe (NonEmpty [Char])
forall a. Maybe a
Nothing
alternateShow :: TypeSpec (Sum a b) -> BinaryShow
alternateShow (SumSpec Maybe (Int, Int)
h Specification a
left right :: Specification b
right@(TypeSpec TypeSpec b
r [])) =
case forall a. HasSpec a => TypeSpec a -> BinaryShow
alternateShow @b TypeSpec b
r of
(BinaryShow [Char]
"SumSpec" [Doc a]
ps) -> [Char] -> [Doc a] -> BinaryShow
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" (Doc a
"|" Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc a
forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification a -> Doc a
forall a ann. Show a => a -> Doc ann
viaShow Specification a
left Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a]
ps)
(BinaryShow [Char]
"Cartesian" [Doc a]
ps) ->
[Char] -> [Doc a] -> BinaryShow
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" (Doc a
"|" Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc a
forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification a -> Doc a
forall a ann. Show a => a -> Doc ann
viaShow Specification a
left Doc a -> [Doc a] -> [Doc a]
forall a. a -> [a] -> [a]
: [Doc a -> Doc a
forall ann. Doc ann -> Doc ann
parens (Doc a
"Cartesian" Doc a -> Doc a -> Doc a
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc a] -> Doc a
forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps)])
BinaryShow
_ ->
[Char] -> [Doc Any] -> BinaryShow
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" [Doc Any
"|" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification a -> Doc Any
forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"|" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
h Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification b -> Doc Any
forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
alternateShow (SumSpec Maybe (Int, Int)
h Specification a
left Specification b
right) =
[Char] -> [Doc Any] -> BinaryShow
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" [Doc Any
"|" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification a -> Doc Any
forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"|" Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Maybe (Int, Int) -> Doc Any
forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
h Doc Any -> Doc Any -> Doc Any
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Specification b -> Doc Any
forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
data SumW dom rng where
InjLeftW :: SumW '[a] (Sum a b)
InjRightW :: SumW '[b] (Sum a b)
instance Show (SumW dom rng) where
show :: SumW dom rng -> [Char]
show SumW dom rng
InjLeftW = [Char]
"injLeft_"
show SumW dom rng
InjRightW = [Char]
"injRight_"
deriving instance (Eq (SumW dom rng))
instance Syntax SumW
instance Semantics SumW where
semantics :: forall (d :: [*]) r. SumW d r -> FunTy d r
semantics SumW d r
InjLeftW = FunTy d r
a -> Sum a b
forall a b. a -> Sum a b
SumLeft
semantics SumW d r
InjRightW = FunTy d r
b -> Sum a b
forall a b. b -> Sum a b
SumRight
instance Logic SumW where
propagateTypeSpec :: forall (as :: [*]) b a.
(AppRequires SumW as b, HasSpec a) =>
SumW as b
-> ListCtx Value as (HOLE a)
-> TypeSpec b
-> [b]
-> Specification a
propagateTypeSpec SumW as b
InjLeftW (Unary HOLE a a
HOLE) (SumSpec Maybe (Int, Int)
_ Specification a
sl Specification b
_) [b]
cant = Specification a
sl Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> (a -> Specification a) -> [a] -> Specification a
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Specification a
forall a. HasSpec a => a -> Specification a
notEqualSpec [a
a | SumLeft a
a <- [b]
cant]
propagateTypeSpec SumW as b
InjRightW (Unary HOLE a b
HOLE) (SumSpec Maybe (Int, Int)
_ Specification a
_ Specification a
sr) [b]
cant = Specification a
sr Specification a -> Specification a -> Specification a
forall a. Semigroup a => a -> a -> a
<> (a -> Specification a) -> [a] -> Specification a
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> Specification a
forall a. HasSpec a => a -> Specification a
notEqualSpec [a
a | SumRight a
a <- [b]
cant]
propagateMemberSpec :: forall (as :: [*]) b a.
(AppRequires SumW as b, HasSpec a) =>
SumW as b
-> ListCtx Value as (HOLE a) -> NonEmpty b -> Specification a
propagateMemberSpec SumW as b
InjLeftW (Unary HOLE a a
HOLE) NonEmpty b
es =
case [a
a | SumLeft a
a <- NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty b
es] of
(a
x : [a]
xs) -> NonEmpty a -> Specification a
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs)
[] ->
NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec (NonEmpty [Char] -> Specification a)
-> NonEmpty [Char] -> Specification a
forall a b. (a -> b) -> a -> b
$
[Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> NonEmpty [Char]) -> [Char] -> NonEmpty [Char]
forall a b. (a -> b) -> a -> b
$
[Char]
"propMemberSpec (sumleft_ HOLE) on (MemberSpec es) with no SumLeft in es: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [b] -> [Char]
forall a. Show a => a -> [Char]
show (NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty b
es)
propagateMemberSpec SumW as b
InjRightW (Unary HOLE a b
HOLE) NonEmpty b
es =
case [a
a | SumRight a
a <- NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty b
es] of
(a
x : [a]
xs) -> NonEmpty a -> Specification a
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (a
x a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
xs)
[] ->
NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec (NonEmpty [Char] -> Specification a)
-> NonEmpty [Char] -> Specification a
forall a b. (a -> b) -> a -> b
$
[Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> NonEmpty [Char]) -> [Char] -> NonEmpty [Char]
forall a b. (a -> b) -> a -> b
$
[Char]
"propagate(InjRight HOLE) on (MemberSpec es) with no SumLeft in es: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [b] -> [Char]
forall a. Show a => a -> [Char]
show (NonEmpty b -> [b]
forall a. NonEmpty a -> [a]
NE.toList NonEmpty b
es)
mapTypeSpec :: forall a b.
(HasSpec a, HasSpec b) =>
SumW '[a] b -> TypeSpec a -> Specification b
mapTypeSpec SumW '[a] b
InjLeftW TypeSpec a
ts = TypeSpec b -> Specification b
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec (TypeSpec b -> Specification b) -> TypeSpec b -> Specification b
forall a b. (a -> b) -> a -> b
$ Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
forall a. Maybe a
Nothing (TypeSpec a -> Specification a
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec TypeSpec a
ts) (NonEmpty [Char] -> Specification b
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec ([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"mapTypeSpec InjLeftW"))
mapTypeSpec SumW '[a] b
InjRightW TypeSpec a
ts = TypeSpec b -> Specification b
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec (TypeSpec b -> Specification b) -> TypeSpec b -> Specification b
forall a b. (a -> b) -> a -> b
$ Maybe (Int, Int)
-> Specification a -> Specification a -> SumSpec a a
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
forall a. Maybe a
Nothing (NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec ([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"mapTypeSpec InjRightW")) (TypeSpec a -> Specification a
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec TypeSpec a
ts)
injLeft_ :: (HasSpec a, HasSpec b, KnownNat (CountCases b)) => Term a -> Term (Sum a b)
injLeft_ :: forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
Term a -> Term (Sum a b)
injLeft_ = SumW '[a] (Sum a b)
-> FunTy (MapList (TermD Deps) '[a]) (TermD Deps (Sum a b))
forall (t :: [*] -> * -> *) (ds :: [*]) r.
AppRequires t ds r =>
t ds r -> FunTy (MapList (TermD Deps) ds) (Term r)
appTerm SumW '[a] (Sum a b)
forall b a. SumW '[b] (Sum b a)
InjLeftW
injRight_ :: (HasSpec a, HasSpec b, KnownNat (CountCases b)) => Term b -> Term (Sum a b)
injRight_ :: forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
Term b -> Term (Sum a b)
injRight_ = SumW '[b] (Sum a b)
-> FunTy (MapList (TermD Deps) '[b]) (TermD Deps (Sum a b))
forall (t :: [*] -> * -> *) (ds :: [*]) r.
AppRequires t ds r =>
t ds r -> FunTy (MapList (TermD Deps) ds) (Term r)
appTerm SumW '[b] (Sum a b)
forall b a. SumW '[b] (Sum a b)
InjRightW
pattern InjRight ::
forall c.
() =>
forall a b.
( c ~ Sum a b
, AppRequires SumW '[b] c
) =>
Term b ->
Term c
pattern $mInjRight :: forall {r} {c}.
Term c
-> (forall {a} {b}.
(c ~ Sum a b, AppRequires SumW '[b] c) =>
Term b -> r)
-> ((# #) -> r)
-> r
InjRight x <- (App (getWitness -> Just InjRightW) (x :> Nil))
pattern InjLeft ::
forall c.
() =>
forall a b.
( c ~ Sum a b
, AppRequires SumW '[a] c
) =>
Term a ->
Term c
pattern $mInjLeft :: forall {r} {c}.
Term c
-> (forall {a} {b}.
(c ~ Sum a b, AppRequires SumW '[a] c) =>
Term a -> r)
-> ((# #) -> r)
-> r
InjLeft x <- App (getWitness -> Just InjLeftW) (x :> Nil)
sumWeightL, sumWeightR :: Maybe (Int, Int) -> Doc a
sumWeightL :: forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
Nothing = Doc a
"1"
sumWeightL (Just (Int
x, Int
_)) = [Char] -> Doc a
forall a. IsString a => [Char] -> a
fromString (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
x)
sumWeightR :: forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
Nothing = Doc a
"1"
sumWeightR (Just (Int
_, Int
x)) = [Char] -> Doc a
forall a. IsString a => [Char] -> a
fromString (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
x)
data BoolW (dom :: [Type]) (rng :: Type) where
NotW :: BoolW '[Bool] Bool
OrW :: BoolW '[Bool, Bool] Bool
deriving instance Eq (BoolW dom rng)
instance Show (BoolW dom rng) where
show :: BoolW dom rng -> [Char]
show BoolW dom rng
NotW = [Char]
"not_"
show BoolW dom rng
OrW = [Char]
"or_"
boolSem :: BoolW dom rng -> FunTy dom rng
boolSem :: forall (dom :: [*]) rng. BoolW dom rng -> FunTy dom rng
boolSem BoolW dom rng
NotW = FunTy dom rng
Bool -> Bool
not
boolSem BoolW dom rng
OrW = FunTy dom rng
Bool -> Bool -> Bool
(||)
instance Semantics BoolW where
semantics :: forall (dom :: [*]) rng. BoolW dom rng -> FunTy dom rng
semantics = BoolW d r -> FunTy d r
forall (dom :: [*]) rng. BoolW dom rng -> FunTy dom rng
boolSem
instance Syntax BoolW
instance Logic BoolW where
propagate :: forall (as :: [*]) b a.
(AppRequires BoolW as b, HasSpec a) =>
BoolW as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
propagate BoolW as b
f ListCtx Value as (HOLE a)
ctxt (ExplainSpec [] SpecificationD Deps b
s) = BoolW as b
-> ListCtx Value as (HOLE a)
-> SpecificationD Deps b
-> Specification a
forall (as :: [*]) b a.
(AppRequires BoolW as b, HasSpec a) =>
BoolW as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
forall (t :: [*] -> * -> *) (as :: [*]) b a.
(Logic t, AppRequires t as b, HasSpec a) =>
t as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
propagate BoolW as b
f ListCtx Value as (HOLE a)
ctxt SpecificationD Deps b
s
propagate BoolW as b
f ListCtx Value as (HOLE a)
ctxt (ExplainSpec [[Char]]
es SpecificationD Deps b
s) = [[Char]] -> Specification a -> Specification a
forall deps a.
[[Char]] -> SpecificationD deps a -> SpecificationD deps a
ExplainSpec [[Char]]
es (Specification a -> Specification a)
-> Specification a -> Specification a
forall a b. (a -> b) -> a -> b
$ BoolW as b
-> ListCtx Value as (HOLE a)
-> SpecificationD Deps b
-> Specification a
forall (as :: [*]) b a.
(AppRequires BoolW as b, HasSpec a) =>
BoolW as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
forall (t :: [*] -> * -> *) (as :: [*]) b a.
(Logic t, AppRequires t as b, HasSpec a) =>
t as b
-> ListCtx Value as (HOLE a) -> Specification b -> Specification a
propagate BoolW as b
f ListCtx Value as (HOLE a)
ctxt SpecificationD Deps b
s
propagate BoolW as b
_ ListCtx Value as (HOLE a)
_ SpecificationD Deps b
TrueSpec = Specification a
forall deps a. SpecificationD deps a
TrueSpec
propagate BoolW as b
_ ListCtx Value as (HOLE a)
_ (ErrorSpec NonEmpty [Char]
msgs) = NonEmpty [Char] -> Specification a
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec NonEmpty [Char]
msgs
propagate BoolW as b
NotW (Unary HOLE a Bool
HOLE) (SuspendedSpec Var b
v Pred
ps) =
(Term a -> Pred) -> Specification a
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term a -> Pred) -> Specification a)
-> (Term a -> Pred) -> Specification a
forall a b. (a -> b) -> a -> b
$ \Term a
v' -> TermD Deps Bool -> BinderD Deps Bool -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let (BoolW '[Bool] Bool -> List (TermD Deps) '[Bool] -> TermD Deps Bool
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App BoolW '[Bool] Bool
NotW (Term a
TermD Deps Bool
v' TermD Deps Bool
-> List (TermD Deps) '[] -> List (TermD Deps) '[Bool]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (TermD Deps) '[]
forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
Var Bool
v Var Bool -> Pred -> BinderD Deps Bool
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
ps)
propagate BoolW as b
NotW (Unary HOLE a Bool
HOLE) SpecificationD Deps b
spec =
Specification Bool -> (Bool -> Specification a) -> Specification a
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec SpecificationD Deps b
Specification Bool
spec (a -> Specification a
forall a. a -> Specification a
equalSpec (a -> Specification a) -> (Bool -> a) -> Bool -> Specification a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> a
Bool -> Bool
not)
propagate BoolW as b
OrW (HOLE a Bool
HOLE :<: Bool
x) (SuspendedSpec Var b
v Pred
ps) =
(Term a -> Pred) -> Specification a
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term a -> Pred) -> Specification a)
-> (Term a -> Pred) -> Specification a
forall a b. (a -> b) -> a -> b
$ \Term a
v' -> TermD Deps Bool -> BinderD Deps Bool -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let (BoolW '[Bool, Bool] Bool
-> List (TermD Deps) '[Bool, Bool] -> TermD Deps Bool
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App BoolW '[Bool, Bool] Bool
OrW (Term a
TermD Deps Bool
v' TermD Deps Bool
-> List (TermD Deps) '[Bool] -> List (TermD Deps) '[Bool, Bool]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Bool -> TermD Deps Bool
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit Bool
x TermD Deps Bool
-> List (TermD Deps) '[] -> List (TermD Deps) '[Bool]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (TermD Deps) '[]
forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
Var Bool
v Var Bool -> Pred -> BinderD Deps Bool
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
ps)
propagate BoolW as b
OrW (Bool
x :>: HOLE a Bool
HOLE) (SuspendedSpec Var b
v Pred
ps) =
(Term a -> Pred) -> Specification a
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained ((Term a -> Pred) -> Specification a)
-> (Term a -> Pred) -> Specification a
forall a b. (a -> b) -> a -> b
$ \Term a
v' -> TermD Deps Bool -> BinderD Deps Bool -> Pred
forall deps a. TermD deps a -> BinderD deps a -> PredD deps
Let (BoolW '[Bool, Bool] Bool
-> List (TermD Deps) '[Bool, Bool] -> TermD Deps Bool
forall deps (t :: [*] -> * -> *) (dom :: [*]) a.
AppRequiresD deps t dom a =>
t dom a -> List (TermD deps) dom -> TermD deps a
App BoolW '[Bool, Bool] Bool
OrW (Bool -> TermD Deps Bool
forall a deps. (Typeable a, Eq a, Show a) => a -> TermD deps a
Lit Bool
x TermD Deps Bool
-> List (TermD Deps) '[Bool] -> List (TermD Deps) '[Bool, Bool]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term a
TermD Deps Bool
v' TermD Deps Bool
-> List (TermD Deps) '[] -> List (TermD Deps) '[Bool]
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> List (TermD Deps) '[]
forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
Var Bool
v Var Bool -> Pred -> BinderD Deps Bool
forall deps a.
(HasSpecD deps a, Show a) =>
Var a -> PredD deps -> BinderD deps a
:-> Pred
ps)
propagate BoolW as b
OrW (HOLE a Bool
HOLE :<: Bool
s) SpecificationD Deps b
spec =
Specification Bool -> (Bool -> Specification a) -> Specification a
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec SpecificationD Deps b
Specification Bool
spec (Bool -> Bool -> Specification Bool
okOr Bool
s)
propagate BoolW as b
OrW (Bool
s :>: HOLE a Bool
HOLE) SpecificationD Deps b
spec =
Specification Bool -> (Bool -> Specification a) -> Specification a
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec SpecificationD Deps b
Specification Bool
spec (Bool -> Bool -> Specification Bool
okOr Bool
s)
mapTypeSpec :: forall a b.
(HasSpec a, HasSpec b) =>
BoolW '[a] b -> TypeSpec a -> Specification b
mapTypeSpec BoolW '[a] b
NotW () = TypeSpec b -> Specification b
forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec ()
not_ :: Term Bool -> Term Bool
not_ :: TermD Deps Bool -> TermD Deps Bool
not_ = BoolW '[Bool] Bool
-> FunTy (MapList (TermD Deps) '[Bool]) (TermD Deps Bool)
forall (t :: [*] -> * -> *) (ds :: [*]) r.
AppRequires t ds r =>
t ds r -> FunTy (MapList (TermD Deps) ds) (Term r)
appTerm BoolW '[Bool] Bool
NotW
okOr :: Bool -> Bool -> Specification Bool
okOr :: Bool -> Bool -> Specification Bool
okOr Bool
constant Bool
need = case (Bool
constant, Bool
need) of
(Bool
True, Bool
True) -> Specification Bool
forall deps a. SpecificationD deps a
TrueSpec
(Bool
True, Bool
False) ->
NonEmpty [Char] -> Specification Bool
forall deps a. NonEmpty [Char] -> SpecificationD deps a
ErrorSpec
([Char] -> NonEmpty [Char]
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
constant [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"||. HOLE) must equal False. That cannot be the case."))
(Bool
False, Bool
False) -> NonEmpty Bool -> Specification Bool
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Bool -> NonEmpty Bool
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
(Bool
False, Bool
True) -> NonEmpty Bool -> Specification Bool
forall a deps. NonEmpty a -> SpecificationD deps a
MemberSpec (Bool -> NonEmpty Bool
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
or_ :: Term Bool -> Term Bool -> Term Bool
or_ :: TermD Deps Bool -> TermD Deps Bool -> TermD Deps Bool
or_ = BoolW '[Bool, Bool] Bool
-> FunTy (MapList (TermD Deps) '[Bool, Bool]) (TermD Deps Bool)
forall (t :: [*] -> * -> *) (ds :: [*]) r.
AppRequires t ds r =>
t ds r -> FunTy (MapList (TermD Deps) ds) (Term r)
appTerm BoolW '[Bool, Bool] Bool
OrW
data SolverStage where
SolverStage ::
HasSpec a =>
{ ()
stageVar :: Var a
, SolverStage -> [Pred]
stagePreds :: [Pred]
, ()
stageSpec :: Specification a
} ->
SolverStage
instance Pretty SolverStage where
pretty :: forall ann. SolverStage -> Doc ann
pretty SolverStage {[Pred]
Var a
Specification a
stageVar :: ()
stagePreds :: SolverStage -> [Pred]
stageSpec :: ()
stageVar :: Var a
stagePreds :: [Pred]
stageSpec :: Specification a
..} =
Var a -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow Var a
stageVar
Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"<-"
Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep'
( [Specification a -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Specification a -> Doc ann
pretty Specification a
stageSpec | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Specification a -> Bool
forall a. Specification a -> Bool
isTrueSpec Specification a
stageSpec]
[Doc ann] -> [Doc ann] -> [Doc ann]
forall a. [a] -> [a] -> [a]
++ [Doc ann
"---" | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Pred] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Pred]
stagePreds, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Specification a -> Bool
forall a. Specification a -> Bool
isTrueSpec Specification a
stageSpec]
[Doc ann] -> [Doc ann] -> [Doc ann]
forall a. [a] -> [a] -> [a]
++ (Pred -> Doc ann) -> [Pred] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map Pred -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Pred -> Doc ann
pretty [Pred]
stagePreds
)
data SolverPlan = SolverPlan
{ SolverPlan -> [SolverStage]
solverPlan :: [SolverStage]
, SolverPlan -> Graph Name
solverDependencies :: Graph Name
}
instance Pretty SolverPlan where
pretty :: forall ann. SolverPlan -> Doc ann
pretty SolverPlan {[SolverStage]
Graph Name
solverPlan :: SolverPlan -> [SolverStage]
solverDependencies :: SolverPlan -> Graph Name
solverPlan :: [SolverStage]
solverDependencies :: Graph Name
..} =
Doc ann
"\nSolverPlan"
Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
/> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep'
[
Doc ann
"\nLinearization:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
/> [SolverStage] -> Doc ann
forall ann. [SolverStage] -> Doc ann
prettyLinear [SolverStage]
solverPlan
]
isTrueSpec :: Specification a -> Bool
isTrueSpec :: forall a. Specification a -> Bool
isTrueSpec SpecificationD Deps a
TrueSpec = Bool
True
isTrueSpec SpecificationD Deps a
_ = Bool
False
prettyLinear :: [SolverStage] -> Doc ann
prettyLinear :: forall ann. [SolverStage] -> Doc ann
prettyLinear = [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep' ([Doc ann] -> Doc ann)
-> ([SolverStage] -> [Doc ann]) -> [SolverStage] -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SolverStage -> Doc ann) -> [SolverStage] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map SolverStage -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. SolverStage -> Doc ann
pretty