{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Circuit.Shared
(
Bias (..),
Pick (..),
Schedule (..),
Shared (..),
SigShared (..),
AlgShared,
)
where
import Circuit.Category (Category (..), K (..))
import Circuit.Channel (Channel (..))
import Circuit.Syntax
( Algebra (..),
SigCompose,
Syntax,
(:+:),
)
import Circuit.Tensor (Bias (..), Tensor (..))
import Circuit.Trace (SigYank)
import Control.Monad (Monad)
import Data.Kind (Type)
import Data.These (These (..))
import Prelude hiding (id, (.))
data Pick = L | R | Both Bias
deriving (Pick -> Pick -> Bool
(Pick -> Pick -> Bool) -> (Pick -> Pick -> Bool) -> Eq Pick
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Pick -> Pick -> Bool
== :: Pick -> Pick -> Bool
$c/= :: Pick -> Pick -> Bool
/= :: Pick -> Pick -> Bool
Eq, Int -> Pick -> ShowS
[Pick] -> ShowS
Pick -> String
(Int -> Pick -> ShowS)
-> (Pick -> String) -> ([Pick] -> ShowS) -> Show Pick
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Pick -> ShowS
showsPrec :: Int -> Pick -> ShowS
$cshow :: Pick -> String
show :: Pick -> String
$cshowList :: [Pick] -> ShowS
showList :: [Pick] -> ShowS
Show)
newtype Schedule s = Schedule
{
forall s. Schedule s -> s -> (s, Pick)
chooseS :: s -> (s, Pick)
}
class (Tensor t arr) => Shared t arr where
sharedBy ::
Schedule s ->
arr (t s a) (t s b) ->
arr (t s c) (t s d) ->
arr (t s (t a c)) (t s (These b d))
instance Shared (,) (->) where
sharedBy :: forall s a b c d.
Schedule s
-> ((s, a) -> (s, b))
-> ((s, c) -> (s, d))
-> (s, (a, c)) -> (s, These b d)
sharedBy Schedule s
sched (s, a) -> (s, b)
f (s, c) -> (s, d)
g (s
s, (a
a, c
c)) =
let (s
s', Pick
pick) = Schedule s -> s -> (s, Pick)
forall s. Schedule s -> s -> (s, Pick)
chooseS Schedule s
sched s
s
in case Pick
pick of
Pick
L ->
let (s
s'', b
b) = (s, a) -> (s, b)
f (s
s', a
a)
in (s
s'', b -> These b d
forall a b. a -> These a b
This b
b)
Pick
R ->
let (s
s'', d
d) = (s, c) -> (s, d)
g (s
s', c
c)
in (s
s'', d -> These b d
forall a b. b -> These a b
That d
d)
Both Bias
LeftFirst ->
let (s
s'', b
b) = (s, a) -> (s, b)
f (s
s', a
a)
(s
s''', d
d) = (s, c) -> (s, d)
g (s
s'', c
c)
in (s
s''', b -> d -> These b d
forall a b. a -> b -> These a b
These b
b d
d)
Both Bias
RightFirst ->
let (s
s'', d
d) = (s, c) -> (s, d)
g (s
s', c
c)
(s
s''', b
b) = (s, a) -> (s, b)
f (s
s'', a
a)
in (s
s''', b -> d -> These b d
forall a b. a -> b -> These a b
These b
b d
d)
{-# INLINE sharedBy #-}
instance (Monad m) => Shared (,) (K m) where
sharedBy :: forall s a b c d.
Schedule s
-> K m (s, a) (s, b)
-> K m (s, c) (s, d)
-> K m (s, (a, c)) (s, These b d)
sharedBy Schedule s
sched (K (s, a) -> m (s, b)
f) (K (s, c) -> m (s, d)
g) =
((s, (a, c)) -> m (s, These b d)) -> K m (s, (a, c)) (s, These b d)
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K (((s, (a, c)) -> m (s, These b d))
-> K m (s, (a, c)) (s, These b d))
-> ((s, (a, c)) -> m (s, These b d))
-> K m (s, (a, c)) (s, These b d)
forall a b. (a -> b) -> a -> b
$ \(s
s, (a
a, c
c)) -> do
let (s
s', Pick
pick) = Schedule s -> s -> (s, Pick)
forall s. Schedule s -> s -> (s, Pick)
chooseS Schedule s
sched s
s
case Pick
pick of
Pick
L -> do
(s'', b) <- (s, a) -> m (s, b)
f (s
s', a
a)
pure (s'', This b)
Pick
R -> do
(s'', d) <- (s, c) -> m (s, d)
g (s
s', c
c)
pure (s'', That d)
Both Bias
LeftFirst -> do
(s'', b) <- (s, a) -> m (s, b)
f (s
s', a
a)
(s''', d) <- g (s'', c)
pure (s''', These b d)
Both Bias
RightFirst -> do
(s'', d) <- (s, c) -> m (s, d)
g (s
s', c
c)
(s''', b) <- f (s'', a)
pure (s''', These b d)
{-# INLINE sharedBy #-}
data SigShared (t :: Type -> Type -> Type) arr rec i o where
SigShared ::
Schedule s ->
rec (t s a) (t s b) ->
rec (t s c) (t s d) ->
SigShared t arr rec (t s (t a c)) (t s (These b d))
instance (Shared t arr') => Algebra (SigShared t) arr arr' where
type Ctx (SigShared t) arr arr' = Shared t arr'
alg :: forall (rec :: * -> * -> *) a b.
Ctx (SigShared t) arr arr' =>
(forall x y. arr x y -> arr' x y)
-> (forall x y. rec x y -> arr' x y)
-> SigShared t arr rec a b
-> arr' a b
alg forall x y. arr x y -> arr' x y
_ forall x y. rec x y -> arr' x y
rec (SigShared Schedule s
sched rec (t s a) (t s b)
f rec (t s c) (t s d)
g) = Schedule s
-> arr' (t s a) (t s b)
-> arr' (t s c) (t s d)
-> arr' (t s (t a c)) (t s (These b d))
forall s a b c d.
Schedule s
-> arr' (t s a) (t s b)
-> arr' (t s c) (t s d)
-> arr' (t s (t a c)) (t s (These b d))
forall (t :: * -> * -> *) (arr :: * -> * -> *) s a b c d.
Shared t arr =>
Schedule s
-> arr (t s a) (t s b)
-> arr (t s c) (t s d)
-> arr (t s (t a c)) (t s (These b d))
sharedBy Schedule s
sched (rec (t s a) (t s b) -> arr' (t s a) (t s b)
forall x y. rec x y -> arr' x y
rec rec (t s a) (t s b)
f) (rec (t s c) (t s d) -> arr' (t s c) (t s d)
forall x y. rec x y -> arr' x y
rec rec (t s c) (t s d)
g)
type AlgShared t arr = Syntax (SigCompose :+: SigShared t :+: SigYank t) arr