Ledger.hs (1514B)
1 module Ledger where 2 import Data.IntMap.Strict (IntMap) 3 import qualified Data.IntMap.Strict as IntMap 4 5 import Algebra 6 import qualified Value as V 7 8 -- A ledger maps from de Bruijn levels (represented as Ints) to quantities. 9 -- This mapping is implemented with an IntMap and a default quantity for all 10 -- variables not in the IntMap. 11 data Ledger q = Ledger (V.Type q) (IntMap (V.Type q)) 12 13 {- 14 -- Pointwise LUB 15 instance LubMonoid q => LubMonoid (Ledger q) where 16 bot = Ledger bot IntMap.empty 17 18 Ledger d0 m0 <^> Ledger d1 m1 = Ledger (d0 <^> d1) (IntMap.unionWith (<^>) m0 m1) 19 -} 20 21 -- Pointwise sum 22 instance AddMonoid q => AddMonoid (Ledger q) where 23 zero = Ledger zero IntMap.empty 24 25 Ledger d0 m0 <+> Ledger d1 m1 = Ledger (d0 <+> d1) (IntMap.unionWith (<+>) m0 m1) 26 27 -- Scalar multiply mapped over the entire ledger 28 instance (MulAction q, MulActionScalar q ~ q) => MulAction (Ledger q) where 29 type MulActionScalar (Ledger q) = V.Type q 30 31 q <⋅> Ledger d m = Ledger (q <⋅> d) ((q <⋅>) <$> m) 32 33 singleton :: AddMonoid q => V.TermLvl -> V.Type q -> Ledger q 34 singleton (V.TermLvl l) q = Ledger zero (IntMap.singleton l q) 35 36 -- split is like uncons for ledgers: given a ledger L that maps a de Bruijn 37 -- level l to quantity q, "split l L" returns (q, L'), where L' is L with the 38 -- mapping for l removed (i.e., l is reset to the default quantity). 39 split :: V.TermLvl -> Ledger q -> (V.Type q, Ledger q) 40 split (V.TermLvl l) (Ledger d m) = 41 (IntMap.findWithDefault d l m, Ledger d (IntMap.delete l m))