packages feed

liquidhaskell-0.8.10.1: include/Language/Haskell/Liquid/RTick/Combinators.hs

--
-- Liquidate your assets: reasoning about resource usage in Liquid Haskell.
--

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

module Language.Haskell.Liquid.RTick.Combinators
  (

  -- Basic:
    Proof         -- Simply the unit type.
  , QED(..)       -- 'ASS': Signify the end of an /unfinished/ proof.
                  -- 'QED': Signify the end of a /complete/ proof.
  , (&&&)         -- Combine proofs.
  , (***)         -- Discard final result at the end of a proof.
  , (?)           -- Appeal to an external theorem.
  , isAss         -- Check whether a proof is complete.
  , toProof       -- Cast to proof.
  , trivial       -- Trivial proof.
  , withTheorem   -- Appeal to an external theorem.
  -- Equational:
  , (==.)         -- Equality.
  , (==?)         -- Equality (assumption).
  , eq            -- Equality. Note: 'eq' is inlined in the logic.
  -- Inequational:
  , (<.)          -- Less than.
  , (<?)          -- Less than (assumption).
  , (<=.)         -- Less than or equal.
  , (<=?)         -- Less than or equal (assumption).
  , (>.)          -- Greater than.
  , (>?)          -- Greater than (assumption).
  , (>=.)         -- Greater than or equal.
  , (>=?)         -- Greater than or equal (assumption).
  , (<=>.)        -- Cost equivalence.
  , (<=>?)        -- Cost equivalence (assumption)
  , (>~>.)        -- Improvement.
  , (>~>?)        -- Improvement (assumption).
  , (.>==)        -- Quantified improvement.
  , (?>==)        -- Quantified improvement (assumption).
  , (<~<.)        -- Diminishment.
  , (<~<?)        -- Diminishment (assumption).
  , (.<==)        -- Quantified diminishment.
  , (?<==)        -- Quantified diminishment (assumption).
  -- Cost separators:
  , (==>.)        -- Quantified improvement.
  , (==>?)        -- Quantified improvement (assumption).
  , (==<.)        -- Quantified diminishment.
  , (==<?)        -- Quantified diminishment (assumption).
  , (==!)
  , assert
  ) where

import Language.Haskell.Liquid.RTick ( Tick(..) )

--
-- Proof combinators for extrinsic cost analysis.
--

-------------------------------------------------------------------------------
-- | Basic:
-------------------------------------------------------------------------------

{-@ assert :: b:{Bool | b} -> {b} @-}
assert :: Bool -> Proof
assert _ = ()

-- unchecked
(==!) :: a -> a -> a
_ ==! x = x


type Proof = ()
data QED   = QED | ASS

