public bool LessEqual(SymGraph <TFunc, TADomain> that) { IImmutableMap <SymValue, Sequence <SymValue> > forwardMap; IImmutableMap <SymValue, SymValue> backwardMap; return(LessEqual(that, out forwardMap, out backwardMap)); }
private SymGraph(TADomain topValue, TADomain bottomValue, bool _) { this.egraph_id = egraphIdGenerator++; this.const_root = FreshSymbol(); TermMap = DoubleImmutableMap <SymValue, TFunc, SymValue> .Empty(SymValue.GetUniqueKey); MultiEdgeMap = DoubleImmutableMap <SymValue, MultiEdge <TFunc, TADomain>, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey); this.abs_map = ImmutableIntKeyMap <SymValue, TADomain> .Empty(SymValue.GetUniqueKey); this.forw_map = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey); EqualTermsMap = ImmutableIntKeyMap <SymValue, Sequence <SymGraphTerm <TFunc> > > .Empty(SymValue.GetUniqueKey); EqualMultiTermsMap = ImmutableIntKeyMap <SymValue, SymGraphTerm <TFunc> > .Empty(SymValue.GetUniqueKey); this.BottomPlaceHolder = FreshSymbol(); this.abs_map = this.abs_map.Add(this.BottomPlaceHolder, bottomValue); this.is_immutable = false; this.history_size = 1; this.Parent = null; this.root_graph = this; Updates = null; this.UnderlyingTopValue = topValue; this.underlying_bottom_value = bottomValue; }
public SymGraph <TFunc, TADomain> Join(SymGraph <TFunc, TADomain> that, bool widening, out bool weaker) { IMergeInfo info; SymGraph <TFunc, TADomain> join = Join(that, out info, widening); weaker = info.Changed; return(join); }
public SymGraph(TADomain topValue, TADomain bottomValue) : this(topValue, bottomValue, false) { if (BottomValue != null) { return; } BottomValue = new SymGraph <TFunc, TADomain> (topValue, bottomValue, false); }
public SymGraph <TFunc, TADomain> Join(SymGraph <TFunc, TADomain> that, out IMergeInfo mergeInfo, bool widen) { SymGraph <TFunc, TADomain> egraph = this; int updateSize; SymGraph <TFunc, TADomain> commonTail = ComputeCommonTail(egraph, that, out updateSize); bool hasCommonTail = true; if (commonTail == null) { hasCommonTail = false; } bool doingIncrementalJoin = hasCommonTail & commonTail != egraph.root_graph & !widen & DoIncrementalJoin; //debug if (DebugOptions.Debug) { Console.WriteLine("SymGraph {0}", widen ? "widen" : "join"); if (commonTail != null) { Console.WriteLine("Last common symbol: {0}", commonTail.LastSymbolId); } Console.WriteLine(" Doing {0}", doingIncrementalJoin ? "incremental join" : "full join"); } SymGraph <TFunc, TADomain> result; MergeInfo <TFunc, TADomain> mergeState; if (doingIncrementalJoin) { result = new SymGraph <TFunc, TADomain> (commonTail); mergeState = new MergeInfo <TFunc, TADomain> (result, egraph, that, widen); mergeState.Replay(commonTail); mergeState.Commit(); } else { result = new SymGraph <TFunc, TADomain> (commonTail); mergeState = new MergeInfo <TFunc, TADomain> (result, egraph, that, widen); mergeState.ReplayEliminations(commonTail); mergeState.AddMapping(egraph.const_root, that.const_root, result.const_root); mergeState.JoinSymbolicValue(egraph.const_root, that.const_root, result.const_root); mergeState.Commit(); } mergeInfo = mergeState; if (DebugOptions.Debug) { Console.WriteLine(" Result update size {0}", result.Updates.Length()); Console.WriteLine("Done with Egraph join: changed = {0}", mergeInfo.Changed ? 1 : 0); } return(result); }
private bool IsSameEGraph(SymGraph <TFunc, TADomain> that) { if (this == that) { return(true); } if (that.Parent == this) { return(that.Updates == Updates); } return(false); }
public bool LessEqual(SymGraph <TFunc, TADomain> that, out IImmutableMap <SymValue, Sequence <SymValue> > forward, out IImmutableMap <SymValue, SymValue> backward) { if (!IsSameEGraph(that)) { return(InternalLessEqual(this, that, out forward, out backward)); } forward = null; backward = null; return(true); }
public SymGraph <TFunc, TADomain> Meet(SymGraph <TFunc, TADomain> that) { if (this == that || IsBottom || that.IsTop) { return(this); } if (that.IsBottom || IsTop) { return(that); } return(this); }
private static IImmutableMap <SymValue, SymValue> CompleteWithCommon(IImmutableMap <SymValue, SymValue> map, SymGraph <TFunc, TADomain> thisGraph, int lastCommonId) { IEnumerable <SymValue> symValues = thisGraph.EqualTermsMap.Keys.Concat(thisGraph.EqualMultiTermsMap.Keys); foreach (SymValue sv in symValues) { if (IsCommon(sv, lastCommonId) && !map.ContainsKey(sv)) { map = map.Add(sv, sv); } } return(map); }
public MergeInfo(SymGraph <TFunc, TADomain> result, SymGraph <TFunc, TADomain> g1, SymGraph <TFunc, TADomain> g2, bool widen) { this.mappings = DoubleImmutableMap <SymValue, SymValue, SymValue> .Empty(SymValue.GetUniqueKey); this.visited_key1 = ImmutableSet <SymValue> .Empty(SymValue.GetUniqueKey); this.visited_multi_edges = new HashSet <Tuple <SymValue, SymValue, MultiEdge <TFunc, TADomain> > > (); this.pending_counts = new DoubleDictionary <SymValue, SymValue, int> (); this.manifested = new HashSet <SymValue> (); this.LastCommonVariable = result.IdGenerator; this.Widen = widen; this.Result = result; this.Graph1 = g1; this.Graph2 = g2; this.Changed = false; }
private SymGraph(SymGraph <TFunc, TADomain> from) { this.egraph_id = egraphIdGenerator++; this.const_root = from.const_root; this.BottomPlaceHolder = from.BottomPlaceHolder; TermMap = from.TermMap; MultiEdgeMap = from.MultiEdgeMap; IdGenerator = from.IdGenerator; this.abs_map = from.abs_map; this.forw_map = from.forw_map; EqualTermsMap = from.EqualTermsMap; EqualMultiTermsMap = from.EqualMultiTermsMap; this.UnderlyingTopValue = from.UnderlyingTopValue; this.underlying_bottom_value = from.underlying_bottom_value; Updates = from.Updates; this.Parent = from; this.root_graph = from.root_graph; this.history_size = from.history_size + 1; from.MarkAsImmutable(); }
private static SymGraph <TFunc, TADomain> ComputeCommonTail(SymGraph <TFunc, TADomain> g1, SymGraph <TFunc, TADomain> g2, out int updateSize) { SymGraph <TFunc, TADomain> graph1 = g1; SymGraph <TFunc, TADomain> graph2 = g2; while (graph1 != graph2) { if (graph1 == null) { break; } if (graph2 == null) { graph1 = null; break; } if (graph1.history_size > graph2.history_size) { graph1 = graph1.Parent; } else if (graph2.history_size > graph1.history_size) { graph2 = graph2.Parent; } else { graph1 = graph1.Parent; graph2 = graph2.Parent; } } SymGraph <TFunc, TADomain> tail = graph1; int historySize = tail != null ? tail.history_size : 0; updateSize = g1.history_size + g2.history_size - 2 * historySize; return(tail); }
public bool IsGraph2 <TFunc1, TAbstractDomain> (SymGraph <TFunc1, TAbstractDomain> graph) where TFunc1 : IEquatable <TFunc1>, IConstantInfo where TAbstractDomain : IAbstractDomainForEGraph <TAbstractDomain>, IEquatable <TAbstractDomain> { return(Equals(this.Graph2, graph) || Equals(this.Graph2.Parent, graph) && Equals(this.Graph2.Updates, graph.Updates)); }
private static bool InternalLessEqual(SymGraph <TFunc, TADomain> thisG, SymGraph <TFunc, TADomain> thatG, out IImmutableMap <SymValue, Sequence <SymValue> > forward, out IImmutableMap <SymValue, SymValue> backward) { int updateSize; SymGraph <TFunc, TADomain> commonTail = ComputeCommonTail(thisG, thatG, out updateSize); if (thisG.IsImmutable) { thisG = thisG.Clone(); } var workList = new WorkList <EqualityPair <TFunc, TADomain> > (); workList.Add(new EqualityPair <TFunc, TADomain> (thisG.const_root, thatG.const_root)); IImmutableSet <SymValue> backwardManifested = ImmutableSet <SymValue> .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, SymValue> backwardMap = ImmutableIntKeyMap <SymValue, SymValue> .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, Sequence <SymValue> > forwardMap = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey); IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey); while (!workList.IsEmpty()) { EqualityPair <TFunc, TADomain> equalityPair = workList.Pull(); SymValue sv1 = equalityPair.Sv1; SymValue sv2 = equalityPair.Sv2; SymValue s; if (VisitedBefore(sv2, backwardManifested, backwardMap, out s)) { if (s != null && s == sv1) { continue; } if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to pre-existing relation: {0} <- {1}", s, sv2); } forward = null; backward = null; return(false); } TADomain val1 = sv1 == null?thisG.UnderlyingTopValue.ForManifestedField() : thisG [sv1]; TADomain val2 = thatG [sv2]; if (!val1.LessEqual(val2)) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to abstract values: !({0} <= {1})", val1, val2); } forward = null; backward = null; return(false); } if (sv1 != null) { backwardMap = backwardMap.Add(sv2, sv1); forwardMap = forwardMap.Add(sv1, forwardMap [sv1].Cons(sv2)); } else { backwardManifested = backwardManifested.Add(sv2); } if (thisG.HasAllBottomFields(sv1)) { continue; } if (thatG.HasAllBottomFields(sv2)) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to bottom field difference"); } forward = null; backward = null; return(false); } foreach (TFunc function in thatG.Functions(sv2)) { SymValue v1 = thisG [function, sv1]; SymValue v2 = thatG [function, sv2]; if (DebugOptions.Debug) { Console.WriteLine(" {0}-{1}->{2} <=? {3}-{4}->{5}", sv1, function, v1, sv2, function, v2); } workList.Add(new EqualityPair <TFunc, TADomain> (v1, v2)); } foreach (var e in thatG.MultiEdges(sv2)) { foreach (SymValue sv in thatG.MultiEdgeMap[sv2, e].AsEnumerable()) { if (!UpdateTrigger(sv, e, ref triggers)) { continue; } SymGraphTerm <TFunc> term = thatG.EqualMultiTermsMap [sv]; var args = new SymValue[term.Args.Length]; for (int i = 0; i < args.Length; i++) { args [i] = backwardMap [term.Args [i]]; } SymValue v1 = thisG.LookupWithoutManifesting(args, e.Function); if (v1 == null) { if (DebugOptions.Debug) { Console.WriteLine("---LessEqual fails due to missing multi term {0}({1})", e.Function, string.Join(", ", term.Args.Select(it => it.ToString()))); } forward = null; backward = null; return(false); } workList.Add(new EqualityPair <TFunc, TADomain> (v1, sv)); } } } forward = forwardMap; backward = CompleteWithCommon(backwardMap, thisG, commonTail.IdGenerator); return(true); }
public void ReplayEliminations(SymGraph <TFunc, TADomain> common) { ReplayEliminations(this.Graph1.Updates, common.Updates); ReplayEliminations(this.Graph2.Updates, common.Updates); }
public bool IsResultGraph <TFunc1, TAbstractDomain> (SymGraph <TFunc1, TAbstractDomain> graph) where TFunc1 : IEquatable <TFunc1>, IConstantInfo where TAbstractDomain : IAbstractDomainForEGraph <TAbstractDomain>, IEquatable <TAbstractDomain> { return(Equals(graph, this.Result)); }
public SymGraph <TFunc, TADomain> Widen(SymGraph <TFunc, TADomain> that) { throw new NotImplementedException(); }
public void Replay(SymGraph <TFunc, TADomain> common) { PrimeMapWithCommon(); Replay(this.Graph1.Updates, common.Updates); Replay(this.Graph2.Updates, common.Updates); }