-- ==========================================================--
-- === Dependancy analyser dependancy.m (1) ===--
-- ==========================================================--
module Dependancy where
import BaseDefs
import Utils
-- ==========================================================--
--
deBindersOf :: [(a,b)] -> [a]
deBindersOf defns = [name | (name, rhs) <- defns]
-- ==========================================================--
--
deValuesOf :: [(a,b)] -> [b]
deValuesOf defns = [rhs | (name, rhs) <- defns]
-- ==========================================================--
--
deFreeVars :: CExpr -> AnnExpr Naam (Set Naam)
deFreeVars (ENum k) = (utSetEmpty, ANum k)
deFreeVars (EVar v) = (utSetSingleton v, AVar v)
deFreeVars (EConstr n) = (utSetEmpty, AConstr n)
deFreeVars (EAp e1 e2)
= (utSetUnion (deFreeVarsOf e1') (deFreeVarsOf e2'), AAp e1' e2')
where e1' = deFreeVars e1
e2' = deFreeVars e2
deFreeVars (ECase e alts)
= (utSetUnion (deFreeVarsOf e') free, ACase e' alts')
where e' = deFreeVars e
alts' = [(t, (ns, deFreeVars e)) | (t, (ns, e)) <- alts]
free = utSetUnionList (map f alts')
f (t, (ns, e)) = utSetSubtraction (deFreeVarsOf e) (utSetFromList ns)
deFreeVars (ELam args body)
= (utSetSubtraction (deFreeVarsOf body') (utSetFromList args), ALam args body')
where body' = deFreeVars body
deFreeVars (ELet isRec defns body)
= (utSetUnion defnsFree bodyFree, ALet isRec defns' body')
where binders = deBindersOf defns
binderSet = utSetFromList binders
values' = map deFreeVars (deValuesOf defns)
defns' = zip binders values'
freeInValues = utSetUnionList (map deFreeVarsOf values')
defnsFree | isRec = utSetSubtraction freeInValues binderSet
| otherwise = freeInValues
body' = deFreeVars body
bodyFree = utSetSubtraction (deFreeVarsOf body') binderSet
-- ==========================================================--
--
deFreeVarsOf :: AnnExpr Naam (Set Naam) -> Set Naam
deFreeVarsOf (free_vars, expr) = free_vars
-- ==========================================================--
--
deDepthFirstSearch :: (Ord a) =>
(a -> [a]) -> -- The map,
(Set a, [a]) -> -- state: visited set,
-- current sequence of vertices
[a] -> -- input vertices sequence
(Set a, [a]) -- final state
deDepthFirstSearch
= foldl . search
where
search relation (visited, sequence) vertex
| utSetElementOf vertex visited = (visited, sequence )
| otherwise = (visited', vertex: sequence')
where
(visited', sequence')
= deDepthFirstSearch relation
(utSetUnion visited (utSetSingleton vertex), sequence)
(relation vertex)
-- ==========================================================--
--
deSpanningSearch :: (Ord a) =>
(a -> [a]) -> -- The map
(Set a, [Set a]) -> -- Current state: visited set,
-- current sequence of vertice sets
[a] -> -- Input sequence of vertices
(Set a, [Set a]) -- Final state
deSpanningSearch
= foldl . search
where
search relation (visited, utSetSequence) vertex
| utSetElementOf vertex visited = (visited, utSetSequence )
| otherwise = (visited', utSetFromList (vertex: sequence): utSetSequence)
where
(visited', sequence)
= deDepthFirstSearch relation
(utSetUnion visited (utSetSingleton vertex), [])
(relation vertex)
-- ==========================================================--
--
deScc :: (Ord a) =>
(a -> [a]) -> -- The "ins" map
(a -> [a]) -> -- The "outs" map
[a] -> -- The root vertices
[Set a] -- The topologically sorted components
deScc ins outs
= spanning . depthFirst
where depthFirst = second . deDepthFirstSearch outs (utSetEmpty, [])
spanning = second . deSpanningSearch ins (utSetEmpty, [])
-- ==========================================================--
--
deDependancy :: CExprP Naam -> CExprP Naam
deDependancy = deDepends . deFreeVars
-- ==========================================================--
--
deDepends (free, ANum n) = ENum n
deDepends (free, AConstr n) = EConstr n
deDepends (free, AVar v) = EVar v
deDepends (free, AAp e1 e2) = EAp (deDepends e1) (deDepends e2)
deDepends (free, ACase body alts) = ECase (deDepends body)
[(t, (ns, deDepends e))
| (t, (ns, e)) <- alts]
deDepends (free, ALam ns body) = ELam ns (deDepends body)
deDepends (free, ALet isRec defns body)
= foldr (deElet isRec) (deDepends body) defnGroups
where
binders = deBindersOf defns
binderSet | isRec = utSetFromList binders
| otherwise = utSetEmpty
edges = [(n, f) | (n, (free, e)) <- defns,
f <- utSetToList (utSetIntersection free binderSet)]
ins v = [u | (u,w) <- edges, v==w]
outs v = [w | (u,w) <- edges, v==u]
components = map utSetToList (deScc ins outs binders)
defnGroups = [[(n, utSureLookup defns "depends`defnGroups" n)
| n <- ns] | ns <- components]
-- ==========================================================--
--
deElet isRec dfs e
= if not isRec || nonRec dfs
then ELet False dfs' e
else ELet True dfs' e
where dfs' = [(n, deDepends e) | (n,e) <- dfs]
nonRec [(n, (free, e))] = not (utSetElementOf n free)
nonRec dfs = False
-- ==========================================================--
-- === End dependancy.m (1) ===--
-- ==========================================================--
|