using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Boogie.GraphUtil; namespace Microsoft.Boogie { public class SimulationRelation { class Graph { HashSet nodes; Dictionary>> successors; Dictionary>> predecessors; public Graph(List> edges) { nodes = new HashSet(); successors = new Dictionary>>(); predecessors = new Dictionary>>(); foreach (Tuple edge in edges) { T source = edge.Item1; L label = edge.Item2; T dest = edge.Item3; nodes.Add(source); nodes.Add(dest); if (!successors.ContainsKey(source)) { successors[source] = new Dictionary>(); } if (!successors[source].ContainsKey(label)) { successors[source][label] = new List(); } if (!predecessors.ContainsKey(dest)) { predecessors[dest] = new Dictionary>(); } if (!predecessors[dest].ContainsKey(label)) { predecessors[dest][label] = new List(); } successors[source][label].Add(dest); predecessors[dest][label].Add(source); } } public IEnumerable Nodes { get { return nodes; } } public IEnumerable Post(T t, L l) { if (successors.ContainsKey(t) && successors[t].ContainsKey(l)) { return successors[t][l]; } else { return Enumerable.Empty(); } } public IEnumerable Post(IEnumerable set, L l) { return set.Select(x => Post(x, l)).Aggregate(Enumerable.Empty(), (p, q) => p.Concat(q)); } public IEnumerable Pre(T t, L l) { if (predecessors.ContainsKey(t) && predecessors[t].ContainsKey(l)) { return predecessors[t][l]; } else { return Enumerable.Empty(); } } public IEnumerable Pre(IEnumerable set, L l) { return set.Select(x => Pre(x, l)).Aggregate(Enumerable.Empty(), (p, q) => p.Concat(q)); } public IEnumerable PostLabels(T t) { if (successors.ContainsKey(t)) { return successors[t].Keys; } else { return Enumerable.Empty(); } } public IEnumerable PreLabels(T t) { if (predecessors.ContainsKey(t)) { return predecessors[t].Keys; } else { return Enumerable.Empty(); } } } Graph aGraph; Graph bGraph; Dictionary> initialConstraints; public SimulationRelation(List> aEdges, List> bEdges, Dictionary> initialConstraints) { this.aGraph = new Graph(aEdges); this.bGraph = new Graph(bEdges); this.initialConstraints = initialConstraints; } public Dictionary> ComputeSimulationRelation() { Dictionary> prevsim; Dictionary> sim; Dictionary, HashSet> remove; Queue> workQueue; prevsim = new Dictionary>(); sim = new Dictionary>(); remove = new Dictionary, HashSet>(); workQueue = new Queue>(); foreach (var a in aGraph.Nodes) { prevsim[a] = new HashSet(bGraph.Nodes); sim[a] = new HashSet(); HashSet aOutgoingLabels = new HashSet(aGraph.PostLabels(a)); foreach (var b in bGraph.Nodes) { IEnumerable bOutgoingLabels = bGraph.PostLabels(b); if (aOutgoingLabels.IsSubsetOf(bOutgoingLabels)) { sim[a].Add(b); } } if (initialConstraints.ContainsKey(a)) { sim[a].IntersectWith(initialConstraints[a]); } foreach (var l in aGraph.PreLabels(a)) { Tuple x = new Tuple(a, l); remove[x] = new HashSet(bGraph.Pre(prevsim[a], l).Except(bGraph.Pre(sim[a], l))); if (remove[x].Count > 0) { workQueue.Enqueue(x); } } } while (workQueue.Count > 0) { Tuple x = workQueue.Dequeue(); A v = x.Item1; foreach (A u in aGraph.Pre(v, x.Item2)) { foreach (B w in remove[x]) { if (sim[u].Contains(w)) { sim[u].Remove(w); foreach (L l in bGraph.PreLabels(w)) { foreach (B b in bGraph.Pre(w, l)) { if (bGraph.Post(b, l).Intersect(sim[u]).Count() == 0) { Tuple z = new Tuple(u, l); if (!remove.ContainsKey(z)) remove[z] = new HashSet(); remove[z].Add(b); workQueue.Enqueue(z); } } } } } } prevsim[v] = new HashSet(sim[v]); remove[x] = new HashSet(); } return sim; } } }