1 module ValueSimplex
where
2 import Control
.Applicative
((<$>), (<*>))
4 import qualified Data
.Map
.Lazy
as Map
5 import Data
.Maybe (fromMaybe)
7 import qualified Data
.Set
as Set
8 import Data
.Tuple
(swap
)
9 import Util
.Function
((...))
10 import Util
.Set
(allSet
, anySet
)
12 newtype ValueSimplex a b
= VS
{vsMap
:: Map
(a
, a
) b
} deriving (Eq
, Show)
22 nodes
:: Ord a
=> ValueSimplex a b
-> Set a
23 nodes vs
= Set
.map fst $ Map
.keysSet
$ vsMap vs
25 pairUp
:: a
-> b
-> (a
, b
)
28 distinctPairsOneWay
:: Ord a
=> Set a
-> Set
(a
, a
)
29 distinctPairsOneWay xs
=
30 case Set
.minView xs
of
32 Just
(x
, xs
') -> Set
.union
33 (distinctPairsOneWay xs
') $
34 Set
.map (pairUp x
) xs
'
36 distinctPairs
:: Ord a
=> Set a
-> Set
(a
, a
)
38 let dpow
= distinctPairsOneWay xs
in
39 Set
.union dpow
$ Set
.map swap dpow
41 vsLookupMaybe
:: Ord a
=> ValueSimplex a b
-> a
-> a
-> Maybe b
42 vsLookupMaybe vs x y
= Map
.lookup (x
, y
) $ vsMap vs
44 vsLookup
:: (Ord a
, Num b
) => ValueSimplex a b
-> a
-> a
-> b
45 vsLookup
= fromMaybe 0 ... vsLookupMaybe
47 fromFunction
:: Ord a
=> (a
-> a
-> b
) -> Set a
-> ValueSimplex a b
48 fromFunction f xs
= VS
$ Map
.fromSet
(uncurry f
) $ distinctPairs xs
50 validTriangle
:: (Ord a
, Num b
) =>
51 (b
-> b
-> Bool) -> ValueSimplex a b
-> a
-> a
-> a
-> Bool
52 validTriangle eq vs x y z
=
53 (vsLookup vs x y
* vsLookup vs y z
* vsLookup vs z x
)
54 `eq`
(vsLookup vs z y
* vsLookup vs y x
* vsLookup vs x z
)
56 status
:: (Ord a
, Ord b
, Num b
) =>
57 (b
-> b
-> Bool) -> ValueSimplex a b
-> VSStatus
59 let dPairs
= distinctPairs
$ nodes vs
in
60 if Map
.keysSet
(vsMap vs
) /= dPairs
62 else if anySet
((<= 0) . (uncurry $ vsLookup vs
)) dPairs
65 case Set
.minView
$ nodes vs
of
68 if allSet
(uncurry $ validTriangle eq vs x
) $ distinctPairsOneWay xs
72 -- price vs x y is the number of ys required to equal one x in value, according
73 -- to the internal state of the ValueSimplex vs
74 price
:: (Ord a
, Fractional b
) => ValueSimplex a b
-> a
-> a
-> Maybe b
75 price vs x y
= (/) <$> vsLookupMaybe vs y x
<*> vsLookupMaybe vs x y