{-# LANGUAGE NoRebindableSyntax #-}
module NumHask.Free.StarSemiring
( StarSemiring (..),
zero,
one,
plus,
times,
star,
plusS,
embed,
lift,
normalize,
eval,
foldStarSemiring,
fromAdditive,
fromMultiplicative,
kleeneSimplify,
)
where
import Data.Set (Set)
import Data.Set qualified as S
import NumHask.Algebra.Additive qualified as NHA
import NumHask.Algebra.Multiplicative qualified as NHM
import NumHask.Algebra.Ring qualified as NHR
import NumHask.Free.Additive qualified as HA
import NumHask.Free.Multiplicative qualified as HM
import Prelude (Eq, Ord, Show, foldr1, otherwise, (.), (==))
data StarSemiring a
= Zero
| One
| Plus (StarSemiring a) (StarSemiring a)
| Times (StarSemiring a) (StarSemiring a)
| Star (StarSemiring a)
| Embed a
deriving (StarSemiring a -> StarSemiring a -> Bool
(StarSemiring a -> StarSemiring a -> Bool)
-> (StarSemiring a -> StarSemiring a -> Bool)
-> Eq (StarSemiring a)
forall a. Eq a => StarSemiring a -> StarSemiring a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => StarSemiring a -> StarSemiring a -> Bool
== :: StarSemiring a -> StarSemiring a -> Bool
$c/= :: forall a. Eq a => StarSemiring a -> StarSemiring a -> Bool
/= :: StarSemiring a -> StarSemiring a -> Bool
Eq, Eq (StarSemiring a)
Eq (StarSemiring a) =>
(StarSemiring a -> StarSemiring a -> Ordering)
-> (StarSemiring a -> StarSemiring a -> Bool)
-> (StarSemiring a -> StarSemiring a -> Bool)
-> (StarSemiring a -> StarSemiring a -> Bool)
-> (StarSemiring a -> StarSemiring a -> Bool)
-> (StarSemiring a -> StarSemiring a -> StarSemiring a)
-> (StarSemiring a -> StarSemiring a -> StarSemiring a)
-> Ord (StarSemiring a)
StarSemiring a -> StarSemiring a -> Bool
StarSemiring a -> StarSemiring a -> Ordering
StarSemiring a -> StarSemiring a -> StarSemiring a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (StarSemiring a)
forall a. Ord a => StarSemiring a -> StarSemiring a -> Bool
forall a. Ord a => StarSemiring a -> StarSemiring a -> Ordering
forall a.
Ord a =>
StarSemiring a -> StarSemiring a -> StarSemiring a
$ccompare :: forall a. Ord a => StarSemiring a -> StarSemiring a -> Ordering
compare :: StarSemiring a -> StarSemiring a -> Ordering
$c< :: forall a. Ord a => StarSemiring a -> StarSemiring a -> Bool
< :: StarSemiring a -> StarSemiring a -> Bool
$c<= :: forall a. Ord a => StarSemiring a -> StarSemiring a -> Bool
<= :: StarSemiring a -> StarSemiring a -> Bool
$c> :: forall a. Ord a => StarSemiring a -> StarSemiring a -> Bool
> :: StarSemiring a -> StarSemiring a -> Bool
$c>= :: forall a. Ord a => StarSemiring a -> StarSemiring a -> Bool
>= :: StarSemiring a -> StarSemiring a -> Bool
$cmax :: forall a.
Ord a =>
StarSemiring a -> StarSemiring a -> StarSemiring a
max :: StarSemiring a -> StarSemiring a -> StarSemiring a
$cmin :: forall a.
Ord a =>
StarSemiring a -> StarSemiring a -> StarSemiring a
min :: StarSemiring a -> StarSemiring a -> StarSemiring a
Ord, Int -> StarSemiring a -> ShowS
[StarSemiring a] -> ShowS
StarSemiring a -> String
(Int -> StarSemiring a -> ShowS)
-> (StarSemiring a -> String)
-> ([StarSemiring a] -> ShowS)
-> Show (StarSemiring a)
forall a. Show a => Int -> StarSemiring a -> ShowS
forall a. Show a => [StarSemiring a] -> ShowS
forall a. Show a => StarSemiring a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> StarSemiring a -> ShowS
showsPrec :: Int -> StarSemiring a -> ShowS
$cshow :: forall a. Show a => StarSemiring a -> String
show :: StarSemiring a -> String
$cshowList :: forall a. Show a => [StarSemiring a] -> ShowS
showList :: [StarSemiring a] -> ShowS
Show)
zero :: StarSemiring a
zero :: forall a. StarSemiring a
zero = StarSemiring a
forall a. StarSemiring a
Zero
one :: StarSemiring a
one :: forall a. StarSemiring a
one = StarSemiring a
forall a. StarSemiring a
One
plus :: StarSemiring a -> StarSemiring a -> StarSemiring a
plus :: forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
plus StarSemiring a
Zero StarSemiring a
b = StarSemiring a
b
plus StarSemiring a
a StarSemiring a
Zero = StarSemiring a
a
plus StarSemiring a
a StarSemiring a
b = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Plus StarSemiring a
a StarSemiring a
b
times :: StarSemiring a -> StarSemiring a -> StarSemiring a
times :: forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
times StarSemiring a
One StarSemiring a
b = StarSemiring a
b
times StarSemiring a
a StarSemiring a
One = StarSemiring a
a
times StarSemiring a
a StarSemiring a
b = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Times StarSemiring a
a StarSemiring a
b
star :: StarSemiring a -> StarSemiring a
star :: forall a. StarSemiring a -> StarSemiring a
star StarSemiring a
Zero = StarSemiring a
forall a. StarSemiring a
One
star StarSemiring a
a = StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a
Star StarSemiring a
a
plusS :: StarSemiring a -> StarSemiring a
plusS :: forall a. StarSemiring a -> StarSemiring a
plusS StarSemiring a
a = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
times StarSemiring a
a (StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a
star StarSemiring a
a)
embed :: a -> StarSemiring a
embed :: forall a. a -> StarSemiring a
embed = a -> StarSemiring a
forall a. a -> StarSemiring a
Embed
lift :: (Eq a, NHR.StarSemiring a) => a -> StarSemiring a
lift :: forall a. (Eq a, StarSemiring a) => a -> StarSemiring a
lift a
a
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
NHA.zero = StarSemiring a
forall a. StarSemiring a
Zero
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Multiplicative a => a
NHM.one = StarSemiring a
forall a. StarSemiring a
One
| Bool
otherwise = a -> StarSemiring a
forall a. a -> StarSemiring a
Embed a
a
normalize :: (Eq a, NHR.StarSemiring a) => StarSemiring a -> StarSemiring a
normalize :: forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
Zero = StarSemiring a
forall a. StarSemiring a
Zero
normalize StarSemiring a
One = StarSemiring a
forall a. StarSemiring a
One
normalize (Embed a
a)
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
NHA.zero = StarSemiring a
forall a. StarSemiring a
Zero
| a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Multiplicative a => a
NHM.one = StarSemiring a
forall a. StarSemiring a
One
| Bool
otherwise = a -> StarSemiring a
forall a. a -> StarSemiring a
Embed a
a
normalize (Plus StarSemiring a
a StarSemiring a
b) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
plus (StarSemiring a -> StarSemiring a
forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
a) (StarSemiring a -> StarSemiring a
forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
b)
normalize (Times StarSemiring a
a StarSemiring a
b) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
times (StarSemiring a -> StarSemiring a
forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
a) (StarSemiring a -> StarSemiring a
forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
b)
normalize (Star StarSemiring a
a) = StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a
star (StarSemiring a -> StarSemiring a
forall a.
(Eq a, StarSemiring a) =>
StarSemiring a -> StarSemiring a
normalize StarSemiring a
a)
eval :: (NHR.StarSemiring a) => StarSemiring a -> a
eval :: forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
Zero = a
forall a. Additive a => a
NHA.zero
eval StarSemiring a
One = a
forall a. Multiplicative a => a
NHM.one
eval (Plus StarSemiring a
a StarSemiring a
b) = StarSemiring a -> a
forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
a a -> a -> a
forall a. Additive a => a -> a -> a
NHA.+ StarSemiring a -> a
forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
b
eval (Times StarSemiring a
a StarSemiring a
b) = StarSemiring a -> a
forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
NHM.* StarSemiring a -> a
forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
b
eval (Star StarSemiring a
a) = a -> a
forall a. StarSemiring a => a -> a
NHR.star (StarSemiring a -> a
forall a. StarSemiring a => StarSemiring a -> a
eval StarSemiring a
a)
eval (Embed a
a) = a
a
instance NHA.Additive (StarSemiring a) where
zero :: StarSemiring a
zero = StarSemiring a
forall a. StarSemiring a
Zero
+ :: StarSemiring a -> StarSemiring a -> StarSemiring a
(+) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
plus
instance NHM.Multiplicative (StarSemiring a) where
one :: StarSemiring a
one = StarSemiring a
forall a. StarSemiring a
One
* :: StarSemiring a -> StarSemiring a -> StarSemiring a
(*) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
times
instance NHR.StarSemiring (StarSemiring a) where
star :: StarSemiring a -> StarSemiring a
star = StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a
star
foldStarSemiring ::
b ->
b ->
(b -> b -> b) ->
(b -> b -> b) ->
(b -> b) ->
(a -> b) ->
StarSemiring a ->
b
foldStarSemiring :: forall b a.
b
-> b
-> (b -> b -> b)
-> (b -> b -> b)
-> (b -> b)
-> (a -> b)
-> StarSemiring a
-> b
foldStarSemiring b
z b
o b -> b -> b
p b -> b -> b
t b -> b
s a -> b
f = StarSemiring a -> b
go
where
go :: StarSemiring a -> b
go StarSemiring a
Zero = b
z
go StarSemiring a
One = b
o
go (Plus StarSemiring a
a StarSemiring a
b) = b -> b -> b
p (StarSemiring a -> b
go StarSemiring a
a) (StarSemiring a -> b
go StarSemiring a
b)
go (Times StarSemiring a
a StarSemiring a
b) = b -> b -> b
t (StarSemiring a -> b
go StarSemiring a
a) (StarSemiring a -> b
go StarSemiring a
b)
go (Star StarSemiring a
a) = b -> b
s (StarSemiring a -> b
go StarSemiring a
a)
go (Embed a
a) = a -> b
f a
a
fromAdditive :: HA.Additive a -> StarSemiring a
fromAdditive :: forall a. Additive a -> StarSemiring a
fromAdditive Additive a
HA.Zero = StarSemiring a
forall a. StarSemiring a
Zero
fromAdditive (HA.Plus Additive a
a Additive a
b) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Plus (Additive a -> StarSemiring a
forall a. Additive a -> StarSemiring a
fromAdditive Additive a
a) (Additive a -> StarSemiring a
forall a. Additive a -> StarSemiring a
fromAdditive Additive a
b)
fromAdditive (HA.Embed a
a) = a -> StarSemiring a
forall a. a -> StarSemiring a
Embed a
a
fromMultiplicative :: HM.Multiplicative a -> StarSemiring a
fromMultiplicative :: forall a. Multiplicative a -> StarSemiring a
fromMultiplicative Multiplicative a
HM.One = StarSemiring a
forall a. StarSemiring a
One
fromMultiplicative (HM.Times Multiplicative a
a Multiplicative a
b) = StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Times (Multiplicative a -> StarSemiring a
forall a. Multiplicative a -> StarSemiring a
fromMultiplicative Multiplicative a
a) (Multiplicative a -> StarSemiring a
forall a. Multiplicative a -> StarSemiring a
fromMultiplicative Multiplicative a
b)
fromMultiplicative (HM.Embed a
a) = a -> StarSemiring a
forall a. a -> StarSemiring a
Embed a
a
kleeneSimplify :: (Ord a) => StarSemiring a -> StarSemiring a
kleeneSimplify :: forall a. Ord a => StarSemiring a -> StarSemiring a
kleeneSimplify = Set (StarSemiring a) -> StarSemiring a
forall a. Set (StarSemiring a) -> StarSemiring a
fromSet (Set (StarSemiring a) -> StarSemiring a)
-> (StarSemiring a -> Set (StarSemiring a))
-> StarSemiring a
-> StarSemiring a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StarSemiring a -> Set (StarSemiring a)
forall a. Ord a => StarSemiring a -> Set (StarSemiring a)
toSet
where
normChild :: (Ord a) => StarSemiring a -> StarSemiring a
normChild :: forall a. Ord a => StarSemiring a -> StarSemiring a
normChild = StarSemiring a -> StarSemiring a
forall a. Ord a => StarSemiring a -> StarSemiring a
kleeneSimplify
toSet :: (Ord a) => StarSemiring a -> Set (StarSemiring a)
toSet :: forall a. Ord a => StarSemiring a -> Set (StarSemiring a)
toSet StarSemiring a
Zero = Set (StarSemiring a)
forall a. Set a
S.empty
toSet (Plus StarSemiring a
a StarSemiring a
b) = Set (StarSemiring a)
-> Set (StarSemiring a) -> Set (StarSemiring a)
forall a. Ord a => Set a -> Set a -> Set a
S.union (StarSemiring a -> Set (StarSemiring a)
forall a. Ord a => StarSemiring a -> Set (StarSemiring a)
toSet StarSemiring a
a) (StarSemiring a -> Set (StarSemiring a)
forall a. Ord a => StarSemiring a -> Set (StarSemiring a)
toSet StarSemiring a
b)
toSet (Times StarSemiring a
a StarSemiring a
b) = StarSemiring a -> Set (StarSemiring a)
forall a. a -> Set a
S.singleton (StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Times (StarSemiring a -> StarSemiring a
forall a. Ord a => StarSemiring a -> StarSemiring a
normChild StarSemiring a
a) (StarSemiring a -> StarSemiring a
forall a. Ord a => StarSemiring a -> StarSemiring a
normChild StarSemiring a
b))
toSet (Star StarSemiring a
a) = StarSemiring a -> Set (StarSemiring a)
forall a. a -> Set a
S.singleton (StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a
Star (StarSemiring a -> StarSemiring a
forall a. Ord a => StarSemiring a -> StarSemiring a
normChild StarSemiring a
a))
toSet StarSemiring a
a = StarSemiring a -> Set (StarSemiring a)
forall a. a -> Set a
S.singleton StarSemiring a
a
fromSet :: Set (StarSemiring a) -> StarSemiring a
fromSet :: forall a. Set (StarSemiring a) -> StarSemiring a
fromSet Set (StarSemiring a)
s = case Set (StarSemiring a) -> [StarSemiring a]
forall a. Set a -> [a]
S.toList Set (StarSemiring a)
s of
[] -> StarSemiring a
forall a. StarSemiring a
Zero
[StarSemiring a]
xs -> (StarSemiring a -> StarSemiring a -> StarSemiring a)
-> [StarSemiring a] -> StarSemiring a
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 StarSemiring a -> StarSemiring a -> StarSemiring a
forall a. StarSemiring a -> StarSemiring a -> StarSemiring a
Plus [StarSemiring a]
xs