gasp-1.4.0.0: Algebra/Category/Objects.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Algebra.Category.Objects where
import Algebra.Classes
import Algebra.Types
import Prelude (Int, Ord (..),otherwise,($),Show, Semigroup(..),show)
import Data.Kind
import Data.Constraint
import Test.QuickCheck
import Test.QuickCheck.Property
import Control.Applicative
type TimesCon con = forall a b. (con a, con b) => con (a⊗b) :: Constraint
type DualCon con = forall a. (con a) => con (Dual a) :: Constraint
type PlusCon con = forall a b. (con a, con b) => con (a⊕b) :: Constraint
type Con' x con = forall a b. (con a, con b) => con (a `x` b) :: Constraint
type UnCon o con = forall a. (con a) => con (o a) :: Constraint
type TimesCon1 con = forall x a b. (con (a (b x))) => con ((a⊗b) x) :: Constraint
type PlusCon1 con = forall {k} (x :: k) a b. (con (a x), con (b x)) => con ((a⊕b) x) :: Constraint
type OneCon1 (con :: Type -> Constraint) = forall x. con x => con (One x) :: Constraint
type ZeroCon1 con = forall x. con x => con (Zero x) :: Constraint
-- type LConTensor con = forall a b. con (a⊗b) => con a :: Constraint
-- type RConTensor con = forall a b. con (a⊗b) => con a :: Constraint
reprCon :: forall con a x i t o. (Con' x con, Con' t con, con i, con o) => Repr x i t o a -> Dict (con a)
reprCon = \case
RPlus a b -> Dict \\ reprCon @con a \\ reprCon @con b
RTimes a b -> Dict \\ reprCon @con a \\ reprCon @con b
RZero -> Dict
ROne -> Dict
reprCon1Comp :: forall (z :: Type) con (a :: Type -> Type) b. CompClosed con -> con z => CRepr a -> CRepr b -> Dict (con (a (b z)))
reprCon1Comp c@CompClosed{} a b = Dict \\ reprCon1 @(b z) c a \\ reprCon1 @z c b
reprCon1 :: forall (z :: Type) (con :: Type -> Constraint) a. con z => CompClosed con -> CRepr a -> Dict (con (a z))
reprCon1 c@CompClosed{..} = \case
RPlus a b -> plus1Closed \\ reprCon1 @z c a \\ reprCon1 @z c b
RTimes a b -> times1Closed \\ reprCon1Comp @z c a b
RZero -> zero1Closed
ROne -> one1Closed
type ProdObj :: forall {k}. (k -> Constraint) -> Constraint
class ProdObj (con :: k -> Constraint) where
objprod :: (con a, con b) => Dict (con (a⊗b))
objfstsnd :: forall z a b. (z ~ (a⊗b), con z) => Dict (con a, con b)
objone :: Dict (con One)
type DualObj :: forall {k}. (k -> Constraint) -> Constraint
class ProdObj con => DualObj (con :: k -> Constraint) where
objdual :: con a => Dict (con (Dual a))
objdual' :: forall z a. (z ~ Dual a, con z) => Dict (con a)
objFstSnd :: forall con a b. ProdObj con => Dict (con (a ⊗ b)) -> Dict (con a, con b)
objFstSnd Dict = objfstsnd @con @(a ⊗ b)
{-
type SumObj :: forall {k}. (k -> Constraint) -> Constraint
class SumObj (con :: k -> Constraint) where -- TensorClosed constraint causes problems in the Free module. (probably GHC bug)
objsum :: (con a, con b) => Dict (con (a⊕b))
objleftright :: forall z a b. (z ~ (a⊕b), con z) => Dict (con a, con b)
objzero :: Dict (con Zero)
objSumProxy :: (SumObj con, con a, con b) => proxy1 a -> proxy2 b -> Dict (con (a⊕b))
objSumProxy _ _ = objsum
objProdProxy :: (ProdObj con, con a, con b) => proxy1 a -> proxy2 b -> Dict (con (a⊗b))
objProdProxy _ _ = objprod
instance ProdObj Trivial where
objprod = Dict
objfstsnd = Dict
objone = Dict
instance SumObj Trivial where
objsum = Dict
objleftright = Dict
objzero = Dict
instance ProdObj Finite where
objprod = Dict
objfstsnd = finiteFstsnd
objone = Dict
instance SumObj Finite where
objsum = Dict
objleftright = finiteLeftRight
objzero = Dict
-}
type Trivial :: k -> Constraint
class Trivial x
instance Trivial x
data Some1 f where
Some1 :: f x -> Some1 f
sizedArbRepr :: Int -> Gen (Some1 (Repr x i t o))
sizedArbRepr n
| n <= 1 = frequency [(1,pure(Some1 RZero)), (3,pure(Some1 ROne))]
| otherwise = do
Some1 l <- sizedArbRepr (n `div` 2)
Some1 r <- sizedArbRepr (n `div` 2)
elements [Some1 (RPlus l r),Some1 (RTimes l r)]
sizedArbSum :: Int -> Gen (Some1 (Repr x i t o))
sizedArbSum n
| n <= 1 = frequency [(1,pure(Some1 RZero)), (3,pure(Some1 ROne))]
| otherwise = do
Some1 l <- sizedArbSum (n `div` 2)
Some1 r <- sizedArbSum (n `div` 2)
elements [Some1 (RPlus l r)]
isArbitrary1 :: CRepr x -> Dict (Arbitrary1 x)
isArbitrary1 = reprCon
isCoArbitrary :: MRepr x -> Dict (CoArbitrary x)
isCoArbitrary = reprCon
instance Arbitrary (Some1 (Repr x i t o)) where
arbitrary = sized sizedArbRepr
forallSumType :: forall {k} x i t o. (forall (a :: k). Repr x i t o a -> Property) -> Property
forallSumType gen = MkProperty $ do
Some1 t <- (sized sizedArbSum :: Gen (Some1 (Repr x i t o)))
unProperty (counterexample ("obj: " <> show t) (property (gen t)))
forallType :: forall {k} x i t o. (forall (a :: k). Repr x i t o a -> Property) -> Property
forallType gen = MkProperty $ do
Some1 t <- (arbitrary :: Gen (Some1 (Repr x i t o)))
unProperty (counterexample ("obj: " <> show t) (property (gen t)))
arbitrary2' :: forall f a b proxy. Arbitrary (f a b) => proxy a -> proxy b -> Gen (f a b)
arbitrary2' _ _ = arbitrary
forallMorphism :: forall f a b x i t o. (Show (f a b), Arbitrary (f a b))
=> Repr x i t o a -> Repr x i t o b -> (f a b -> Property) -> Property
forallMorphism t1 t2 = forAll (arbitrary2' t1 t2)