packages feed

liquidhaskell-0.8.2.0: tests/equationalproofs/todo/MonadicLawsAssoc.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ExtendedDefaultRules #-}

{-@ LIQUID "--higherorder"      @-}
{-@ LIQUID "--autoproofs"      @-}
{-@ LIQUID "--totality"        @-}
{-@ LIQUID "--exact-data-cons" @-}
module Append where

import Axiomatize
import Equational
import Prelude hiding (return, (>>=))


data L a = N |  C a (L a)

-- | Definition of the list monad

{-@ axiomatize return @-}
$(axiomatize
  [d| return :: a -> L a
      return x = C x N
    |])


{-@ axiomatize append @-}
$(axiomatize
  [d| append :: L a -> L a -> L a
      append N ys        = ys
      append (C x xs) ys = C x (append xs ys)
    |])

{-@ axiomatize bind @-}
$(axiomatize
  [d| bind :: L a -> (a -> L a) -> L a
      bind N        f = N
      bind (C x xs) f = append (f x) (xs `bind` f)
    |])

-- | Left Associativity: (m >>= f) >>= g ≡  m >>= (\x -> f x >>= g)


helper :: Eq a => a -> L a -> (a -> L a) -> (a -> L a) -> Proof
{-@ helper ::  x:a -> xs:L a -> f:(a -> L a) -> g:(a -> L a) 
            ->   {v: Proof| bind (append (f x) (bind N f)) g == append (bind (f x) g) (bind (bind N f) g)} @-}
helper x xs f g 
--   = auto 2 (bind (append fx N) g == bind fx  g )
--     = refl (bind (append (f x) (bind N f)) g) `by` pr1 `by` pr2 `by` pr3 `by` pr4 `by` pr5 
     = auto 2 (bind (append (f x) N) g ==  bind (f x) g ) 
  where 
{- 
    e1  = bind (append (f x) (bind N f)) g
    pr1 = axiom_bind_N f 
    e2  = bind (append (f x) N) g
    pr2 = prop_app_nil (f x)
    e3  = bind (f x) g 
    pr3 = prop_app_nil (bind (f x)  g)
    e4  = append (bind (f x) g) N
    pr4 = axiom_bind_N f     
    e5  = append (bind (f x) g) (bind N f)
    pr5 = axiom_bind_N g   
    e6  = append (bind (f x) g) (bind (bind N f) g)

-}


helper x xs f g 
  = undefined -- auto 2 ((append (f x) (xs `bind` f)) `bind` g ==  append (f x `bind` g) ((xs `bind` f) `bind` g)) 


{-@ prop_app_nil :: ys:L a -> {v:Proof | append ys N == ys} @-}
prop_app_nil :: (Eq a) => L a -> Proof
prop_app_nil N        = auto 1 (append N N        == N     )
prop_app_nil (C x xs) = auto 1 (append (C x xs) N == C x xs)

prop_left_assoc :: Eq a => L a -> (a -> L a) -> (a -> L a) -> Proof
{-@ prop_left_assoc :: m: L a -> f:(a -> L a) -> g:(a -> L a) -> Proof @-}
prop_left_assoc N f g 
  = refl ((N `bind` f) `bind` g) `by` pr1 `by` pr2 `by` pr3 
  where
    e1  = (N `bind` f) `bind` g
    pr1 = axiom_bind_N f 
    e2  = N `bind` g
    pr2 = axiom_bind_N g
    e3  = N
    pr3 = axiom_bind_N ((\x -> f x `bind` g))
    e4  = N `bind` (\x -> f x `bind` g)


prop_left_assoc (C x xs) f g 
  = undefined -- refl ((C x xs `bind` f) `bind` g) 
  where
    e1  = (C x xs `bind` f) `bind` g

    e2 = (append (f x) (xs `bind` f)) `bind` g 




    ei =  append (f x `bind` g) ((xs `bind` f) `bind` g)
    ej =  append ((\x -> f x `bind` g) x) ((xs `bind` f) `bind` g)



    ek =  append ((\x -> f x `bind` g) x) (xs `bind` (\x -> f x `bind` g))
    en =  C x xs `bind` (\x -> f x `bind` g)

-- | List definition


instance Eq a => Eq (L a) where
  N == N                 = True
  (C x xs) == (C x' xs') = x == x' && xs == xs'

{-@ data L [llen] @-}
{-@ invariant {v: L a | llen v >= 0} @-}

{-@ measure llen @-}
llen :: L a -> Int
llen N = 0
llen (C x xs) = 1 + llen xs