{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImpredicativeTypes #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Constrained.TheKnot where
import Constrained.Base
import Constrained.Conformance
import Constrained.Generic
import Constrained.NumSpec
import Constrained.Syntax
import Constrained.Core (
Evidence (..),
NonEmpty ((:|)),
Var (..),
eqVar,
freshen,
unValue,
unionWithMaybe,
)
import Constrained.Env
import Constrained.GenT
import Constrained.Graph hiding (dependency, irreflexiveDependencyOn, noDependencies)
import qualified Constrained.Graph as Graph
import Constrained.List
import Control.Monad
import Control.Monad.Writer (Writer, runWriter, tell)
import Data.Foldable
import Data.Kind
import Data.List (nub, partition)
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)
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 $bSumSpec :: forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
$mSumSpec :: forall {r} {a} {b}.
SumSpec a b
-> (Maybe (Int, Int) -> Specification a -> Specification b -> r)
-> ((# #) -> r)
-> r
SumSpec a b c <- SumSpecRaw _ a b c
where
SumSpec Maybe (Int, Int)
a Specification a
b Specification b
c = forall a b.
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
SumSpecRaw forall a. Maybe a
Nothing Maybe (Int, Int)
a Specification a
b Specification b
c
{-# COMPLETE SumSpec #-}
{-# COMPLETE SumSpecRaw #-}
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)
| forall a. Specification a -> Bool
isErrorLike Specification a
sa
, forall a. Specification a -> Bool
isErrorLike Specification b
sb =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList forall a b. (a -> b) -> a -> b
$
[[Char]]
msgs forall a. [a] -> [a] -> [a]
++ [[Char]
"All branches in a caseOn" forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tString forall a. [a] -> [a] -> [a]
++ [Char]
" simplify to False.", forall a. Show a => a -> [Char]
show SumSpec a b
s]
| Bool
otherwise = forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec 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) SumSpec a b
sumspec of
(BinaryShow [Char]
_ [Doc a]
ps) -> forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall ann. Doc ann -> Doc ann
parens (forall a. IsString a => [Char] -> a
fromString ([Char]
"SumSpec" forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tstring) forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps)
BinaryShow
NonBinary ->
[Char]
"(SumSpec"
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tstring
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
hint)
forall a. [a] -> [a] -> [a]
++ [Char]
" ("
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
l
forall a. [a] -> [a] -> [a]
++ [Char]
") "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
hint)
forall a. [a] -> [a] -> [a]
++ [Char]
" ("
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification b
r
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 forall a. Eq a => a -> a -> Bool
== [Char]
y then forall a. a -> Maybe a
Just [Char]
x else forall a. a -> Maybe a
Just ([Char]
"(" forall a. [a] -> [a] -> [a]
++ [Char]
x forall a. [a] -> [a] -> [a]
++ [Char]
" | " forall a. [a] -> [a] -> [a]
++ [Char]
y forall a. [a] -> [a] -> [a]
++ [Char]
")")
combTypeName (Just [Char]
x) Maybe [Char]
Nothing = forall a. a -> Maybe a
Just [Char]
x
combTypeName Maybe [Char]
Nothing (Just [Char]
x) = forall a. a -> Maybe a
Just [Char]
x
combTypeName Maybe [Char]
Nothing Maybe [Char]
Nothing = 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' =
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') (forall a. (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
unionWithMaybe 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 forall a. Semigroup a => a -> a -> a
<> Specification a
sa') (Specification b
sb 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 forall a. Num a => a -> a -> a
+ a
fA', b
fB 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 = forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec forall a. Maybe a
Nothing forall a. Monoid a => a
mempty 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 = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal @(CountCases a) forall {k} (t :: k). Proxy t
Proxy)
totalWeight :: List (Weighted f) as -> Maybe Int
totalWeight :: forall {k} (f :: k -> *) (as :: [k]).
List (Weighted f) as -> Maybe Int
totalWeight = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Sum a -> a
getSum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} b (f :: k -> *) (as :: [k]).
Monoid b =>
(forall (a :: k). f a -> b) -> List f as -> b
foldMapList (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Sum a
Semigroup.Sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (a :: k). Weighted f a -> Maybe Int
weight)
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 = 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' = forall a b.
(HasSpec a, HasSpec b, KnownNat (CountCases b)) =>
[[Char]] -> SumSpec a b -> Specification (Sum a b)
guardSumSpec [[Char]
"When combining SumSpecs", [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show TypeSpec (Sum a b)
s, [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show TypeSpec (Sum a b)
s'] (TypeSpec (Sum a b)
s forall a. Semigroup a => a -> a -> a
<> TypeSpec (Sum 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
_) = 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) = 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 = forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genError forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"genFromTypeSpec @SumSpec: empty")
| Bool
emptyA = forall a b. b -> Sum a b
SumRight forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification b
sb
| Bool
emptyB = forall a b. a -> Sum a b
SumLeft forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
sa
| Int
fA forall a. Eq a => a -> a -> Bool
== Int
0, Int
fB forall a. Eq a => a -> a -> Bool
== Int
0 = forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genError forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"All frequencies 0")
| Bool
otherwise =
forall a (m :: * -> *).
(Typeable a, MonadGenError m) =>
[(Int, GenT GE a)] -> GenT m a
frequencyT
[ (Int
fA, forall a b. a -> Sum a b
SumLeft forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
sa)
, (Int
fB, forall a b. b -> Sum a b
SumRight forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification b
sb)
]
where
(forall a. Ord a => a -> a -> a
max Int
0 -> Int
fA, forall a. Ord a => a -> a -> a
max Int
0 -> Int
fB) = forall a. a -> Maybe a -> a
fromMaybe (Int
1, forall a. KnownNat (CountCases a) => Int
countCases @b) Maybe (Int, Int)
h
emptyA :: Bool
emptyA = forall a. Specification a -> Bool
isErrorLike Specification a
sa
emptyB :: Bool
emptyB = 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) = forall a b. a -> Sum a b
SumLeft forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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) = forall a b. b -> Sum a b
SumRight forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f 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) =
forall (as :: [*]).
HasSpec (SumOver as) =>
Term (SumOver as) -> List (Weighted Binder) as -> Pred
Case
Term (Sum a b)
ct
( (forall {k} (f :: k -> *) (a :: k). Maybe Int -> f a -> Weighted f a
Weighted (forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Int, Int)
h) forall a b. (a -> b) -> a -> b
$ forall a p. (HasSpec a, IsPred p) => (Term a -> p) -> Binder a
bind forall a b. (a -> b) -> a -> b
$ \Term a
a -> forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies Term a
a Specification a
sa)
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> (forall {k} (f :: k -> *) (a :: k). Maybe Int -> f a -> Weighted f a
Weighted (forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Int, Int)
h) forall a b. (a -> b) -> a -> b
$ forall a p. (HasSpec a, IsPred p) => (Term a -> p) -> Binder a
bind forall a b. (a -> b) -> a -> b
$ \Term b
b -> forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies Term b
b Specification b
sb)
forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> 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) = forall n.
Number n =>
Specification n -> Specification n -> Specification n
addSpecInt (forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification a
leftspec) (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 (forall a. Specification a -> Bool
isErrorLike Specification a
x, forall a. Specification a -> Bool
isErrorLike Specification b
y) of
(Bool
True, Bool
True) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ (forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification a
x forall a. Semigroup a => a -> a -> a
<> forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification b
y)
(Bool, Bool)
_ -> 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) -> forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" (Doc a
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left forall a. a -> [a] -> [a]
: [Doc a]
ps)
(BinaryShow [Char]
"Cartesian" [Doc a]
ps) ->
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" (Doc a
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left forall a. a -> [a] -> [a]
: [forall ann. Doc ann -> Doc ann
parens (Doc a
"Cartesian" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps)])
BinaryShow
_ ->
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" [Doc Any
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
alternateShow (SumSpec Maybe (Int, Int)
h Specification a
left Specification b
right) =
forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"SumSpec" [Doc Any
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightL Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"|" forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a. Maybe (Int, Int) -> Doc a
sumWeightR Maybe (Int, Int)
h forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
sumType :: (Maybe String) -> String
sumType :: Maybe [Char] -> [Char]
sumType Maybe [Char]
Nothing = [Char]
""
sumType (Just [Char]
x) = [Char]
" type=" forall a. [a] -> [a] -> [a]
++ [Char]
x
instance (Arbitrary (Specification a), Arbitrary (Specification b)) => Arbitrary (SumSpec a b) where
arbitrary :: Gen (SumSpec a b)
arbitrary =
forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
3, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing)
, (Int
10, forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
100) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Random a => (a, a) -> Gen a
choose (Int
0, Int
100)))
, (Int
1, forall a. Arbitrary a => Gen a
arbitrary)
]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Arbitrary a => Gen a
arbitrary
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Arbitrary a => Gen a
arbitrary
shrink :: SumSpec a b -> [SumSpec a b]
shrink (SumSpec Maybe (Int, Int)
h Specification a
a Specification b
b) = [forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
h' Specification a
a' Specification b
b' | (Maybe (Int, Int)
h', Specification a
a', Specification b
b') <- forall a. Arbitrary a => a -> [a]
shrink (Maybe (Int, Int)
h, Specification a
a, Specification b
b)]
instance HasSimpleRep Bool
instance HasSpec Bool where
shrinkWithTypeSpec :: TypeSpec Bool -> Bool -> [Bool]
shrinkWithTypeSpec TypeSpec Bool
_ = forall a. Arbitrary a => a -> [a]
shrink
cardinalTypeSpec :: TypeSpec Bool -> Specification Integer
cardinalTypeSpec (SumSpec Maybe (Int, Int)
_ Specification ()
a Specification ()
b) =
forall a. NonEmpty a -> Specification a
MemberSpec (forall a. [a] -> NonEmpty a
NE.fromList [Integer
0, Integer
1, Integer
2]) forall a. Semigroup a => a -> a -> a
<> forall n.
Number n =>
Specification n -> Specification n -> Specification n
addSpecInt (forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification ()
a) (forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification ()
b)
cardinalTrueSpec :: Specification Integer
cardinalTrueSpec = forall a. NonEmpty a -> Specification a
MemberSpec (forall (f :: * -> *) a. Applicative f => a -> f a
pure Integer
2)
caseBoolSpec ::
HasSpec a => Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec :: forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec Bool -> Specification a
cont = case Specification Bool -> [Bool]
possibleValues Specification Bool
spec of
[] -> forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"No possible values in caseBoolSpec"])
[Bool
b] -> Bool -> Specification a
cont Bool
b
[Bool]
_ -> forall a. Monoid a => a
mempty
where
possibleValues :: Specification Bool -> [Bool]
possibleValues Specification Bool
s = forall a. (a -> Bool) -> [a] -> [a]
filter (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec Specification Bool
s) [Bool
True, Bool
False]
data BoolW (sym :: Symbol) (dom :: [Type]) (rng :: Type) where
NotW :: BoolW "not_" '[Bool] Bool
OrW :: BoolW "or_" '[Bool, Bool] Bool
deriving instance Eq (BoolW s dom rng)
instance Show (BoolW s dom rng) where
show :: BoolW s dom rng -> [Char]
show BoolW s dom rng
NotW = [Char]
"not_"
show BoolW s dom rng
OrW = [Char]
"or_"
boolSem :: BoolW sym dom rng -> FunTy dom rng
boolSem :: forall (sym :: Symbol) (dom :: [*]) rng.
BoolW sym dom rng -> FunTy dom rng
boolSem BoolW sym dom rng
NotW = Bool -> Bool
not
boolSem BoolW sym dom rng
OrW = Bool -> Bool -> Bool
(||)
instance Semantics BoolW where
semantics :: forall (sym :: Symbol) (dom :: [*]) rng.
BoolW sym dom rng -> FunTy dom rng
semantics = forall (sym :: Symbol) (dom :: [*]) rng.
BoolW sym dom rng -> FunTy dom rng
boolSem
instance Syntax BoolW
instance (HasSpec Bool, TypeSpec Bool ~ SumSpec () ()) => Logic "not_" BoolW '[Bool] Bool where
propagate :: forall hole.
Context "not_" BoolW '[Bool] Bool hole
-> Specification Bool -> Specification hole
propagate Context "not_" BoolW '[Bool] Bool hole
ctxt (ExplainSpec [] Specification Bool
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "not_" BoolW '[Bool] Bool hole
ctxt Specification Bool
s
propagate Context "not_" BoolW '[Bool] Bool hole
ctxt (ExplainSpec [[Char]]
es Specification Bool
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "not_" BoolW '[Bool] Bool hole
ctxt Specification Bool
s
propagate Context "not_" BoolW '[Bool] Bool hole
_ Specification Bool
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "not_" BoolW '[Bool] Bool hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BoolW "not_" '[Bool] Bool
NotW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App BoolW "not_" '[Bool] Bool
NotW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BoolW "not_" '[Bool] Bool
NotW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec (forall a. a -> Specification a
equalSpec forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not)
propagate Context "not_" BoolW '[Bool] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for NotW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "not_" BoolW '[Bool] Bool hole
ctx)
mapTypeSpec :: forall a b.
('[Bool] ~ '[a], Bool ~ b, HasSpec a, HasSpec b) =>
BoolW "not_" '[a] b -> TypeSpec a -> Specification b
mapTypeSpec BoolW "not_" '[a] b
NotW (SumSpec Maybe (Int, Int)
h Specification ()
a Specification ()
b) = forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec forall a b. (a -> b) -> a -> b
$ forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec Maybe (Int, Int)
h Specification ()
b Specification ()
a
not_ :: Term Bool -> Term Bool
not_ :: Term Bool -> Term Bool
not_ = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm BoolW "not_" '[Bool] Bool
NotW
instance HasSpec Bool => Logic "or_" BoolW '[Bool, Bool] Bool where
propagate :: forall hole.
Context "or_" BoolW '[Bool, Bool] Bool hole
-> Specification Bool -> Specification hole
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
ctxt (ExplainSpec [] Specification Bool
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
ctxt Specification Bool
s
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
ctxt (ExplainSpec [[Char]]
es Specification Bool
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
ctxt Specification Bool
s
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
_ Specification Bool
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BoolW "or_" '[Bool, Bool] Bool
OrW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App BoolW "or_" '[Bool, Bool] Bool
OrW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BoolW "or_" '[Bool, Bool] Bool
OrW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App BoolW "or_" '[Bool, Bool] Bool
OrW (forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BoolW "or_" '[Bool, Bool] Bool
OrW (Ctx hole y
HOLE :<> (Bool
s :: Bool) :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec (Bool -> Bool -> Specification Bool
okOr Bool
s)
propagate (Context BoolW "or_" '[Bool, Bool] Bool
OrW ((Bool
s :: Bool) :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec (Bool -> Bool -> Specification Bool
okOr Bool
s)
propagate Context "or_" BoolW '[Bool, Bool] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for OrW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "or_" BoolW '[Bool, Bool] Bool hole
ctx)
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) -> forall a. Specification a
TrueSpec
(Bool
True, Bool
False) ->
forall a. NonEmpty [Char] -> Specification a
ErrorSpec
(forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Bool
constant forall a. [a] -> [a] -> [a]
++ [Char]
"||. HOLE) must equal False. That cannot be the case."))
(Bool
False, Bool
False) -> forall a. NonEmpty a -> Specification a
MemberSpec (forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False)
(Bool
False, Bool
True) -> forall a. NonEmpty a -> Specification a
MemberSpec (forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True)
or_ :: Term Bool -> Term Bool -> Term Bool
or_ :: Term Bool -> Term Bool -> Term Bool
or_ = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm BoolW "or_" '[Bool, Bool] Bool
OrW
instance (HasSpec Bool, Eq a, Typeable a) => Logic "==." BaseW '[a, a] Bool where
propagate :: forall hole.
Context "==." BaseW '[a, a] Bool hole
-> Specification Bool -> Specification hole
propagate Context "==." BaseW '[a, a] Bool hole
ctxt (ExplainSpec [] Specification Bool
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "==." BaseW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "==." BaseW '[a, a] Bool hole
ctxt (ExplainSpec [[Char]]
es Specification Bool
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "==." BaseW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "==." BaseW '[a, a] Bool hole
_ Specification Bool
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "==." BaseW '[a, a] Bool hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BaseW "==." '[a, a] Bool
EqualW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. Eq a => BaseW "==." '[a, a] Bool
EqualW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "==." '[a, a] Bool
EqualW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. Eq a => BaseW "==." '[a, a] Bool
EqualW (forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "==." '[a, a] Bool
EqualW (Ctx hole y
HOLE :<> (a
s :: a) :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. a -> Specification a
equalSpec a
s; Bool
False -> forall a. HasSpec a => a -> Specification a
notEqualSpec a
s
propagate (Context BaseW "==." '[a, a] Bool
EqualW ((a
s :: a) :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. a -> Specification a
equalSpec a
s; Bool
False -> forall a. HasSpec a => a -> Specification a
notEqualSpec a
s
propagate ctx :: Context "==." BaseW '[a, a] Bool hole
ctx@(Context BaseW "==." '[a, a] Bool
_ CList 'Pre '[a, a] hole y
_) Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for EqualW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "==." BaseW '[a, a] Bool hole
ctx)
rewriteRules :: (TypeList '[a, a], Typeable '[a, a], HasSpec Bool,
All HasSpec '[a, a]) =>
BaseW "==." '[a, a] Bool
-> List Term '[a, a]
-> Evidence (AppRequires "==." BaseW '[a, a] Bool)
-> Maybe (Term Bool)
rewriteRules BaseW "==." '[a, a] Bool
EqualW (Term a
t :> Term a
t' :> List Term as1
Nil) Evidence (AppRequires "==." BaseW '[a, a] Bool)
Evidence
| Term a
t forall a. Eq a => a -> a -> Bool
== Term a
t' = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => a -> Term a
lit Bool
True
| Bool
otherwise = forall a. Maybe a
Nothing
saturate :: BaseW "==." '[a, a] Bool -> List Term '[a, a] -> [Pred]
saturate BaseW "==." '[a, a] Bool
EqualW (FromGeneric (InjLeft Term a
_) :> Term a
t :> List Term as1
Nil) = [forall a. HasSpec a => Term a -> TypeSpec a -> Pred
toPreds Term a
t (forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec forall a. Maybe a
Nothing forall a. Specification a
TrueSpec (forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"saturatePred")))]
saturate BaseW "==." '[a, a] Bool
EqualW (FromGeneric (InjRight Term b
_) :> Term a
t :> List Term as1
Nil) = [forall a. HasSpec a => Term a -> TypeSpec a -> Pred
toPreds Term a
t (forall a b.
Maybe (Int, Int)
-> Specification a -> Specification b -> SumSpec a b
SumSpec forall a. Maybe a
Nothing (forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"saturatePred")) forall a. Specification a
TrueSpec)]
saturate BaseW "==." '[a, a] Bool
_ List Term '[a, a]
_ = []
infix 4 ==.
(==.) :: HasSpec a => Term a -> Term a -> Term Bool
==. :: forall a. HasSpec a => Term a -> Term a -> Term Bool
(==.) = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a. Eq a => BaseW "==." '[a, a] Bool
EqualW
toPredsNumSpec ::
OrdLike n =>
Term n ->
NumSpec n ->
Pred
toPredsNumSpec :: forall n. OrdLike n => Term n -> NumSpec n -> Pred
toPredsNumSpec Term n
v (NumSpecInterval Maybe n
ml Maybe n
mu) =
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall a b. (a -> b) -> a -> b
$
[forall p. IsPred p => p -> Pred
assert forall a b. (a -> b) -> a -> b
$ forall a. Literal a => a -> Term a
Lit n
l forall a. OrdLike a => Term a -> Term a -> Term Bool
<=. Term n
v | n
l <- forall a. Maybe a -> [a]
maybeToList Maybe n
ml]
forall a. [a] -> [a] -> [a]
++ [forall p. IsPred p => p -> Pred
assert forall a b. (a -> b) -> a -> b
$ Term n
v forall a. OrdLike a => Term a -> Term a -> Term Bool
<=. forall a. Literal a => a -> Term a
Lit n
u | n
u <- forall a. Maybe a -> [a]
maybeToList Maybe n
mu]
instance HasSpec Integer where
type TypeSpec Integer = NumSpec Integer
emptySpec :: TypeSpec Integer
emptySpec = forall a. Ord a => NumSpec a
emptyNumSpec
combineSpec :: TypeSpec Integer -> TypeSpec Integer -> Specification Integer
combineSpec = forall n.
(HasSpec n, Ord n, TypeSpec n ~ NumSpec n) =>
NumSpec n -> NumSpec n -> Specification n
combineNumSpec
genFromTypeSpec :: forall (m :: * -> *).
(HasCallStack, MonadGenError m) =>
TypeSpec Integer -> GenT m Integer
genFromTypeSpec = forall (m :: * -> *) n.
(MonadGenError m, Show n, Random n, Ord n, Num n,
MaybeBounded n) =>
NumSpec n -> GenT m n
genFromNumSpec
shrinkWithTypeSpec :: TypeSpec Integer -> Integer -> [Integer]
shrinkWithTypeSpec = forall n. Arbitrary n => NumSpec n -> n -> [n]
shrinkWithNumSpec
conformsTo :: HasCallStack => Integer -> TypeSpec Integer -> Bool
conformsTo = forall n. Ord n => n -> NumSpec n -> Bool
conformsToNumSpec
toPreds :: Term Integer -> TypeSpec Integer -> Pred
toPreds = forall n. OrdLike n => Term n -> NumSpec n -> Pred
toPredsNumSpec
cardinalTypeSpec :: TypeSpec Integer -> Specification Integer
cardinalTypeSpec = forall n.
(Integral n, MaybeBounded n) =>
NumSpec n -> Specification Integer
cardinalNumSpec
guardTypeSpec :: [[Char]] -> TypeSpec Integer -> Specification Integer
guardTypeSpec = forall n.
(Ord n, HasSpec n, TypeSpec n ~ NumSpec n) =>
[[Char]] -> NumSpec n -> Specification n
guardNumSpec
instance
OrdLike a =>
Logic "<=." NumOrdW '[a, a] Bool
where
propagate :: forall hole.
Context "<=." NumOrdW '[a, a] Bool hole
-> Specification Bool -> Specification hole
propagate Context "<=." NumOrdW '[a, a] Bool hole
ctxt (ExplainSpec [] Specification Bool
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "<=." NumOrdW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "<=." NumOrdW '[a, a] Bool hole
ctxt (ExplainSpec [[Char]]
es Specification Bool
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "<=." NumOrdW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "<=." NumOrdW '[a, a] Bool hole
_ Specification Bool
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "<=." NumOrdW '[a, a] Bool hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context NumOrdW "<=." '[a, a] Bool
LessOrEqualW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. OrdLike a => NumOrdW "<=." '[a, a] Bool
LessOrEqualW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context NumOrdW "<=." '[a, a] Bool
LessOrEqualW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. OrdLike a => NumOrdW "<=." '[a, a] Bool
LessOrEqualW (forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context NumOrdW "<=." '[a, a] Bool
LessOrEqualW (Ctx hole y
HOLE :<> a
l :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. OrdLike a => a -> Specification a
leqSpec a
l; Bool
False -> forall a. OrdLike a => a -> Specification a
gtSpec a
l
propagate (Context NumOrdW "<=." '[a, a] Bool
LessOrEqualW (a
l :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. OrdLike a => a -> Specification a
geqSpec a
l; Bool
False -> forall a. OrdLike a => a -> Specification a
ltSpec a
l
propagate Context "<=." NumOrdW '[a, a] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for LessOrEqualW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "<=." NumOrdW '[a, a] Bool hole
ctx)
infixr 4 <=.
(<=.) :: forall a. OrdLike a => Term a -> Term a -> Term Bool
<=. :: forall a. OrdLike a => Term a -> Term a -> Term Bool
(<=.) = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a. OrdLike a => NumOrdW "<=." '[a, a] Bool
LessOrEqualW
instance
OrdLike a =>
Logic "<." NumOrdW '[a, a] Bool
where
propagate :: forall hole.
Context "<." NumOrdW '[a, a] Bool hole
-> Specification Bool -> Specification hole
propagate Context "<." NumOrdW '[a, a] Bool hole
ctxt (ExplainSpec [] Specification Bool
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "<." NumOrdW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "<." NumOrdW '[a, a] Bool hole
ctxt (ExplainSpec [[Char]]
es Specification Bool
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "<." NumOrdW '[a, a] Bool hole
ctxt Specification Bool
s
propagate Context "<." NumOrdW '[a, a] Bool hole
_ Specification Bool
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "<." NumOrdW '[a, a] Bool hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context NumOrdW "<." '[a, a] Bool
LessW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. OrdLike a => NumOrdW "<." '[a, a] Bool
LessW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context NumOrdW "<." '[a, a] Bool
LessW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var Bool
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a. OrdLike a => NumOrdW "<." '[a, a] Bool
LessW (forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var Bool
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context NumOrdW "<." '[a, a] Bool
LessW (Ctx hole y
HOLE :<> a
l :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. OrdLike a => a -> Specification a
ltSpec a
l; Bool
False -> forall a. OrdLike a => a -> Specification a
geqSpec a
l
propagate (Context NumOrdW "<." '[a, a] Bool
LessW (a
l :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall a.
HasSpec a =>
Specification Bool -> (Bool -> Specification a) -> Specification a
caseBoolSpec Specification Bool
spec forall a b. (a -> b) -> a -> b
$ \case Bool
True -> forall a. OrdLike a => a -> Specification a
gtSpec a
l; Bool
False -> forall a. OrdLike a => a -> Specification a
leqSpec a
l
propagate Context "<." NumOrdW '[a, a] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for LessW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "<." NumOrdW '[a, a] Bool hole
ctx)
infixr 4 <.
(<.) :: forall a. OrdLike a => Term a -> Term a -> Term Bool
<. :: forall a. OrdLike a => Term a -> Term a -> Term Bool
(<.) = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a. OrdLike a => NumOrdW "<." '[a, a] Bool
LessW
instance
OrdLike a =>
Logic ">=." NumOrdW '[a, a] Bool
where
propagate :: forall hole.
Context ">=." NumOrdW '[a, a] Bool hole
-> Specification Bool -> Specification hole
propagate (Context NumOrdW ">=." '[a, a] Bool
GreaterOrEqualW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate (forall (dom :: [*]) rng (t :: Symbol -> [*] -> * -> *)
(s :: Symbol) hole y.
(All HasSpec dom, HasSpec rng) =>
t s dom rng -> CList 'Pre dom hole y -> Context s t dom rng hole
Context forall a. OrdLike a => NumOrdW "<=." '[a, a] Bool
LessOrEqualW (a
x forall a (as1 :: [*]) hole y.
Literal a =>
a -> CList 'Pre as1 hole y -> CList 'Pre (a : as1) hole y
:|> forall hole. HasSpec hole => Ctx hole hole
HOLE forall y hole (as1 :: [*]).
HasSpec y =>
Ctx hole y
-> (forall i j. CList 'Post as1 i j) -> CList 'Pre (y : as1) hole y
:<> forall hole y. CList 'Post '[] hole y
End)) Specification Bool
spec
propagate (Context NumOrdW ">=." '[a, a] Bool
GreaterOrEqualW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate (forall (dom :: [*]) rng (t :: Symbol -> [*] -> * -> *)
(s :: Symbol) hole y.
(All HasSpec dom, HasSpec rng) =>
t s dom rng -> CList 'Pre dom hole y -> Context s t dom rng hole
Context forall a. OrdLike a => NumOrdW "<=." '[a, a] Bool
LessOrEqualW (forall hole. HasSpec hole => Ctx hole hole
HOLE forall y hole (as1 :: [*]).
HasSpec y =>
Ctx hole y
-> (forall i j. CList 'Post as1 i j) -> CList 'Pre (y : as1) hole y
:<> a
x forall a (as1 :: [*]) hole y.
Literal a =>
a -> CList 'Post as1 hole y -> CList 'Post (a : as1) hole y
:<| forall hole y. CList 'Post '[] hole y
End)) Specification Bool
spec
propagate Context ">=." NumOrdW '[a, a] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for GreaterOrEqualW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context ">=." NumOrdW '[a, a] Bool hole
ctx)
infixr 4 >=.
(>=.) :: forall a. OrdLike a => Term a -> Term a -> Term Bool
>=. :: forall a. OrdLike a => Term a -> Term a -> Term Bool
(>=.) = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a. OrdLike a => NumOrdW ">=." '[a, a] Bool
GreaterOrEqualW
instance
OrdLike a =>
Logic ">." NumOrdW '[a, a] Bool
where
propagate :: forall hole.
Context ">." NumOrdW '[a, a] Bool hole
-> Specification Bool -> Specification hole
propagate (Context NumOrdW ">." '[a, a] Bool
GreaterW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) Specification Bool
spec =
forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate (forall (dom :: [*]) rng (t :: Symbol -> [*] -> * -> *)
(s :: Symbol) hole y.
(All HasSpec dom, HasSpec rng) =>
t s dom rng -> CList 'Pre dom hole y -> Context s t dom rng hole
Context forall a. OrdLike a => NumOrdW "<." '[a, a] Bool
LessW (a
x forall a (as1 :: [*]) hole y.
Literal a =>
a -> CList 'Pre as1 hole y -> CList 'Pre (a : as1) hole y
:|> forall hole. HasSpec hole => Ctx hole hole
HOLE forall y hole (as1 :: [*]).
HasSpec y =>
Ctx hole y
-> (forall i j. CList 'Post as1 i j) -> CList 'Pre (y : as1) hole y
:<> forall hole y. CList 'Post '[] hole y
End)) Specification Bool
spec
propagate (Context NumOrdW ">." '[a, a] Bool
GreaterW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) Specification Bool
spec =
forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate (forall (dom :: [*]) rng (t :: Symbol -> [*] -> * -> *)
(s :: Symbol) hole y.
(All HasSpec dom, HasSpec rng) =>
t s dom rng -> CList 'Pre dom hole y -> Context s t dom rng hole
Context forall a. OrdLike a => NumOrdW "<." '[a, a] Bool
LessW (forall hole. HasSpec hole => Ctx hole hole
HOLE forall y hole (as1 :: [*]).
HasSpec y =>
Ctx hole y
-> (forall i j. CList 'Post as1 i j) -> CList 'Pre (y : as1) hole y
:<> a
x forall a (as1 :: [*]) hole y.
Literal a =>
a -> CList 'Post as1 hole y -> CList 'Post (a : as1) hole y
:<| forall hole y. CList 'Post '[] hole y
End)) Specification Bool
spec
propagate Context ">." NumOrdW '[a, a] Bool hole
ctx Specification Bool
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for GreaterW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context ">." NumOrdW '[a, a] Bool hole
ctx)
infixr 4 >.
(>.) :: forall a. OrdLike a => Term a -> Term a -> Term Bool
>. :: forall a. OrdLike a => Term a -> Term a -> Term Bool
(>.) = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a. OrdLike a => NumOrdW ">." '[a, a] Bool
GreaterW
simplifySpec :: HasSpec a => Specification a -> Specification a
simplifySpec :: forall a. HasSpec a => Specification a -> Specification a
simplifySpec Specification a
spec = case 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 forall a. HasCallStack => GE (Specification a) -> Specification a
fromGESpec forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a -> m a
explain
(forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"\nWhile calling simplifySpec on var " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Var a
x forall a. [a] -> [a] -> [a]
++ [Char]
"\noptP=\n" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Pred
optP forall a. [a] -> [a] -> [a]
++ [Char]
"\n"))
(forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
optP)
MemberSpec NonEmpty a
xs -> forall a. NonEmpty a -> Specification a
MemberSpec NonEmpty a
xs
ErrorSpec NonEmpty [Char]
es -> forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
es
TypeSpec TypeSpec a
ts [a]
cant -> forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec TypeSpec a
ts [a]
cant
Specification a
TrueSpec -> forall a. Specification a
TrueSpec
ExplainSpec [[Char]]
es Specification a
s -> forall a. [[Char]] -> Specification a -> Specification a
explainSpecOpt [[Char]]
es (forall a. HasSpec a => Specification a -> Specification a
simplifySpec Specification a
s)
ifElse :: (IsPred p, IsPred q) => Term Bool -> p -> q -> Pred
ifElse :: forall p q. (IsPred p, IsPred q) => Term Bool -> p -> q -> Pred
ifElse Term Bool
b p
p q
q = forall p. IsPred p => Term Bool -> p -> Pred
whenTrue Term Bool
b p
p forall a. Semigroup a => a -> a -> a
<> forall p. IsPred p => Term Bool -> p -> Pred
whenTrue (Term Bool -> Term Bool
not_ Term Bool
b) q
q
whenTrue :: forall p. IsPred p => Term Bool -> p -> Pred
whenTrue :: forall p. IsPred p => Term Bool -> p -> Pred
whenTrue (Lit Bool
True) (forall p. IsPred p => p -> Pred
toPred -> Pred
p) = Pred
p
whenTrue (Lit Bool
False) p
_ = Pred
TruePred
whenTrue Term Bool
b (forall p. IsPred p => p -> Pred
toPred -> FalsePred {}) = forall p. IsPred p => p -> Pred
assert (Term Bool -> Term Bool
not_ Term Bool
b)
whenTrue Term Bool
_ (forall p. IsPred p => p -> Pred
toPred -> Pred
TruePred) = Pred
TruePred
whenTrue Term Bool
b (forall p. IsPred p => p -> Pred
toPred -> Pred
p) = HasSpec Bool => Term Bool -> Pred -> Pred
When Term 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 <- forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
x' = forall a. a -> Maybe a
Just Term a
t'
| V Var a
x' <- Term a
t', Just a :~: a
Refl <- forall a a'.
(Typeable a, Typeable a') =>
Var a -> Var a' -> Maybe (a :~: a')
eqVar Var a
x Var a
x' = forall a. a -> Maybe a
Just Term a
t
pinnedBy Var a
x (And [Pred]
ps) = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. [Maybe a] -> [a]
catMaybes forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy Var a
x) [Pred]
ps
pinnedBy Var a
_ Pred
_ = forall a. Maybe a
Nothing
optimisePred :: Pred -> Pred
optimisePred :: Pred -> Pred
optimisePred Pred
p =
Pred -> Pred
simplifyPred
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasSpec Bool => Pred -> Pred
letSubexpressionElimination
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
letFloating
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
aggressiveInlining
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
simplifyPred
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) = forall w a. Writer w a -> (a, w)
runWriter forall a b. (a -> b) -> a -> b
$ FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go (forall a. HasVariables a => a -> FreeVars
freeVars Pred
pred) [] Pred
pred
underBinder :: FreeVars -> Var a -> p -> FreeVars
underBinder FreeVars
fvs Var a
x p
p = FreeVars
fvs forall (t :: * -> *). Foldable t => FreeVars -> t Name -> FreeVars
`without` [forall a. HasSpec a => Var a -> Name
Name Var a
x] forall a. Semigroup a => a -> a -> a
<> Name -> Int -> FreeVars
singleton (forall a. HasSpec a => Var a -> Name
Name Var a
x) (forall a. HasVariables a => Name -> a -> Int
countOf (forall a. HasSpec a => Var a -> Name
Name Var a
x) p
p)
underBinderSub :: Subst -> Var a -> Subst
underBinderSub Subst
sub Var a
x =
[ Var a
x' forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= Term a
t
| Var a
x' := Term a
t <- Subst
sub
, forall a. Maybe a -> Bool
isNothing forall a b. (a -> b) -> a -> b
$ 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 forall a. HasSpec a => Var a -> Pred -> Binder a
:->) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go (forall {a} {p}.
(HasSpec a, HasVariables p) =>
FreeVars -> Var a -> p -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (forall {a}. Typeable a => Subst -> Var a -> Subst
underBinderSub Subst
sub Var a
x) Pred
p
onlyUsedUniquely :: Name -> Pred -> Bool
onlyUsedUniquely Name
n Pred
p = case Pred
p of
Assert Term Bool
t
| Name
n forall a. HasVariables a => Name -> a -> Bool
`appearsIn` Term Bool
t -> forall a. Set a -> Int
Set.size (forall a. HasVariables a => a -> Set Name
freeVarSet Term Bool
t) forall a. Eq a => a -> a -> Bool
== Int
1
| Bool
otherwise -> Bool
True
And [Pred]
ps -> forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Name -> Pred -> Bool
onlyUsedUniquely Name
n) [Pred]
ps
Pred
_ -> Bool
False
go :: FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go FreeVars
fvs Subst
sub Pred
pred2 = case Pred
pred2 of
ElemPred Bool
bool Term a
t NonEmpty a
xs
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term a
t)
, Lit a
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Bool -> Term a -> NonEmpty a -> Pred
ElemPred Bool
bool (forall a. Literal a => a -> Term a
Lit a
a) NonEmpty a
xs
| Bool
otherwise -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Bool -> Term a -> NonEmpty a -> Pred
ElemPred Bool
bool Term a
t NonEmpty a
xs
Subst Var a
x Term a
t Pred
p -> FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go FreeVars
fvs Subst
sub (forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p)
Reifies Term b
t' Term a
t a -> b
f
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term a
t)
, Lit a
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b.
(HasSpec a, HasSpec b) =>
Term b -> Term a -> (a -> b) -> Pred
Reifies Term b
t' (forall a. Literal a => a -> Term a
Lit a
a) a -> b
f
| Bool
otherwise -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b.
(HasSpec a, HasSpec b) =>
Term b -> Term a -> (a -> b) -> Pred
Reifies Term b
t' Term a
t a -> b
f
ForAll Term t
set Binder a
b
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term t
set)
, Lit t
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term t
set -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall a. a -> Binder a -> Pred
`unBind` Binder a
b) (forall t e. Forallable t e => t -> [e]
forAllToList t
a)
| Bool
otherwise -> forall t a.
(Forallable t a, HasSpec t, HasSpec a) =>
Term t -> Binder a -> Pred
ForAll Term t
set forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub Binder a
b
Case Term (SumOver as)
t List (Weighted Binder) as
bs
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term (SumOver as)
t)
, Lit SumOver as
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term (SumOver as)
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (as :: [*]) r.
SumOver as
-> List Binder as
-> (forall a. HasSpec a => Var a -> a -> Pred -> r)
-> r
runCaseOn SumOver as
a (forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList forall {k} (f :: k -> *) (a :: k). Weighted f a -> f a
thing List (Weighted Binder) as
bs) forall a b. (a -> b) -> a -> b
$ \Var a
x a
v Pred
p -> Env -> Pred -> Pred
substPred (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 Binder) as1
Nil) <- List (Weighted Binder) as
bs -> do
let t' :: Term (SumOver as)
t' = forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term (SumOver as)
t
Pred
p' <- FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go (forall {a} {p}.
(HasSpec a, HasVariables p) =>
FreeVars -> Var a -> p -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (Var a
x forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= Term (SumOver as)
t' forall a. a -> [a] -> [a]
: Subst
sub) Pred
p
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (as :: [*]).
HasSpec (SumOver as) =>
Term (SumOver as) -> List (Weighted Binder) as -> Pred
Case Term (SumOver as)
t (forall {k} (f :: k -> *) (a :: k). Maybe Int -> f a -> Weighted f a
Weighted Maybe Int
w (Var a
x forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
p') forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)
| Bool
otherwise -> forall (as :: [*]).
HasSpec (SumOver as) =>
Term (SumOver as) -> List (Weighted Binder) as -> Pred
Case Term (SumOver as)
t forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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 (forall {k} (m :: * -> *) (f :: k -> *) (a :: k) (g :: k -> *).
Applicative m =>
(f a -> m (g a)) -> Weighted f a -> m (Weighted g a)
traverseWeighted forall a b. (a -> b) -> a -> b
$ forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub) List (Weighted Binder) as
bs
When Term Bool
b Pred
tp
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term Bool
b)
, Lit Bool
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term Bool
b -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ if Bool
a then Pred
tp else Pred
TruePred
| Bool
otherwise -> forall p. IsPred p => Term Bool -> p -> Pred
whenTrue Term Bool
b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go FreeVars
fvs Subst
sub Pred
tp
Let Term a
t (Var a
x :-> Pred
p)
| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Name
n -> Name -> FreeVars -> Int
count Name
n FreeVars
fvs forall a. Ord a => a -> a -> Bool
<= Int
1) (forall a. HasVariables a => a -> Set Name
freeVarSet Term a
t) -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p
| Name -> Pred -> Bool
onlyUsedUniquely (forall a. HasSpec a => Var a -> Name
Name Var a
x) Pred
p -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Name
Name Var a
x forall a. HasVariables a => Name -> a -> Bool
`appearsIn` Pred
p -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
p
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term a
t)
, Lit a
a <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Binder a -> Pred
unBind a
a (Var a
x forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
p)
| Bool
otherwise -> forall a. Term a -> Binder a -> Pred
Let Term a
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Var a
x forall a. HasSpec a => Var a -> Pred -> Binder a
:->) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go (forall {a} {p}.
(HasSpec a, HasVariables p) =>
FreeVars -> Var a -> p -> FreeVars
underBinder FreeVars
fvs Var a
x Pred
p) (Var a
x forall a. HasSpec a => Var a -> Term a -> SubstEntry
:= Term a
t forall a. a -> [a] -> [a]
: Subst
sub) Pred
p
Exists (forall b. Term b -> b) -> GE a
k Binder a
b -> forall a. ((forall b. Term b -> b) -> GE a) -> Binder a -> Pred
Exists (forall b. Term b -> b) -> GE a
k forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FreeVars -> Subst -> Binder a -> Writer Any (Binder a)
goBinder FreeVars
fvs Subst
sub Binder a
b
And [Pred]
ps -> forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (FreeVars -> Subst -> Pred -> WriterT Any Identity Pred
go FreeVars
fvs Subst
sub) [Pred]
ps
Assert Term Bool
t
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term Bool
t)
, Lit Bool
b <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term Bool
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall p. IsPred p => p -> Pred
toPred Bool
b
| Bool
otherwise -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
GenHint Hint a
_ Term a
t
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term a
t)
, Lit {} <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
TruePred
| Bool
otherwise -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
DependsOn Term a
t Term b
t'
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term a
t)
, Lit {} <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term a
t -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Pred
TruePred
| Bool -> Bool
not (forall a. Term a -> Bool
isLit Term b
t')
, Lit {} <- forall a. Subst -> Term a -> Term a
substituteAndSimplifyTerm Subst
sub Term b
t' -> do
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ Bool -> Any
Any Bool
True
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Pred
TruePred
| Bool
otherwise -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Pred
TruePred -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
FalsePred {} -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Monitor {} -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Pred
pred2
Explain NonEmpty [Char]
es Pred
p -> NonEmpty [Char] -> Pred -> Pred
Explain NonEmpty [Char]
es forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FreeVars -> Subst -> Pred -> WriterT Any Identity 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 forall w a. Writer w a -> (a, w)
runWriter forall a b. (a -> b) -> a -> b
$ forall a. Subst -> Term a -> Writer Any (Term a)
substituteTerm' Subst
sub Term a
t of
(Term a
t', Any Bool
b)
| Bool
b -> 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 -> forall a. HasSpec a => Var a -> Term a
V Var a
v
Lit a
l -> forall a. Literal a => a -> Term a
Lit a
l
App (t sym dom a
f :: t sym bs a) (forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList forall a. Term a -> Term a
simplifyTerm -> List Term dom
ts)
| Just List Value dom
vs <- forall (as :: [*]). List Term as -> Maybe (List Value as)
fromLits List Term dom
ts -> forall a. Literal a => a -> Term a
Lit forall a b. (a -> b) -> a -> b
$ forall (ts :: [*]) (f :: * -> *) r.
TypeList ts =>
(forall a. f a -> a) -> FunTy ts r -> List f ts -> r
uncurryList_ forall a. Value a -> a
unValue (forall (t :: Symbol -> [*] -> * -> *) (s :: Symbol) (d :: [*]) r.
Semantics t =>
t s d r -> FunTy d r
semantics t sym dom a
f) List Value dom
vs
| Just Term a
t <- forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng.
(Logic s t dom rng, TypeList dom, Typeable dom, HasSpec rng,
All HasSpec dom) =>
t s dom rng
-> List Term dom
-> Evidence (AppRequires s t dom rng)
-> Maybe (Term rng)
rewriteRules @sym @t @bs @a t sym dom a
f List Term dom
ts (forall (c :: Constraint). c => Evidence c
Evidence @(AppRequires sym t bs a)) -> forall a. Term a -> Term a
simplifyTerm Term a
t
| Bool
otherwise -> forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App t sym dom a
f List Term dom
ts
simplifyPred :: Pred -> Pred
simplifyPred :: Pred -> Pred
simplifyPred = \case
GenHint Hint a
h Term a
t -> case forall a. Term a -> Term a
simplifyTerm Term a
t of
Lit {} -> Pred
TruePred
Term a
t' -> forall a. HasGenHint a => Hint a -> Term a -> Pred
GenHint Hint a
h Term a
t'
p :: Pred
p@(ElemPred Bool
bool Term a
t NonEmpty a
xs) -> case forall a. Term a -> Term a
simplifyTerm Term a
t of
Lit a
x -> case (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
TruePred
(Bool
True, Bool
False) -> NonEmpty [Char] -> Pred
FalsePred ([Char]
"notElemPred reduces to True" forall a. a -> [a] -> NonEmpty a
:| [forall a. Show a => a -> [Char]
show Pred
p])
(Bool
False, Bool
True) -> NonEmpty [Char] -> Pred
FalsePred ([Char]
"elemPred reduces to False" forall a. a -> [a] -> NonEmpty a
:| [forall a. Show a => a -> [Char]
show Pred
p])
(Bool
False, Bool
False) -> Pred
TruePred
Term a
t' -> forall a. HasSpec a => Bool -> Term a -> NonEmpty a -> Pred
ElemPred Bool
bool Term a
t' NonEmpty a
xs
Subst Var a
x Term a
t Pred
p -> Pred -> Pred
simplifyPred forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p
Assert Term Bool
t -> Term Bool -> Pred
Assert forall a b. (a -> b) -> a -> b
$ forall a. Term a -> Term a
simplifyTerm Term Bool
t
Reifies Term b
t' Term a
t a -> b
f -> case forall a. Term a -> Term a
simplifyTerm Term a
t of
Lit a
a ->
forall a. HasSpec a => Bool -> Term a -> NonEmpty a -> Pred
ElemPred Bool
True (forall a. Term a -> Term a
simplifyTerm Term b
t') (forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> b
f a
a))
Term a
t'' -> forall a b.
(HasSpec a, HasSpec b) =>
Term b -> Term a -> (a -> b) -> Pred
Reifies (forall a. Term a -> Term a
simplifyTerm Term b
t') Term a
t'' a -> b
f
ForAll (Term t
ts :: Term t) (Binder a
b :: Binder a) -> case forall a. Term a -> Term a
simplifyTerm Term t
ts of
Lit t
as -> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall a. a -> Binder a -> Pred
`unBind` Binder a
b) (forall t e. Forallable t e => t -> [e]
forAllToList t
as)
Term t
set' -> case forall a. Binder a -> Binder a
simplifyBinder Binder a
b of
Var a
_ :-> Pred
TruePred -> Pred
TruePred
Binder a
b' -> forall t a.
(Forallable t a, HasSpec t, HasSpec a) =>
Term t -> Binder a -> Pred
ForAll Term t
set' Binder a
b'
DependsOn Term a
_ Lit {} -> Pred
TruePred
DependsOn Lit {} Term b
_ -> Pred
TruePred
DependsOn Term a
x Term b
y -> forall a b. (HasSpec a, HasSpec b) => Term a -> Term b -> Pred
DependsOn Term a
x Term b
y
Case Term (SumOver as)
t List (Weighted Binder) as
bs -> forall (as :: [*]).
HasSpec (SumOver as) =>
Term (SumOver as) -> List (Weighted Binder) as -> Pred
mkCase (forall a. Term a -> Term a
simplifyTerm Term (SumOver as)
t) (forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList (forall {k1} {k2} (f :: k1 -> *) (a :: k1) (g :: k2 -> *) (b :: k2).
(f a -> g b) -> Weighted f a -> Weighted g b
mapWeighted forall a. Binder a -> Binder a
simplifyBinder) List (Weighted Binder) as
bs)
When Term Bool
b Pred
p -> forall p. IsPred p => Term Bool -> p -> Pred
whenTrue (forall a. Term a -> Term a
simplifyTerm Term Bool
b) (Pred -> Pred
simplifyPred Pred
p)
Pred
TruePred -> Pred
TruePred
FalsePred NonEmpty [Char]
es -> NonEmpty [Char] -> Pred
FalsePred NonEmpty [Char]
es
And [Pred]
ps -> forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ([Pred] -> [Pred]
simplifyPreds [Pred]
ps)
Let Term a
t Binder a
b -> case forall a. Term a -> Term a
simplifyTerm Term a
t of
t' :: Term a
t'@App {} -> forall a. Term a -> Binder a -> Pred
Let Term a
t' (forall a. Binder a -> Binder a
simplifyBinder Binder a
b)
Term a
t' | Var a
x :-> Pred
p <- Binder a
b -> Pred -> Pred
simplifyPred forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t' Pred
p
Exists (forall b. Term b -> b) -> GE a
k Binder a
b -> case forall a. Binder a -> Binder a
simplifyBinder Binder a
b of
Var a
_ :-> Pred
TruePred -> Pred
TruePred
Var a
x :-> Pred
p | Just Term a
t <- forall a. HasSpec a => Var a -> Pred -> Maybe (Term a)
pinnedBy Var a
x Pred
p -> Pred -> Pred
simplifyPred forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p
Binder a
b' -> forall a. ((forall b. Term b -> b) -> GE a) -> Binder a -> Pred
Exists (forall b. Term b -> b) -> GE a
k Binder a
b'
Monitor {} -> Pred
TruePred
Explain NonEmpty [Char]
es Pred
p -> NonEmpty [Char] -> Pred -> Pred
explanation NonEmpty [Char]
es forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
p
simplifyPreds :: [Pred] -> [Pred]
simplifyPreds :: [Pred] -> [Pred]
simplifyPreds = [Pred] -> [Pred] -> [Pred]
go [] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map Pred -> Pred
simplifyPred
where
go :: [Pred] -> [Pred] -> [Pred]
go [Pred]
acc [] = forall a. [a] -> [a]
reverse [Pred]
acc
go [Pred]
_ (FalsePred NonEmpty [Char]
err : [Pred]
_) = [NonEmpty [Char] -> Pred
FalsePred NonEmpty [Char]
err]
go [Pred]
acc (Pred
TruePred : [Pred]
ps) = [Pred] -> [Pred] -> [Pred]
go [Pred]
acc [Pred]
ps
go [Pred]
acc (Pred
p : [Pred]
ps) = [Pred] -> [Pred] -> [Pred]
go (Pred
p forall a. a -> [a] -> [a]
: [Pred]
acc) [Pred]
ps
simplifyBinder :: Binder a -> Binder a
simplifyBinder :: forall a. Binder a -> Binder a
simplifyBinder (Var a
x :-> Pred
p) = Var a
x forall a. HasSpec a => Var a -> Pred -> Binder 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 = forall {a}. GE (Specification a) -> GE (Specification a)
localGESpec forall a b. (a -> b) -> a -> b
$ case Pred -> Pred
simplifyPred Pred
pred3 of
ElemPred Bool
True Term a
t NonEmpty a
xs -> forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. NonEmpty a -> Specification a
MemberSpec NonEmpty a
xs) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term a
t
ElemPred Bool
False (Term a
t :: Term b) NonEmpty a
xs -> 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) (forall a. NonEmpty a -> [a]
NE.toList NonEmpty a
xs)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term a
t
Monitor {} -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
GenHint Hint a
h Term a
t -> forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. HasGenHint a => Hint a -> Specification a
giveHint Hint a
h) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term a
t
Subst Var a
x' Term a
t Pred
p' -> forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x (forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x' Term a
t Pred
p')
Pred
TruePred -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
FalsePred NonEmpty [Char]
es -> forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genError NonEmpty [Char]
es
And [Pred]
ps -> do
Specification a
spec <- forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x) [Pred]
ps
case Specification a
spec of
ExplainSpec [[Char]]
es (SuspendedSpec Var a
y Pred
ps') -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. [[Char]] -> Specification a -> Specification a
explainSpecOpt [[Char]]
es (forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
y forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
ps')
SuspendedSpec Var a
y Pred
ps' -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
y forall a b. (a -> b) -> a -> b
$ Pred -> Pred
simplifyPred Pred
ps'
Specification a
s -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Specification a
s
Let Term a
t Binder a
b -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
x (forall a. Term a -> Binder a -> Pred
Let Term a
t Binder a
b)
Exists (forall b. Term b -> b) -> GE a
k Binder a
b -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
x (forall a. ((forall b. Term b -> b) -> GE a) -> Binder a -> Pred
Exists (forall b. Term b -> b) -> GE a
k Binder a
b)
Assert (Lit Bool
True) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
Assert (Lit Bool
False) -> forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
genError1 (forall a. Show a => a -> [Char]
show Pred
pred3)
Assert (Elem Term a
_ (Lit [])) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"Empty list in ElemPat", forall a. Show a => a -> [Char]
show Pred
pred3]))
Assert (Elem Term a
t (Lit (a
y : [a]
ys))) -> forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. NonEmpty a -> Specification a
MemberSpec (a
y forall a. a -> [a] -> NonEmpty a
:| [a]
ys)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term a
t
Assert Term Bool
t -> forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. a -> Specification a
equalSpec Bool
True) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term Bool
t
ForAll (Lit t
s) Binder a
b -> forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\a
val -> forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x forall a b. (a -> b) -> a -> b
$ forall a. a -> Binder a -> Pred
unBind a
val Binder a
b) (forall t e. Forallable t e => t -> [e]
forAllToList t
s)
ForAll Term t
t Binder a
b -> do
Specification a
bSpec <- forall a. Binder a -> GE (Specification a)
computeSpecBinderSimplified Binder a
b
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall t e.
(Forallable t e, HasSpec t, HasSpec e) =>
Specification e -> Specification t
fromForAllSpec Specification a
bSpec) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term t
t
Case (Lit SumOver as
val) List (Weighted Binder) as
bs -> forall (as :: [*]) r.
SumOver as
-> List Binder as
-> (forall a. HasSpec a => Var a -> a -> Pred -> r)
-> r
runCaseOn SumOver as
val (forall {k} (f :: k -> *) (g :: k -> *) (as :: [k]).
(forall (a :: k). f a -> g a) -> List f as -> List g as
mapList forall {k} (f :: k -> *) (a :: k). Weighted f a -> f a
thing List (Weighted Binder) as
bs) forall a b. (a -> b) -> a -> b
$ \Var a
va a
vaVal Pred
psa -> forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x (Env -> Pred -> Pred
substPred (forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
va a
vaVal) Pred
psa)
Case Term (SumOver as)
t List (Weighted Binder) as
branches -> do
List (Weighted Specification) as
branchSpecs <- 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 (forall {k} (m :: * -> *) (f :: k -> *) (a :: k) (g :: k -> *).
Applicative m =>
(f a -> m (g a)) -> Weighted f a -> m (Weighted g a)
traverseWeighted forall a. Binder a -> GE (Specification a)
computeSpecBinderSimplified) List (Weighted Binder) as
branches
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
caseSpec (forall a. a -> Maybe a
Just (forall {k} (t :: k). Typeable t => [Char]
showType @a)) List (Weighted Specification) as
branchSpecs) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term (SumOver as)
t
When (Lit Bool
b) Pred
tp -> if Bool
b then forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
tp else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Specification a
TrueSpec
When {} -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
x Pred
pred3
Reifies (Lit b
a) (Lit a
val) a -> b
f
| a -> b
f a
val forall a. Eq a => a -> a -> Bool
== b
a -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Specification a
TrueSpec
| Bool
otherwise ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"Value does not reify to literal: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
val forall a. [a] -> [a] -> [a]
++ [Char]
" -/> " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show b
a])
Reifies Term b
t' (Lit a
val) a -> b
f ->
forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec (forall a. a -> Specification a
equalSpec (a -> b
f a
val)) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
x Term b
t'
Reifies Lit {} Term a
_ a -> b
_ ->
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalError forall a b. (a -> b) -> a -> b
$ forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"Dependency error in computeSpec: Reifies", [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Pred
pred3]
Explain NonEmpty [Char]
es Pred
p -> do
Specification a
s <- forall a. [[Char]] -> GE a -> GE a
pushGE (forall a. NonEmpty a -> [a]
NE.toList NonEmpty [Char]
es) (forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
p)
case Specification a
s of
SuspendedSpec Var a
x2 Pred
p2 -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Pred -> Specification a
SuspendedSpec Var a
x2 (NonEmpty [Char] -> Pred -> Pred
explanation NonEmpty [Char]
es Pred
p2)
Specification a
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec NonEmpty [Char]
es Specification a
s
DependsOn {} ->
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalError forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"The impossible happened in computeSpec: DependsOn"
, [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Var a
x
, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (forall a ann. Pretty a => a -> Doc ann
pretty Pred
pred3)
]
Reifies {} ->
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalError forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList
[[Char]
"The impossible happened in computeSpec: Reifies", [Char]
" " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Var a
x, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall ann. Int -> Doc ann -> Doc ann
indent Int
2 (forall a ann. Pretty a => a -> Doc ann
pretty Pred
pred3)]
where
localGESpec :: GE (Specification a) -> GE (Specification a)
localGESpec GE (Specification a)
ge = case GE (Specification a)
ge of
(GenError NonEmpty (NonEmpty [Char])
xs) -> forall a. a -> GE a
Result forall a b. (a -> b) -> a -> b
$ forall a. NonEmpty [Char] -> Specification a
ErrorSpec (NonEmpty (NonEmpty [Char]) -> NonEmpty [Char]
catMessageList NonEmpty (NonEmpty [Char])
xs)
(FatalError NonEmpty (NonEmpty [Char])
es) -> forall a. NonEmpty (NonEmpty [Char]) -> GE a
FatalError NonEmpty (NonEmpty [Char])
es
(Result Specification a
v) -> forall a. a -> GE a
Result Specification 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 = 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) = 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) = forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpecSimplified Var a
x Pred
p
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
_)) = forall a. IsString a => [Char] -> a
fromString (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)) = forall a. IsString a => [Char] -> a
fromString (forall a. Show a => a -> [Char]
show Int
x)
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
| forall (as2 :: [*]). List (Weighted Specification) as2 -> Bool
allBranchesFail List (Weighted Specification) as
ss =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec
( forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"When simplifying SumSpec, all branches in a caseOn" forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
sumType Maybe [Char]
tString forall a. [a] -> [a] -> [a]
++ [Char]
" simplify to False."
, forall a. Show a => a -> [Char]
show Specification (SumOver as)
spec
]
)
| Bool
True = Specification (SumOver as)
spec
where
spec :: Specification (SumOver as)
spec = 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 = forall a. HasCallStack => [Char] -> a
error [Char]
"The impossible happened in allBranchesFail"
allBranchesFail (Weighted Maybe Int
_ Specification a
s :> List (Weighted Specification) as1
Nil) = 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
_)) = forall a. Specification a -> Bool
isErrorLike Specification a
s Bool -> Bool -> 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 = forall a. HasCallStack => [Char] -> a
error [Char]
"The impossible happened in caseSpec"
loop Maybe [Char]
_ (Weighted Specification a
s :> List (Weighted Specification) as1
Nil) = forall {k} (f :: k -> *) (a :: k). 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) =
(forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec forall a b. (a -> b) -> a -> b
$ forall a b.
Maybe [Char]
-> Maybe (Int, Int)
-> Specification a
-> Specification b
-> SumSpec a b
SumSpecRaw Maybe [Char]
mTypeString Maybe (Int, Int)
theWeights (forall {k} (f :: k -> *) (a :: k). Weighted f a -> f a
thing Weighted Specification a
s) (forall (as :: [*]).
HasSpec (SumOver as) =>
Maybe [Char]
-> List (Weighted Specification) as -> Specification (SumOver as)
loop forall a. Maybe a
Nothing List (Weighted Specification) as1
ss1))
where
theWeights :: Maybe (Int, Int)
theWeights =
case (forall {k} (f :: k -> *) (a :: k). Weighted f a -> Maybe Int
weight Weighted Specification a
s, forall {k} (f :: k -> *) (as :: [k]).
List (Weighted f) as -> Maybe Int
totalWeight List (Weighted Specification) as1
ss1) of
(Maybe Int
Nothing, Maybe Int
Nothing) -> forall a. Maybe a
Nothing
(Maybe Int
a, Maybe Int
b) -> forall a. a -> Maybe a
Just (forall a. a -> Maybe a -> a
fromMaybe Int
1 Maybe Int
a, forall a. a -> Maybe a -> a
fromMaybe (forall {k} (f :: k -> *) (as :: [k]). List f as -> Int
lengthList List (Weighted Specification) as1
ss1) Maybe Int
b)
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 (forall a. HasSpec a => Specification a -> Specification a
simplifySpec -> Specification a
spec) = case Specification a
spec of
ExplainSpec [] Specification a
s -> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
s
ExplainSpec [[Char]]
es Specification a
s -> forall (m :: * -> *) a. MonadGenError m => [[Char]] -> m a -> m a
push [[Char]]
es (forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
s)
MemberSpec NonEmpty a
as -> forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain1 ([Char]
"genFromSpecT on spec" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
spec) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Applicative m => Gen a -> GenT m a
pureGen (forall a. HasCallStack => [a] -> Gen a
elements (forall a. NonEmpty a -> [a]
NE.toList NonEmpty a
as))
Specification a
TrueSpec -> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT (forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => TypeSpec a
emptySpec @a)
SuspendedSpec Var a
x Pred
p
| Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall a. HasSpec a => Var a -> Name
Name Var a
x forall a. HasVariables a => Name -> a -> Bool
`appearsIn` Pred
p -> do
!Env
_ <- forall (m :: * -> *). MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds forall a. Monoid a => a
mempty Pred
p
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT forall a. Specification a
TrueSpec
| Bool
otherwise -> do
Env
env <- forall (m :: * -> *). MonadGenError m => Env -> Pred -> GenT m Env
genFromPreds forall a. Monoid a => a
mempty Pred
p
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 <- forall (m :: * -> *). Applicative m => GenT m GenMode
getMode
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a -> m a
explain
( forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"genFromSpecT on (TypeSpec tspec cant) at type " forall a. [a] -> [a] -> [a]
++ forall {k} (t :: k). Typeable t => [Char]
showType @a
, [Char]
"tspec = "
, forall a. Show a => a -> [Char]
show TypeSpec a
s
, [Char]
"cant = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall a x. (Show a, Typeable a) => [a] -> Doc x
short [a]
cant)
, [Char]
"with mode " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show GenMode
mode
]
)
forall a b. (a -> b) -> a -> b
$
forall a (m :: * -> *).
(HasSpec a, HasCallStack, MonadGenError m) =>
TypeSpec a -> GenT m a
genFromTypeSpec TypeSpec a
s forall a (m :: * -> *).
(Typeable a, MonadGenError m) =>
GenT m a -> (a -> Bool) -> GenT m a
`suchThatT` (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [a]
cant)
ErrorSpec NonEmpty [Char]
e -> forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genError NonEmpty [Char]
e
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 <- forall a. GenT GE a -> Gen (Either (NonEmpty (NonEmpty [Char])) a)
catchGen 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
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a. HasCallStack => [Char] -> a
error forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char
'\n' forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (NonEmpty [Char]) -> [Char]
catMessages) 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 = forall a. Gen a -> QCGen -> Int -> a
unGen (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 <- forall a. Gen a -> IO a
generate forall a b. (a -> b) -> a -> b
$ forall a. GenT GE a -> Gen a
genFromGenT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) x.
MonadGenError m =>
GenT GE x -> GenT m (GE x)
inspect (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 (forall a. NonEmpty a -> [a]
NE.toList NonEmpty [Char]
x))
ok :: a -> IO ()
ok a
x =
if 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 -> 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 -> 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 -> forall a. Show a => a -> IO ()
print Specification a
spec forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Show a => a -> IO ()
print a
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> IO ()
ok a
x
type DependGraph = Graph.Graph Name
dependency :: HasVariables t => Name -> t -> DependGraph
dependency :: forall t. HasVariables t => Name -> t -> DependGraph
dependency Name
x (forall a. HasVariables a => a -> Set Name
freeVarSet -> Set Name
xs) = forall node. Ord node => node -> Set node -> Graph node
Graph.dependency Name
x Set Name
xs
irreflexiveDependencyOn ::
forall t t'. (HasVariables t, HasVariables t') => t -> t' -> DependGraph
irreflexiveDependencyOn :: forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
irreflexiveDependencyOn (forall a. HasVariables a => a -> Set Name
freeVarSet -> Set Name
xs) (forall a. HasVariables a => a -> Set Name
freeVarSet -> Set Name
ys) = forall node. Ord node => Set node -> Set node -> Graph node
Graph.irreflexiveDependencyOn Set Name
xs Set Name
ys
noDependencies :: HasVariables t => t -> DependGraph
noDependencies :: forall t. HasVariables t => t -> DependGraph
noDependencies (forall a. HasVariables a => a -> Set Name
freeVarSet -> Set Name
xs) = forall node. Ord node => Set node -> Graph node
Graph.noDependencies Set Name
xs
type Hints = DependGraph
respecting :: Hints -> DependGraph -> DependGraph
respecting :: DependGraph -> DependGraph -> DependGraph
respecting DependGraph
hints DependGraph
g = DependGraph
g forall node. Ord node => Graph node -> Graph node -> Graph node
`subtractGraph` forall node. Graph node -> Graph node
opGraph DependGraph
hints
solvableFrom :: Name -> Set Name -> DependGraph -> Bool
solvableFrom :: Name -> Set Name -> DependGraph -> Bool
solvableFrom Name
x Set Name
s DependGraph
g =
let less :: Set Name
less = forall node. Ord node => node -> Graph node -> Set node
dependencies Name
x DependGraph
g
in Set Name
s forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set Name
less Bool -> Bool -> Bool
&& Bool -> Bool
not (Name
x forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Name
less)
computeDependencies :: Pred -> DependGraph
computeDependencies :: Pred -> DependGraph
computeDependencies = \case
ElemPred Bool
_bool Term a
term NonEmpty a
_xs -> forall a. Term a -> DependGraph
computeTermDependencies Term a
term
Monitor {} -> forall a. Monoid a => a
mempty
Subst Var a
x Term a
t Pred
p -> Pred -> DependGraph
computeDependencies (forall a. HasSpec a => Var a -> Term a -> Pred -> Pred
substitutePred Var a
x Term a
t Pred
p)
Assert Term Bool
t -> forall a. Term a -> DependGraph
computeTermDependencies Term Bool
t
Reifies Term b
t' Term a
t a -> b
_ -> Term b
t' forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` Term a
t
ForAll Term t
set Binder a
b ->
let innerG :: DependGraph
innerG = forall a. Binder a -> DependGraph
computeBinderDependencies Binder a
b
in DependGraph
innerG forall a. Semigroup a => a -> a -> a
<> Term t
set forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` forall node. Graph node -> Set node
nodes DependGraph
innerG
Term a
x `DependsOn` Term b
y -> Term a
x forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` Term b
y
Case Term (SumOver as)
t List (Weighted Binder) as
bs ->
let innerG :: DependGraph
innerG = forall {k} b (f :: k -> *) (as :: [k]).
Monoid b =>
(forall (a :: k). f a -> b) -> List f as -> b
foldMapList (forall a. Binder a -> DependGraph
computeBinderDependencies forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (a :: k). Weighted f a -> f a
thing) List (Weighted Binder) as
bs
in DependGraph
innerG forall a. Semigroup a => a -> a -> a
<> Term (SumOver as)
t forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` forall node. Graph node -> Set node
nodes DependGraph
innerG
When Term Bool
b Pred
p ->
let pG :: DependGraph
pG = Pred -> DependGraph
computeDependencies Pred
p
oG :: DependGraph
oG = forall node. Graph node -> Set node
nodes DependGraph
pG forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` Term Bool
b
in DependGraph
oG forall a. Semigroup a => a -> a -> a
<> DependGraph
pG
Pred
TruePred -> forall a. Monoid a => a
mempty
FalsePred {} -> forall a. Monoid a => a
mempty
And [Pred]
ps -> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pred -> DependGraph
computeDependencies [Pred]
ps
Exists (forall b. Term b -> b) -> GE a
_ Binder a
b -> forall a. Binder a -> DependGraph
computeBinderDependencies Binder a
b
Let Term a
t Binder a
b -> forall t. HasVariables t => t -> DependGraph
noDependencies Term a
t forall a. Semigroup a => a -> a -> a
<> forall a. Binder a -> DependGraph
computeBinderDependencies Binder a
b
GenHint Hint a
_ Term a
t -> forall t. HasVariables t => t -> DependGraph
noDependencies Term a
t
Explain NonEmpty [Char]
_ Pred
p -> Pred -> DependGraph
computeDependencies Pred
p
computeBinderDependencies :: Binder a -> DependGraph
computeBinderDependencies :: forall a. Binder a -> DependGraph
computeBinderDependencies (Var a
x :-> Pred
p) =
forall node. Ord node => node -> Graph node -> Graph node
deleteNode (forall a. HasSpec a => Var a -> Name
Name Var a
x) forall a b. (a -> b) -> a -> b
$ Pred -> DependGraph
computeDependencies Pred
p
computeTermDependencies :: Term a -> DependGraph
computeTermDependencies :: forall a. Term a -> DependGraph
computeTermDependencies = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Term a -> (DependGraph, Set Name)
computeTermDependencies'
computeTermDependencies' :: Term a -> (DependGraph, Set Name)
computeTermDependencies' :: forall a. Term a -> (DependGraph, Set Name)
computeTermDependencies' = \case
(App t sym dom a
_ List Term dom
args) -> forall (as :: [*]). List Term as -> (DependGraph, Set Name)
go List Term dom
args
Lit {} -> (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
(V Var a
x) -> (forall t. HasVariables t => t -> DependGraph
noDependencies (forall a. HasSpec a => Var a -> Name
Name Var a
x), forall a. a -> Set a
Set.singleton (forall a. HasSpec a => Var a -> Name
Name Var a
x))
where
go :: List Term as -> (DependGraph, Set Name)
go :: forall (as :: [*]). List Term as -> (DependGraph, Set Name)
go List Term as
Nil = (forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty)
go (Term a
t :> List Term as1
ts) =
let (DependGraph
gr, Set Name
ngr) = forall (as :: [*]). List Term as -> (DependGraph, Set Name)
go List Term as1
ts
(DependGraph
tgr, Set Name
ntgr) = forall a. Term a -> (DependGraph, Set Name)
computeTermDependencies' Term a
t
in (Set Name
ntgr forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` Set Name
ngr forall a. Semigroup a => a -> a -> a
<> DependGraph
tgr forall a. Semigroup a => a -> a -> a
<> DependGraph
gr, Set Name
ngr forall a. Semigroup a => a -> a -> a
<> Set Name
ntgr)
shrinkWithSpec :: forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec :: forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec (forall a. HasSpec a => Specification a -> Specification a
simplifySpec -> Specification a
spec) a
a = forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec) forall a b. (a -> b) -> a -> b
$ case Specification a
spec of
ExplainSpec [[Char]]
_ Specification a
s -> forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
s a
a
TypeSpec TypeSpec a
s [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 = 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 -> forall a. GE [a] -> [a]
listFromGE forall a b. (a -> b) -> a -> b
$ do
Bool
xaGood <- forall (m :: * -> *). MonadGenError m => Env -> Pred -> m Bool
checkPred (forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
a) Pred
p
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
xaGood forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
fatalError1 [Char]
"Trying to shrink a bad value, don't do that!"
Env
initialEnv <- Env -> Pred -> GE Env
envFromPred (forall a. (Typeable a, Show a) => Var a -> a -> Env
singletonEnv Var a
x a
a) Pred
p
forall (m :: * -> *) a. Monad m => a -> m a
return
[ a
a'
|
Env
env' <- Env -> SolverPlan -> [Env]
shrinkEnvFromPlan Env
initialEnv SolverPlan
plan
,
Just a
a' <- [forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
env' Var a
x]
,
a
a' forall a. Eq a => a -> a -> Bool
/= a
a
]
| Bool
otherwise = forall a. HasCallStack => [Char] -> a
error [Char]
"Bad pred"
shrinkEnvFromPlan :: Env -> SolverPlan -> [Env]
shrinkEnvFromPlan :: Env -> SolverPlan -> [Env]
shrinkEnvFromPlan Env
initialEnv SolverPlan {[SolverStage]
DependGraph
solverDependencies :: SolverPlan -> DependGraph
solverPlan :: SolverPlan -> [SolverStage]
solverDependencies :: DependGraph
solverPlan :: [SolverStage]
..} = Env -> [SolverStage] -> [Env]
go forall a. Monoid a => a
mempty [SolverStage]
solverPlan
where
go :: Env -> [SolverStage] -> [Env]
go Env
_ [] = []
go Env
env ((Env -> SolverStage -> SolverStage
substStage Env
env -> SolverStage {[Pred]
Var a
Specification a
stageSpec :: ()
stagePreds :: SolverStage -> [Pred]
stageVar :: ()
stageSpec :: Specification a
stagePreds :: [Pred]
stageVar :: Var a
..}) : [SolverStage]
plan) = do
Just a
a <- [forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
initialEnv Var a
stageVar]
[ Env
env' forall a. Semigroup a => a -> a -> a
<> Env
fixedEnv
| a
a' <- forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
stageSpec a
a
, let env' :: 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]
]
forall a. [a] -> [a] -> [a]
++ Env -> [SolverStage] -> [Env]
go (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
env [] = 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
stageSpec :: Specification a
stagePreds :: [Pred]
stageVar :: Var a
stageSpec :: ()
stagePreds :: SolverStage -> [Pred]
stageVar :: ()
..}) : [SolverStage]
plan) =
case forall a. Typeable a => Env -> Var a -> Maybe a
lookupEnv Env
initialEnv Var a
stageVar forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. HasSpec a => Specification a -> a -> Maybe a
fixupWithSpec Specification a
stageSpec of
Maybe a
Nothing -> forall a. Maybe a
Nothing
Just a
a -> Env -> [SolverStage] -> Maybe Env
fixupPlan (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 forall a b. (a -> b) -> a -> b
$ forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage Var a
y (Env -> Pred -> Pred
substPred Env
env 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) = forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage Var a
x [Pred]
ps'' (Specification a
spec forall a. Semigroup a => a -> a -> a
<> Specification a
spec')
where
([Pred]
ps', [Pred]
ps'') = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition ((Int
1 forall a. Eq a => a -> a -> Bool
==) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> Int
Set.size forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasVariables a => a -> Set Name
freeVarSet) [Pred]
ps
spec' :: Specification a
spec' = forall a. HasCallStack => GE (Specification a) -> Specification a
fromGESpec forall a b. (a -> b) -> a -> b
$ forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x ([Pred] -> Pred
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 forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec = forall a. a -> Maybe a
Just a
a
| Bool
otherwise = case Specification a
spec of
MemberSpec (a
x :| [a]
_) -> forall a. a -> Maybe a
Just a
x
Specification a
_ -> forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
spec) (forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec forall a. Specification a
TrueSpec a
a)
computeHints :: [Pred] -> Hints
computeHints :: [Pred] -> DependGraph
computeHints [Pred]
ps =
forall node. Ord node => Graph node -> Graph node
transitiveClosure forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [Term a
x forall t t'.
(HasVariables t, HasVariables t') =>
t -> t' -> DependGraph
`irreflexiveDependencyOn` Term b
y | DependsOn Term a
x Term b
y <- [Pred]
ps]
prepareLinearization :: Pred -> GE SolverPlan
prepareLinearization :: Pred -> GE SolverPlan
prepareLinearization Pred
p = do
let preds :: [Pred]
preds = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Pred -> [Pred]
saturatePred forall a b. (a -> b) -> a -> b
$ Pred -> [Pred]
flattenPred Pred
p
hints :: DependGraph
hints = [Pred] -> DependGraph
computeHints [Pred]
preds
graph :: DependGraph
graph = forall node. Ord node => Graph node -> Graph node
transitiveClosure forall a b. (a -> b) -> a -> b
$ DependGraph
hints forall a. Semigroup a => a -> a -> a
<> DependGraph -> DependGraph -> DependGraph
respecting DependGraph
hints (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Pred -> DependGraph
computeDependencies [Pred]
preds)
[SolverStage]
plan <-
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a -> m a
explain
( forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"Linearizing"
, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ Doc Any
" preds: " forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty [Pred]
preds
, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ Doc Any
" graph: " forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty DependGraph
graph
]
)
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadGenError m =>
[Pred] -> DependGraph -> m [SolverStage]
linearize [Pred]
preds DependGraph
graph
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ SolverPlan -> SolverPlan
backPropagation forall a b. (a -> b) -> a -> b
$ [SolverStage] -> DependGraph -> SolverPlan
SolverPlan [SolverStage]
plan DependGraph
graph
flattenPred :: Pred -> [Pred]
flattenPred :: Pred -> [Pred]
flattenPred Pred
pIn = Set Int -> [Pred] -> [Pred]
go (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' forall a. [a] -> [a] -> [a]
++ [Pred]
ps)
Let Term a
t Binder a
b -> forall a.
Set Int
-> Binder a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
goBinder Set Int
fvs Binder a
b [Pred]
ps (\Var a
x -> (forall p. IsPred p => p -> Pred
assert (Term a
t forall a. HasSpec a => Term a -> Term a -> Term Bool
==. (forall a. HasSpec a => Var a -> Term a
V Var a
x)) forall a. a -> [a] -> [a]
:))
Exists (forall b. Term b -> b) -> GE a
_ Binder a
b -> forall a.
Set Int
-> Binder a
-> [Pred]
-> (HasSpec a => Var a -> [Pred] -> [Pred])
-> [Pred]
goBinder Set Int
fvs Binder a
b [Pred]
ps (forall a b. a -> b -> a
const forall a. a -> a
id)
When Term Bool
b Pred
pp -> forall a b. (a -> b) -> [a] -> [b]
map (HasSpec Bool => Term Bool -> Pred -> Pred
When Term Bool
b) (Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred
pp]) forall a. [a] -> [a] -> [a]
++ Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred]
ps
Explain NonEmpty [Char]
es Pred
pp -> 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]) forall a. [a] -> [a] -> [a]
++ Set Int -> [Pred] -> [Pred]
go Set Int
fvs [Pred]
ps
Pred
_ -> Pred
p 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 = HasSpec a => Var a -> [Pred] -> [Pred]
k Var a
x' forall a b. (a -> b) -> a -> b
$ Set Int -> [Pred] -> [Pred]
go (forall a. Ord a => a -> Set a -> Set a
Set.insert (forall a. Var a -> Int
nameOf Var a
x') Set Int
fvs) (Pred
p' forall a. a -> [a] -> [a]
: [Pred]
ps)
where
(Var a
x', Pred
p') = 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] -> DependGraph -> m [SolverStage]
linearize [Pred]
preds DependGraph
graph = do
[Name]
sorted <- case forall node. Ord node => Graph node -> Either [node] [node]
topsort DependGraph
graph of
Left [Name]
cycle ->
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a
fatalError1
( forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$
Doc Any
"linearize: Dependency cycle in graph:"
forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep'
[ Doc Any
"cycle:" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall a ann. Pretty a => a -> Doc ann
pretty [Name]
cycle
, Doc Any
"graph:" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall a ann. Pretty a => a -> Doc ann
pretty DependGraph
graph
]
)
Right [Name]
sorted -> forall (f :: * -> *) a. Applicative f => a -> f a
pure [Name]
sorted
[Name] -> [(Set Name, Pred)] -> m [SolverStage]
go [Name]
sorted [(forall a. HasVariables a => a -> Set Name
freeVarSet Pred
ps, Pred
ps) | Pred
ps <- forall a. (a -> Bool) -> [a] -> [a]
filter Pred -> Bool
isRelevantPred [Pred]
preds]
where
isRelevantPred :: Pred -> Bool
isRelevantPred Pred
TruePred = Bool
False
isRelevantPred DependsOn {} = Bool
False
isRelevantPred (Assert (Lit Bool
True)) = Bool
False
isRelevantPred Pred
_ = Bool
True
go :: [Name] -> [(Set Name, Pred)] -> m [SolverStage]
go [] [] = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go [] [(Set Name, Pred)]
ps
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a b. (a, b) -> a
fst [(Set Name, Pred)]
ps =
case NonEmpty [Char] -> Env -> [Pred] -> Maybe (NonEmpty [Char])
checkPredsE (forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"Linearizing fails") forall a. Monoid a => a
mempty (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Set Name, Pred)]
ps) of
Maybe (NonEmpty [Char])
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Just NonEmpty [Char]
msgs -> forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
genError NonEmpty [Char]
msgs
| Bool
otherwise =
forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalError forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"Dependency error in `linearize`: "
, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall ann. Int -> Doc ann -> Doc ann
indent Int
2 forall a b. (a -> b) -> a -> b
$ Doc Any
"graph: " forall ann. Doc ann -> Doc ann -> Doc ann
/> forall a ann. Pretty a => a -> Doc ann
pretty DependGraph
graph
, forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$
forall ann. Int -> Doc ann -> Doc ann
indent Int
2 forall a b. (a -> b) -> a -> b
$
Doc Any
"the following left-over constraints are not defining constraints for a unique variable:"
forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep' (forall a b. (a -> b) -> [a] -> [b]
map (forall a ann. Pretty a => a -> Doc ann
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (Name -> Set Name -> Bool
isLastVariable Name
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(Set Name, Pred)]
ps
(SolverStage -> SolverStage
normalizeSolverStage (forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage Var a
x (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Set Name, Pred)]
nps) forall a. Monoid a => a
mempty) forall a. a -> [a] -> [a]
:) 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 forall a. Ord a => a -> Set a -> Bool
`Set.member` Set Name
set Bool -> Bool -> Bool
&& Name -> Set Name -> DependGraph -> Bool
solvableFrom Name
n (forall a. Ord a => a -> Set a -> Set a
Set.delete Name
n Set Name
set) DependGraph
graph
mergeSolverStage :: SolverStage -> [SolverStage] -> [SolverStage]
mergeSolverStage :: SolverStage -> [SolverStage] -> [SolverStage]
mergeSolverStage (SolverStage Var a
x [Pred]
ps Specification a
spec) [SolverStage]
plan =
[ case 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 ->
forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage
Var a
y
([Pred]
ps forall a. [a] -> [a] -> [a]
++ [Pred]
ps')
( forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec
( forall a. [a] -> NonEmpty a
NE.fromList
( [ [Char]
"Solving var " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Var a
x forall a. [a] -> [a] -> [a]
++ [Char]
" fails."
, [Char]
"Merging the Specs"
, [Char]
" 1. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
spec
, [Char]
" 2. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
spec'
]
)
)
(Specification a
spec 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 (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 =
forall ann. [Doc ann] -> Doc ann
vsep'
[ Doc ann
"Simplified spec:" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall a ann. Pretty a => a -> Doc ann
pretty Specification a
spec
, forall a ann. Pretty a => a -> Doc ann
pretty SolverPlan
plan
]
| Bool
otherwise = Doc ann
"Simplfied spec:" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall a ann. Pretty a => a -> Doc ann
pretty Specification a
spec
printPlan :: HasSpec a => Specification a -> IO ()
printPlan :: forall a. HasSpec a => Specification a -> IO ()
printPlan = forall a. Show a => a -> IO ()
print forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a ann. HasSpec a => Specification a -> Doc ann
prettyPlan
isEmptyPlan :: SolverPlan -> Bool
isEmptyPlan :: SolverPlan -> Bool
isEmptyPlan (SolverPlan [SolverStage]
plan DependGraph
_) = 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 [] DependGraph
_) = 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) DependGraph
gr) = do
(Specification a
spec', [Specification a]
specs) <- forall (m :: * -> *) r. MonadGenError m => GE r -> m r
runGE
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain1
( forall a. Show a => a -> [Char]
show
( Doc Any
"Computing specs for variable "
forall a. Semigroup a => a -> a -> a
<> forall a ann. Pretty a => a -> Doc ann
pretty Var a
x forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep' (forall a b. (a -> b) -> [a] -> [b]
map forall a ann. Pretty a => a -> Doc ann
pretty [Pred]
ps)
)
)
forall a b. (a -> b) -> a -> b
$ do
[Specification a]
ispecs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a.
(HasSpec a, HasCallStack) =>
Var a -> Pred -> GE (Specification a)
computeSpec Var a
x) [Pred]
ps
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [Specification a]
ispecs, [Specification a]
ispecs)
a
val <-
forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT
( forall a. NonEmpty [Char] -> Specification a -> Specification a
addToErrorSpec
( forall a. [a] -> NonEmpty a
NE.fromList
( ( [Char]
"\nStepPlan for variable: "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Var a
x
forall a. [a] -> [a] -> [a]
++ [Char]
" fails to produce Specification, probably overconstrained."
forall a. [a] -> [a] -> [a]
++ [Char]
"PS = "
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unlines (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> [Char]
show [Pred]
ps)
)
forall a. a -> [a] -> [a]
: ([Char]
"Original spec " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
spec)
forall a. a -> [a] -> [a]
: [Char]
"Predicates"
forall a. a -> [a] -> [a]
: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
(\Pred
pred Specification a
specx -> [Char]
" pred " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Pred
pred forall a. [a] -> [a] -> [a]
++ [Char]
" -> " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
specx)
[Pred]
ps
[Specification a]
specs
)
)
(Specification a
spec forall a. Semigroup a => a -> a -> a
<> Specification a
spec')
)
let env1 :: Env
env1 = forall a. (Typeable a, Show a) => Var a -> a -> Env -> Env
extendEnv Var a
x a
val Env
env
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Env
env1, SolverPlan -> SolverPlan
backPropagation forall a b. (a -> b) -> a -> b
$ [SolverStage] -> DependGraph -> SolverPlan
SolverPlan (Env -> SolverStage -> SolverStage
substStage Env
env1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SolverStage]
pl) (forall node. Ord node => node -> Graph node -> Graph node
deleteNode (forall a. HasSpec a => Var a -> Name
Name Var a
x) DependGraph
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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pred -> Pred
optimisePred -> Pred
preds) =
do
SolverPlan
plan <- forall (m :: * -> *) r. MonadGenError m => GE r -> m r
runGE 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 = forall (f :: * -> *) a. Applicative f => a -> f a
pure Env
env
go Env
env SolverPlan
plan = do
(Env
env', SolverPlan
plan') <-
forall (m :: * -> *) a. MonadGenError m => [Char] -> m a -> m a
explain1 (forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ Doc Any
"Stepping the plan:" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep [forall a ann. Pretty a => a -> Doc ann
pretty SolverPlan
plan, forall a ann. Pretty a => a -> Doc ann
pretty Env
env]) forall a b. (a -> b) -> a -> b
$ 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 DependGraph
graph) = [SolverStage] -> DependGraph -> SolverPlan
SolverPlan ([SolverStage] -> [SolverStage] -> [SolverStage]
go [] (forall a. [a] -> [a]
reverse [SolverStage]
initplan)) DependGraph
graph
where
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 forall a. a -> [a] -> [a]
: [SolverStage]
acc) [SolverStage]
plan'
where
newStages :: [SolverStage]
newStages = 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' = 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') Term a
t)) =
forall b.
HasSpec b =>
Specification a -> Var b -> Term b -> [SolverStage]
termVarEqCases Specification a
specl Var a
x' Term a
t
newStage Specification a
specr (Assert (Equal Term a
t (V Var a
x'))) =
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
| forall a. a -> Set a
Set.singleton (forall a. HasSpec a => Var a -> Name
Name Var a
x) forall a. Eq a => a -> a -> Bool
== forall a. HasVariables a => a -> Set Name
freeVarSet Term b
t =
[forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage Var b
x' [] forall a b. (a -> b) -> a -> b
$ forall a. NonEmpty a -> Specification a
MemberSpec (forall a. Eq a => NonEmpty a -> NonEmpty a
NE.nub (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
v -> forall a. GE a -> a
errorGE forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadGenError m => Env -> Term a -> m a
runTerm (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 <- 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] <- forall a. Set a -> [a]
Set.toList forall a b. (a -> b) -> a -> b
$ forall a. HasVariables a => a -> Set Name
freeVarSet Term b
t
, Result Ctx a b
ctx <- forall (m :: * -> *) v a.
(MonadGenError m, HasCallStack, HasSpec a, HasSpec v) =>
Var v -> Term a -> m (Ctx v a)
toCtx Var a
y Term b
t =
[forall a.
HasSpec a =>
Var a -> [Pred] -> Specification a -> SolverStage
SolverStage Var a
y [] (forall v a.
HasSpec v =>
Specification a -> Ctx v a -> Specification v
propagateSpec Specification a
specx Ctx a b
ctx)]
termVarEqCases Specification a
_ Var b
_ Term b
_ = []
mapSpec ::
forall s t a b.
(Logic s t '[a] b, HasSpec a, HasSpec b) => t s '[a] b -> Specification a -> Specification b
mapSpec :: forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) a b.
(Logic s t '[a] b, HasSpec a, HasSpec b) =>
t s '[a] b -> Specification a -> Specification b
mapSpec t s '[a] b
f (ExplainSpec [[Char]]
es Specification a
s) = forall a. [[Char]] -> Specification a -> Specification a
explainSpecOpt [[Char]]
es (forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) a b.
(Logic s t '[a] b, HasSpec a, HasSpec b) =>
t s '[a] b -> Specification a -> Specification b
mapSpec t s '[a] b
f Specification a
s)
mapSpec t s '[a] b
f Specification a
TrueSpec = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng a b.
(Logic s t dom rng, dom ~ '[a], rng ~ b, HasSpec a, HasSpec b) =>
t s '[a] b -> TypeSpec a -> Specification b
mapTypeSpec @_ @_ @'[a] @b t s '[a] b
f (forall a. HasSpec a => TypeSpec a
emptySpec @a)
mapSpec t s '[a] b
_ (ErrorSpec NonEmpty [Char]
err) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
err
mapSpec t s '[a] b
f (MemberSpec NonEmpty a
as) = forall a. NonEmpty a -> Specification a
MemberSpec forall a b. (a -> b) -> a -> b
$ forall a. Eq a => NonEmpty a -> NonEmpty a
NE.nub forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (t :: Symbol -> [*] -> * -> *) (s :: Symbol) (d :: [*]) r.
Semantics t =>
t s d r -> FunTy d r
semantics t s '[a] b
f) NonEmpty a
as
mapSpec t s '[a] b
f (SuspendedSpec Var a
x Pred
p) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term b
x' ->
forall a. ((forall b. Term b -> b) -> GE a) -> Binder a -> Pred
Exists (\forall b. Term b -> b
_ -> forall (m :: * -> *) a.
(MonadGenError m, HasCallStack) =>
NonEmpty [Char] -> m a
fatalError (forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"mapSpec")) (Var a
x forall a. HasSpec a => Var a -> Pred -> Binder a
:-> forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold [Term Bool -> Pred
Assert forall a b. (a -> b) -> a -> b
$ (Term b
x' forall a. HasSpec a => Term a -> Term a -> Term Bool
==. forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm t s '[a] b
f (forall a. HasSpec a => Var a -> Term a
V Var a
x)), Pred
p])
mapSpec t s '[a] b
f (TypeSpec TypeSpec a
ts [a]
cant) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng a b.
(Logic s t dom rng, dom ~ '[a], rng ~ b, HasSpec a, HasSpec b) =>
t s '[a] b -> TypeSpec a -> Specification b
mapTypeSpec @s @t @'[a] @b t s '[a] b
f TypeSpec a
ts forall a. Semigroup a => a -> a -> a
<> forall a (f :: * -> *).
(HasSpec a, Foldable f) =>
f a -> Specification a
notMemberSpec (forall a b. (a -> b) -> [a] -> [b]
map (forall (t :: Symbol -> [*] -> * -> *) (s :: Symbol) (d :: [*]) r.
Semantics t =>
t s d r -> FunTy d r
semantics t s '[a] b
f) [a]
cant)
saturatePred :: Pred -> [Pred]
saturatePred :: Pred -> [Pred]
saturatePred Pred
p =
Pred
p forall a. a -> [a] -> [a]
: case Pred
p of
Explain NonEmpty [Char]
_es Pred
x -> Pred -> [Pred]
saturatePred Pred
x
Assert ((App (t sym dom Bool
sym :: t s dom Bool) List Term dom
xs) :: Term Bool) -> forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng.
Logic s t dom rng =>
t s dom Bool -> List Term dom -> [Pred]
saturate @s @t @dom @Bool t sym dom Bool
sym List Term dom
xs
Pred
_ -> []
pairView :: forall a b. (HasSpec a, HasSpec b) => Term (Prod a b) -> Maybe (Term a, Term b)
pairView :: forall a b.
(HasSpec a, HasSpec b) =>
Term (Prod a b) -> Maybe (Term a, Term b)
pairView (App (forall (s1 :: Symbol) (t1 :: Symbol -> [*] -> * -> *) (d1 :: [*])
r1 (s2 :: Symbol) (t2 :: Symbol -> [*] -> * -> *) (d2 :: [*]) r2.
(Logic s1 t1 d1 r1, Logic s2 t2 d2 r2) =>
t1 s1 d1 r1
-> t2 s2 d2 r2
-> Maybe (t1 s1 d1 r1, s1 :~: s2, t1 :~: t2, d1 :~: d2, r1 :~: r2)
sameFunSym forall a b. (a -> b) -> a -> b
$ forall a b. BaseW "prod_" '[a, b] (Prod a b)
ProdW @a @b -> Just (BaseW "prod_" '[a, b] (Prod a b)
_, "prod_" :~: sym
Refl, BaseW :~: t
Refl, '[a, b] :~: dom
Refl, Prod a b :~: Prod a b
Refl)) (Term a
x :> Term a
y :> List Term as1
Nil)) = forall a. a -> Maybe a
Just (Term a
x, Term a
y)
pairView Term (Prod a b)
_ = forall a. Maybe a
Nothing
cartesian ::
forall a b.
(HasSpec a, HasSpec b) =>
Specification a ->
Specification b ->
Specification (Prod a b)
cartesian :: forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian (ErrorSpec NonEmpty [Char]
es) (ErrorSpec NonEmpty [Char]
fs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec (NonEmpty [Char]
es forall a. Semigroup a => a -> a -> a
<> NonEmpty [Char]
fs)
cartesian (ErrorSpec NonEmpty [Char]
es) Specification b
_ = forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall a. a -> NonEmpty a -> NonEmpty a
NE.cons [Char]
"cartesian left" NonEmpty [Char]
es)
cartesian Specification a
_ (ErrorSpec NonEmpty [Char]
es) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec (forall a. a -> NonEmpty a -> NonEmpty a
NE.cons [Char]
"cartesian right" NonEmpty [Char]
es)
cartesian Specification a
s Specification b
s' = forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec forall a b. (a -> b) -> a -> b
$ forall a b. Specification a -> Specification b -> PairSpec a b
Cartesian Specification a
s Specification b
s'
data PairSpec a b = Cartesian (Specification a) (Specification b)
instance (Arbitrary (Specification a), Arbitrary (Specification b)) => Arbitrary (PairSpec a b) where
arbitrary :: Gen (PairSpec a b)
arbitrary = forall a b. Specification a -> Specification b -> PairSpec a b
Cartesian forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Arbitrary a => Gen a
arbitrary
shrink :: PairSpec a b -> [PairSpec a b]
shrink (Cartesian Specification a
a Specification b
b) = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a b. Specification a -> Specification b -> PairSpec a b
Cartesian forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => a -> [a]
shrink (Specification a
a, Specification b
b)
instance (HasSpec a, HasSpec b) => HasSpec (Prod a b) where
type TypeSpec (Prod a b) = PairSpec a b
type Prerequisites (Prod a b) = (HasSpec a, HasSpec b)
emptySpec :: TypeSpec (Prod a b)
emptySpec = forall a b. Specification a -> Specification b -> PairSpec a b
Cartesian forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
combineSpec :: TypeSpec (Prod a b)
-> TypeSpec (Prod a b) -> Specification (Prod a b)
combineSpec (Cartesian Specification a
a Specification b
b) (Cartesian Specification a
a' Specification b
b') = forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian (Specification a
a forall a. Semigroup a => a -> a -> a
<> Specification a
a') (Specification b
b forall a. Semigroup a => a -> a -> a
<> Specification b
b')
conformsTo :: HasCallStack => Prod a b -> TypeSpec (Prod a b) -> Bool
conformsTo (Prod a
a b
b) (Cartesian Specification a
sa Specification b
sb) = forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec a
a Specification a
sa Bool -> Bool -> Bool
&& forall a. HasSpec a => a -> Specification a -> Bool
conformsToSpec b
b Specification b
sb
genFromTypeSpec :: forall (m :: * -> *).
(HasCallStack, MonadGenError m) =>
TypeSpec (Prod a b) -> GenT m (Prod a b)
genFromTypeSpec (Cartesian Specification a
sa Specification b
sb) = forall a b. a -> b -> Prod a b
Prod forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification a
sa forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a (m :: * -> *).
(HasCallStack, HasSpec a, MonadGenError m) =>
Specification a -> GenT m a
genFromSpecT Specification b
sb
shrinkWithTypeSpec :: TypeSpec (Prod a b) -> Prod a b -> [Prod a b]
shrinkWithTypeSpec (Cartesian Specification a
sa Specification b
sb) (Prod a
a b
b) =
[forall a b. a -> b -> Prod a b
Prod a
a' b
b | a
a' <- forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification a
sa a
a]
forall a. [a] -> [a] -> [a]
++ [forall a b. a -> b -> Prod a b
Prod a
a b
b' | b
b' <- forall a. HasSpec a => Specification a -> a -> [a]
shrinkWithSpec Specification b
sb b
b]
toPreds :: Term (Prod a b) -> TypeSpec (Prod a b) -> Pred
toPreds Term (Prod a b)
x (Cartesian Specification a
sf Specification b
ss) =
forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies (forall a b. (HasSpec a, HasSpec b) => Term (Prod a b) -> Term a
prodFst_ Term (Prod a b)
x) Specification a
sf
forall a. Semigroup a => a -> a -> a
<> forall a. HasSpec a => Term a -> Specification a -> Pred
satisfies (forall a b. (HasSpec a, HasSpec b) => Term (Prod a b) -> Term b
prodSnd_ Term (Prod a b)
x) Specification b
ss
cardinalTypeSpec :: TypeSpec (Prod a b) -> Specification Integer
cardinalTypeSpec (Cartesian Specification a
x Specification b
y) = (forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification a
x) forall a. Num a => a -> a -> a
+ (forall a.
(Number Integer, HasSpec a) =>
Specification a -> Specification Integer
cardinality Specification b
y)
typeSpecHasError :: TypeSpec (Prod a b) -> Maybe (NonEmpty [Char])
typeSpecHasError (Cartesian Specification a
x Specification b
y) =
case (forall a. Specification a -> Bool
isErrorLike Specification a
x, forall a. Specification a -> Bool
isErrorLike Specification b
y) of
(Bool
False, Bool
False) -> forall a. Maybe a
Nothing
(Bool
True, Bool
False) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification a
x
(Bool
False, Bool
True) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification b
y
(Bool
True, Bool
True) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ (forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification a
x forall a. Semigroup a => a -> a -> a
<> forall a. Specification a -> NonEmpty [Char]
errorLikeMessage Specification b
y)
alternateShow :: TypeSpec (Prod a b) -> BinaryShow
alternateShow (Cartesian 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]
"Cartesian" [Doc a]
ps) -> forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"Cartesian" (Doc a
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left forall a. a -> [a] -> [a]
: [Doc a]
ps)
(BinaryShow [Char]
"SumSpec" [Doc a]
ps) -> forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"Cartesian" (Doc a
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left forall a. a -> [a] -> [a]
: [Doc a
"SumSpec" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps])
BinaryShow
_ -> forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"Cartesian" [Doc Any
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
alternateShow (Cartesian Specification a
left Specification b
right) = forall a. [Char] -> [Doc a] -> BinaryShow
BinaryShow [Char]
"Cartesian" [Doc Any
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification a
left, Doc Any
"," forall ann. Doc ann -> Doc ann -> Doc ann
<+> forall a ann. Show a => a -> Doc ann
viaShow Specification b
right]
instance (HasSpec a, HasSpec b) => Show (PairSpec a b) where
show :: PairSpec a b -> [Char]
show pair :: PairSpec a b
pair@(Cartesian Specification a
l Specification b
r) = case forall a. HasSpec a => TypeSpec a -> BinaryShow
alternateShow @(Prod a b) PairSpec a b
pair of
(BinaryShow [Char]
"Cartesian" [Doc a]
ps) -> forall a. Show a => a -> [Char]
show forall a b. (a -> b) -> a -> b
$ forall ann. Doc ann -> Doc ann
parens (Doc a
"Cartesian" forall ann. Doc ann -> Doc ann -> Doc ann
/> forall ann. [Doc ann] -> Doc ann
vsep [Doc a]
ps)
BinaryShow
_ -> [Char]
"(Cartesian " forall a. [a] -> [a] -> [a]
++ [Char]
"(" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification a
l forall a. [a] -> [a] -> [a]
++ [Char]
") (" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Specification b
r forall a. [a] -> [a] -> [a]
++ [Char]
"))"
instance (HasSpec a, HasSpec b) => Logic "prodFst_" BaseW '[Prod a b] a where
propagate :: forall hole.
Context "prodFst_" BaseW '[Prod a b] a hole
-> Specification a -> Specification hole
propagate Context "prodFst_" BaseW '[Prod a b] a hole
ctxt (ExplainSpec [] Specification a
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prodFst_" BaseW '[Prod a b] a hole
ctxt Specification a
s
propagate Context "prodFst_" BaseW '[Prod a b] a hole
ctxt (ExplainSpec [[Char]]
es Specification a
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prodFst_" BaseW '[Prod a b] a hole
ctxt Specification a
s
propagate Context "prodFst_" BaseW '[Prod a b] a hole
_ Specification a
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "prodFst_" BaseW '[Prod a b] a hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BaseW "prodFst_" '[Prod a b] a
ProdFstW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var a
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall rng b. BaseW "prodFst_" '[Prod rng b] rng
ProdFstW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var a
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "prodFst_" '[Prod a b] a
ProdFstW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (TypeSpec TypeSpec a
ts [a]
cant) =
forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian @a @b (forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec TypeSpec a
ts [a]
cant) forall a. Specification a
TrueSpec
propagate (Context BaseW "prodFst_" '[Prod a b] a
ProdFstW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (MemberSpec NonEmpty a
es) =
forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian @a @b (forall a. NonEmpty a -> Specification a
MemberSpec NonEmpty a
es) forall a. Specification a
TrueSpec
propagate Context "prodFst_" BaseW '[Prod a b] a hole
ctx Specification a
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for ProdFstW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "prodFst_" BaseW '[Prod a b] a hole
ctx)
rewriteRules :: (TypeList '[Prod a b], Typeable '[Prod a b], HasSpec a,
All HasSpec '[Prod a b]) =>
BaseW "prodFst_" '[Prod a b] a
-> List Term '[Prod a b]
-> Evidence (AppRequires "prodFst_" BaseW '[Prod a b] a)
-> Maybe (Term a)
rewriteRules BaseW "prodFst_" '[Prod a b] a
ProdFstW ((forall a b.
(HasSpec a, HasSpec b) =>
Term (Prod a b) -> Maybe (Term a, Term b)
pairView -> Just (Term a
x, Term b
_)) :> List Term as1
Nil) Evidence (AppRequires "prodFst_" BaseW '[Prod a b] a)
Evidence = forall a. a -> Maybe a
Just Term a
x
rewriteRules BaseW "prodFst_" '[Prod a b] a
_ List Term '[Prod a b]
_ Evidence (AppRequires "prodFst_" BaseW '[Prod a b] a)
_ = forall a. Maybe a
Nothing
mapTypeSpec :: forall a b.
('[Prod a b] ~ '[a], a ~ b, HasSpec a, HasSpec b) =>
BaseW "prodFst_" '[a] b -> TypeSpec a -> Specification b
mapTypeSpec BaseW "prodFst_" '[a] b
ProdFstW (Cartesian Specification b
s Specification b
_) = Specification b
s
prodFst_ :: (HasSpec a, HasSpec b) => Term (Prod a b) -> Term a
prodFst_ :: forall a b. (HasSpec a, HasSpec b) => Term (Prod a b) -> Term a
prodFst_ = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall rng b. BaseW "prodFst_" '[Prod rng b] rng
ProdFstW
instance (HasSpec a, HasSpec b) => Logic "prodSnd_" BaseW '[Prod a b] b where
propagate :: forall hole.
Context "prodSnd_" BaseW '[Prod a b] b hole
-> Specification b -> Specification hole
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
ctxt (ExplainSpec [] Specification b
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
ctxt Specification b
s
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
ctxt (ExplainSpec [[Char]]
es Specification b
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
ctxt Specification b
s
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
_ Specification b
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BaseW "prodSnd_" '[Prod a b] b
ProdSndW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var b
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a rng. BaseW "prodSnd_" '[Prod a rng] rng
ProdSndW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var b
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "prodSnd_" '[Prod a b] b
ProdSndW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (TypeSpec TypeSpec b
ts [b]
cant) =
forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian @a @b forall a. Specification a
TrueSpec (forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec TypeSpec b
ts [b]
cant)
propagate (Context BaseW "prodSnd_" '[Prod a b] b
ProdSndW (Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (MemberSpec NonEmpty b
es) =
forall a b.
(HasSpec a, HasSpec b) =>
Specification a -> Specification b -> Specification (Prod a b)
cartesian @a @b forall a. Specification a
TrueSpec (forall a. NonEmpty a -> Specification a
MemberSpec NonEmpty b
es)
propagate Context "prodSnd_" BaseW '[Prod a b] b hole
ctx Specification b
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for ProdSndW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "prodSnd_" BaseW '[Prod a b] b hole
ctx)
rewriteRules :: (TypeList '[Prod a b], Typeable '[Prod a b], HasSpec b,
All HasSpec '[Prod a b]) =>
BaseW "prodSnd_" '[Prod a b] b
-> List Term '[Prod a b]
-> Evidence (AppRequires "prodSnd_" BaseW '[Prod a b] b)
-> Maybe (Term b)
rewriteRules BaseW "prodSnd_" '[Prod a b] b
ProdSndW ((forall a b.
(HasSpec a, HasSpec b) =>
Term (Prod a b) -> Maybe (Term a, Term b)
pairView -> Just (Term a
_, Term b
y)) :> List Term as1
Nil) Evidence (AppRequires "prodSnd_" BaseW '[Prod a b] b)
Evidence = forall a. a -> Maybe a
Just Term b
y
rewriteRules BaseW "prodSnd_" '[Prod a b] b
_ List Term '[Prod a b]
_ Evidence (AppRequires "prodSnd_" BaseW '[Prod a b] b)
_ = forall a. Maybe a
Nothing
mapTypeSpec :: forall a b.
('[Prod a b] ~ '[a], b ~ b, HasSpec a, HasSpec b) =>
BaseW "prodSnd_" '[a] b -> TypeSpec a -> Specification b
mapTypeSpec BaseW "prodSnd_" '[a] b
ProdSndW (Cartesian Specification a
_ Specification b
s) = Specification b
s
prodSnd_ :: (HasSpec a, HasSpec b) => Term (Prod a b) -> Term b
prodSnd_ :: forall a b. (HasSpec a, HasSpec b) => Term (Prod a b) -> Term b
prodSnd_ = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a rng. BaseW "prodSnd_" '[Prod a rng] rng
ProdSndW
sameFst :: Eq a1 => a1 -> [Prod a1 a2] -> [a2]
sameFst :: forall a1 a2. Eq a1 => a1 -> [Prod a1 a2] -> [a2]
sameFst a1
a [Prod a1 a2]
ps = [a2
b | Prod a1
a' a2
b <- [Prod a1 a2]
ps, a1
a forall a. Eq a => a -> a -> Bool
== a1
a']
sameSnd :: Eq a1 => a1 -> [Prod a2 a1] -> [a2]
sameSnd :: forall a1 a2. Eq a1 => a1 -> [Prod a2 a1] -> [a2]
sameSnd a1
b [Prod a2 a1]
ps = [a2
a | Prod a2
a a1
b' <- [Prod a2 a1]
ps, a1
b forall a. Eq a => a -> a -> Bool
== a1
b']
instance (HasSpec a, HasSpec b) => Logic "prod_" BaseW '[a, b] (Prod a b) where
propagate :: forall hole.
Context "prod_" BaseW '[a, b] (Prod a b) hole
-> Specification (Prod a b) -> Specification hole
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
ctxt (ExplainSpec [] Specification (Prod a b)
s) = forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
ctxt Specification (Prod a b)
s
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
ctxt (ExplainSpec [[Char]]
es Specification (Prod a b)
s) = forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]]
es forall a b. (a -> b) -> a -> b
$ forall (s :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
rng hole.
Logic s t dom rng =>
Context s t dom rng hole -> Specification rng -> Specification hole
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
ctxt Specification (Prod a b)
s
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
_ Specification (Prod a b)
TrueSpec = forall a. Specification a
TrueSpec
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
_ (ErrorSpec NonEmpty [Char]
msgs) = forall a. NonEmpty [Char] -> Specification a
ErrorSpec NonEmpty [Char]
msgs
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (Ctx hole y
HOLE :<> a
x :<| CList 'Post as1 Any Any
End)) (SuspendedSpec Var (Prod a b)
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a b. BaseW "prod_" '[a, b] (Prod a b)
ProdW (Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var (Prod a b)
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (a
x :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (SuspendedSpec Var (Prod a b)
v Pred
ps) =
forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term hole
v' -> forall a. Term a -> Binder a -> Pred
Let (forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (dom :: [*])
a.
AppRequires sym t dom a =>
t sym dom a -> List Term dom -> Term a
App forall a b. BaseW "prod_" '[a, b] (Prod a b)
ProdW (forall a. Literal a => a -> Term a
Lit a
x forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> Term hole
v' forall {k} (f :: k -> *) (a :: k) (as1 :: [k]).
f a -> List f as1 -> List f (a : as1)
:> forall {k} (f :: k -> *). List f '[]
Nil)) (Var (Prod a b)
v forall a. HasSpec a => Var a -> Pred -> Binder a
:-> Pred
ps)
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (a
a :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) ts :: Specification (Prod a b)
ts@(TypeSpec (Cartesian Specification a
sa Specification hole
sb) [Prod a b]
cant)
| a
a forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
sa = Specification hole
sb forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a. HasSpec a => a -> Specification a
notEqualSpec (forall a1 a2. Eq a1 => a1 -> [Prod a1 a2] -> [a2]
sameFst a
a [Prod a b]
cant)
| Bool
otherwise =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec
(forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"propagate (pair_ " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
a forall a. [a] -> [a] -> [a]
++ [Char]
" HOLE) has conformance failure on a", forall a. Show a => a -> [Char]
show Specification (Prod a b)
ts])
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (Ctx hole y
HOLE :<> a
b :<| CList 'Post as1 Any Any
End)) ts :: Specification (Prod a b)
ts@(TypeSpec (Cartesian Specification hole
sa Specification a
sb) [Prod a b]
cant)
| a
b forall a. HasSpec a => a -> Specification a -> Bool
`conformsToSpec` Specification a
sb = Specification hole
sa forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap forall a. HasSpec a => a -> Specification a
notEqualSpec (forall a1 a2. Eq a1 => a1 -> [Prod a2 a1] -> [a2]
sameSnd a
b [Prod a b]
cant)
| Bool
otherwise =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec
(forall a. [a] -> NonEmpty a
NE.fromList [[Char]
"propagate (pair_ HOLE " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
b forall a. [a] -> [a] -> [a]
++ [Char]
") has conformance failure on b", forall a. Show a => a -> [Char]
show Specification (Prod a b)
ts])
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (a
a :|> Ctx hole y
HOLE :<> CList 'Post as1 Any Any
forall i j. CList 'Post as1 i j
End)) (MemberSpec NonEmpty (Prod a b)
es) =
case (forall a. Eq a => [a] -> [a]
nub (forall a1 a2. Eq a1 => a1 -> [Prod a1 a2] -> [a2]
sameFst a
a (forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Prod a b)
es))) of
(b
w : [b]
ws) -> forall a. NonEmpty a -> Specification a
MemberSpec (b
w forall a. a -> [a] -> NonEmpty a
:| [b]
ws)
[] ->
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"propagate (pair_ HOLE " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
a forall a. [a] -> [a] -> [a]
++ [Char]
") on (MemberSpec " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Prod a b)
es)
, [Char]
"Where " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
a forall a. [a] -> [a] -> [a]
++ [Char]
" does not appear as the fst component of anything in the MemberSpec."
]
propagate (Context BaseW "prod_" '[a, b] (Prod a b)
ProdW (Ctx hole y
HOLE :<> a
b :<| CList 'Post as1 Any Any
End)) (MemberSpec NonEmpty (Prod a b)
es) =
case (forall a. Eq a => [a] -> [a]
nub (forall a1 a2. Eq a1 => a1 -> [Prod a2 a1] -> [a2]
sameSnd a
b (forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Prod a b)
es))) of
(a
w : [a]
ws) -> forall a. NonEmpty a -> Specification a
MemberSpec (a
w forall a. a -> [a] -> NonEmpty a
:| [a]
ws)
[] ->
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$
forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"propagate (pair_ HOLE " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
b forall a. [a] -> [a] -> [a]
++ [Char]
") on (MemberSpec " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show (forall a. NonEmpty a -> [a]
NE.toList NonEmpty (Prod a b)
es)
, [Char]
"Where " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show a
b forall a. [a] -> [a] -> [a]
++ [Char]
" does not appear as the snd component of anything in the MemberSpec."
]
propagate Context "prod_" BaseW '[a, b] (Prod a b) hole
ctx Specification (Prod a b)
_ =
forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char]
"Logic instance for ProdW with wrong number of arguments. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Context "prod_" BaseW '[a, b] (Prod a b) hole
ctx)
prod_ :: (HasSpec a, HasSpec b) => Term a -> Term b -> Term (Prod a b)
prod_ :: forall a b.
(HasSpec a, HasSpec b) =>
Term a -> Term b -> Term (Prod a b)
prod_ = forall (sym :: Symbol) (t :: Symbol -> [*] -> * -> *) (ds :: [*])
r.
AppRequires sym t ds r =>
t sym ds r -> FunTy (MapList Term ds) (Term r)
appTerm forall a b. BaseW "prod_" '[a, b] (Prod a b)
ProdW
instance (HasSpec a, Arbitrary (TypeSpec a)) => Arbitrary (Specification a) where
arbitrary :: Gen (Specification a)
arbitrary = do
Specification a
baseSpec <-
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
1, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Specification a
TrueSpec)
,
( Int
7
, do
[a]
zs <- forall a. Eq a => [a] -> [a]
nub forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Gen a -> Gen [a]
listOf1 (forall a. (HasCallStack, HasSpec a) => Specification a -> Gen a
genFromSpec forall a. Specification a
TrueSpec)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( forall a. [a] -> NonEmpty [Char] -> Specification a
memberSpecList
[a]
zs
( forall a. [a] -> NonEmpty a
NE.fromList
[ [Char]
"In (Arbitrary Specification) this should never happen"
, [Char]
"listOf1 generates empty list."
]
)
)
)
, (Int
10, forall a. HasSpec a => TypeSpec a -> Specification a
typeSpec forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary)
,
( Int
1
, do
Int
len <- forall a. Random a => (a, a) -> Gen a
choose (Int
1, Int
5)
forall a. HasSpec a => TypeSpec a -> [a] -> Specification a
TypeSpec forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Int -> Gen a -> Gen [a]
vectorOf Int
len (forall a. (HasCallStack, HasSpec a) => Specification a -> Gen a
genFromSpec forall a. Specification a
TrueSpec)
)
, (Int
1, forall a. NonEmpty [Char] -> Specification a
ErrorSpec forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary)
,
(Int
1, forall a. Arbitrary a => Gen a
arbitrary)
]
forall a. HasCallStack => [(Int, Gen a)] -> Gen a
frequency
[ (Int
1, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec)
, (Int
1, forall a. [[Char]] -> Specification a -> Specification a
ExplainSpec [[Char]
"Arbitrary"] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary)
,
( Int
1
, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> forall a p.
(HasSpec a, IsPred p) =>
((forall b. Term b -> b) -> GE a) -> (Term a -> p) -> Pred
exists (\forall b. Term b -> b
eval -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall b. Term b -> b
eval Term a
x) forall a b. (a -> b) -> a -> b
$ \Term a
y ->
[ forall p. IsPred p => p -> Pred
assert forall a b. (a -> b) -> a -> b
$ Term a
x forall a. HasSpec a => Term a -> Term a -> Term Bool
==. Term a
y
, Term a
y forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec
]
)
, (Int
1, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> forall a p.
(HasSpec a, IsPred p) =>
Term a -> (Term a -> p) -> Pred
letBind Term a
x forall a b. (a -> b) -> a -> b
$ \Term a
y -> Term a
y forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec)
,
( Int
1
, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> forall a p.
(HasSpec a, IsPred p) =>
((forall b. Term b -> b) -> GE a) -> (Term a -> p) -> Pred
exists (\forall b. Term b -> b
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True) forall a b. (a -> b) -> a -> b
$ \Term Bool
b ->
forall p q. (IsPred p, IsPred q) => Term Bool -> p -> q -> Pred
ifElse Term Bool
b (Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec) (Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec)
)
,
( Int
1
, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> forall a p.
(HasSpec a, IsPred p) =>
((forall b. Term b -> b) -> GE a) -> (Term a -> p) -> Pred
exists (\forall b. Term b -> b
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True) forall a b. (a -> b) -> a -> b
$ \Term Bool
b ->
[ forall p q. (IsPred p, IsPred q) => Term Bool -> p -> q -> Pred
ifElse Term Bool
b Bool
True (Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec)
, Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec
]
)
,
( Int
1
, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> forall a p.
(HasSpec a, IsPred p) =>
((forall b. Term b -> b) -> GE a) -> (Term a -> p) -> Pred
exists (\forall b. Term b -> b
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False) forall a b. (a -> b) -> a -> b
$ \Term Bool
b ->
[ forall p q. (IsPred p, IsPred q) => Term Bool -> p -> q -> Pred
ifElse Term Bool
b (Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec) Bool
True
, Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec
]
)
,
( Int
1
, forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a p.
(IsPred p, HasSpec a) =>
(Term a -> p) -> Specification a
constrained forall a b. (a -> b) -> a -> b
$ \Term a
x -> NonEmpty [Char] -> Pred -> Pred
explanation (forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"its very subtle, you won't get it.") forall a b. (a -> b) -> a -> b
$ Term a
x forall a. HasSpec a => Term a -> Specification a -> Pred
`satisfies` Specification a
baseSpec
)
, (Int
10, forall (f :: * -> *) a. Applicative f => a -> f a
pure Specification a
baseSpec)
]