{-@ toProof :: a -> Proof @-}
toProof :: a -> Proof
toProof _ = ()
{-# INLINE toProof #-}

{-@ trivial :: Proof @-}
trivial :: Proof
trivial = ()
{-# INLINE trivial #-}

{-@ measure isAss @-}
isAss :: QED -> Bool
isAss ASS = True
isAss QED = False

{-@ assume (***) :: a -> qed:QED -> { if (isAss qed) then false else true } @-}
infixl 1 ***
(***) :: a -> QED -> Proof
_ *** _ = ()
{-# INLINE (***) #-}

{-@ (?) :: x:a -> Proof -> { v:a | x == v } @-}
infixl 3 ?
(?) :: a -> Proof -> a
x ? _ = x
{-# INLINE (?) #-}

{-@ (&&&) :: Proof -> Proof -> Proof @-}
infixl 3 &&&
(&&&) :: Proof -> Proof -> Proof
x &&& _ = x
{-# INLINE (&&&) #-}

{-@ withTheorem :: x:a -> Proof -> { v:a | x == v } @-}
withTheorem :: a -> Proof -> a
withTheorem x _ = x
{-# INLINE withTheorem #-}

-------------------------------------------------------------------------------
-- | Equational:
-------------------------------------------------------------------------------

--
-- Equality.
--
{-@ (==.) :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-}
infixl 3 ==.
(==.) :: a -> a -> a
_ ==. x = x
{-# INLINE (==.) #-}

{-@ assume (==?) :: x:a -> y:a -> { v:a | x == v && y == v } @-}
infixl 3 ==?
(==?) :: a -> a -> a
_ ==? x = x
{-# INLINE (==?) #-}

--
-- Equality. Note: 'eq' is inlined in the logic, so can be used in
-- reflected functions.
--
{-@ eq :: x:a -> { y:a | x == y } -> { v:a | x == v && y == v } @-}
eq :: a -> a -> a
_ `eq` x = x
{-# INLINE eq #-}

-------------------------------------------------------------------------------
-- | Inequational:
-------------------------------------------------------------------------------

--
-- Less than.
--
{-@ (<.) :: m:a -> { n:a | m < n } -> { o:a | o == n } @-}
infixl 3 <.
(<.) :: a -> a -> a
_ <. n = n
{-# INLINE (<.) #-}

{-@ assume (<?) :: m:a -> n:a -> { o:a | o == n && m < n } @-}
infixl 3 <?
(<?) :: a -> a -> a
_ <? n = n
{-# INLINE (<?) #-}

--
-- Less than or equal.
--
{-@ (<=.) :: m:a -> { n:a | m <= n } -> { o:a | o == n } @-}
infixl 3 <=.
(<=.) :: a -> a -> a
_ <=. n = n
{-# INLINE (<=.) #-}

{-@ assume (<=?) :: m:a -> n:a -> { o:a | o == n && m <= n } @-}
infixl 3 <=?
(<=?) :: a -> a -> a
_ <=? n = n
{-# INLINE (<=?) #-}

--
-- Greater than.
--
{-@ (>.) :: m:a -> { n:a | m > n } -> { o:a | o == n } @-}
infixl 3 >.
(>.) :: a -> a -> a
_ >. y = y
{-# INLINE (>.) #-}

{-@ assume (>?) :: m:a -> n:a -> { o:a | o == n && m > n } @-}
infixl 3 >?
(>?) :: a -> a -> a
_ >? y = y
{-# INLINE (>?) #-}

--
-- Greater than or equal.
--
{-@ (>=.) :: m:a -> { n:a | m >= n } -> { o:a | o == n } @-}
infixl 3 >=.
(>=.) :: a -> a -> a
_ >=. n = n
{-# INLINE (>=.) #-}

{-@ assume (>=?) :: m:a -> n:a -> { o:a | o == n && m >= n } @-}
infixl 3 >=?
(>=?) :: a -> a -> a
_ >=? n = n
{-# INLINE (>=?) #-}

--
-- Cost equivalence.
--
{-@ predicate COSTEQ T1 T2 = tval T1 == tval T2 && tcost T1 == tcost T2 @-}

{-@ (<=>.)
  :: t1:Tick a
  -> { t2:Tick a | COSTEQ t1 t2 }
  -> { t3:Tick a | COSTEQ t1 t2 && COSTEQ t1 t3 && COSTEQ t2 t3 }
@-}
infixl 3 <=>.
(<=>.) :: Tick a -> Tick a -> Tick a
(<=>.) _ t2 = t2
{-# INLINE (<=>.) #-}

{-@ assume (<=>?)
  :: t1:Tick a -> t2:Tick a
  -> { t3:Tick a | COSTEQ t1 t2 && COSTEQ t1 t3 && t2 == t3 }
@-}
infixl 3 <=>?
(<=>?) :: Tick a -> Tick a -> Tick a
(<=>?) _ t2 = t2
{-# INLINE (<=>?) #-}

--
-- Improvement.
--
{-@ predicate IMP T1 T2 = tval T1 == tval T2 && tcost T1 >= tcost T2 @-}

{-@ (>~>.)
  :: t1:Tick a
  -> { t2:Tick a | IMP t1 t2 }
  -> { t3:Tick a | IMP t1 t2 && IMP t1 t3 && t2 == t3 }
@-}
infixl 3 >~>.
(>~>.) :: Tick a -> Tick a -> Tick a
(>~>.) _ t2 = t2
{-# INLINE (>~>.) #-}

{-@ assume (>~>?)
  :: t1:Tick a -> t2:Tick a
  -> { t3:Tick a | IMP t1 t2 && IMP t1 t3 && t2 == t3 }
@-}
infixl 3 >~>?
(>~>?) :: Tick a -> Tick a -> Tick a
(>~>?) _ t2 = t2
{-# INLINE (>~>?) #-}

--
-- Quantified improvement.
--
{-@ predicate QIMP T1 N T2 = tval T1 == tval T2 && tcost T1 == tcost T2 + N @-}

{-@ (.>==)
  :: t1:Tick a
  -> n:Int
  -> { t2:Tick a | QIMP t1 n t2 }
  -> { t3:Tick a | QIMP t1 n t2 && QIMP t1 n t3 && t2 == t3 }
@-}
infixl 3 .>==
(.>==) :: Tick a -> Int -> Tick a -> Tick a
(.>==) _ _ t2 = t2
{-# INLINE (.>==) #-}

{-@ assume (?>==)
  :: t1:Tick a -> n:Nat -> t2:Tick a
  -> { t3:Tick a | QIMP t1 n t2 && QIMP t1 n t3 && t2 == t3 }
@-}
infixl 3 ?>==
(?>==) :: Tick a -> Int -> Tick a -> Tick a
(?>==) _ _ t2 = t2
{-# INLINE (?>==) #-}

--
-- Diminishment.
--
{-@ predicate DIM T1 T2 = tval T1 == tval T2 && tcost T1 <= tcost T2 @-}

{-@ (<~<.)
  :: t1:Tick a
  -> { t2:Tick a | DIM t1 t2 }
  -> { t3:Tick a | DIM t1 t2 && DIM t1 t3 && t2 == t3 }
@-}
infixl 3 <~<.
(<~<.) :: Tick a -> Tick a -> Tick a
(<~<.) _ t2 = t2
{-# INLINE (<~<.) #-}

{-@ assume (<~<?)
  :: t1:Tick a -> t2:Tick a
  -> { t3:Tick a | DIM t1 t2 && DIM t1 t3 && t2 == t3 }
@-}
infixl 3 <~<?
(<~<?) :: Tick a -> Tick a -> Tick a
(<~<?) _ t2 = t2
{-# INLINE (<~<?) #-}

--
-- Quantified diminishment.
--
{-@ predicate QDIM T1 N T2 = tval T1 == tval T2 && tcost T1 + N == tcost T2 @-}

{-@ (.<==)
  :: t1:Tick a
  -> n:Nat
  -> { t2:Tick a | QDIM t1 n t2 }
  -> { t3:Tick a | QDIM t1 n t2 && QDIM t1 n t3 && t2 == t3 }
@-}
infixl 3 .<==
(.<==) :: Tick a -> Int -> Tick a -> Tick a
(.<==) _ _ t2 = t2
{-# INLINE (.<==) #-}

{-@ assume (?<==)
  :: t1:Tick a -> n:Nat -> t2:Tick a
  -> { t3:Tick a | QDIM t1 n t2 && QDIM t1 n t3 && t2 == t3 }
@-}
infixl 3 ?<==
(?<==) :: Tick a -> Int -> Tick a -> Tick a
(?<==) _ _ t2 = t2
{-# INLINE (?<==) #-}

-------------------------------------------------------------------------------
-- | Cost separators:
-------------------------------------------------------------------------------

--
-- Quantified improvement.
--
{-@ (==>.) :: (a -> b) -> a -> b @-}
infixl 3 ==>.
(==>.) :: (a -> b) -> a -> b
f ==>. a = f a
{-# INLINE (==>.) #-}

--
-- Quantified improvement (assumption).
--
{-@ (==>?) :: (a -> b) -> a -> b @-}
infixl 3 ==>?
(==>?) :: (a -> b) -> a -> b
f ==>? a = f a
{-# INLINE (==>?) #-}

--
-- Quantified diminishment.
--
{-@ (==<.) :: (a -> b) -> a -> b @-}
infixl 3 ==<.
(==<.) :: (a -> b) -> a -> b
f ==<. a = f a
{-# INLINE (==<.) #-}

--
-- Quantified diminishment (assumption).
--
{-@ (==<?) :: (a -> b) -> a -> b @-}
infixl 3 ==<?
(==<?) :: (a -> b) -> a -> b
f ==<? a = f a
{-# INLINE (==<?) #-}