{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
#if __GLASGOW_HASKELL__ < 801
#define nonDetCmpType cmpType
#endif
module GHC.TypeLits.Normalise.Unify
(
CType (..)
, CoreSOP
, normaliseNat
, normaliseNatEverywhere
, normaliseSimplifyNat
, reifySOP
, UnifyItem (..)
, CoreUnify
, substsSOP
, substsSubst
, UnifyResult (..)
, unifyNats
, unifiers
, fvSOP
, subtractIneq
, solveIneq
, ineqToSubst
, subtractionToPred
, instantSolveIneq
, solvedInEqSmallestConstraint
, isNatural
)
where
import Control.Arrow (first, second)
import Control.Monad.Trans.Writer.Strict
import Data.Function (on)
import Data.List ((\\), intersect, nub)
import Data.Maybe (fromMaybe, mapMaybe, isJust)
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Base (isTrue#,(==#))
import GHC.Integer (smallInteger)
import GHC.Integer.Logarithms (integerLogBase#)
#if MIN_VERSION_ghc(9,0,0)
import GHC.Builtin.Types (boolTy, promotedTrueDataCon, typeNatKind)
import GHC.Builtin.Types.Literals
(typeNatAddTyCon, typeNatExpTyCon, typeNatLeqTyCon, typeNatMulTyCon, typeNatSubTyCon)
import GHC.Core.Predicate (EqRel (NomEq), Pred (EqPred), classifyPredType, mkPrimEqPred)
import GHC.Core.TyCon (TyCon)
import GHC.Core.Type
(PredType, TyVar, coreView, eqType, mkNumLitTy, mkTyConApp, mkTyVarTy, nonDetCmpType, typeKind)
import GHC.Core.TyCo.Rep (Kind, Type (..), TyLit (..))
import GHC.Tc.Plugin (TcPluginM, tcPluginTrace)
import GHC.Tc.Types.Constraint (Ct, ctEvidence, ctEvId, ctEvPred, isGiven)
import GHC.Types.Unique.Set
(UniqSet, unionManyUniqSets, emptyUniqSet, unionUniqSets, unitUniqSet)
import GHC.Utils.Outputable (Outputable (..), (<+>), ($$), text)
#else
import Outputable (Outputable (..), (<+>), ($$), text)
import TcPluginM (TcPluginM, tcPluginTrace)
import TcTypeNats (typeNatAddTyCon, typeNatExpTyCon, typeNatMulTyCon,
typeNatSubTyCon, typeNatLeqTyCon)
import TyCon (TyCon)
import Type (TyVar,
coreView, eqType, mkNumLitTy, mkTyConApp, mkTyVarTy,
nonDetCmpType, PredType, typeKind)
import TyCoRep (Kind, Type (..), TyLit (..))
import TysWiredIn (boolTy, promotedTrueDataCon, typeNatKind)
import UniqSet (UniqSet, unionManyUniqSets, emptyUniqSet, unionUniqSets,
unitUniqSet)
#if MIN_VERSION_ghc(8,10,0)
import Constraint (Ct, ctEvidence, ctEvId, ctEvPred, isGiven)
import Predicate (EqRel (NomEq), Pred (EqPred), classifyPredType, mkPrimEqPred)
#else
import TcRnMonad (Ct, ctEvidence, isGiven)
import TcRnTypes (ctEvPred)
import Type (EqRel (NomEq), PredTree (EqPred), classifyPredType, mkPrimEqPred)
#endif
#endif
import GHC.TypeLits.Normalise.SOP
import GHC.TypeLits (Nat)
newtype CType = CType { CType -> Type
unCType :: Type }
deriving Rational -> CType -> SDoc
CType -> SDoc
(CType -> SDoc) -> (Rational -> CType -> SDoc) -> Outputable CType
forall a. (a -> SDoc) -> (Rational -> a -> SDoc) -> Outputable a
pprPrec :: Rational -> CType -> SDoc
$cpprPrec :: Rational -> CType -> SDoc
ppr :: CType -> SDoc
$cppr :: CType -> SDoc
Outputable
instance Eq CType where
(CType Type
ty1) == :: CType -> CType -> Bool
== (CType Type
ty2) = Type -> Type -> Bool
eqType Type
ty1 Type
ty2
instance Ord CType where
compare :: CType -> CType -> Ordering
compare (CType Type
ty1) (CType Type
ty2) = Type -> Type -> Ordering
nonDetCmpType Type
ty1 Type
ty2
type CoreSOP = SOP TyVar CType
type CoreProduct = Product TyVar CType
type CoreSymbol = Symbol TyVar CType
normaliseNat :: Type -> Writer [(Type,Type)] CoreSOP
normaliseNat :: Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
ty | Just Type
ty1 <- Type -> Maybe Type
coreView Type
ty = Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
ty1
normaliseNat (TyVarTy Var
v) = CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (m :: * -> *) a. Monad m => a -> m a
return ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Var -> Symbol Var CType
forall v c. v -> Symbol v c
V Var
v]])
normaliseNat (LitTy (NumTyLit Integer
i)) = CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (m :: * -> *) a. Monad m => a -> m a
return ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
i]])
normaliseNat (TyConApp TyCon
tc [Type
x,Type
y])
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
typeNatAddTyCon = CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd (CoreSOP -> CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP
-> WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
x WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
y
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
typeNatSubTyCon = do
[(Type, Type)] -> WriterT [(Type, Type)] Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell [(Type
x,Type
y)]
CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd (CoreSOP -> CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP
-> WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
x
WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (-Integer
1)]]) (CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
y)
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
typeNatMulTyCon = CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul (CoreSOP -> CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP
-> WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
x WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
y
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
typeNatExpTyCon = CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
normaliseExp (CoreSOP -> CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP
-> WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
x WriterT [(Type, Type)] Identity (CoreSOP -> CoreSOP)
-> Writer [(Type, Type)] CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
y
normaliseNat Type
t = CoreSOP -> Writer [(Type, Type)] CoreSOP
forall (m :: * -> *) a. Monad m => a -> m a
return ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [CType -> Symbol Var CType
forall v c. c -> Symbol v c
C (Type -> CType
CType Type
t)]])
maybeRunWriter
:: Monoid a
=> Writer a (Maybe b)
-> Writer a (Maybe b)
maybeRunWriter :: Writer a (Maybe b) -> Writer a (Maybe b)
maybeRunWriter Writer a (Maybe b)
w =
case Writer a (Maybe b) -> (Maybe b, a)
forall w a. Writer w a -> (a, w)
runWriter Writer a (Maybe b)
w of
(Maybe b
Nothing, a
_) -> Maybe b -> Writer a (Maybe b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe b
forall a. Maybe a
Nothing
(Maybe b
b, a
a) -> a -> WriterT a Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell a
a WriterT a Identity () -> Writer a (Maybe b) -> Writer a (Maybe b)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Maybe b -> Writer a (Maybe b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe b
b
normaliseNatEverywhere :: Type -> Writer [(Type, Type)] (Maybe Type)
normaliseNatEverywhere :: Type -> Writer [(Type, Type)] (Maybe Type)
normaliseNatEverywhere Type
ty0
| TyConApp TyCon
tc [Type]
_fields <- Type
ty0
, TyCon
tc TyCon -> [TyCon] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TyCon]
knownTyCons = do
Maybe Type
ty1M <- Writer [(Type, Type)] (Maybe Type)
-> Writer [(Type, Type)] (Maybe Type)
forall a b. Monoid a => Writer a (Maybe b) -> Writer a (Maybe b)
maybeRunWriter (Type -> Writer [(Type, Type)] (Maybe Type)
go Type
ty0)
let ty1 :: Type
ty1 = Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe Type
ty0 Maybe Type
ty1M
Type
ty2 <- Type -> Writer [(Type, Type)] Type
normaliseSimplifyNat Type
ty1
Maybe Type -> Writer [(Type, Type)] (Maybe Type)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (if Type
ty2 Type -> Type -> Bool
`eqType` Type
ty1 then Maybe Type
ty1M else Type -> Maybe Type
forall a. a -> Maybe a
Just Type
ty2)
| Bool
otherwise = Type -> Writer [(Type, Type)] (Maybe Type)
go Type
ty0
where
knownTyCons :: [TyCon]
knownTyCons :: [TyCon]
knownTyCons = [TyCon
typeNatExpTyCon, TyCon
typeNatMulTyCon, TyCon
typeNatSubTyCon, TyCon
typeNatAddTyCon]
go :: Type -> Writer [(Type, Type)] (Maybe Type)
go :: Type -> Writer [(Type, Type)] (Maybe Type)
go (TyConApp TyCon
tc_ [Type]
fields0_) = do
[Maybe Type]
fields1_ <- (Type -> Writer [(Type, Type)] (Maybe Type))
-> [Type] -> WriterT [(Type, Type)] Identity [Maybe Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Writer [(Type, Type)] (Maybe Type)
-> Writer [(Type, Type)] (Maybe Type)
forall a b. Monoid a => Writer a (Maybe b) -> Writer a (Maybe b)
maybeRunWriter (Writer [(Type, Type)] (Maybe Type)
-> Writer [(Type, Type)] (Maybe Type))
-> (Type -> Writer [(Type, Type)] (Maybe Type))
-> Type
-> Writer [(Type, Type)] (Maybe Type)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Writer [(Type, Type)] (Maybe Type)
cont) [Type]
fields0_
if (Maybe Type -> Bool) -> [Maybe Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Maybe Type -> Bool
forall a. Maybe a -> Bool
isJust [Maybe Type]
fields1_ then
Maybe Type -> Writer [(Type, Type)] (Maybe Type)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Type -> Maybe Type
forall a. a -> Maybe a
Just (TyCon -> [Type] -> Type
TyConApp TyCon
tc_ ((Type -> Maybe Type -> Type) -> [Type] -> [Maybe Type] -> [Type]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe [Type]
fields0_ [Maybe Type]
fields1_)))
else
Maybe Type -> Writer [(Type, Type)] (Maybe Type)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Type
forall a. Maybe a
Nothing
where
cont :: Type -> Writer [(Type, Type)] (Maybe Type)
cont = if TyCon
tc_ TyCon -> [TyCon] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TyCon]
knownTyCons then Type -> Writer [(Type, Type)] (Maybe Type)
go else Type -> Writer [(Type, Type)] (Maybe Type)
normaliseNatEverywhere
go Type
_ = Maybe Type -> Writer [(Type, Type)] (Maybe Type)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Type
forall a. Maybe a
Nothing
normaliseSimplifyNat :: Type -> Writer [(Type, Type)] Type
normaliseSimplifyNat :: Type -> Writer [(Type, Type)] Type
normaliseSimplifyNat Type
ty
| HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
ty Type -> Type -> Bool
`eqType` Type
typeNatKind = do
CoreSOP
ty' <- Type -> Writer [(Type, Type)] CoreSOP
normaliseNat Type
ty
Type -> Writer [(Type, Type)] Type
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Writer [(Type, Type)] Type)
-> Type -> Writer [(Type, Type)] Type
forall a b. (a -> b) -> a -> b
$ CoreSOP -> Type
reifySOP (CoreSOP -> Type) -> CoreSOP -> Type
forall a b. (a -> b) -> a -> b
$ CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c
simplifySOP CoreSOP
ty'
| Bool
otherwise = Type -> Writer [(Type, Type)] Type
forall (m :: * -> *) a. Monad m => a -> m a
return Type
ty
reifySOP :: CoreSOP -> Type
reifySOP :: CoreSOP -> Type
reifySOP = [Either (Product Var CType) (Product Var CType)] -> Type
combineP ([Either (Product Var CType) (Product Var CType)] -> Type)
-> (CoreSOP -> [Either (Product Var CType) (Product Var CType)])
-> CoreSOP
-> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Product Var CType
-> Either (Product Var CType) (Product Var CType))
-> [Product Var CType]
-> [Either (Product Var CType) (Product Var CType)]
forall a b. (a -> b) -> [a] -> [b]
map Product Var CType -> Either (Product Var CType) (Product Var CType)
negateP ([Product Var CType]
-> [Either (Product Var CType) (Product Var CType)])
-> (CoreSOP -> [Product Var CType])
-> CoreSOP
-> [Either (Product Var CType) (Product Var CType)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreSOP -> [Product Var CType]
forall v c. SOP v c -> [Product v c]
unS
where
negateP :: CoreProduct -> Either CoreProduct CoreProduct
negateP :: Product Var CType -> Either (Product Var CType) (Product Var CType)
negateP (P ((I Integer
i):ps :: [Symbol Var CType]
ps@(Symbol Var CType
_:[Symbol Var CType]
_))) | Integer
i Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== (-Integer
1) = Product Var CType -> Either (Product Var CType) (Product Var CType)
forall a b. a -> Either a b
Left ([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps)
negateP (P ((I Integer
i):[Symbol Var CType]
ps)) | Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Product Var CType -> Either (Product Var CType) (Product Var CType)
forall a b. a -> Either a b
Left ([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P ((Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer -> Integer
forall a. Num a => a -> a
abs Integer
i))Symbol Var CType -> [Symbol Var CType] -> [Symbol Var CType]
forall a. a -> [a] -> [a]
:[Symbol Var CType]
ps))
negateP Product Var CType
ps = Product Var CType -> Either (Product Var CType) (Product Var CType)
forall a b. b -> Either a b
Right Product Var CType
ps
combineP :: [Either CoreProduct CoreProduct] -> Type
combineP :: [Either (Product Var CType) (Product Var CType)] -> Type
combineP [] = Integer -> Type
mkNumLitTy Integer
0
combineP [Either (Product Var CType) (Product Var CType)
p] = (Product Var CType -> Type)
-> (Product Var CType -> Type)
-> Either (Product Var CType) (Product Var CType)
-> Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\Product Var CType
p' -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon
[Integer -> Type
mkNumLitTy Integer
0, Product Var CType -> Type
reifyProduct Product Var CType
p'])
Product Var CType -> Type
reifyProduct Either (Product Var CType) (Product Var CType)
p
combineP [Either (Product Var CType) (Product Var CType)
p1,Either (Product Var CType) (Product Var CType)
p2] = (Product Var CType -> Type)
-> (Product Var CType -> Type)
-> Either (Product Var CType) (Product Var CType)
-> Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(\Product Var CType
x -> (Product Var CType -> Type)
-> (Product Var CType -> Type)
-> Either (Product Var CType) (Product Var CType)
-> Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(\Product Var CType
y -> let r :: Type
r = TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon [Product Var CType -> Type
reifyProduct Product Var CType
x
,Product Var CType -> Type
reifyProduct Product Var CType
y]
in TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon [Integer -> Type
mkNumLitTy Integer
0, Type
r])
(\Product Var CType
y -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon [Product Var CType -> Type
reifyProduct Product Var CType
y, Product Var CType -> Type
reifyProduct Product Var CType
x])
Either (Product Var CType) (Product Var CType)
p2)
(\Product Var CType
x -> (Product Var CType -> Type)
-> (Product Var CType -> Type)
-> Either (Product Var CType) (Product Var CType)
-> Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(\Product Var CType
y -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon [Product Var CType -> Type
reifyProduct Product Var CType
x, Product Var CType -> Type
reifyProduct Product Var CType
y])
(\Product Var CType
y -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatAddTyCon [Product Var CType -> Type
reifyProduct Product Var CType
x, Product Var CType -> Type
reifyProduct Product Var CType
y])
Either (Product Var CType) (Product Var CType)
p2)
Either (Product Var CType) (Product Var CType)
p1
combineP (Either (Product Var CType) (Product Var CType)
p:[Either (Product Var CType) (Product Var CType)]
ps) = let es :: Type
es = [Either (Product Var CType) (Product Var CType)] -> Type
combineP [Either (Product Var CType) (Product Var CType)]
ps
in (Product Var CType -> Type)
-> (Product Var CType -> Type)
-> Either (Product Var CType) (Product Var CType)
-> Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\Product Var CType
x -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatSubTyCon
[Type
es, Product Var CType -> Type
reifyProduct Product Var CType
x])
(\Product Var CType
x -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatAddTyCon
[Product Var CType -> Type
reifyProduct Product Var CType
x, Type
es])
Either (Product Var CType) (Product Var CType)
p
reifyProduct :: CoreProduct -> Type
reifyProduct :: Product Var CType -> Type
reifyProduct (P [Symbol Var CType]
ps) =
let ps' :: [Type]
ps' = (Either (Symbol Var CType) (CoreSOP, [Product Var CType]) -> Type)
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Either (Symbol Var CType) (CoreSOP, [Product Var CType]) -> Type
reifySymbol ((Symbol Var CType
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])])
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Symbol Var CType]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Symbol Var CType
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
mergeExp [] [Symbol Var CType]
ps)
in (Type -> Type -> Type) -> Type -> [Type] -> Type
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Type
t1 Type
t2 -> TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatMulTyCon [Type
t1,Type
t2]) ([Type] -> Type
forall a. [a] -> a
head [Type]
ps') ([Type] -> [Type]
forall a. [a] -> [a]
tail [Type]
ps')
where
mergeExp :: CoreSymbol -> [Either CoreSymbol (CoreSOP,[CoreProduct])]
-> [Either CoreSymbol (CoreSOP,[CoreProduct])]
mergeExp :: Symbol Var CType
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
mergeExp (E CoreSOP
s Product Var CType
p) [] = [(CoreSOP, [Product Var CType])
-> Either (Symbol Var CType) (CoreSOP, [Product Var CType])
forall a b. b -> Either a b
Right (CoreSOP
s,[Product Var CType
p])]
mergeExp (E CoreSOP
s1 Product Var CType
p1) (Either (Symbol Var CType) (CoreSOP, [Product Var CType])
y:[Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
ys)
| Right (CoreSOP
s2,[Product Var CType]
p2) <- Either (Symbol Var CType) (CoreSOP, [Product Var CType])
y
, CoreSOP
s1 CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
s2
= (CoreSOP, [Product Var CType])
-> Either (Symbol Var CType) (CoreSOP, [Product Var CType])
forall a b. b -> Either a b
Right (CoreSOP
s1,(Product Var CType
p1Product Var CType -> [Product Var CType] -> [Product Var CType]
forall a. a -> [a] -> [a]
:[Product Var CType]
p2)) Either (Symbol Var CType) (CoreSOP, [Product Var CType])
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
forall a. a -> [a] -> [a]
: [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
ys
| Bool
otherwise
= (CoreSOP, [Product Var CType])
-> Either (Symbol Var CType) (CoreSOP, [Product Var CType])
forall a b. b -> Either a b
Right (CoreSOP
s1,[Product Var CType
p1]) Either (Symbol Var CType) (CoreSOP, [Product Var CType])
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
forall a. a -> [a] -> [a]
: Either (Symbol Var CType) (CoreSOP, [Product Var CType])
y Either (Symbol Var CType) (CoreSOP, [Product Var CType])
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
forall a. a -> [a] -> [a]
: [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
ys
mergeExp Symbol Var CType
x [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
ys = Symbol Var CType
-> Either (Symbol Var CType) (CoreSOP, [Product Var CType])
forall a b. a -> Either a b
Left Symbol Var CType
x Either (Symbol Var CType) (CoreSOP, [Product Var CType])
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
-> [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
forall a. a -> [a] -> [a]
: [Either (Symbol Var CType) (CoreSOP, [Product Var CType])]
ys
reifySymbol :: Either CoreSymbol (CoreSOP,[CoreProduct]) -> Type
reifySymbol :: Either (Symbol Var CType) (CoreSOP, [Product Var CType]) -> Type
reifySymbol (Left (I Integer
i) ) = Integer -> Type
mkNumLitTy Integer
i
reifySymbol (Left (C CType
c) ) = CType -> Type
unCType CType
c
reifySymbol (Left (V Var
v) ) = Var -> Type
mkTyVarTy Var
v
reifySymbol (Left (E CoreSOP
s Product Var CType
p)) = TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatExpTyCon [CoreSOP -> Type
reifySOP CoreSOP
s,Product Var CType -> Type
reifyProduct Product Var CType
p]
reifySymbol (Right (CoreSOP
s1,[Product Var CType]
s2)) = TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatExpTyCon
[CoreSOP -> Type
reifySOP CoreSOP
s1
,CoreSOP -> Type
reifySOP ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
s2)
]
subtractIneq
:: (CoreSOP, CoreSOP, Bool)
-> CoreSOP
subtractIneq :: (CoreSOP, CoreSOP, Bool) -> CoreSOP
subtractIneq (CoreSOP
x,CoreSOP
y,Bool
isLE)
| Bool
isLE
= CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd CoreSOP
y (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (-Integer
1)]]) CoreSOP
x)
| Bool
otherwise
= CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd CoreSOP
x (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (-Integer
1)]]) (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd CoreSOP
y ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]])))
sopToIneq
:: CoreSOP
-> Maybe Ineq
sopToIneq :: CoreSOP -> Maybe (CoreSOP, CoreSOP, Bool)
sopToIneq (S [P ((I Integer
i):[Symbol Var CType]
l),Product Var CType
r])
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0
= (CoreSOP, CoreSOP, Bool) -> Maybe (CoreSOP, CoreSOP, Bool)
forall a. a -> Maybe a
Just (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer -> Integer
forall a. Num a => a -> a
negate Integer
i)]]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
l]),[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
r],Bool
True)
sopToIneq (S [Product Var CType
r,P ((I Integer
i:[Symbol Var CType]
l))])
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0
= (CoreSOP, CoreSOP, Bool) -> Maybe (CoreSOP, CoreSOP, Bool)
forall a. a -> Maybe a
Just (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer -> Integer
forall a. Num a => a -> a
negate Integer
i)]]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
l]),[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
r],Bool
True)
sopToIneq CoreSOP
_ = Maybe (CoreSOP, CoreSOP, Bool)
forall a. Maybe a
Nothing
ineqToSubst
:: Ineq
-> Maybe CoreUnify
ineqToSubst :: (CoreSOP, CoreSOP, Bool) -> Maybe CoreUnify
ineqToSubst (CoreSOP
x,S [P [V Var
v]],Bool
True)
= CoreUnify -> Maybe CoreUnify
forall a. a -> Maybe a
Just (Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
v CoreSOP
x)
ineqToSubst (CoreSOP, CoreSOP, Bool)
_
= Maybe CoreUnify
forall a. Maybe a
Nothing
subtractionToPred
:: (Type,Type)
-> (PredType, Kind)
subtractionToPred :: (Type, Type) -> (Type, Type)
subtractionToPred (Type
x,Type
y) =
(Type -> Type -> Type
mkPrimEqPred (TyCon -> [Type] -> Type
mkTyConApp TyCon
typeNatLeqTyCon [Type
y,Type
x])
(TyCon -> [Type] -> Type
mkTyConApp TyCon
promotedTrueDataCon [])
,Type
boolTy)
type CoreUnify = UnifyItem TyVar CType
data UnifyItem v c = SubstItem { UnifyItem v c -> v
siVar :: v
, UnifyItem v c -> SOP v c
siSOP :: SOP v c
}
| UnifyItem { UnifyItem v c -> SOP v c
siLHS :: SOP v c
, UnifyItem v c -> SOP v c
siRHS :: SOP v c
}
deriving UnifyItem v c -> UnifyItem v c -> Bool
(UnifyItem v c -> UnifyItem v c -> Bool)
-> (UnifyItem v c -> UnifyItem v c -> Bool) -> Eq (UnifyItem v c)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall v c. (Eq v, Eq c) => UnifyItem v c -> UnifyItem v c -> Bool
/= :: UnifyItem v c -> UnifyItem v c -> Bool
$c/= :: forall v c. (Eq v, Eq c) => UnifyItem v c -> UnifyItem v c -> Bool
== :: UnifyItem v c -> UnifyItem v c -> Bool
$c== :: forall v c. (Eq v, Eq c) => UnifyItem v c -> UnifyItem v c -> Bool
Eq
instance (Outputable v, Outputable c) => Outputable (UnifyItem v c) where
ppr :: UnifyItem v c -> SDoc
ppr (SubstItem {v
SOP v c
siSOP :: SOP v c
siVar :: v
siSOP :: forall v c. UnifyItem v c -> SOP v c
siVar :: forall v c. UnifyItem v c -> v
..}) = v -> SDoc
forall a. Outputable a => a -> SDoc
ppr v
siVar SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
" := " SDoc -> SDoc -> SDoc
<+> SOP v c -> SDoc
forall a. Outputable a => a -> SDoc
ppr SOP v c
siSOP
ppr (UnifyItem {SOP v c
siRHS :: SOP v c
siLHS :: SOP v c
siRHS :: forall v c. UnifyItem v c -> SOP v c
siLHS :: forall v c. UnifyItem v c -> SOP v c
..}) = SOP v c -> SDoc
forall a. Outputable a => a -> SDoc
ppr SOP v c
siLHS SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
" :~ " SDoc -> SDoc -> SDoc
<+> SOP v c -> SDoc
forall a. Outputable a => a -> SDoc
ppr SOP v c
siRHS
substsSOP :: (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP :: [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [] SOP v c
u = SOP v c
u
substsSOP ((SubstItem {v
SOP v c
siSOP :: SOP v c
siVar :: v
siSOP :: forall v c. UnifyItem v c -> SOP v c
siVar :: forall v c. UnifyItem v c -> v
..}):[UnifyItem v c]
s) SOP v c
u = [UnifyItem v c] -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [UnifyItem v c]
s (v -> SOP v c -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => v -> SOP v c -> SOP v c -> SOP v c
substSOP v
siVar SOP v c
siSOP SOP v c
u)
substsSOP ((UnifyItem {}):[UnifyItem v c]
s) SOP v c
u = [UnifyItem v c] -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [UnifyItem v c]
s SOP v c
u
substSOP :: (Ord v, Ord c) => v -> SOP v c -> SOP v c -> SOP v c
substSOP :: v -> SOP v c -> SOP v c -> SOP v c
substSOP v
tv SOP v c
e = (SOP v c -> SOP v c -> SOP v c) -> [SOP v c] -> SOP v c
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 SOP v c -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd ([SOP v c] -> SOP v c)
-> (SOP v c -> [SOP v c]) -> SOP v c -> SOP v c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Product v c -> SOP v c) -> [Product v c] -> [SOP v c]
forall a b. (a -> b) -> [a] -> [b]
map (v -> SOP v c -> Product v c -> SOP v c
forall v c.
(Ord v, Ord c) =>
v -> SOP v c -> Product v c -> SOP v c
substProduct v
tv SOP v c
e) ([Product v c] -> [SOP v c])
-> (SOP v c -> [Product v c]) -> SOP v c -> [SOP v c]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SOP v c -> [Product v c]
forall v c. SOP v c -> [Product v c]
unS
substProduct :: (Ord v, Ord c) => v -> SOP v c -> Product v c -> SOP v c
substProduct :: v -> SOP v c -> Product v c -> SOP v c
substProduct v
tv SOP v c
e = (SOP v c -> SOP v c -> SOP v c) -> [SOP v c] -> SOP v c
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 SOP v c -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul ([SOP v c] -> SOP v c)
-> (Product v c -> [SOP v c]) -> Product v c -> SOP v c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Symbol v c -> SOP v c) -> [Symbol v c] -> [SOP v c]
forall a b. (a -> b) -> [a] -> [b]
map (v -> SOP v c -> Symbol v c -> SOP v c
forall v c. (Ord v, Ord c) => v -> SOP v c -> Symbol v c -> SOP v c
substSymbol v
tv SOP v c
e) ([Symbol v c] -> [SOP v c])
-> (Product v c -> [Symbol v c]) -> Product v c -> [SOP v c]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product v c -> [Symbol v c]
forall v c. Product v c -> [Symbol v c]
unP
substSymbol :: (Ord v, Ord c) => v -> SOP v c -> Symbol v c -> SOP v c
substSymbol :: v -> SOP v c -> Symbol v c -> SOP v c
substSymbol v
_ SOP v c
_ s :: Symbol v c
s@(I Integer
_) = [Product v c] -> SOP v c
forall v c. [Product v c] -> SOP v c
S [[Symbol v c] -> Product v c
forall v c. [Symbol v c] -> Product v c
P [Symbol v c
s]]
substSymbol v
_ SOP v c
_ s :: Symbol v c
s@(C c
_) = [Product v c] -> SOP v c
forall v c. [Product v c] -> SOP v c
S [[Symbol v c] -> Product v c
forall v c. [Symbol v c] -> Product v c
P [Symbol v c
s]]
substSymbol v
tv SOP v c
e (V v
tv')
| v
tv v -> v -> Bool
forall a. Eq a => a -> a -> Bool
== v
tv' = SOP v c
e
| Bool
otherwise = [Product v c] -> SOP v c
forall v c. [Product v c] -> SOP v c
S [[Symbol v c] -> Product v c
forall v c. [Symbol v c] -> Product v c
P [v -> Symbol v c
forall v c. v -> Symbol v c
V v
tv']]
substSymbol v
tv SOP v c
e (E SOP v c
s Product v c
p) = SOP v c -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
normaliseExp (v -> SOP v c -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => v -> SOP v c -> SOP v c -> SOP v c
substSOP v
tv SOP v c
e SOP v c
s) (v -> SOP v c -> Product v c -> SOP v c
forall v c.
(Ord v, Ord c) =>
v -> SOP v c -> Product v c -> SOP v c
substProduct v
tv SOP v c
e Product v c
p)
substsSubst :: (Ord v, Ord c) => [UnifyItem v c] -> [UnifyItem v c] -> [UnifyItem v c]
substsSubst :: [UnifyItem v c] -> [UnifyItem v c] -> [UnifyItem v c]
substsSubst [UnifyItem v c]
s = (UnifyItem v c -> UnifyItem v c)
-> [UnifyItem v c] -> [UnifyItem v c]
forall a b. (a -> b) -> [a] -> [b]
map UnifyItem v c -> UnifyItem v c
subt
where
subt :: UnifyItem v c -> UnifyItem v c
subt si :: UnifyItem v c
si@(SubstItem {v
SOP v c
siSOP :: SOP v c
siVar :: v
siSOP :: forall v c. UnifyItem v c -> SOP v c
siVar :: forall v c. UnifyItem v c -> v
..}) = UnifyItem v c
si {siSOP :: SOP v c
siSOP = [UnifyItem v c] -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [UnifyItem v c]
s SOP v c
siSOP}
subt si :: UnifyItem v c
si@(UnifyItem {SOP v c
siRHS :: SOP v c
siLHS :: SOP v c
siRHS :: forall v c. UnifyItem v c -> SOP v c
siLHS :: forall v c. UnifyItem v c -> SOP v c
..}) = UnifyItem v c
si {siLHS :: SOP v c
siLHS = [UnifyItem v c] -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [UnifyItem v c]
s SOP v c
siLHS, siRHS :: SOP v c
siRHS = [UnifyItem v c] -> SOP v c -> SOP v c
forall v c. (Ord v, Ord c) => [UnifyItem v c] -> SOP v c -> SOP v c
substsSOP [UnifyItem v c]
s SOP v c
siRHS}
{-# INLINEABLE substsSubst #-}
data UnifyResult
= Win
| Lose
| Draw [CoreUnify]
instance Outputable UnifyResult where
ppr :: UnifyResult -> SDoc
ppr UnifyResult
Win = String -> SDoc
text String
"Win"
ppr (Draw [CoreUnify]
subst) = String -> SDoc
text String
"Draw" SDoc -> SDoc -> SDoc
<+> [CoreUnify] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [CoreUnify]
subst
ppr UnifyResult
Lose = String -> SDoc
text String
"Lose"
unifyNats :: Ct -> CoreSOP -> CoreSOP -> TcPluginM UnifyResult
unifyNats :: Ct -> CoreSOP -> CoreSOP -> TcPluginM UnifyResult
unifyNats Ct
ct CoreSOP
u CoreSOP
v = do
String -> SDoc -> TcPluginM ()
tcPluginTrace String
"unifyNats" (Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
ct SDoc -> SDoc -> SDoc
$$ CoreSOP -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreSOP
u SDoc -> SDoc -> SDoc
$$ CoreSOP -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreSOP
v)
UnifyResult -> TcPluginM UnifyResult
forall (m :: * -> *) a. Monad m => a -> m a
return (Ct -> CoreSOP -> CoreSOP -> UnifyResult
unifyNats' Ct
ct CoreSOP
u CoreSOP
v)
unifyNats' :: Ct -> CoreSOP -> CoreSOP -> UnifyResult
unifyNats' :: Ct -> CoreSOP -> CoreSOP -> UnifyResult
unifyNats' Ct
ct CoreSOP
u CoreSOP
v
= if CoreSOP -> CoreSOP -> Bool
eqFV CoreSOP
u CoreSOP
v
then if CoreSOP -> Bool
containsConstants CoreSOP
u Bool -> Bool -> Bool
|| CoreSOP -> Bool
containsConstants CoreSOP
v
then if CoreSOP
u CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
v
then UnifyResult
Win
else [CoreUnify] -> UnifyResult
Draw ((CoreUnify -> Bool) -> [CoreUnify] -> [CoreUnify]
forall a. (a -> Bool) -> [a] -> [a]
filter CoreUnify -> Bool
diffFromConstraint (Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers Ct
ct CoreSOP
u CoreSOP
v))
else if CoreSOP
u CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
v
then UnifyResult
Win
else UnifyResult
Lose
else [CoreUnify] -> UnifyResult
Draw ((CoreUnify -> Bool) -> [CoreUnify] -> [CoreUnify]
forall a. (a -> Bool) -> [a] -> [a]
filter CoreUnify -> Bool
diffFromConstraint (Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers Ct
ct CoreSOP
u CoreSOP
v))
where
diffFromConstraint :: CoreUnify -> Bool
diffFromConstraint (UnifyItem CoreSOP
x CoreSOP
y) = Bool -> Bool
not (CoreSOP
x CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
u Bool -> Bool -> Bool
&& CoreSOP
y CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
v)
diffFromConstraint CoreUnify
_ = Bool
True
unifiers :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers Ct
ct u :: CoreSOP
u@(S [P [V Var
x]]) CoreSOP
v
= case Type -> Pred
classifyPredType (Type -> Pred) -> Type -> Pred
forall a b. (a -> b) -> a -> b
$ CtEvidence -> Type
ctEvPred (CtEvidence -> Type) -> CtEvidence -> Type
forall a b. (a -> b) -> a -> b
$ Ct -> CtEvidence
ctEvidence Ct
ct of
EqPred EqRel
NomEq Type
t1 Type
_
| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
u) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t1 Bool -> Bool -> Bool
|| CtEvidence -> Bool
isGiven (Ct -> CtEvidence
ctEvidence Ct
ct) -> [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x CoreSOP
v]
Pred
_ -> []
unifiers Ct
ct CoreSOP
u v :: CoreSOP
v@(S [P [V Var
x]])
= case Type -> Pred
classifyPredType (Type -> Pred) -> Type -> Pred
forall a b. (a -> b) -> a -> b
$ CtEvidence -> Type
ctEvPred (CtEvidence -> Type) -> CtEvidence -> Type
forall a b. (a -> b) -> a -> b
$ Ct -> CtEvidence
ctEvidence Ct
ct of
EqPred EqRel
NomEq Type
_ Type
t2
| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
v) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t2 Bool -> Bool -> Bool
|| CtEvidence -> Bool
isGiven (Ct -> CtEvidence
ctEvidence Ct
ct) -> [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x CoreSOP
u]
Pred
_ -> []
unifiers Ct
ct u :: CoreSOP
u@(S [P [C CType
_]]) CoreSOP
v
= case Type -> Pred
classifyPredType (Type -> Pred) -> Type -> Pred
forall a b. (a -> b) -> a -> b
$ CtEvidence -> Type
ctEvPred (CtEvidence -> Type) -> CtEvidence -> Type
forall a b. (a -> b) -> a -> b
$ Ct -> CtEvidence
ctEvidence Ct
ct of
EqPred EqRel
NomEq Type
t1 Type
t2
| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
u) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t1 Bool -> Bool -> Bool
|| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
v) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t2 -> [CoreSOP -> CoreSOP -> CoreUnify
forall v c. SOP v c -> SOP v c -> UnifyItem v c
UnifyItem CoreSOP
u CoreSOP
v]
Pred
_ -> []
unifiers Ct
ct CoreSOP
u v :: CoreSOP
v@(S [P [C CType
_]])
= case Type -> Pred
classifyPredType (Type -> Pred) -> Type -> Pred
forall a b. (a -> b) -> a -> b
$ CtEvidence -> Type
ctEvPred (CtEvidence -> Type) -> CtEvidence -> Type
forall a b. (a -> b) -> a -> b
$ Ct -> CtEvidence
ctEvidence Ct
ct of
EqPred EqRel
NomEq Type
t1 Type
t2
| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
u) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t1 Bool -> Bool -> Bool
|| Type -> CType
CType (CoreSOP -> Type
reifySOP CoreSOP
v) CType -> CType -> Bool
forall a. Eq a => a -> a -> Bool
/= Type -> CType
CType Type
t2 -> [CoreSOP -> CoreSOP -> CoreUnify
forall v c. SOP v c -> SOP v c -> UnifyItem v c
UnifyItem CoreSOP
u CoreSOP
v]
Pred
_ -> []
unifiers Ct
ct CoreSOP
u CoreSOP
v = Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct CoreSOP
u CoreSOP
v
unifiers' :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
_ct (S [P [V Var
x]]) (S []) = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
0]])]
unifiers' Ct
_ct (S []) (S [P [V Var
x]]) = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
0]])]
unifiers' Ct
_ct (S [P [V Var
x]]) CoreSOP
s = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x CoreSOP
s]
unifiers' Ct
_ct CoreSOP
s (S [P [V Var
x]]) = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
x CoreSOP
s]
unifiers' Ct
_ct s1 :: CoreSOP
s1@(S [P [C CType
_]]) CoreSOP
s2 = [CoreSOP -> CoreSOP -> CoreUnify
forall v c. SOP v c -> SOP v c -> UnifyItem v c
UnifyItem CoreSOP
s1 CoreSOP
s2]
unifiers' Ct
_ct CoreSOP
s1 s2 :: CoreSOP
s2@(S [P [C CType
_]]) = [CoreSOP -> CoreSOP -> CoreUnify
forall v c. SOP v c -> SOP v c -> UnifyItem v c
UnifyItem CoreSOP
s1 CoreSOP
s2]
unifiers' Ct
ct (S [P [E CoreSOP
s1 Product Var CType
p1]]) (S [P [E CoreSOP
s2 Product Var CType
p2]])
| CoreSOP
s1 CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
s2 = Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p1]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p2])
unifiers' Ct
ct (S [P [E (S [P [Symbol Var CType]
s1]) Product Var CType
p1]]) (S [P [Symbol Var CType]
p2])
| (Symbol Var CType -> Bool) -> [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Symbol Var CType -> [Symbol Var CType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Symbol Var CType]
p2) [Symbol Var CType]
s1
= let base :: [Symbol Var CType]
base = [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
intersect [Symbol Var CType]
s1 [Symbol Var CType]
p2
diff :: [Symbol Var CType]
diff = [Symbol Var CType]
p2 [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
s1
in Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
diff]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [CoreSOP -> Product Var CType -> Symbol Var CType
forall v c. SOP v c -> Product v c -> Symbol v c
E ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
base]) ([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (-Integer
1)]),CoreSOP -> Product Var CType -> Symbol Var CType
forall v c. SOP v c -> Product v c -> Symbol v c
E ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
base]) Product Var CType
p1]])
unifiers' Ct
ct (S [P [Symbol Var CType]
p2]) (S [P [E (S [P [Symbol Var CType]
s1]) Product Var CType
p1]])
| (Symbol Var CType -> Bool) -> [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Symbol Var CType -> [Symbol Var CType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Symbol Var CType]
p2) [Symbol Var CType]
s1
= let base :: [Symbol Var CType]
base = [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
intersect [Symbol Var CType]
s1 [Symbol Var CType]
p2
diff :: [Symbol Var CType]
diff = [Symbol Var CType]
p2 [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
s1
in Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [CoreSOP -> Product Var CType -> Symbol Var CType
forall v c. SOP v c -> Product v c -> Symbol v c
E ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
base]) ([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (-Integer
1)]),CoreSOP -> Product Var CType -> Symbol Var CType
forall v c. SOP v c -> Product v c -> Symbol v c
E ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
base]) Product Var CType
p1]]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
diff])
unifiers' Ct
ct (S [P [E (S [P [I Integer
i]]) Product Var CType
p]]) (S [P [I Integer
j]])
= case Integer -> Integer -> Maybe Integer
integerLogBase Integer
i Integer
j of
Just Integer
k -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
k]])
Maybe Integer
Nothing -> []
unifiers' Ct
ct (S [P [I Integer
j]]) (S [P [E (S [P [I Integer
i]]) Product Var CType
p]])
= case Integer -> Integer -> Maybe Integer
integerLogBase Integer
i Integer
j of
Just Integer
k -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
k]])
Maybe Integer
Nothing -> []
unifiers' Ct
ct (S [P [E CoreSOP
s1 Product Var CType
p1]]) (S [Product Var CType
p2]) = case Product Var CType -> Maybe ([CoreSOP], [Product Var CType])
collectBases Product Var CType
p2 of
Just (CoreSOP
b:[CoreSOP]
bs,[Product Var CType]
ps) | (CoreSOP -> Bool) -> [CoreSOP] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
s1) (CoreSOP
bCoreSOP -> [CoreSOP] -> [CoreSOP]
forall a. a -> [a] -> [a]
:[CoreSOP]
bs) ->
Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p1]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps)
Maybe ([CoreSOP], [Product Var CType])
_ -> []
unifiers' Ct
ct (S [Product Var CType
p2]) (S [P [E CoreSOP
s1 Product Var CType
p1]]) = case Product Var CType -> Maybe ([CoreSOP], [Product Var CType])
collectBases Product Var CType
p2 of
Just (CoreSOP
b:[CoreSOP]
bs,[Product Var CType]
ps) | (CoreSOP -> Bool) -> [CoreSOP] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
s1) (CoreSOP
bCoreSOP -> [CoreSOP] -> [CoreSOP]
forall a. a -> [a] -> [a]
:[CoreSOP]
bs) ->
Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p1])
Maybe ([CoreSOP], [Product Var CType])
_ -> []
unifiers' Ct
ct (S [P ((I Integer
i):[Symbol Var CType]
ps)]) (S [P [I Integer
j]]) =
case Integer -> Integer -> Maybe Integer
safeDiv Integer
j Integer
i of
Just Integer
k -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
k]])
Maybe Integer
_ -> []
unifiers' Ct
ct (S [P [I Integer
j]]) (S [P ((I Integer
i):[Symbol Var CType]
ps)]) =
case Integer -> Integer -> Maybe Integer
safeDiv Integer
j Integer
i of
Just Integer
k -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
k]])
Maybe Integer
_ -> []
unifiers' Ct
ct (S [P [Symbol Var CType]
ps1]) (S [P [Symbol Var CType]
ps2])
| [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
psx = []
| Bool
otherwise = Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps1'']) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps2''])
where
ps1' :: [Symbol Var CType]
ps1' = [Symbol Var CType]
ps1 [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
psx
ps2' :: [Symbol Var CType]
ps2' = [Symbol Var CType]
ps2 [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
psx
ps1'' :: [Symbol Var CType]
ps1'' | [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
ps1' = [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]
| Bool
otherwise = [Symbol Var CType]
ps1'
ps2'' :: [Symbol Var CType]
ps2'' | [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
ps2' = [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]
| Bool
otherwise = [Symbol Var CType]
ps2'
psx :: [Symbol Var CType]
psx = [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
intersect [Symbol Var CType]
ps1 [Symbol Var CType]
ps2
unifiers' Ct
ct (S ((P [I Integer
i]):[Product Var CType]
ps1)) (S ((P [I Integer
j]):[Product Var CType]
ps2))
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
j = Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps1) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S (([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer
jInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
i)])Product Var CType -> [Product Var CType] -> [Product Var CType]
forall a. a -> [a] -> [a]
:[Product Var CType]
ps2))
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
j = Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S (([Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer
iInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
j)])Product Var CType -> [Product Var CType] -> [Product Var CType]
forall a. a -> [a] -> [a]
:[Product Var CType]
ps1)) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps2)
unifiers' Ct
ct s1 :: CoreSOP
s1@(S [Product Var CType]
ps1) s2 :: CoreSOP
s2@(S [Product Var CType]
ps2) = case CoreSOP -> Maybe (CoreSOP, CoreSOP, Bool)
sopToIneq CoreSOP
k1 of
Just (CoreSOP
s1',CoreSOP
s2',Bool
_)
| CoreSOP
s1' CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
/= CoreSOP
s1 Bool -> Bool -> Bool
|| CoreSOP
s2' CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
/= CoreSOP
s1
, Bool
-> ((Bool, Set CType) -> Bool) -> Maybe (Bool, Set CType) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True ((Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(&&) ((Bool, Bool) -> Bool)
-> ((Bool, Set CType) -> (Bool, Bool)) -> (Bool, Set CType) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set CType -> Bool) -> (Bool, Set CType) -> (Bool, Bool)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Set CType -> Bool
forall a. Set a -> Bool
Set.null) (WriterT (Set CType) Maybe Bool -> Maybe (Bool, Set CType)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural CoreSOP
s1'))
, Bool
-> ((Bool, Set CType) -> Bool) -> Maybe (Bool, Set CType) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
True ((Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(&&) ((Bool, Bool) -> Bool)
-> ((Bool, Set CType) -> (Bool, Bool)) -> (Bool, Set CType) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Set CType -> Bool) -> (Bool, Set CType) -> (Bool, Bool)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Set CType -> Bool
forall a. Set a -> Bool
Set.null) (WriterT (Set CType) Maybe Bool -> Maybe (Bool, Set CType)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural CoreSOP
s2'))
-> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct CoreSOP
s1' CoreSOP
s2'
Maybe (CoreSOP, CoreSOP, Bool)
_ | [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
psx
, [Product Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Product Var CType]
ps1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Product Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Product Var CType]
ps2
-> case [CoreUnify] -> [CoreUnify]
forall a. Eq a => [a] -> [a]
nub ([[CoreUnify]] -> [CoreUnify]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ((Product Var CType -> Product Var CType -> [CoreUnify])
-> [Product Var CType] -> [Product Var CType] -> [[CoreUnify]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Product Var CType
x Product Var CType
y -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
x]) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
y])) [Product Var CType]
ps1 [Product Var CType]
ps2)) of
[] -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers'' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps1) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps2)
[CoreUnify
k] | [Product Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Product Var CType]
ps1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Product Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Product Var CType]
ps2 -> [CoreUnify
k]
[CoreUnify]
_ -> []
| [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
psx
, CtEvidence -> Bool
isGiven (Ct -> CtEvidence
ctEvidence Ct
ct)
-> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers'' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps1) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps2)
| [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
psx
-> []
Maybe (CoreSOP, CoreSOP, Bool)
_ -> Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers' Ct
ct ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps1'') ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps2'')
where
k1 :: CoreSOP
k1 = (CoreSOP, CoreSOP, Bool) -> CoreSOP
subtractIneq (CoreSOP
s1,CoreSOP
s2,Bool
True)
ps1' :: [Product Var CType]
ps1' = [Product Var CType]
ps1 [Product Var CType] -> [Product Var CType] -> [Product Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Product Var CType]
psx
ps2' :: [Product Var CType]
ps2' = [Product Var CType]
ps2 [Product Var CType] -> [Product Var CType] -> [Product Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Product Var CType]
psx
ps1'' :: [Product Var CType]
ps1'' | [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
ps1' = [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
0]]
| Bool
otherwise = [Product Var CType]
ps1'
ps2'' :: [Product Var CType]
ps2'' | [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
ps2' = [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
0]]
| Bool
otherwise = [Product Var CType]
ps2'
psx :: [Product Var CType]
psx = [Product Var CType] -> [Product Var CType] -> [Product Var CType]
forall a. Eq a => [a] -> [a] -> [a]
intersect [Product Var CType]
ps1 [Product Var CType]
ps2
unifiers'' :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers'' :: Ct -> CoreSOP -> CoreSOP -> [CoreUnify]
unifiers'' Ct
ct (S [P [I Integer
i],P [V Var
v]]) CoreSOP
s2
| CtEvidence -> Bool
isGiven (Ct -> CtEvidence
ctEvidence Ct
ct) = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
v (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd CoreSOP
s2 ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer -> Integer
forall a. Num a => a -> a
negate Integer
i)]]))]
unifiers'' Ct
ct CoreSOP
s1 (S [P [I Integer
i],P [V Var
v]])
| CtEvidence -> Bool
isGiven (Ct -> CtEvidence
ctEvidence Ct
ct) = [Var -> CoreSOP -> CoreUnify
forall v c. v -> SOP v c -> UnifyItem v c
SubstItem Var
v (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd CoreSOP
s1 ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I (Integer -> Integer
forall a. Num a => a -> a
negate Integer
i)]]))]
unifiers'' Ct
_ CoreSOP
_ CoreSOP
_ = []
collectBases :: CoreProduct -> Maybe ([CoreSOP],[CoreProduct])
collectBases :: Product Var CType -> Maybe ([CoreSOP], [Product Var CType])
collectBases = ([(CoreSOP, Product Var CType)]
-> ([CoreSOP], [Product Var CType]))
-> Maybe [(CoreSOP, Product Var CType)]
-> Maybe ([CoreSOP], [Product Var CType])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(CoreSOP, Product Var CType)] -> ([CoreSOP], [Product Var CType])
forall a b. [(a, b)] -> ([a], [b])
unzip (Maybe [(CoreSOP, Product Var CType)]
-> Maybe ([CoreSOP], [Product Var CType]))
-> (Product Var CType -> Maybe [(CoreSOP, Product Var CType)])
-> Product Var CType
-> Maybe ([CoreSOP], [Product Var CType])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Symbol Var CType -> Maybe (CoreSOP, Product Var CType))
-> [Symbol Var CType] -> Maybe [(CoreSOP, Product Var CType)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Symbol Var CType -> Maybe (CoreSOP, Product Var CType)
forall v c. Symbol v c -> Maybe (SOP v c, Product v c)
go ([Symbol Var CType] -> Maybe [(CoreSOP, Product Var CType)])
-> (Product Var CType -> [Symbol Var CType])
-> Product Var CType
-> Maybe [(CoreSOP, Product Var CType)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Var CType -> [Symbol Var CType]
forall v c. Product v c -> [Symbol v c]
unP
where
go :: Symbol v c -> Maybe (SOP v c, Product v c)
go (E SOP v c
s1 Product v c
p1) = (SOP v c, Product v c) -> Maybe (SOP v c, Product v c)
forall a. a -> Maybe a
Just (SOP v c
s1,Product v c
p1)
go Symbol v c
_ = Maybe (SOP v c, Product v c)
forall a. Maybe a
Nothing
fvSOP :: CoreSOP -> UniqSet TyVar
fvSOP :: CoreSOP -> UniqSet Var
fvSOP = [UniqSet Var] -> UniqSet Var
forall a. [UniqSet a] -> UniqSet a
unionManyUniqSets ([UniqSet Var] -> UniqSet Var)
-> (CoreSOP -> [UniqSet Var]) -> CoreSOP -> UniqSet Var
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Product Var CType -> UniqSet Var)
-> [Product Var CType] -> [UniqSet Var]
forall a b. (a -> b) -> [a] -> [b]
map Product Var CType -> UniqSet Var
fvProduct ([Product Var CType] -> [UniqSet Var])
-> (CoreSOP -> [Product Var CType]) -> CoreSOP -> [UniqSet Var]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreSOP -> [Product Var CType]
forall v c. SOP v c -> [Product v c]
unS
fvProduct :: CoreProduct -> UniqSet TyVar
fvProduct :: Product Var CType -> UniqSet Var
fvProduct = [UniqSet Var] -> UniqSet Var
forall a. [UniqSet a] -> UniqSet a
unionManyUniqSets ([UniqSet Var] -> UniqSet Var)
-> (Product Var CType -> [UniqSet Var])
-> Product Var CType
-> UniqSet Var
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Symbol Var CType -> UniqSet Var)
-> [Symbol Var CType] -> [UniqSet Var]
forall a b. (a -> b) -> [a] -> [b]
map Symbol Var CType -> UniqSet Var
fvSymbol ([Symbol Var CType] -> [UniqSet Var])
-> (Product Var CType -> [Symbol Var CType])
-> Product Var CType
-> [UniqSet Var]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Var CType -> [Symbol Var CType]
forall v c. Product v c -> [Symbol v c]
unP
fvSymbol :: CoreSymbol -> UniqSet TyVar
fvSymbol :: Symbol Var CType -> UniqSet Var
fvSymbol (I Integer
_) = UniqSet Var
forall a. UniqSet a
emptyUniqSet
fvSymbol (C CType
_) = UniqSet Var
forall a. UniqSet a
emptyUniqSet
fvSymbol (V Var
v) = Var -> UniqSet Var
forall a. Uniquable a => a -> UniqSet a
unitUniqSet Var
v
fvSymbol (E CoreSOP
s Product Var CType
p) = CoreSOP -> UniqSet Var
fvSOP CoreSOP
s UniqSet Var -> UniqSet Var -> UniqSet Var
forall a. UniqSet a -> UniqSet a -> UniqSet a
`unionUniqSets` Product Var CType -> UniqSet Var
fvProduct Product Var CType
p
eqFV :: CoreSOP -> CoreSOP -> Bool
eqFV :: CoreSOP -> CoreSOP -> Bool
eqFV = UniqSet Var -> UniqSet Var -> Bool
forall a. Eq a => a -> a -> Bool
(==) (UniqSet Var -> UniqSet Var -> Bool)
-> (CoreSOP -> UniqSet Var) -> CoreSOP -> CoreSOP -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` CoreSOP -> UniqSet Var
fvSOP
containsConstants :: CoreSOP -> Bool
containsConstants :: CoreSOP -> Bool
containsConstants = (Product Var CType -> Bool) -> [Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Symbol Var CType -> Bool) -> [Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Symbol Var CType
c -> case Symbol Var CType
c of {(C CType
_) -> Bool
True; Symbol Var CType
_ -> Bool
False}) ([Symbol Var CType] -> Bool)
-> (Product Var CType -> [Symbol Var CType])
-> Product Var CType
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Product Var CType -> [Symbol Var CType]
forall v c. Product v c -> [Symbol v c]
unP) ([Product Var CType] -> Bool)
-> (CoreSOP -> [Product Var CType]) -> CoreSOP -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoreSOP -> [Product Var CType]
forall v c. SOP v c -> [Product v c]
unS
safeDiv :: Integer -> Integer -> Maybe Integer
safeDiv :: Integer -> Integer -> Maybe Integer
safeDiv Integer
i Integer
j
| Integer
j Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
0
| Bool
otherwise = case Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
divMod Integer
i Integer
j of
(Integer
k,Integer
0) -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
k
(Integer, Integer)
_ -> Maybe Integer
forall a. Maybe a
Nothing
integerLogBase :: Integer -> Integer -> Maybe Integer
integerLogBase :: Integer -> Integer -> Maybe Integer
integerLogBase Integer
x Integer
y | Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
1 Bool -> Bool -> Bool
&& Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 =
let z1 :: Int#
z1 = Integer -> Integer -> Int#
integerLogBase# Integer
x Integer
y
z2 :: Int#
z2 = Integer -> Integer -> Int#
integerLogBase# Integer
x (Integer
yInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
in if Int# -> Bool
isTrue# (Int#
z1 Int# -> Int# -> Int#
==# Int#
z2)
then Maybe Integer
forall a. Maybe a
Nothing
else Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Int# -> Integer
smallInteger Int#
z1)
integerLogBase Integer
_ Integer
_ = Maybe Integer
forall a. Maybe a
Nothing
isNatural :: CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural :: CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural (S []) = Bool -> WriterT (Set CType) Maybe Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
isNatural (S [P []]) = Bool -> WriterT (Set CType) Maybe Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
isNatural (S [P (I Integer
i:[Symbol Var CType]
ps)])
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 = CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps])
| Bool
otherwise = Bool -> WriterT (Set CType) Maybe Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
isNatural (S [P (V Var
_:[Symbol Var CType]
ps)]) = CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps])
isNatural (S [P (E CoreSOP
s Product Var CType
p:[Symbol Var CType]
ps)]) = do
Bool
sN <- CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural CoreSOP
s
Bool
pN <- CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p])
if Bool
sN Bool -> Bool -> Bool
&& Bool
pN
then CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps])
else Maybe (Bool, Set CType) -> WriterT (Set CType) Maybe Bool
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT Maybe (Bool, Set CType)
forall a. Maybe a
Nothing
isNatural (S [P [I (-1)],P [E CoreSOP
s Product Var CType
p]]) = Bool -> Bool -> Bool
(&&) (Bool -> Bool -> Bool)
-> WriterT (Set CType) Maybe Bool
-> WriterT (Set CType) Maybe (Bool -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural CoreSOP
s WriterT (Set CType) Maybe (Bool -> Bool)
-> WriterT (Set CType) Maybe Bool -> WriterT (Set CType) Maybe Bool
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p])
isNatural (S [P (C CType
c:[Symbol Var CType]
ps)]) = do
Set CType -> WriterT (Set CType) Maybe ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell (CType -> Set CType
forall a. a -> Set a
Set.singleton CType
c)
CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ps])
isNatural (S (Product Var CType
p:[Product Var CType]
ps)) = do
Bool
pN <- CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p])
Bool
pK <- CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
ps)
case (Bool
pN,Bool
pK) of
(Bool
True,Bool
True) -> Bool -> WriterT (Set CType) Maybe Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
(Bool
False,Bool
False) -> Bool -> WriterT (Set CType) Maybe Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
(Bool, Bool)
_ -> Maybe (Bool, Set CType) -> WriterT (Set CType) Maybe Bool
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT Maybe (Bool, Set CType)
forall a. Maybe a
Nothing
solveIneq
:: Word
-> Ineq
-> Ineq
-> WriterT (Set CType) Maybe Bool
solveIneq :: Word
-> (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT (Set CType) Maybe Bool
solveIneq Word
0 (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT (Set CType) Maybe Bool
forall a. WriterT (Set CType) Maybe a
noRewrite
solveIneq Word
k want :: (CoreSOP, CoreSOP, Bool)
want@(CoreSOP
_,CoreSOP
_,Bool
True) have :: (CoreSOP, CoreSOP, Bool)
have@(CoreSOP
_,CoreSOP
_,Bool
True)
| (CoreSOP, CoreSOP, Bool)
want (CoreSOP, CoreSOP, Bool) -> (CoreSOP, CoreSOP, Bool) -> Bool
forall a. Eq a => a -> a -> Bool
== (CoreSOP, CoreSOP, Bool)
have
= Bool -> WriterT (Set CType) Maybe Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
| Bool
otherwise
= do
let
new :: [([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)]
new = (((CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))])
-> Maybe
([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType))
-> [(CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]]
-> [([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\(CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
f -> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> Maybe
([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))], Set CType)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT ((CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
f (CoreSOP, CoreSOP, Bool)
want (CoreSOP, CoreSOP, Bool)
have)) [(CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]]
ineqRules
solved :: [([(Bool, Set CType)], Set CType)]
solved = (([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)
-> ([(Bool, Set CType)], Set CType))
-> [([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)]
-> [([(Bool, Set CType)], Set CType)]
forall a b. (a -> b) -> [a] -> [b]
map (([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> [(Bool, Set CType)])
-> ([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)
-> ([(Bool, Set CType)], Set CType)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first ((((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))
-> Maybe (Bool, Set CType))
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> [(Bool, Set CType)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (WriterT (Set CType) Maybe Bool -> Maybe (Bool, Set CType)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (WriterT (Set CType) Maybe Bool -> Maybe (Bool, Set CType))
-> (((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))
-> WriterT (Set CType) Maybe Bool)
-> ((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))
-> Maybe (Bool, Set CType)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool) -> WriterT (Set CType) Maybe Bool)
-> ((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))
-> WriterT (Set CType) Maybe Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Word
-> (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT (Set CType) Maybe Bool
solveIneq (Word
kWord -> Word -> Word
forall a. Num a => a -> a -> a
-Word
1))))) [([((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))],
Set CType)]
new
solved1 :: [((Bool, Set CType), Set CType)]
solved1 = (([(Bool, Set CType)], Set CType)
-> ((Bool, Set CType), Set CType))
-> [([(Bool, Set CType)], Set CType)]
-> [((Bool, Set CType), Set CType)]
forall a b. (a -> b) -> [a] -> [b]
map (([(Bool, Set CType)] -> (Bool, Set CType))
-> ([(Bool, Set CType)], Set CType)
-> ((Bool, Set CType), Set CType)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first [(Bool, Set CType)] -> (Bool, Set CType)
forall a. [(Bool, Set a)] -> (Bool, Set a)
solvedInEqSmallestConstraint) [([(Bool, Set CType)], Set CType)]
solved
solved2 :: [(Bool, Set CType)]
solved2 = (((Bool, Set CType), Set CType) -> (Bool, Set CType))
-> [((Bool, Set CType), Set CType)] -> [(Bool, Set CType)]
forall a b. (a -> b) -> [a] -> [b]
map (\((Bool
b,Set CType
s1),Set CType
s2) -> (Bool
b,Set CType -> Set CType -> Set CType
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set CType
s1 Set CType
s2)) [((Bool, Set CType), Set CType)]
solved1
solved3 :: (Bool, Set CType)
solved3 = [(Bool, Set CType)] -> (Bool, Set CType)
forall a. [(Bool, Set a)] -> (Bool, Set a)
solvedInEqSmallestConstraint [(Bool, Set CType)]
solved2
if [([(Bool, Set CType)], Set CType)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([(Bool, Set CType)], Set CType)]
solved then
WriterT (Set CType) Maybe Bool
forall a. WriterT (Set CType) Maybe a
noRewrite
else do
Maybe (Bool, Set CType) -> WriterT (Set CType) Maybe Bool
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT ((Bool, Set CType) -> Maybe (Bool, Set CType)
forall a. a -> Maybe a
Just (Bool, Set CType)
solved3)
solveIneq Word
_ (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = Bool -> WriterT (Set CType) Maybe Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
solvedInEqSmallestConstraint :: [(Bool,Set a)] -> (Bool, Set a)
solvedInEqSmallestConstraint :: [(Bool, Set a)] -> (Bool, Set a)
solvedInEqSmallestConstraint = (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
forall a. (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
go (Bool
False, Set a
forall a. Set a
Set.empty)
where
go :: (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
go (Bool, Set a)
bs [] = (Bool, Set a)
bs
go (Bool
b,Set a
s) ((Bool
b1,Set a
s1):[(Bool, Set a)]
solved)
| Bool -> Bool
not Bool
b Bool -> Bool -> Bool
&& Bool
b1
= (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
go (Bool
b1,Set a
s1) [(Bool, Set a)]
solved
| Bool
b Bool -> Bool -> Bool
&& Bool
b1
, Set a -> Int
forall a. Set a -> Int
Set.size Set a
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Set a -> Int
forall a. Set a -> Int
Set.size Set a
s1
= (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
go (Bool
b1,Set a
s1) [(Bool, Set a)]
solved
| Bool
otherwise
= (Bool, Set a) -> [(Bool, Set a)] -> (Bool, Set a)
go (Bool
b,Set a
s) [(Bool, Set a)]
solved
instantSolveIneq
:: Word
-> Ineq
-> WriterT (Set CType) Maybe Bool
instantSolveIneq :: Word -> (CoreSOP, CoreSOP, Bool) -> WriterT (Set CType) Maybe Bool
instantSolveIneq Word
k (CoreSOP, CoreSOP, Bool)
u = Word
-> (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT (Set CType) Maybe Bool
solveIneq Word
k (CoreSOP, CoreSOP, Bool)
u (CoreSOP
forall v c. SOP v c
one,CoreSOP
forall v c. SOP v c
one,Bool
True)
where
one :: SOP v c
one = [Product v c] -> SOP v c
forall v c. [Product v c] -> SOP v c
S [[Symbol v c] -> Product v c
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol v c
forall v c. Integer -> Symbol v c
I Integer
1]]
type Ineq = (CoreSOP, CoreSOP, Bool)
type IneqRule = Ineq -> Ineq -> WriterT (Set CType) Maybe [(Ineq,Ineq)]
noRewrite :: WriterT (Set CType) Maybe a
noRewrite :: WriterT (Set CType) Maybe a
noRewrite = Maybe (a, Set CType) -> WriterT (Set CType) Maybe a
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT Maybe (a, Set CType)
forall a. Maybe a
Nothing
ineqRules
:: [IneqRule]
ineqRules :: [(CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]]
ineqRules =
[ (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
leTrans
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
plusMonotone
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
timesMonotone
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
powMonotone
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
pow2MonotoneSpecial
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
haveSmaller
, (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
haveBigger
]
leTrans :: IneqRule
leTrans :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
leTrans want :: (CoreSOP, CoreSOP, Bool)
want@(CoreSOP
a,CoreSOP
b,Bool
le) (CoreSOP
x,CoreSOP
y,Bool
_)
| S [P [I Integer
a']] <- CoreSOP
a
, S [P [I Integer
x']] <- CoreSOP
x
, Integer
x' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
a'
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP
a,CoreSOP
y,Bool
le))]
| S [P [I Integer
b']] <- CoreSOP
b
, S [P [I Integer
y']] <- CoreSOP
y
, Integer
y' Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
b'
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP
x,CoreSOP
b,Bool
le))]
leTrans (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
plusMonotone :: IneqRule
plusMonotone :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
plusMonotone (CoreSOP, CoreSOP, Bool)
want (CoreSOP, CoreSOP, Bool)
have
| Just (CoreSOP, CoreSOP, Bool)
want' <- CoreSOP -> Maybe (CoreSOP, CoreSOP, Bool)
sopToIneq ((CoreSOP, CoreSOP, Bool) -> CoreSOP
subtractIneq (CoreSOP, CoreSOP, Bool)
want)
, (CoreSOP, CoreSOP, Bool)
want' (CoreSOP, CoreSOP, Bool) -> (CoreSOP, CoreSOP, Bool) -> Bool
forall a. Eq a => a -> a -> Bool
/= (CoreSOP, CoreSOP, Bool)
want
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want',(CoreSOP, CoreSOP, Bool)
have)]
| Just (CoreSOP, CoreSOP, Bool)
have' <- CoreSOP -> Maybe (CoreSOP, CoreSOP, Bool)
sopToIneq ((CoreSOP, CoreSOP, Bool) -> CoreSOP
subtractIneq (CoreSOP, CoreSOP, Bool)
have)
, (CoreSOP, CoreSOP, Bool)
have' (CoreSOP, CoreSOP, Bool) -> (CoreSOP, CoreSOP, Bool) -> Bool
forall a. Eq a => a -> a -> Bool
/= (CoreSOP, CoreSOP, Bool)
have
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP, CoreSOP, Bool)
have')]
plusMonotone (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
haveSmaller :: IneqRule
haveSmaller :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
haveSmaller (CoreSOP, CoreSOP, Bool)
want (CoreSOP, CoreSOP, Bool)
have
| (S (Product Var CType
x:Product Var CType
y:[Product Var CType]
ys),CoreSOP
us,Bool
True) <- (CoreSOP, CoreSOP, Bool)
have
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S (Product Var CType
xProduct Var CType -> [Product Var CType] -> [Product Var CType]
forall a. a -> [a] -> [a]
:[Product Var CType]
ys),CoreSOP
us,Bool
True))
,((CoreSOP, CoreSOP, Bool)
want,([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S (Product Var CType
yProduct Var CType -> [Product Var CType] -> [Product Var CType]
forall a. a -> [a] -> [a]
:[Product Var CType]
ys),CoreSOP
us,Bool
True))
]
| (S [P [I Integer
1]], S [P (I Integer
_:p :: [Symbol Var CType]
p@(Symbol Var CType
_:[Symbol Var CType]
_))],Bool
True) <- (CoreSOP, CoreSOP, Bool)
have
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]],[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
p],Bool
True))]
haveSmaller (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
haveBigger :: IneqRule
haveBigger :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
haveBigger (CoreSOP, CoreSOP, Bool)
want (CoreSOP, CoreSOP, Bool)
have
| (CoreSOP
_ ,S [Product Var CType]
vs,Bool
True) <- (CoreSOP, CoreSOP, Bool)
want
, (CoreSOP
as,S [Product Var CType]
bs,Bool
True) <- (CoreSOP, CoreSOP, Bool)
have
, let vs' :: [Product Var CType]
vs' = [Product Var CType]
vs [Product Var CType] -> [Product Var CType] -> [Product Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Product Var CType]
bs
, Bool -> Bool
not ([Product Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Product Var CType]
vs')
= do
Bool
b <- CoreSOP -> WriterT (Set CType) Maybe Bool
isNatural ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
vs')
if Bool
b then
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP
as,CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPAdd ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
bs) ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType]
vs'),Bool
True))]
else
WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
haveBigger (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
timesMonotone :: IneqRule
timesMonotone :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
timesMonotone want :: (CoreSOP, CoreSOP, Bool)
want@(CoreSOP
a,CoreSOP
b,Bool
le) have :: (CoreSOP, CoreSOP, Bool)
have@(CoreSOP
x,CoreSOP
y,Bool
_)
| S [P a' :: [Symbol Var CType]
a'@(Symbol Var CType
_:Symbol Var CType
_:[Symbol Var CType]
_)] <- CoreSOP
a
, S [P [Symbol Var CType]
x'] <- CoreSOP
x
, S [P [Symbol Var CType]
y'] <- CoreSOP
y
, let ax :: [Symbol Var CType]
ax = [Symbol Var CType]
a' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
x'
, let ay :: [Symbol Var CType]
ay = [Symbol Var CType]
a' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
y'
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
ax)
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
ay)
, let az :: CoreSOP
az = if [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
ax Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
ay then [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ax] else [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ay]
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
az CoreSOP
x, CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
az CoreSOP
y,Bool
le))]
| S [P b' :: [Symbol Var CType]
b'@(Symbol Var CType
_:Symbol Var CType
_:[Symbol Var CType]
_)] <- CoreSOP
b
, S [P [Symbol Var CType]
x'] <- CoreSOP
x
, S [P [Symbol Var CType]
y'] <- CoreSOP
y
, let bx :: [Symbol Var CType]
bx = [Symbol Var CType]
b' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
x'
, let by :: [Symbol Var CType]
by = [Symbol Var CType]
b' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
y'
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
bx)
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
by)
, let bz :: CoreSOP
bz = if [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
bx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
by then [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
bx] else [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
by]
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
bz CoreSOP
x, CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
bz CoreSOP
y,Bool
le))]
| S [P x' :: [Symbol Var CType]
x'@(Symbol Var CType
_:Symbol Var CType
_:[Symbol Var CType]
_)] <- CoreSOP
x
, S [P [Symbol Var CType]
a'] <- CoreSOP
a
, S [P [Symbol Var CType]
b'] <- CoreSOP
b
, let xa :: [Symbol Var CType]
xa = [Symbol Var CType]
x' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
a'
, let xb :: [Symbol Var CType]
xb = [Symbol Var CType]
x' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
b'
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
xa)
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
xb)
, let xz :: CoreSOP
xz = if [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
xa Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
xb then [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
xa] else [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
xb]
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
xz CoreSOP
a, CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
xz CoreSOP
b,Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
| S [P y' :: [Symbol Var CType]
y'@(Symbol Var CType
_:Symbol Var CType
_:[Symbol Var CType]
_)] <- CoreSOP
y
, S [P [Symbol Var CType]
a'] <- CoreSOP
a
, S [P [Symbol Var CType]
b'] <- CoreSOP
b
, let ya :: [Symbol Var CType]
ya = [Symbol Var CType]
y' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
a'
, let yb :: [Symbol Var CType]
yb = [Symbol Var CType]
y' [Symbol Var CType] -> [Symbol Var CType] -> [Symbol Var CType]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Symbol Var CType]
b'
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
ya)
, Bool -> Bool
not ([Symbol Var CType] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Symbol Var CType]
yb)
, let yz :: CoreSOP
yz = if [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
ya Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= [Symbol Var CType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Symbol Var CType]
yb then [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
ya] else [Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Symbol Var CType]
yb]
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
yz CoreSOP
a, CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
yz CoreSOP
b,Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
timesMonotone (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
powMonotone :: IneqRule
powMonotone :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
powMonotone (CoreSOP, CoreSOP, Bool)
want (CoreSOP
x, S [P [E CoreSOP
yS Product Var CType
yP]],Bool
le)
= case CoreSOP
x of
S [P [E CoreSOP
xS Product Var CType
xP]]
| CoreSOP
xS CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
yS
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
xP],[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
yP],Bool
le))]
| Product Var CType
xP Product Var CType -> Product Var CType -> Bool
forall a. Eq a => a -> a -> Bool
== Product Var CType
yP
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP
xS,CoreSOP
yS,Bool
le))]
CoreSOP
_ | CoreSOP
x CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
yS
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]],[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
yP],Bool
le))]
CoreSOP
_ -> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
powMonotone (CoreSOP
a,S [P [E CoreSOP
bS Product Var CType
bP]],Bool
le) (CoreSOP, CoreSOP, Bool)
have
= case CoreSOP
a of
S [P [E CoreSOP
aS Product Var CType
aP]]
| CoreSOP
aS CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
bS
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
aP],[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
bP],Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
| Product Var CType
aP Product Var CType -> Product Var CType -> Bool
forall a. Eq a => a -> a -> Bool
== Product Var CType
bP
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP
aS,CoreSOP
bS,Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
CoreSOP
_ | CoreSOP
a CoreSOP -> CoreSOP -> Bool
forall a. Eq a => a -> a -> Bool
== CoreSOP
bS
-> [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [(([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
1]],[Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
bP],Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
CoreSOP
_ -> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
powMonotone (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
pow2MonotoneSpecial :: IneqRule
pow2MonotoneSpecial :: (CoreSOP, CoreSOP, Bool)
-> (CoreSOP, CoreSOP, Bool)
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
pow2MonotoneSpecial (CoreSOP
a,CoreSOP
b,Bool
le) (CoreSOP, CoreSOP, Bool)
have
| Just CoreSOP
a' <- Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
2 CoreSOP
a
, Just CoreSOP
b' <- Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
2 CoreSOP
b
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP
a',CoreSOP
b',Bool
le),(CoreSOP, CoreSOP, Bool)
have)]
pow2MonotoneSpecial (CoreSOP, CoreSOP, Bool)
want (CoreSOP
x,CoreSOP
y,Bool
le)
| Just CoreSOP
x' <- Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
2 CoreSOP
x
, Just CoreSOP
y' <- Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
2 CoreSOP
y
= [((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
-> WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [((CoreSOP, CoreSOP, Bool)
want,(CoreSOP
x',CoreSOP
y',Bool
le))]
pow2MonotoneSpecial (CoreSOP, CoreSOP, Bool)
_ (CoreSOP, CoreSOP, Bool)
_ = WriterT
(Set CType)
Maybe
[((CoreSOP, CoreSOP, Bool), (CoreSOP, CoreSOP, Bool))]
forall a. WriterT (Set CType) Maybe a
noRewrite
facSOP
:: Integer
-> CoreSOP
-> Maybe CoreSOP
facSOP :: Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
n (S [P [Symbol Var CType]
ps]) = ([CoreSOP] -> CoreSOP) -> Maybe [CoreSOP] -> Maybe CoreSOP
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S ([Product Var CType] -> CoreSOP)
-> ([CoreSOP] -> [Product Var CType]) -> [CoreSOP] -> CoreSOP
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Product Var CType]] -> [Product Var CType]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Product Var CType]] -> [Product Var CType])
-> ([CoreSOP] -> [[Product Var CType]])
-> [CoreSOP]
-> [Product Var CType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CoreSOP -> [Product Var CType])
-> [CoreSOP] -> [[Product Var CType]]
forall a b. (a -> b) -> [a] -> [b]
map CoreSOP -> [Product Var CType]
forall v c. SOP v c -> [Product v c]
unS) ((Symbol Var CType -> Maybe CoreSOP)
-> [Symbol Var CType] -> Maybe [CoreSOP]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (Integer -> Symbol Var CType -> Maybe CoreSOP
facSymbol Integer
n) [Symbol Var CType]
ps)
facSOP Integer
_ CoreSOP
_ = Maybe CoreSOP
forall a. Maybe a
Nothing
facSymbol
:: Integer
-> CoreSymbol
-> Maybe CoreSOP
facSymbol :: Integer -> Symbol Var CType -> Maybe CoreSOP
facSymbol Integer
n (I Integer
i)
| Just Integer
j <- Integer -> Integer -> Maybe Integer
integerLogBase Integer
n Integer
i
= CoreSOP -> Maybe CoreSOP
forall a. a -> Maybe a
Just ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [[Symbol Var CType] -> Product Var CType
forall v c. [Symbol v c] -> Product v c
P [Integer -> Symbol Var CType
forall v c. Integer -> Symbol v c
I Integer
j]])
facSymbol Integer
n (E CoreSOP
s Product Var CType
p)
| Just CoreSOP
s' <- Integer -> CoreSOP -> Maybe CoreSOP
facSOP Integer
n CoreSOP
s
= CoreSOP -> Maybe CoreSOP
forall a. a -> Maybe a
Just (CoreSOP -> CoreSOP -> CoreSOP
forall v c. (Ord v, Ord c) => SOP v c -> SOP v c -> SOP v c
mergeSOPMul CoreSOP
s' ([Product Var CType] -> CoreSOP
forall v c. [Product v c] -> SOP v c
S [Product Var CType
p]))
facSymbol Integer
_ Symbol Var CType
_ = Maybe CoreSOP
forall a. Maybe a
Nothing