public MergeState(EGraph result, EGraph g1, EGraph g2) { this.Result = result; this.G1 = g1; this.G2 = g2; this.Map = DoubleFunctionalMap.Empty; this.changed = false; // capture the idCounter before we update the result structure. this.lastCommonVariable = result.idCounter; }
private bool IsOldSymbol(SymbolicValue sv) { EGraph parent = this.parent; if (parent == null) { return(false); } return(sv.UniqueId <= parent.LastSymbolId); }
private EGraph ComputeCommonTail(EGraph g1, EGraph g2, out int updateSize) { EGraph current1 = g1; EGraph current2 = g2; if (g1.historySize <= 3 && g2.historySize > 100) { updateSize = g1.historySize + g2.historySize; if (g1.root == g2.root) { return(g1.root); } return(null); } if (g2.historySize <= 3 && g1.historySize > 100) { updateSize = g1.historySize + g2.historySize; if (g1.root == g2.root) { return(g1.root); } return(null); } while (current1 != current2) { if (current1 == null) { // no common tail current2 = null; break; } if (current2 == null) { // no common tail current1 = null; break; } if (current1.historySize > current2.historySize) { current1 = current1.parent; continue; } if (current2.historySize > current1.historySize) { current2 = current2.parent; continue; } // they have equal size current1 = current1.parent; current2 = current2.parent; } // now current1 == current2 == tail EGraph tail = current1; int tailSize = (tail != null)?tail.historySize:0; updateSize = g1.historySize + g2.historySize - tailSize - tailSize; return(tail); }
private SymbolicValue AddJointEdge(SymbolicValue v1target, SymbolicValue v2target, IUniqueKey function, SymbolicValue resultRoot) { SymbolicValue rtarget = (SymbolicValue)Map[v1target, v2target]; bool newBinding = false; if (rtarget == null) { // if we have visited v1target before, then the result graph is not isomorphic to G1 if (Map.ContainsKey1(v1target) || IsCommon(v1target) && v1target != v2target) { this.changed = true; } newBinding = true; if (v1target.UniqueId <= lastCommonVariable && v1target == v2target) { rtarget = v1target; // reuse old symbol } else { rtarget = Result.FreshSymbolicValue(); } this.Map = this.Map.Add(v1target, v2target, rtarget); } else { // See if info is already present SymbolicValue oldTarget = Result.LookupWithoutManifesting(resultRoot, function); if (oldTarget == rtarget) { // no change, don't record or change anything return(null); } } Result[resultRoot, function] = rtarget; AbstractValue aval1 = G1[v1target]; AbstractValue aval2 = G2[v2target]; AbstractValue aresult = G1.elementLattice.Join(aval1, aval2); Result[rtarget] = aresult; if (!G1.elementLattice.LowerThanOrEqual(aresult, aval1)) { this.changed = true; } if (Analyzer.Debug) { Console.WriteLine("AddJointEdge: {0} -{1}-> [{2},{3},{4}]", resultRoot, EGraph.Function2String(function), v1target, v2target, rtarget); } return((newBinding)?rtarget:null); }
public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out IMergeInfo mergeInfo) { EGraph eg1 = this; EGraph eg2 = (EGraph)g2; int updateSize; EGraph common = ComputeCommonTail(eg1, eg2, out updateSize); EGraph result; bool doReplay = true; if (common == null) { doReplay = false; result = new EGraph(eg1.elementLattice); result.Block = joinPoint; } else { result = new EGraph(common, joinPoint); } if (Analyzer.Debug) { Console.WriteLine("Last common symbol: {0}", common.idCounter); } if (Analyzer.Statistics) { Console.WriteLine("G1:{0} G2:{1} Tail:{2} UpdateSize:{3}", eg1.historySize, eg2.historySize, result.historySize, updateSize); } MergeState ms = new MergeState(result, eg1, eg2); // Heuristic for using Replay vs. full update doReplay &= (common != eg1.root); doReplay &= (eg1.historySize > 3); doReplay &= (eg2.historySize > 3); if (doReplay) { ms.Replay(common); } else { ms.AddMapping(eg1.constRoot, eg2.constRoot, result.constRoot); ms.JoinSymbolicValue(eg1.constRoot, eg2.constRoot, result.constRoot); } mergeInfo = ms; return(result); }
public EGraph(MathematicalLattice elementLattice) { this.elementLattice = elementLattice; this.constRoot = FreshSymbolicValue(); this.termMap = DoubleFunctionalMap.Empty; this.absMap = FunctionalMap.Empty; this.forwMap = FunctionalMap.Empty; this.eqTermMap = DoubleFunctionalMap.Empty; this.constant = false; this.parent = null; this.root = this; this.historySize = 1; this.updates = null; }
public SerializedGraphData(List <Graph> graphs, List <GraphNode> graphNodes, List <WayPoint> wayPoints) { Graphs = new Dictionary <string, SerializedGraphData.EGraph>(); GraphNodes = new Dictionary <string, SerializedGraphData.EGraphNode>(); Waypoints = new Dictionary <string, SerializedGraphData.EWayPoint>(); foreach (Graph graph in graphs) { EGraph exportableGraph = new EGraph(); var graphNodeReferences = new List <string>(); foreach (GraphNode gn in graph.nodes) { graphNodeReferences.Add(gn.offset.ToString()); } exportableGraph.graphNodeReferences = graphNodeReferences.ToArray(); Graphs.Add(graph.offset.ToString(), exportableGraph); } foreach (GraphNode graphNode in graphNodes) { EGraphNode exportableGraphNode = new EGraphNode(); exportableGraphNode.wayPointReference = graphNode.wayPoint.offset.ToString(); var exportableArcs = new List <EArc>(); foreach (Arc arc in graphNode.arcList.list) { exportableArcs.Add(new EArc() { capabilities = arc.capabilities, targetGraphNodeReference = arc.graphNode.offset.ToString(), weight = arc.weight }); } exportableGraphNode.arcs = exportableArcs.ToArray(); GraphNodes.Add(graphNode.offset.ToString(), exportableGraphNode); } foreach (WayPoint wp in wayPoints) { EWayPoint exportableWayPoint = new EWayPoint(); exportableWayPoint.position = wp.position; exportableWayPoint.radius = wp.radius; Waypoints.Add(wp.offset.ToString(), exportableWayPoint); } }
/// <summary> /// Copy constructor /// </summary> /// <param name="from"></param> private EGraph(EGraph from, CfgBlock at) { this.constRoot = from.constRoot; this.termMap = from.termMap; this.idCounter = from.idCounter; this.absMap = from.absMap; this.elementLattice = from.elementLattice; this.forwMap = from.forwMap; this.eqTermMap = from.eqTermMap; // keep history this.updates = from.updates; this.parent = from; this.root = from.root; this.historySize = from.historySize + 1; this.Block = at; // set from to constant from.constant = true; }
public void EmitTrace(TypeSystem ts, int length, int lineEmitted) { EGraph current = this; while (current != null && length > 0) { if (current.Block != null) { Node b = current.Block.EndSourceContext(); int line = b.SourceContext.EndLine; if (line != 0 && line != lineEmitted) { ts.HandleError(b, Error.RelatedErrorLocation); lineEmitted = line; length--; } } current = current.parent; } }
public void Replay(EGraph common) { Replay(this.G1.updates, common.updates); Replay(this.G2.updates, common.updates); }
private EGraph ComputeCommonTail(EGraph g1, EGraph g2, out int updateSize) { EGraph current1 = g1; EGraph current2 = g2; if (g1.historySize <= 3 && g2.historySize > 100) { updateSize = g1.historySize + g2.historySize; if (g1.root == g2.root) { return g1.root; } return null; } if (g2.historySize <= 3 && g1.historySize > 100) { updateSize = g1.historySize + g2.historySize; if (g1.root == g2.root) { return g1.root; } return null; } while (current1 != current2) { if (current1 == null) { // no common tail current2 = null; break; } if (current2 == null) { // no common tail current1 = null; break; } if (current1.historySize > current2.historySize) { current1 = current1.parent; continue; } if (current2.historySize > current1.historySize) { current2 = current2.parent; continue; } // they have equal size current1 = current1.parent; current2 = current2.parent; } // now current1 == current2 == tail EGraph tail = current1; int tailSize = (tail != null)?tail.historySize:0; updateSize = g1.historySize + g2.historySize - tailSize - tailSize; return tail; }
public IEGraph Join(IEGraph g2, CfgBlock joinPoint, out IMergeInfo mergeInfo) { EGraph eg1 = this; EGraph eg2 = (EGraph)g2; int updateSize; EGraph common = ComputeCommonTail(eg1, eg2, out updateSize); EGraph result; bool doReplay = true; if (common == null) { doReplay = false; result = new EGraph(eg1.elementLattice); result.Block = joinPoint; } else { result = new EGraph(common, joinPoint); } if (Analyzer.Debug) { Console.WriteLine("Last common symbol: {0}", common.idCounter); } if (Analyzer.Statistics) { Console.WriteLine("G1:{0} G2:{1} Tail:{2} UpdateSize:{3}", eg1.historySize, eg2.historySize, result.historySize, updateSize); } MergeState ms = new MergeState(result, eg1, eg2); // Heuristic for using Replay vs. full update doReplay &= (common != eg1.root); doReplay &= (eg1.historySize > 3); doReplay &= (eg2.historySize > 3); if (doReplay) { ms.Replay(common); } else { ms.AddMapping(eg1.constRoot, eg2.constRoot, result.constRoot); ms.JoinSymbolicValue(eg1.constRoot, eg2.constRoot, result.constRoot); } mergeInfo = ms; return result; }
/// <summary> /// Copy constructor /// </summary> /// <param name="from"></param> private EGraph(EGraph from, CfgBlock at) { this.constRoot = from.constRoot; this.termMap = from.termMap; this.idCounter = from.idCounter; this.absMap = from.absMap; this.elementLattice = from.elementLattice; this.forwMap = from.forwMap; this.eqTermMap = from.eqTermMap; // keep history this.updates = from.updates; this.parent = from; this.root = from.root; this.historySize = from.historySize+1; this.Block = at; // set from to constant from.constant = true; }