private SymbolicValue this[SymbolicValue arg, IUniqueKey function] { get { arg = Find(arg); SymbolicValue v = (SymbolicValue)this.termMap[arg, function]; if (v == null) { v = FreshSymbolicValue(); this.termMap = this.termMap.Add(arg, function, v); this.eqTermMap = this.eqTermMap.Add(v, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } else { v = Find(v); } return(v); } set { arg = Find(arg); value = Find(value); this.termMap = this.termMap.Add(arg, function, value); this.eqTermMap = this.eqTermMap.Add(value, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } }
public void EliminateAll(ISymValue arg) { SymbolicValue sv = Find(arg); this.AddEliminateAllUpdate(sv); // must be before RemoveAll, as it reads termMap this.termMap = this.termMap.RemoveAll(sv); }
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 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 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 void Eliminate(IUniqueKey function, params ISymValue[] args) { if (args.Length == 0) { this.termMap = this.termMap.Remove(this.constRoot, function); this.AddEliminateEdgeUpdate(this.constRoot, function); return; } if (args.Length == 1) { SymbolicValue sv = Find(args[0]); this.termMap = this.termMap.Remove(sv, function); this.AddEliminateEdgeUpdate(sv, function); return; } Debug.Assert(false, "EGraph currently only implements unary and nullary function terms"); }
private void DrainEqualityWorkList(WorkList wl) { while (!wl.IsEmpty()) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) { continue; } // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach (IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep, f]; } else { PushEquality(wl, this[v1rep, f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach (IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1, av2); } }
/// <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; }
private void DrainEqualityWorkList(WorkList wl) { while ( ! wl.IsEmpty() ) { EqPair eqpair = (EqPair)wl.Pull(); SymbolicValue v1rep = Find(eqpair.v1); SymbolicValue v2rep = Find(eqpair.v2); if (v1rep == v2rep) continue; // always map new to older var if (v1rep.UniqueId < v2rep.UniqueId) { SymbolicValue temp = v1rep; v1rep = v2rep; v2rep = temp; } // perform congruence closure here: foreach(IUniqueKey f in this.Functions(v1rep)) { SymbolicValue target = this.LookupWithoutManifesting(v2rep, f); if (target == null) { this[v2rep, f] = this[v1rep,f]; } else { PushEquality(wl, this[v1rep,f], target); } } MathematicalLattice.Element av1 = this[v1rep]; MathematicalLattice.Element av2 = this[v2rep]; // merge term map of v1 into v2 foreach(IUniqueKey eterm in this.eqTermMap.Keys2(v1rep)) { this.eqTermMap = this.eqTermMap.Add(v2rep, eterm, null); } this.forwMap = this.forwMap.Add(v1rep, v2rep); this[v2rep] = this.elementLattice.Meet(av1,av2); } }
private SymbolicValue this[SymbolicValue arg, IUniqueKey function] { get { arg = Find(arg); SymbolicValue v = (SymbolicValue)this.termMap[arg, function]; if (v == null) { v = FreshSymbolicValue(); this.termMap = this.termMap.Add(arg, function, v); this.eqTermMap = this.eqTermMap.Add(v, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } else { v = Find(v); } return v; } set { arg = Find(arg); value = Find(value); this.termMap = this.termMap.Add(arg, function, value); this.eqTermMap = this.eqTermMap.Add(value, new EGraphTerm(function, arg), null); this.AddEdgeUpdate(arg, function); } }
/// <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 AddMapping(SymbolicValue v1, SymbolicValue v2, SymbolicValue result) { this.Map = this.Map.Add(v1, v2, result); }
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; }