packages feed

linearscan-0.8.0: LinearScan/Graph.hs

{-# OPTIONS_GHC -cpp -XMagicHash #-}
{- For Hugs, use the option -F"cpp -P -traditional" -}

module LinearScan.Graph where


import Debug.Trace (trace, traceShow, traceShowId)
import qualified Prelude
import qualified Data.IntMap
import qualified Data.IntSet
import qualified Data.List
import qualified Data.Ord
import qualified Data.Functor.Identity
import qualified Hask.Utils

import qualified LinearScan.Eqtype as Eqtype
import qualified LinearScan.Seq as Seq
import qualified LinearScan.Ssrbool as Ssrbool
import qualified LinearScan.Ssrnat as Ssrnat



#ifdef __GLASGOW_HASKELL__
import qualified GHC.Base as GHC.Base
import qualified GHC.Prim as GHC.Prim
#else
-- HUGS
import qualified LinearScan.IOExts as IOExts
#endif


#ifdef __GLASGOW_HASKELL__
--unsafeCoerce :: a -> b
unsafeCoerce = GHC.Base.unsafeCoerce#
#else
-- HUGS
--unsafeCoerce :: a -> b
unsafeCoerce = IOExts.unsafeCoerce
#endif

data Graph =
   Build_Graph ([] Eqtype.Equality__Coq_sort) ([] Eqtype.Equality__Coq_sort) 
 (Eqtype.Equality__Coq_sort -> (,) Eqtype.Equality__Coq_sort
 Eqtype.Equality__Coq_sort)

vertices :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type -> Graph
            -> [] Eqtype.Equality__Coq_sort
vertices a b g =
  case g of {
   Build_Graph vertices0 edges0 edge_f0 -> vertices0}

edges :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type -> Graph ->
         [] Eqtype.Equality__Coq_sort
edges a b g =
  case g of {
   Build_Graph vertices0 edges0 edge_f0 -> edges0}

edge_f :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type -> Graph ->
          Eqtype.Equality__Coq_sort -> (,) Eqtype.Equality__Coq_sort
          Eqtype.Equality__Coq_sort
edge_f a b g =
  case g of {
   Build_Graph vertices0 edges0 edge_f0 -> edge_f0}

emptyGraph :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
              (Eqtype.Equality__Coq_sort -> (,) Eqtype.Equality__Coq_sort
              Eqtype.Equality__Coq_sort) -> Graph
emptyGraph a b f =
  Build_Graph [] [] f

addVertex :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
             Eqtype.Equality__Coq_sort -> Graph -> Graph
addVertex a b v g =
  let {vg = vertices a b g} in
  Build_Graph
  (case Ssrbool.in_mem v (Ssrbool.mem (Seq.seq_predType a) (unsafeCoerce vg)) of {
    Prelude.True -> vg;
    Prelude.False -> (:) v vg}) (edges a b g) (edge_f a b g)

addEdge :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
           Eqtype.Equality__Coq_sort -> Graph -> Graph
addEdge a b e g =
  let {
   g' = let {eg = edges a b g} in
        Build_Graph (vertices a b g)
        (case Ssrbool.in_mem e
                (Ssrbool.mem (Seq.seq_predType b) (unsafeCoerce eg)) of {
          Prelude.True -> eg;
          Prelude.False -> (:) e eg}) (edge_f a b g)}
  in
  case edge_f a b g' e of {
   (,) a0 z -> addVertex a b a0 (addVertex a b z g')}

removeEdge :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
              Eqtype.Equality__Coq_sort -> Graph -> Graph
removeEdge a b x g =
  Build_Graph (vertices a b g) (Seq.rem b x (edges a b g)) (edge_f a b g)

connections :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
               (((,) Eqtype.Equality__Coq_sort Eqtype.Equality__Coq_sort) ->
               Eqtype.Equality__Coq_sort) -> Eqtype.Equality__Coq_sort ->
               Graph -> [] Eqtype.Equality__Coq_sort
connections a b f x g =
  Prelude.filter
    ((Prelude..) ((Prelude..) (\y -> Eqtype.eq_op a y x) f) (edge_f a b g))
    (edges a b g)

outbound :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
            Eqtype.Equality__Coq_sort -> Graph -> []
            Eqtype.Equality__Coq_sort
outbound a b =
  connections a b Prelude.fst

inbound :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
           Eqtype.Equality__Coq_sort -> Graph -> [] Eqtype.Equality__Coq_sort
inbound a b =
  connections a b Prelude.snd

removeVertex :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type ->
                Eqtype.Equality__Coq_sort -> Graph -> Graph
removeVertex a b v g =
  Prelude.foldr (removeEdge a b) (Build_Graph (Seq.rem a v (vertices a b g))
    (edges a b g) (edge_f a b g)) (outbound a b v g)

topsort :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_type -> Graph ->
           (Eqtype.Equality__Coq_sort -> Prelude.Bool) ->
           (Eqtype.Equality__Coq_sort -> [] Eqtype.Equality__Coq_sort) -> (,)
           ([] Eqtype.Equality__Coq_sort)
           ([] ((,) Prelude.Int Eqtype.Equality__Coq_sort))
topsort a b g0 splittable split =
  let {
   go fuel depth g =
     (\fO fS n -> if n Prelude.<= 0 then fO () else fS (n Prelude.- 1))
       (\_ -> (,) (vertices a b g)
       (Prelude.map (\i -> (,) depth i) (edges a b g)))
       (\fuel0 ->
       let {
        noInbound = Prelude.filter (\v -> Seq.nilp (inbound a b v g))
                      (vertices a b g)}
       in
       case noInbound of {
        [] ->
         case edges a b g of {
          [] -> (,) [] [];
          (:) e l ->
           let {
            x = case Prelude.filter (\e0 -> splittable e0) (edges a b g) of {
                 [] -> e;
                 (:) e' l0 -> e'}}
           in
           go fuel0 ((Prelude.succ) depth)
             (Prelude.foldr (addEdge a b) (removeEdge a b x g) (split x))};
        (:) s l ->
         case go fuel0 ((Prelude.succ) depth)
                (Prelude.foldr (removeVertex a b) g noInbound) of {
          (,) ns' es' -> (,) ((Prelude.++) noInbound ns')
           ((Prelude.++)
             (Prelude.map (\i -> (,) depth i)
               (Seq.flatten (Prelude.map (\n -> outbound a b n g) noInbound)))
             es')}})
       fuel}
  in go (Ssrnat.double (Data.List.length (vertices a b g0))) 0 g0