packages feed

safe-coupling-0.1.0.0: src/ApplicativeBins/Theorem.hs

{-@ LIQUID "--reflection"     @-}
{-@ LIQUID "--ple"            @-}

module ApplicativeBins.Theorem where

import           Monad.PrM
import           Data.Dist

import           Monad.PrM.Relational.TCB.EDist
import           ApplicativeBins.Bins

import           Language.Haskell.Liquid.ProofCombinators
import           Misc.ProofCombinators

{-@ binsDist :: p:Prob -> {q:Prob|p <= q} -> n:PDouble 
             -> {dist (kant distDouble) (bins p n) (bins q n) <= n * (q - p)} / [n] @-}
binsDist :: Prob -> Prob -> Double -> ()
binsDist p q n | n < 1.0 
  = pureDist distDouble 0 0 
  ? assert (0 <= n) 
  ? assert (0 <= (q - p)) 
  ? assert (dist (kant distDouble) (bins p n) (bins q n) <= n * (q - p)) 
binsDist p q n
  =   liftA2Dist d d d 1 ((n - 1) * (q - p)) 1 (q - p) 0
          plus (bins p (n - 1)) (bernoulli p) 
          plus (bins q (n - 1)) (bernoulli q)
          (binsDist p q (n - 1))
          (bernoulliDist d p q)
          plusDist
  where d = distDouble

{-@ plusDist :: x1:Double -> y1:Double -> x2:Double -> y2:Double 
             -> {distD (plus x1 y1) (plus x2 y2) <= distD x1 x2 + distD y1 y2} @-}
plusDist :: Double -> Double -> Double -> Double -> ()
plusDist _ _ _ _ = ()