{-# LANGUAGE OverloadedStrings #-}
module Circuit.Agent.Delivery
(
deliversToSemiring,
DelRel,
copyRel,
discardRel,
broadcastRel,
emptyRel,
namedRel,
deliveryRel,
deliversRel,
deliveryMatrix,
topologyMatrix,
isNilpotent,
matrixPowers,
)
where
import Circuit.Mat.Dense (Matrix (..), fromLists, matTimes, toLists)
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Text (Text, empty)
import Data.Vector.Unboxed qualified as VU
import Harpie.Array qualified as A
import NumHask.Algebra.Additive (Additive (..))
import NumHask.Algebra.Multiplicative (Multiplicative (..))
import Prelude hiding ((*), (+))
deliversToSemiring ::
(Additive r, Multiplicative r) =>
[Text] ->
Text ->
r
deliversToSemiring :: forall r. (Additive r, Multiplicative r) => [Text] -> Text -> r
deliversToSemiring [Text]
recipients Text
who
| [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
recipients = r
forall a. Additive a => a
zero
| [Text]
recipients [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== [Text
empty] = r
forall a. Additive a => a
zero
| (Text
"all" :: Text) Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
recipients = r
forall a. Multiplicative a => a
one
| Text
who Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
recipients = r
forall a. Multiplicative a => a
one
| Bool
otherwise = r
forall a. Additive a => a
zero
type DelRel a = Set ((), a)
copyRel :: Set a -> Set (a, (a, a))
copyRel :: forall a. Set a -> Set (a, (a, a))
copyRel Set a
agents = (a -> (a, (a, a))) -> Set a -> Set (a, (a, a))
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic (\a
a -> (a
a, (a
a, a
a))) Set a
agents
discardRel :: Set a -> Set (a, ())
discardRel :: forall a. Set a -> Set (a, ())
discardRel Set a
agents = (a -> (a, ())) -> Set a -> Set (a, ())
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic (\a
a -> (a
a, ())) Set a
agents
broadcastRel :: Set a -> DelRel a
broadcastRel :: forall a. Set a -> DelRel a
broadcastRel Set a
agents = (a -> ((), a)) -> Set a -> Set ((), a)
forall a b. (a -> b) -> Set a -> Set b
Set.mapMonotonic ((),) Set a
agents
emptyRel :: DelRel a
emptyRel :: forall a. DelRel a
emptyRel = Set ((), a)
forall a. Set a
Set.empty
namedRel :: a -> DelRel a
namedRel :: forall a. a -> DelRel a
namedRel a
a = ((), a) -> Set ((), a)
forall a. a -> Set a
Set.singleton ((), a
a)
deliveryRel ::
Set Text ->
[Text] ->
DelRel Text
deliveryRel :: Set Text -> [Text] -> DelRel Text
deliveryRel Set Text
agents [Text]
tos
| [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
tos = DelRel Text
forall a. DelRel a
emptyRel
| [Text]
tos [Text] -> [Text] -> Bool
forall a. Eq a => a -> a -> Bool
== [Text
empty] = DelRel Text
forall a. DelRel a
emptyRel
| (Text
"all" :: Text) Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
tos = Set Text -> DelRel Text
forall a. Set a -> DelRel a
broadcastRel Set Text
agents
| Bool
otherwise = [((), Text)] -> DelRel Text
forall a. Ord a => [a] -> Set a
Set.fromList [((), Text
a) | Text
a <- [Text]
tos]
deliversRel :: DelRel Text -> Set Text -> Bool
deliversRel :: DelRel Text -> Set Text -> Bool
deliversRel DelRel Text
rel Set Text
subs = Bool -> Bool
not (Set Text -> Bool
forall a. Set a -> Bool
Set.null (Set Text
image Set Text -> Set Text -> Set Text
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` Set Text
subs))
where
image :: Set Text
image = (((), Text) -> Text) -> DelRel Text -> Set Text
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map ((), Text) -> Text
forall a b. (a, b) -> b
snd DelRel Text
rel
deliveryMatrix ::
(Additive r, Multiplicative r) =>
[Text] ->
[[Text]] ->
Matrix r
deliveryMatrix :: forall r.
(Additive r, Multiplicative r) =>
[Text] -> [[Text]] -> Matrix r
deliveryMatrix [Text]
agents [[Text]]
recipients =
[[r]] -> Matrix r
forall a. [[a]] -> Matrix a
fromLists [(Text -> r) -> [Text] -> [r]
forall a b. (a -> b) -> [a] -> [b]
map ([Text] -> Text -> r
forall r. (Additive r, Multiplicative r) => [Text] -> Text -> r
deliversToSemiring [Text]
recips) [Text]
agents | [Text]
recips <- [[Text]]
recipients]
topologyMatrix ::
(Additive r, Multiplicative r) =>
[Text] ->
[(Text, [Text])] ->
Matrix r
topologyMatrix :: forall r.
(Additive r, Multiplicative r) =>
[Text] -> [(Text, [Text])] -> Matrix r
topologyMatrix [Text]
agents [(Text, [Text])]
posts =
[[r]] -> Matrix r
forall a. [[a]] -> Matrix a
fromLists
[ [ [r] -> r
forall {t}. Additive t => [t] -> t
sum' [[Text] -> Text -> r
forall r. (Additive r, Multiplicative r) => [Text] -> Text -> r
deliversToSemiring [Text]
recipients Text
who | (Text
whoFrom, [Text]
recipients) <- [(Text, [Text])]
posts, Text
whoFrom Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fromAgent]
| Text
who <- [Text]
agents
]
| Text
fromAgent <- [Text]
agents
]
where
sum' :: [t] -> t
sum' [] = t
forall a. Additive a => a
zero
sum' (t
x : [t]
xs) = t
x t -> t -> t
forall a. Additive a => a -> a -> a
+ [t] -> t
sum' [t]
xs
matrixPowers ::
(Additive r, Multiplicative r) =>
Int ->
Matrix r ->
[Matrix r]
matrixPowers :: forall r.
(Additive r, Multiplicative r) =>
Int -> Matrix r -> [Matrix r]
matrixPowers Int
n Matrix r
m = Int -> [Matrix r] -> [Matrix r]
forall a. Int -> [a] -> [a]
take Int
n ((Matrix r -> Matrix r) -> Matrix r -> [Matrix r]
forall a. (a -> a) -> a -> [a]
iterate (Matrix r -> Matrix r -> Matrix r
forall a.
(Additive a, Multiplicative a) =>
Matrix a -> Matrix a -> Matrix a
matTimes Matrix r
m) Matrix r
m)
isNilpotent ::
(Additive r, Multiplicative r, Eq r) =>
Matrix r ->
Bool
isNilpotent :: forall r. (Additive r, Multiplicative r, Eq r) => Matrix r -> Bool
isNilpotent Matrix r
m = (Matrix r -> Bool) -> [Matrix r] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Matrix r -> Bool
isZeroMatrix (Int -> Matrix r -> [Matrix r]
forall r.
(Additive r, Multiplicative r) =>
Int -> Matrix r -> [Matrix r]
matrixPowers (Matrix r -> Int
forall {a}. Matrix a -> Int
rows Matrix r
m) Matrix r
m)
where
rows :: Matrix a -> Int
rows (Matrix Array a
a) = case Vector Int -> [Int]
forall a. Unbox a => Vector a -> [a]
VU.toList (Array a -> Vector Int
forall a. Array a -> Vector Int
A.shape Array a
a) of
(Int
r : [Int]
_) -> Int
r
[Int]
_ -> Int
0
isZeroMatrix :: Matrix r -> Bool
isZeroMatrix = ([r] -> Bool) -> [[r]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((r -> Bool) -> [r] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
forall a. Additive a => a
zero)) ([[r]] -> Bool) -> (Matrix r -> [[r]]) -> Matrix r -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix r -> [[r]]
forall a. Matrix a -> [[a]]
toLists