0 | module Data.Graph.Indexed.Ring.Relevant
3 | import Data.Graph.Indexed.Ring.Relevant.Candidates
5 | import Data.SortedMap
7 | import public Data.Graph.Indexed.Ring.Relevant.Types
16 | computeCyclomaticN : {k : _} -> IGraph k e n -> Nat
17 | computeCyclomaticN g = S (size g) `minus` k
19 | 0 EdgMap : Nat -> Type
20 | EdgMap k = SortedMap (Edg k) Integer
24 | getBitsEdges : {k : _} -> (g : IGraph k e n) -> EdgMap k
25 | getBitsEdges g = setBits (map ignore $
edges g) 1 empty
27 | setBits : List (Edg k) -> Integer -> EdgMap k -> EdgMap k
28 | setBits [] bitp sm = sm
29 | setBits (y :: xs) bitp sm = setBits xs (shiftL bitp 1) (insert y bitp sm)
35 | getBitsRing : EdgMap k -> Integer -> List (Fin k) -> Integer
36 | getBitsRing sm i (x::xs@(y::_)) = case mkEdge x y () >>= lookup' sm of
37 | Nothing => getBitsRing sm i xs
38 | Just z => getBitsRing sm (i .|. z) xs
39 | getBitsRing sm i _ = i
43 | testSigBit : Integer -> Integer -> Ordering
44 | testSigBit i j = compare (xor i j) (i .&. j)
51 | -> (processedRs : SnocList (Integer))
52 | -> (unprocessedRs : List (Integer))
53 | -> (List Integer, Bool)
54 | isInSet ring sy [] = (sy <>> [ring], True)
55 | isInSet ring sy (x :: xs) =
56 | case testSigBit ring x of
58 | let remainder := xor ring x
59 | in if remainder == 0
60 | then (sy <>> x :: xs, False)
61 | else isInSet remainder (sy :< x) xs
63 | case compare ring x of
64 | GT => (sy :< ring <>> x :: xs, True)
65 | _ => isInSet ring (sy :< x) xs
67 | record BCycle (k : Nat) where
72 | 0 BCycles : Nat -> Type
73 | BCycles = List . BCycle
78 | -> (sm, eq : List Integer)
79 | -> (xs, cr, mcb : BCycles k)
80 | -> (BCycles k, BCycles k)
81 | getCrAndMCB' v size sm eq [] cr mcb = (cr,mcb)
82 | getCrAndMCB' v size sm eq (c :: cs) cr mcb =
83 | case c.ncycle.size > size of
84 | True => case length mcb == v of
86 | False => case isInSet c.bitp [<] eq of
88 | getCrAndMCB' v size eq eq cs cr mcb
90 | getCrAndMCB' v c.ncycle.size eq neweq cs (c :: cr) (c :: mcb)
91 | False => case isInSet c.bitp [<] sm of
93 | getCrAndMCB' v size sm eq cs cr mcb
95 | case isInSet c.bitp [<] eq of
97 | getCrAndMCB' v c.ncycle.size sm eq cs (c :: cr) mcb
99 | getCrAndMCB' v c.ncycle.size sm neweq cs (c :: cr) (c :: mcb)
105 | getCrAndMCB : Nat -> BCycles k -> (BCycles k, BCycles k)
106 | getCrAndMCB v xs = getCrAndMCB' v 0 [] [] xs [] []
108 | convert : ISubgraph o k e n -> (BCycles o, BCycles o) -> CycleSets k
109 | convert g (m,b) = CS (map conv m) (map conv b)
111 | conv : BCycle o -> Cycle k
112 | conv (BC c _) = cast {from = NCycle k} $
{path $= map (origin g)} c
114 | fromCandidates : Candidates k e -> CycleSets k
115 | fromCandidates Empty = CS [] []
116 | fromCandidates (Isolate x nc) = let c := cast {to = Cycle k} nc in CS [c] [c]
117 | fromCandidates (System o g xss) =
118 | let ebits := getBitsEdges g
119 | ci' := sortBy (compare `on` size) xss
120 | cs := map (getCycle ebits) ci'
121 | v := computeCyclomaticN g
122 | in convert g $
getCrAndMCB v cs
124 | where getCycle : EdgMap o -> NCycle o -> BCycle o
125 | getCycle ebits nc = BC nc $
getBitsRing ebits 0 nc.path
130 | componentCycles : Subgraph k e n -> CycleSets k
131 | componentCycles = fromCandidates . componentCandidates
135 | computeCrAndMCB : {k : _} -> IGraph k e n -> CycleSets k
136 | computeCrAndMCB g =
137 | let css := map fromCandidates (candidates g)
138 | in CS (css >>= cr) (css >>= mcb)