packages feed

MiniAgda-0.2014.1.9: test/succeed/Stack.ma

-- 2010-07-13,-27  state-less stack object

data Maybe (A : Set) : Set
{ nothing : Maybe A
; just : A -> Maybe A
}

-- stack object
sized codata Stack (A : Set) : Size -> Set
{ stack : [i : Size] ->
  (top  : Maybe A) ->
  (pop  : Stack A i) ->
  (push : A -> Stack A i) -> Stack A $i
} 

-- functional to construct push action
cofun pushFunc : [A : Set] -> [i : Size] -> |i| ->
                 ([j : Size] -> |j| < |i| -> Stack A j -> A -> Stack A j) ->
                 Stack A i -> A -> Stack A i
{ pushFunc A ($ i) f s a = stack i (just a) s (f i (pushFunc A i f s a))
} 
-- f : [j : Size] -> |j| < |$i| -> Stack A j -> A -> Stack A j
-- s : Stack A $i
-- by subtyping
-- f : [j : Size] -> |j| < |i| -> Stack A j -> A -> Stack A j
-- s : Stack A i
-- hence  pushFunc A i f s a : Stack A i
--   f i (...) : A -> Stack A i
-- rhs : Stack A $i

-- tying the knot
cofun pushFix  : [A : Set] -> [i : Size] -> |i| -> Stack A i -> A -> Stack A i
{ pushFix A ($ i) = pushFunc A ($ i) (pushFix A)
}
-- on the rhs, we have the typing of the recursive call
--   pushFix A : [j : Size] -> |j| < |$i| -> Stack A j -> A -> Stack A j

-- constructing the empty stack
cofun empty : [A : Set] -> [i : Size] -> |i| -> Stack A i
{ empty A ($ i) = stack i nothing (empty A i) (pushFix A i (empty A i))
}
 
{- original circular program

data Stack a = Stack 
  { top  :: Maybe a
  , pop  :: Stack a
  , push :: a -> Stack a
  } 

-- circular auxiliary program to construct stacks 
push' :: Stack a -> a -> Stack a
push' s a = s'
  where s' = Stack (Just a) s (push' s')

-- the empty stack
empty :: Stack a
empty = Stack Nothing empty (push' empty)

-}

{-

  push' s a = fix (\ s' -> Stack (Just a) s (push' s'))

-}