packages feed

compdata-dags-0.2.1: examples/Examples/Repmin.hs

{-# LANGUAGE TypeOperators  #-}
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE FlexibleContexts #-}

module Examples.Repmin where

import Data.Comp.AG
import Data.Comp.Dag
import qualified Data.Comp.Dag.AG as Dag
import Data.Comp.Term
import Examples.Types

newtype MinS = MinS Int deriving (Eq,Ord)
newtype MinI = MinI Int

-- | Repmin as an AG on terms.

repmin :: Term IntTreeF -> Term IntTreeF
repmin = snd . runAG (minS |*| rep) minI init
  where init (MinS i,_) = MinI i

-- | Repmin as an AG on dags.

repminG :: Dag IntTreeF -> Term IntTreeF
repminG =  snd . Dag.runAG const (minS |*| rep) minI init
  where init (MinS i,_) = MinI i


globMin :: (?above :: atts, MinI :< atts) => Int
globMin = let MinI i = above in i

minS ::  Syn IntTreeF atts MinS
minS (Leaf i)    =  MinS i
minS (Node a b)  =  min (below a) (below b)

minI :: Inh IntTreeF atts MinI
minI _ = empty

rep ::  (MinI :< atts) => Syn IntTreeF atts (Term IntTreeF)
rep (Leaf _)    =  iLeaf globMin
rep (Node a b)  =  iNode (below a) (below b)


-- | Repmin as a rewriting AG on dags.

repminG' :: Dag IntTreeF -> Dag IntTreeF
repminG' = snd . Dag.runRewrite const minS minI rep' init
  where init (MinS i) = MinI i

rep' ::  (MinI :< atts) => Rewrite IntTreeF atts IntTreeF
rep' (Leaf _)    =  iLeaf globMin
rep' (Node a b)  =  iNode (Hole a) (Hole b)

repmin' :: Term IntTreeF -> Term IntTreeF
repmin' = snd . runRewrite minS minI rep' init
  where init (MinS i) = MinI i