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
import qualified LinearScan.IOExts as IOExts
#endif
#ifdef __GLASGOW_HASKELL__
unsafeCoerce = GHC.Base.unsafeCoerce#
#else
unsafeCoerce = IOExts.unsafeCoerce
#endif
data Graph =
Build_Graph ([] Eqtype.Equality__Coq_sort) ([]
((,) Eqtype.Equality__Coq_sort
Eqtype.Equality__Coq_sort))
vertices :: Eqtype.Equality__Coq_type -> Graph -> []
Eqtype.Equality__Coq_sort
vertices a g =
case g of {
Build_Graph vertices0 edges0 -> vertices0}
edges :: Eqtype.Equality__Coq_type -> Graph -> []
((,) Eqtype.Equality__Coq_sort Eqtype.Equality__Coq_sort)
edges a g =
case g of {
Build_Graph vertices0 edges0 -> edges0}
emptyGraph :: Eqtype.Equality__Coq_type -> Graph
emptyGraph a =
Build_Graph [] []
addVertex :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_sort -> Graph
-> Graph
addVertex a v g =
let {vg = vertices a 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 g)
addEdge :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_sort -> Graph ->
Graph
addEdge a e g =
let {eg = edges a g} in
Build_Graph (vertices a g)
(case Ssrbool.in_mem e
(Ssrbool.mem (Seq.seq_predType (Eqtype.prod_eqType a a))
(unsafeCoerce eg)) of {
Prelude.True -> eg;
Prelude.False -> (:) (unsafeCoerce e) eg})
removeEdge :: Eqtype.Equality__Coq_type -> ((,) Eqtype.Equality__Coq_sort
Eqtype.Equality__Coq_sort) -> Graph -> Graph
removeEdge a x g =
Build_Graph (vertices a g)
(unsafeCoerce
(Seq.rem (Eqtype.prod_eqType a a) (unsafeCoerce x)
(unsafeCoerce (edges a g))))
outbound :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_sort -> Graph
-> [] ((,) Eqtype.Equality__Coq_sort Eqtype.Equality__Coq_sort)
outbound a x g =
Prelude.filter (\e -> Eqtype.eq_op a x (Prelude.fst e)) (edges a g)
inbound :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_sort -> Graph ->
[] ((,) Eqtype.Equality__Coq_sort Eqtype.Equality__Coq_sort)
inbound a x g =
Prelude.filter (\e -> Eqtype.eq_op a x (Prelude.snd e)) (edges a g)
removeVertex :: Eqtype.Equality__Coq_type -> Eqtype.Equality__Coq_sort ->
Graph -> Graph
removeVertex a v g =
Prelude.foldr (removeEdge a) (Build_Graph (Seq.rem a v (vertices a g))
(edges a g)) ((Prelude.++) (inbound a v g) (outbound a v g))
topsort :: Eqtype.Equality__Coq_type -> (Eqtype.Equality__Coq_sort ->
Prelude.Bool) -> (Eqtype.Equality__Coq_sort -> Graph -> Graph) ->
Graph -> [] Eqtype.Equality__Coq_sort
topsort a splittable split g0 =
let {
go fuel g =
(\fO fS n -> if n Prelude.<= 0 then fO () else fS (n Prelude.- 1))
(\_ ->
vertices a g)
(\fuel0 ->
let {
noInbound = Prelude.filter (\v -> Seq.nilp (inbound a v g))
(vertices a g)}
in
case noInbound of {
[] ->
case vertices a g of {
[] -> [];
(:) v vs ->
case Prelude.filter (\x -> splittable x) ((:) v vs) of {
[] -> vertices a g;
(:) x l -> go fuel0 (split x g)}};
(:) s l ->
(Prelude.++) noInbound
(go fuel0 (Prelude.foldr (removeVertex a) g noInbound))})
fuel}
in go (Ssrnat.double (Data.List.length (vertices a g0))) g0