/// <summary> /// Checks whether the property map grants the requested access privilege and throws an exception if it doesn't. /// </summary> /// <param name="access">required access privilege</param> /// <exception cref="InvalidOperationException">if requested access privilege is not supported</exception> public static void RequireAccess <TThis, TValue>(this IPropMap <TThis, TValue> pmap, EAccess access) { bool granted; switch (pmap.Access) { case EAccess.NoAccess: granted = access == EAccess.NoAccess; break; case EAccess.ReadOnly: granted = access == EAccess.NoAccess || access == EAccess.ReadOnly; break; case EAccess.WriteOnly: granted = access == EAccess.NoAccess || access == EAccess.WriteOnly; break; case EAccess.ReadWrite: granted = true; break; default: throw new NotImplementedException(); } if (!granted) { throw new InvalidOperationException("Need " + access.ToString() + " access to a property map, but got only " + pmap.Access.ToString() + " access"); } }
/*public static void ComputeImmediatePostDominators<T>(this IGraphAdapter<T> a, * IList<T> nodes, T exit) where T : class * { * if (a.Preds[exit].Length == 0) * { * // special case: exit code is not reachable. * // This can happen due to infinite loops which do not return from the * // current method. * * // no fix yet... * } * * ComputeImmediateDominators(a.Preds, a.Succs, a.PostOrderIndex, * a.IPDom, nodes, exit); * a.IPDom[exit] = null; * a.InvertRelation(a.IPDom, a.IPDoms, nodes); * a.IPDom[exit] = exit; * }*/ /// <summary> /// Computes the lowest common ancestor tree of any set of given nodes. /// </summary> /// <typeparam name="T">The node type</typeparam> /// <param name="nodes">The query set of nodes from which the LCA tree should be computed (>= 2 elements)</param> /// <param name="prel">The parent relation: assigns each node to its parent</param> /// <param name="root">The root node</param> /// <param name="rporel">The index relation: assigns each node to its postorder index</param> /// <param name="lprel">The LCA relation (output): assigns each node of the query set to its LCA parent</param> public static void GetLCATree <T>(IEnumerable <T> nodes, IPropMap <T, T> prel, T root, IPropMap <T, int> porel, IPropMap <T, T> lprel) { PriorityQueue <Tuple <T, T> > pq = new PriorityQueue <Tuple <T, T> >(); pq.Resolve = (x, y) => { if (!object.Equals(x.Item1, x.Item2)) { lprel[x.Item1] = x.Item2; } if (!object.Equals(y.Item1, x.Item2)) { lprel[y.Item1] = x.Item2; } return(Tuple.Create(x.Item2, x.Item2)); }; foreach (T node in nodes) { pq.Enqueue(-porel[node], Tuple.Create(node, node)); } while (!pq.IsEmpty) { var kvp = pq.Dequeue(); if (object.Equals(kvp.Value.Item2, root)) { break; } var par = prel[kvp.Value.Item2]; var next = Tuple.Create(kvp.Value.Item1, par); pq.Enqueue(-porel[next.Item2], next); } }
/// <summary> /// Performs a depth-first search on the graph and retrieves a post-order sorting. /// </summary> /// <param name="succrel">successor relation</param> /// <param name="indexMap">index map for receiving the post order indices</param> /// <param name="nodes">nodes to consider</param> /// <param name="start">start node</param> /// <param name="reverse">whether a reverse post-order sorting is desired</param> /// <returns>all visited nodes in post-order sorting or inverse post-order sorting</returns> public static T[] GetPostOrder <T>(IPropMap <T, T[]> succrel, IPropMap <T, int> indexMap, IList <T> nodes, T start, bool reverse) { indexMap.Reset(nodes, -1); Stack <T> result = new Stack <T>(); int index = 0; PostOrderDFS(succrel, indexMap, result, start, ref index); indexMap.Reset(nodes, -1); List <T> order = new List <T>(nodes.Count); index = 0; foreach (T node in result) { if (indexMap[node] < 0) { order.Add(node); indexMap[node] = index++; } } if (reverse) { order.Reverse(); } return(order.ToArray()); }
/// <summary> /// Returns <c>true</c> if <paramref name="w"/> is an ancestor of <c>v</c>. /// </summary> /// <param name="indexrel">pre-order index relation</param> /// <param name="lastrel">pre-order last index relation</param> public static bool IsAncestor <T>( IPropMap <T, int> indexrel, IPropMap <T, T> lastrel, T w, T v) { return(indexrel[w] <= indexrel[v] && indexrel[v] <= indexrel[lastrel[w]]); }
/// <summary> /// Sets all specified keys of the property map to the specified reset value. /// </summary> /// <param name="pmap">the property map</param> /// <param name="nodes">the elements whose property values are to be reset</param> /// <param name="value">reset value</param> public static void Reset <TThis, TValue>(this IPropMap <TThis, TValue> pmap, IEnumerable <TThis> nodes, TValue value) { pmap.RequireAccess(EAccess.WriteOnly); foreach (TThis node in nodes) { pmap[node] = value; } }
private int[] _repShuffle; // Used to pick the "right" representant for // Havlak's loop analysis /// <summary> /// Constructs an instance of the union-find data structure. /// </summary> /// <param name="a">set adapter</param> /// <param name="elems">The list set elements. It is assumed that the list index of each set element /// matched the index returned by the set adapter.</param> public UnionFind(ISetAdapter <T> a, IList <T> elems) { _index = a.Index; _elems = new List <T>(elems); _repShuffle = new int[elems.Count]; for (int i = 0; i < _elems.Count; i++) { Debug.Assert(_index[_elems[i]] == i); _repShuffle[i] = i; } _impl = new DisjointSets(elems.Count); }
public SlimMuxInterconnectHelper(IAutoBinder binder) { _binder = binder; _signal2Idx = new CacheDictionary <SignalRef, int>(CreateFUSignalIndex); _dep = new DelegatePropMap <TimedSignalFlow, int>(tf => _signal2Idx[tf.Source]); _dst = new DelegatePropMap <TimedSignalFlow, int>(tf => _signal2Idx[tf.Target]); _pipeSource = new DelegatePropMap <int, int>(GetPipeSource); _pipeSink = new DelegatePropMap <int, int>(GetPipeSink); _pipeDelay = new DelegatePropMap <int, long>(GetPipeDelay); _pmPreds = new DelegatePropMap <int, IEnumerable <int> >(GetPreds); _pmSuccs = new DelegatePropMap <int, IEnumerable <int> >(GetSuccs); _isFixed = new DelegatePropMap <int, bool>(GetIsFixed); }
public IndexedIntSetAdapter(int[] indices) { Contract.Requires <ArgumentException>(indices != null); int max = indices.Max(); _bwdIndices = Arrays.Same(-1, max + 1); for (int i = 0; i < indices.Length; i++) { _bwdIndices[indices[i]] = i; } _idxMap = new DelegatePropMap <int, int>(i => _bwdIndices[i]); }
private static void PostOrderDFS <T>( IPropMap <T, T[]> succs, IPropMap <T, int> indexMap, Stack <T> result, T node, ref int index) { Contract.Requires <ArgumentNullException>(succs != null); Contract.Requires <ArgumentNullException>(indexMap != null); Contract.Requires <ArgumentNullException>(result != null); if (indexMap[node] < 0) { indexMap[node] = index++; foreach (T succ in succs[node]) { PostOrderDFS(succs, indexMap, result, succ, ref index); } } result.Push(node); }
/// <summary> /// Computes the immediate dominators of the specified graph nodes. /// </summary> /// <remarks> /// This is an algorithm from Cooper, Harvey and Kennedy for the computation /// of immediate dominators in a control flow graph. /// Reference: /// <para> /// SOFTWARE—PRACTICE AND EXPERIENCE 2001; 4:1–10 /// </para><para> /// Keith D. Cooper, Timothy J. Harvey and Ken Kennedy /// </para><para> /// A Simple, Fast Dominance Algorithm /// </para> /// </remarks> /// <param name="succrel">successor relation</param> /// <param name="predrel">predecessor relation</param> /// <param name="index">node index map</param> /// <param name="dom">immediate dominators relation</param> /// <param name="nodes">nodes to consider</param> /// <param name="start">start node</param> public static void ComputeImmediateDominators <T>( IPropMap <T, T[]> succrel, IPropMap <T, T[]> predrel, IPropMap <T, int> index, IPropMap <T, T> dom, IList <T> nodes, T start) where T : class { T[] order = GetPostOrder(succrel, index, nodes, start, true); dom[start] = start; bool changed = true; while (changed) { changed = false; foreach (T node in order) { if (node.Equals(start)) { continue; } T newIdom = null; T[] preds = predrel[node]; foreach (T p in preds) { if (dom[p] != null) { if (newIdom == null) { newIdom = p; } else { newIdom = Intersect(dom, index, p, newIdom); } } } if (dom[node] != newIdom) { dom[node] = newIdom; changed = true; } } } }
/// <summary> /// Inverts a property map-based relation. /// </summary> /// <param name="a">graph adapter providing temporary list storage</param> /// <param name="srcrel">source property map</param> /// <param name="dstrel">destination property map for inverted relation</param> /// <param name="nodes">nodes to be considered for the inversion</param> public static void InvertRelation <T>(this IGraphAdapter <T> a, IPropMap <T, T[]> srcrel, IPropMap <T, T[]> dstrel, IEnumerable <T> nodes) { a.CreateDefaultTempStorage(nodes); srcrel.RequireAccess(EAccess.ReadOnly); dstrel.RequireAccess(EAccess.WriteOnly); foreach (T node in nodes) { foreach (T adj in srcrel[node]) { a.TempList[adj].Add(node); } } foreach (T node in nodes) { dstrel[node] = a.TempList[node].ToArray(); } a.TempList.Clear(nodes); }
/** This is part of the dmonance algorithm from Cooper, Harvey and Kennedy * */ private static T Intersect <T>( IPropMap <T, T> dom, IPropMap <T, int> index, T b1, T b2) where T : class { T finger1 = b1; T finger2 = b2; while (finger1 != finger2) { while (index[finger1] > index[finger2]) { finger1 = dom[finger1]; } while (index[finger2] > index[finger1]) { finger2 = dom[finger2]; } } return(finger1); }
/// <summary> /// Finds the shortest paths from a specified entry node to all other nodes. /// </summary> /// <typeparam name="T">node type</typeparam> /// <param name="nodes">nodes to consider</param> /// <param name="start">start node</param> /// <param name="succs">successor relation</param> /// <param name="rootDist">relation for storing the distance from each node to the start node</param> /// <param name="pred">predecessor relation</param> /// <param name="dist">adjacent node distance relation</param> public static void FindShortestPaths <T>(IEnumerable <T> nodes, T start, IPropMap <T, T[]> succs, IPropMap <T, int> rootDist, IPropMap <T, T> pred, IPropMap <Tuple <T, T>, int> dist) { foreach (T node in nodes) { rootDist[node] = int.MaxValue; pred[node] = default(T); } rootDist[start] = 0; PriorityQueue <IEnumerable <T> > q = new PriorityQueue <IEnumerable <T> >() { Resolve = (x, y) => x.Union(y).Distinct() }; q.Enqueue(0, Enumerable.Repeat(start, 1)); while (!q.IsEmpty) { var kvp = q.Dequeue(); int d = (int)kvp.Key; IEnumerable <T> curs = kvp.Value; foreach (T cur in curs) { if (d != rootDist[cur]) { continue; } foreach (T succ in succs[cur]) { int newDist = rootDist[cur] + dist[Tuple.Create(cur, succ)]; if (newDist < rootDist[succ]) { rootDist[succ] = newDist; pred[succ] = cur; q.Enqueue(newDist, Enumerable.Repeat(succ, 1)); } } } } }
public ASLAPAdapter(ISchedulingAdapter <T> scha, IPropMap <T, long> aslapIndex) { _scha = scha; _aslapIndex = aslapIndex; }
public SetAdapter(IPropMap <int, int> indexMap) { _indexMap = indexMap; }
public IntSetAdapter() { _idMap = new DelegatePropMap <int, int>(i => i); }
public MobilityALAP(IPropMap <T, long> asapMap, IPropMap <T, long> alapMap) : base(true) { _asapMap = asapMap; _alapMap = alapMap; }
/// <summary> /// Sets all specified keys of the property map to <c>default(TValue)</c>. /// </summary> /// <param name="pmap">the property map</param> /// <param name="nodes">the elements whose property values are to be reset</param> public static void Clear <TThis, TValue>(this IPropMap <TThis, TValue> pmap, IEnumerable <TThis> nodes) { pmap.Reset(nodes, default(TValue)); }