safe-coupling-0.1.0.0: src/Monad/PrM/Relational/TCB/EDist.hs
-----------------------------------------------------------------
-- | Expected Distance Specifications for PrM Primitives ------
-----------------------------------------------------------------
{-@ LIQUID "--reflection" @-}
module Monad.PrM.Relational.TCB.EDist where
import Data.Dist
import Data.List
import Monad.PrM
import Monad.PrM.Relational.TCB.Spec
{-@ measure Monad.PrM.Relational.TCB.EDist.kant :: Dist a -> Dist (PrM a) @-}
{-@ assume kant :: d:Dist a -> {dd:Dist (PrM a) | dd = Monad.PrM.Relational.TCB.EDist.kant d } @-}
kant :: Dist a -> Dist (PrM a)
kant = undefined
{-@ reflect edist @-}
{-@ edist :: Dist a -> PrM a -> PrM a -> {v:Double | 0 <= v } @-}
edist :: Dist a -> PrM a -> PrM a -> Double
edist d = dist (kant d)
{-@ assume pureDist :: d:Dist a -> x1:a -> x2:a
-> { dist (kant d) (ppure x1) (ppure x2) = dist d x1 x2} @-}
pureDist :: Dist a -> a -> a -> ()
pureDist _ _ _ = ()
{-@ assume bindDist :: d:Dist b -> m:Double -> p:(a -> a -> Bool)
-> f1:(a -> PrM b) -> e1:PrM a
-> f2:(a -> PrM b) -> e2:{PrM a | lift p e1 e2}
-> lemma:(x1:a -> {x2:a| p x1 x2 }
-> { dist (kant d) (f1 x1) (f2 x2) <= m})
-> { dist (kant d) (bind e1 f1) (bind e2 f2) <= m } @-}
bindDist :: Dist b -> Double -> (a -> a -> Bool) -> (a -> PrM b) -> PrM a -> (a -> PrM b) -> PrM a -> (a -> a -> ()) -> ()
bindDist _ _ _ _ _ _ _ _ = ()
{-@ assume fmapDist :: da:Dist a -> db:Dist b
-> m:Double
-> f1:(a -> b) -> e1:PrM a
-> f2:(a -> b) -> e2:PrM a
-> (x1:a -> x2:a -> { dist db (f1 x1) (f2 x2) <= dist da x1 x2 + m})
-> { dist (kant db) (fmap f1 e1) (fmap f2 e2) <= dist (kant da) e1 e2 + m } @-}
fmapDist :: Dist a -> Dist b -> Double -> (a -> b) -> PrM a -> (a -> b) -> PrM a -> (a -> a -> ()) -> ()
fmapDist _ _ _ _ _ _ _ _ = ()
{-@ assume liftA2Dist :: da:Dist a -> db:Dist b -> dc:Dist c
-> ma:Double -> ka:Double -> mb:Double -> kb:Double -> m:Double
-> f1:(a -> b -> c) -> e1:PrM a -> u1:PrM b
-> f2:(a -> b -> c) -> e2:PrM a -> u2:PrM b
-> {_:()|dist (kant da) e1 e2 <= ka}
-> {_:()|dist (kant db) u1 u2 <= kb}
-> (x1:a -> y1:b -> x2:a -> y2:b
-> {dist dc (f1 x1 y1) (f2 x2 y2) <= ma * dist da x1 x2 + mb * dist db y1 y2 + m})
-> {dist (kant dc) (liftA2 f1 e1 u1) (liftA2 f2 e2 u2) <= ma * ka + mb * kb + m} @-}
liftA2Dist :: Dist a -> Dist b -> Dist c -> Double -> Double -> Double -> Double -> Double
-> (a -> b -> c) -> PrM a -> PrM b -> (a -> b -> c) -> PrM a -> PrM b
-> () -> () -> (a -> b -> a -> b -> ())
-> ()
liftA2Dist _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ = ()
{-@ assume unifDist :: d:Dist a -> xsl:[a] -> xsr:{[a] | xsl == xsr}
-> { dist (kant d) (unif xsl) (unif xsr) == 0 } @-}
unifDist :: Dist a -> [a] -> [a] -> ()
unifDist _ _ _ = ()
{-@ assume choiceDist :: d:Dist a -> p:Prob -> e1:PrM a -> e1':PrM a
-> q:{Prob | p = q } -> e2:PrM a -> e2':PrM a
-> { dist (kant d) (choice p e1 e1') (choice q e2 e2') <= p * (dist (kant d) e1 e2) + (1.0 - p) * (dist (kant d) e1' e2')} @-}
choiceDist :: Dist a -> Prob -> PrM a -> PrM a -> Prob -> PrM a -> PrM a -> ()
choiceDist _ _ _ _ _ _ _ = ()
{-@ assume bernoulliDist :: d:Dist Double -> p:Prob -> {q:Prob | p <= q}
-> {dist (kant d) (bernoulli p) (bernoulli q) <= dist d 1 0 * (q - p)} @-}
bernoulliDist :: Dist Double -> Prob -> Prob -> ()
bernoulliDist d p q = ()
where _ = dist (kant d) (bernoulli p) (bernoulli q) <= dist d 1 0 * (q - p)