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 static EnvironmentDomain <K, V> TopValue(Func <K, int> keyConverter) { if (KeyConverter == null) { KeyConverter = keyConverter; } return(new EnvironmentDomain <K, V> (ImmutableIntKeyMap <K, V> .Empty(KeyConverter))); }
public static EnvironmentDomain <K, V> BottomValue(Func <K, int> keyConverter) { if (keyConverter == null) { throw new ArgumentNullException("keyConverter"); } return(new EnvironmentDomain <K, V> (ImmutableIntKeyMap <K, V> .Empty(keyConverter).Factory(), null)); }
public IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > EdgeRenaming(Pair <APC, APC> edge, bool isJoinPoint) { IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > forwardRenaming; if (this.forwardRenamings.TryGetValue(edge, out forwardRenaming)) { return(forwardRenaming); } IImmutableMap <SymbolicValue, Sequence <SymbolicValue> > renaming = null; Domain afterBegin; PostStateLookup(edge.Key, out afterBegin); if (afterBegin == null || afterBegin.IsBottom) { return(null); } Domain beforeEnd; PreStateLookup(edge.Value, out beforeEnd); if (beforeEnd != null) { IImmutableMap <SymValue, Sequence <SymValue> > forward; if (!TryComputeFromJoinCache(afterBegin, beforeEnd, edge.Value, out forward)) { IImmutableMap <SymValue, SymValue> backward; if (!afterBegin.LessEqual(beforeEnd, out forward, out backward)) { throw new InvalidOperationException("Should never happen"); } if (isJoinPoint && forward == null) { forward = afterBegin.GetForwardIdentityMap(); } } if (forward != null) { renaming = ImmutableIntKeyMap <SymbolicValue, Sequence <SymbolicValue> > .Empty(SymbolicValue.GetUniqueKey); foreach (SymValue sv in forward.Keys) { Sequence <SymbolicValue> targets = null; foreach (SymValue target in forward[sv].AsEnumerable()) { targets = targets.Cons(new SymbolicValue(target)); } if (targets != null) { renaming = renaming.Add(new SymbolicValue(sv), targets); } } } } this.forwardRenamings.Add(edge, renaming); return(renaming); }
public IImmutableMap <SymValue, Sequence <SymValue> > GetForwardIdentityMap() { var res = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey); foreach (var sv in this.EqualTermsMap.Keys.Union(this.EqualMultiTermsMap.Keys)) { res = res.Add(sv, Sequence <SymValue> .Cons(sv, null)); } return(res); }
private IImmutableMap <SymValue, Sequence <SymValue> > GetForwardGraphMap(Func <Tuple <SymValue, SymValue, SymValue>, SymValue> sourceSelector) { IImmutableMap <SymValue, Sequence <SymValue> > res = ImmutableIntKeyMap <SymValue, Sequence <SymValue> > .Empty(SymValue.GetUniqueKey); foreach (var tuple in this.merge_triples.AsEnumerable()) { SymValue sv = sourceSelector(tuple); if (sv != null) { res = res.Add(sv, res [sv].Cons(tuple.Item3)); } } return(res); }
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 Dump(TextWriter tw) { var set = new HashSet <SymValue> (); var workList = new WorkList <SymValue> (); IImmutableMap <SymValue, int> triggers = ImmutableIntKeyMap <SymValue, int> .Empty(SymValue.GetUniqueKey); tw.WriteLine("EGraphId: {0}", this.egraph_id); tw.WriteLine("LastSymbolId: {0}", LastSymbolId); foreach (TFunc function in TermMap.Keys2(this.const_root)) { SymValue sv = this [this.const_root, function]; tw.WriteLine("{0} = {1}", function, sv); workList.Add(sv); } while (!workList.IsEmpty()) { SymValue sv = workList.Pull(); if (!set.Add(sv)) { continue; } foreach (TFunc function in TermMap.Keys2(sv)) { SymValue target = this [sv, function]; tw.WriteLine("{0}({2}) = {1})", function, target, sv); workList.Add(target); } foreach (var edge in MultiEdgeMap.Keys2(sv)) { foreach (SymValue target in MultiEdgeMap[sv, edge].AsEnumerable()) { if (!UpdateTrigger(target, edge, ref triggers)) { continue; } SymGraphTerm <TFunc> term = EqualMultiTermsMap [target]; if (term.Args != null) { tw.WriteLine("{0}({1}) = {2}", term.Function, term.Args.ToString(", "), target); workList.Add(target); } } } } tw.WriteLine("**Abstract value map"); foreach (SymValue sv in set) { TADomain abstractValue = this [sv]; if (!abstractValue.IsTop) { tw.WriteLine("{0} -> {1}", sv, abstractValue); } } }