on master help sign in
Last polishments before it's public
commitce7a95774ce3a07d4bab4d9b4bc00f016098f724 authorArmando Santos <armandoifsantos@gmail.com> dateThu 9 Jan 2020, 15:03 (7 years ago) parent6fa500d
5 files changed+206−34
app/Main.hs+17−18 src/Dist.hs+15 src/Dist/Internal.hs+85−11 src/Matrix/Type.hs+71−5 src/Relation/Internal.hs+18
app/Main.hs+17−18
@@ -23,7 +23,7 @@ switch :: Outcome -> Outcome
2323switch Win = Lose
2424switch Lose = Win
2525
26−firstChoice :: Dist Outcome
26+firstChoice :: Matrix Double () Outcome
2727firstChoice = col [1/3, 2/3]
2828
2929secondChoice :: Matrix Double Outcome Outcome
@@ -31,7 +31,7 @@ secondChoice = fromF' switch
3131
3232-- Dice sum
3333
34−type SS = Natural 1 6
34+type SS = Natural 1 6 -- Sample Space
3535
3636sumSS :: SS -> SS -> Natural 2 12
3737sumSS = coerceNat (+)
@@ -48,13 +48,13 @@ conditionSS = coerceNat2 condition
4848
4949conditionalThrows = fromF' (uncurry conditionSS) . khatri (khatri die die) die
5050
51−die :: Dist SS
52−die = uniform [nat @1 @6 1 .. nat 6]
51+die :: Matrix Double () SS
52+die = col $ map (const (1/6)) [nat @1 @6 1 .. nat 6]
5353
5454-- Sprinkler
5555
56−rain :: Dist Bool
57−rain = choose 0.8
56+rain :: Matrix Double () Bool
57+rain = col [0.8, 0.2]
5858
5959sprinkler :: Matrix Double Bool Bool
6060sprinkler = fromLists [[0.6, 0.99], [0.4, 0.01]]
@@ -62,7 +62,7 @@ sprinkler = fromLists [[0.6, 0.99], [0.4, 0.01]]
6262grass :: Matrix Double (Bool, Bool) Bool
6363grass = fromLists [[1, 0.2, 0.1, 0.01], [0, 0.8, 0.9, 0.99]]
6464
65−state :: Dist (Bool, (Bool, Bool))
65+state :: Matrix Double () (Bool, (Bool, Bool))
6666state = khatri grass identity . khatri sprinkler identity . rain
6767
6868grass_wet :: Matrix Double (Bool, (Bool, Bool)) One
@@ -73,16 +73,15 @@ rainning = row [0,1] . kp2 . kp2
7373
7474main :: IO ()
7575main = do
76− -- putStrLn "Monty Hall Problem solution:"
77− -- prettyPrint (secondChoice . firstChoice)
78− -- putStrLn "\n Sum of dices probability:"
79− -- prettyPrint (sumSSM `comp` khatri die die)
80− -- prettyPrintDist @(Natural 2 12) (sumSSM . khatri die die)
81− -- putStrLn "\n Conditional dice throw:"
82− -- prettyPrintDist @(Natural 3 18) conditionalThrows
83− -- putStrLn "\n Checking that the last result is indeed a distribution: "
84− -- prettyPrint (bang . sumSSM . khatri die die)
76+ putStrLn "Monty Hall Problem solution:"
77+ prettyPrint (secondChoice . firstChoice)
78+ putStrLn "\n Sum of dices probability:"
79+ prettyPrint (sumSSM `comp` khatri die die)
80+ putStrLn "\n Conditional dice throw:"
81+ prettyPrint conditionalThrows
82+ putStrLn "\n Checking that the last result is indeed a distribution: "
83+ prettyPrint (bang . sumSSM . khatri die die)
8584 putStrLn "\n Probability of grass being wet:"
8685 prettyPrint (grass_wet . state)
87− -- putStrLn "\n Probability of rain:"
88− -- prettyPrint (rainning . state)
86+ putStrLn "\n Probability of rain:"
87+ prettyPrint (rainning . state)
src/Dist.hs+15
@@ -35,6 +35,21 @@ module Dist
3535 -- * 'Dist' and 'Prob' type synonyms
3636 Dist (..),
3737 Prob,
38+
39+ -- * Functor instance equivalent functions
40+ fmapD,
41+
42+ -- * Applicative equivalent functions
43+ unitD,
44+ multD,
45+
46+ -- * Selective equivalent functions
47+ selectD,
48+
49+ -- * Monad equivalent functions
50+ returnD,
51+ bindD,
52+
3853 -- * Distribution construction functions
3954 choose,
4055 shape,
src/Dist/Internal.hs+85−11
@@ -1,3 +1,4 @@
1+{-# LANGUAGE GADTs #-}
12{-# LANGUAGE AllowAmbiguousTypes #-}
23{-# LANGUAGE TypeApplications #-}
34{-# LANGUAGE KindSignatures #-}
@@ -10,6 +11,15 @@ module Dist.Internal
1011 (
1112 Dist(..),
1213 Prob,
14+
15+ fmapD,
16+ unitD,
17+ multD,
18+ selectD,
19+ returnD,
20+ bindD,
21+ (??),
22+
1323 choose,
1424 shape,
1525 linear,
@@ -33,14 +43,78 @@ type Prob = Double
3343
3444-- | Type synonym for column vector matrices. This represents a probability
3545-- distribution.
36−type Dist a = (FromLists Prob () (Normalize a)) => Matrix Prob () a
46+newtype Dist a = D (Matrix Prob () a)
47+
48+-- | Functor instance
49+fmapD ::
50+ ( Bounded a,
51+ Bounded b,
52+ Enum a,
53+ Enum b,
54+ Eq b,
55+ KnownNat (Count (Normalize a)),
56+ KnownNat (Count (Normalize b)),
57+ FromLists Prob (Normalize b) (Normalize a)
58+ )
59+ =>
60+ (a -> b) -> Dist a -> Dist b
61+fmapD f (D m) = D (fromF' f `comp` m)
62+
63+-- | Applicative/Monoidal instance 'unit' function
64+unitD :: Dist ()
65+unitD = D (one 1)
66+
67+-- | Applicative/Monoidal instance 'mult' function
68+multD ::
69+ ( KnownNat (Count (Normalize a)),
70+ KnownNat (Count (Normalize b)),
71+ KnownNat (Count (Normalize (a, b))),
72+ FromLists Prob (Normalize (a, b)) (Normalize a),
73+ FromLists Prob (Normalize (a, b)) (Normalize b),
74+ Normalize (a, b) ~ Normalize (Normalize a, Normalize b)
75+ ) => Dist a -> Dist b -> Dist (a, b)
76+multD (D a) (D b) = D (khatri a b)
77+
78+-- | Selective instance function
79+selectD ::
80+ ( Normalize (Either a b) ~ Either (Normalize a) (Normalize b),
81+ FromLists Prob (Normalize b) (Normalize b),
82+ KnownNat (Count (Normalize b))
83+ ) => Dist (Either a b) -> Matrix Prob a b -> Dist b
84+selectD (D d) m = D (junc m identity `comp` d)
85+
86+
87+-- | Monad instance 'return' function
88+returnD :: forall a . (Enum a, FromLists Prob () (Normalize a), KnownNat (Count a)) => a -> Dist a
89+returnD a = D (col l)
90+ where
91+ i = fromInteger $ natVal (Proxy :: Proxy (Count a))
92+ x = fromEnum a
93+ l = take x [0,0..] ++ [1] ++ take (i - x - 1) [0,0..]
94+
95+-- | Monad instance '(>>=)' function
96+bindD :: Dist a -> Matrix Prob a b -> Dist b
97+bindD (D d) m = D (m `comp` d)
98+
99+-- | Extract probabilities given an Event.
100+(??) ::
101+ ( Enum a,
102+ KnownNat (Count a),
103+ FromLists Prob () (Normalize a)
104+ ) => (a -> Bool) -> Dist a -> Prob
105+(??) p d =
106+ let l = toValues d
107+ x = filter (p . fst) l
108+ in sum . map snd $ x
109+
110+-- Distribution Construction
37111
38112-- | Constructs a Bernoulli distribution
39−choose :: Prob -> Dist a
40−choose prob = col [prob, 1 - prob]
113+choose :: (FromLists Prob () (Normalize a)) => Prob -> Dist a
114+choose prob = D (col [prob, 1 - prob])
41115
42116-- | Creates a distribution given a shape function
43−shape :: (Prob -> Prob) -> [a] -> Dist a
117+shape :: (FromLists Prob () (Normalize a)) => (Prob -> Prob) -> [a] -> Dist a
44118shape _ [] = error "Probability.shape: empty list"
45119shape f xs =
46120 let incr = 1 / fromIntegral (length xs - 1)
@@ -48,24 +122,24 @@ shape f xs =
48122 in fromFreqs (zip xs ps)
49123
50124-- | Constructs a Linear distribution
51−linear :: [a] -> Dist a
125+linear :: (FromLists Prob () (Normalize a)) => [a] -> Dist a
52126linear = shape id
53127
54128-- | Constructs an Uniform distribution
55−uniform :: [a] -> Dist a
129+uniform :: (FromLists Prob () (Normalize a)) => [a] -> Dist a
56130uniform = shape (const 1)
57131
58132-- | Constructs an Negative Exponential distribution
59−negExp :: [a] -> Dist a
133+negExp :: (FromLists Prob () (Normalize a)) => [a] -> Dist a
60134negExp = shape (\x -> exp (-x))
61135
62136-- | Constructs an Normal distribution
63−normal :: [a] -> Dist a
137+normal :: (FromLists Prob () (Normalize a)) => [a] -> Dist a
64138normal = shape (normalCurve 0.5 0.5)
65139
66140-- | Transforms a 'Dist' into a list of pairs.
67141toValues :: forall a . (Enum a, KnownNat (Count a), FromLists Prob () (Normalize a)) => Dist a -> [(a, Prob)]
68−toValues d =
142+toValues (D d) =
69143 let rows = fromInteger (natVal (Proxy :: Proxy (Count a)))
70144 probs = toList d
71145 res = zip (map toEnum [0..rows]) probs
@@ -89,8 +163,8 @@ prettyPrintDist = putStrLn . prettyDist @a
89163
90164-- Auxiliary functions
91165
92−fromFreqs :: [(a,Prob)] -> Dist a
93−fromFreqs xs = col (map (\(x,p) -> p/q) xs)
166+fromFreqs :: (FromLists Prob () (Normalize a)) => [(a,Prob)] -> Dist a
167+fromFreqs xs = D (col (map (\(x,p) -> p/q) xs))
94168 where q = sum $ map snd xs
95169
96170normalCurve :: Prob -> Prob -> Prob -> Prob
src/Matrix/Type.hs+71−5
@@ -83,6 +83,20 @@ module Matrix.Type
8383 bang,
8484 constant,
8585
86+ -- * Functor instance equivalent function
87+ fmapM,
88+
89+ -- * Applicative/Monoidal instance equivalent functions
90+ unitM,
91+ multM,
92+
93+ -- * Selective equivalent instance function
94+ selectM,
95+
96+ -- * Monad equivalent instance function
97+ returnM,
98+ bindM,
99+
86100 -- * Misc
87101 -- ** Get dimensions
88102 columns,
@@ -91,9 +105,6 @@ module Matrix.Type
91105 -- ** Matrix Transposition
92106 tr,
93107
94− -- ** Selective operator
95− select,
96−
97108 -- ** McCarthy's Conditional
98109 cond,
99110
@@ -214,6 +225,61 @@ infixl 2 ===
214225 Matrix e cols (Either a b)
215226(===) = split
216227
228+-- Functor hierarchy
229+
230+-- | Functor instance equivalent function
231+fmapM ::
232+ ( Bounded a,
233+ Bounded b,
234+ Enum a,
235+ Enum b,
236+ Eq b,
237+ Num e,
238+ Ord e,
239+ KnownNat (I.Count (I.Normalize a)),
240+ KnownNat (I.Count (I.Normalize b)),
241+ I.FromLists e (I.Normalize b) (I.Normalize a)
242+ )
243+ =>
244+ (a -> b) -> Matrix e c a -> Matrix e c b
245+fmapM f m = fromF' f `comp` m
246+
247+-- | Applicative instance equivalent 'unit' function,
248+unitM :: (Num e) => Matrix e () ()
249+unitM = one 1
250+
251+-- | Applicative instance equivalent 'unit' function,
252+multM ::
253+ ( KnownNat (I.Count (I.Normalize a)),
254+ KnownNat (I.Count (I.Normalize b)),
255+ KnownNat (I.Count (I.Normalize (a, b))),
256+ Num e,
257+ I.FromLists e (I.Normalize (a, b)) (I.Normalize a),
258+ I.FromLists e (I.Normalize (a, b)) (I.Normalize b),
259+ I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
260+ ) => Matrix e c a -> Matrix e c b -> Matrix e c (a, b)
261+multM a b = khatri a b
262+
263+
264+-- | Monad instance equivalent 'return' function,
265+returnM ::
266+ forall e a .
267+ ( Num e,
268+ Enum e,
269+ Enum a,
270+ I.FromLists e () (I.Normalize a),
271+ KnownNat (I.Count a)
272+ ) => a -> Matrix e One a
273+returnM a = col l
274+ where
275+ i = fromInteger $ natVal (Proxy :: Proxy (I.Count a))
276+ x = fromEnum a
277+ l = take x [0,0..] ++ [1] ++ take (i - x - 1) [0,0..]
278+
279+-- | Monad instance equivalent '(>>=)' function,
280+bindM :: (Num e) => Matrix e a b -> Matrix e b c -> Matrix e a c
281+bindM = flip comp
282+
217283-- Construction
218284
219285-- | Build a matrix out of a list of list of elements. Throws a runtime
@@ -544,13 +610,13 @@ tr (M m) = M (I.tr m)
544610
545611-- | Selective functors 'select' operator equivalent inspired by the
546612-- ArrowMonad solution presented in the paper.
547−select ::
613+selectM ::
548614 ( Num e,
549615 I.FromLists e (I.Normalize b) (I.Normalize b),
550616 KnownNat (I.Count (I.Normalize b)),
551617 I.Normalize (Either a b) ~ Either (I.Normalize a) (I.Normalize b)
552618 ) => Matrix e cols (Either a b) -> Matrix e a b -> Matrix e cols b
553−select (M m) (M y) = M (I.select m y)
619+selectM (M m) (M y) = M (I.select m y)
554620
555621-- McCarthy's Conditional
556622
src/Relation/Internal.hs+18
@@ -6,6 +6,24 @@
66{-# LANGUAGE DerivingVia #-}
77{-# LANGUAGE DataKinds #-}
88
9+-----------------------------------------------------------------------------
10+-- |
11+-- Module : Relation.Internal
12+-- Copyright : (c) Armando Santos 2019-2020
13+-- Maintainer : armandoifsantos@gmail.com
14+-- Stability : experimental
15+--
16+-- The AoP discipline generalises functions to relations which are
17+-- Boolean matrices.
18+--
19+-- This module offers many of the combinators of the Algebra of
20+-- Programming discipline. It is still under construction and very
21+-- experimental.
22+--
23+-- This is an Internal module and it is no supposed to be imported.
24+--
25+-----------------------------------------------------------------------------
26+
927module Relation.Internal
1028 (
1129 )