private SymValue FindCandidate(SymValue[] args, TFunc function) { int length = args.Length; var multiEdge = new MultiEdge <TFunc, TADomain> (function, 0, length); for (Sequence <SymValue> list = MultiEdgeMap [args [0], multiEdge]; list != null; list = list.Tail) { SymGraphTerm <TFunc> term = EqualMultiTermsMap [list.Head]; if (term.Args.Length == length) { bool found = true; for (int i = 0; i < length; ++i) { if (Find(term.Args [i]) != args [i]) { found = false; break; } } if (found) { return(list.Head); } } } return(null); }
public IEnumerable <SymGraphTerm <TFunc> > EqMultiTerms(SymValue sv) { SymGraphTerm <TFunc> term = EqualMultiTermsMap [sv]; if (term.Args != null && IsValidMultiTerm(term)) { yield return(term); } }
public void Commit() { if (Changed) { return; } bool needContinue = false; foreach (var edge in this.Graph1.ValidMultiTerms) { SymGraphTerm <TFunc> term = edge.Value; var args = new SymValue[term.Args.Length]; for (int i = 0; i < args.Length; ++i) { SymValue sv = term.Args[i]; if (IsMappingAlreadyAdded(sv, null)) { if (this.mappings.Keys2(sv) != null && this.mappings.Keys2(sv).Count() == 1) { args[i] = this.mappings[sv, this.mappings.Keys2(sv).First()]; } } else { needContinue = true; break; } if (args[i] == null) { Changed = true; return; } } if (needContinue) { continue; } SymValue symbol = this.Result.LookupWithoutManifesting(args, term.Function); if (symbol != null) { SymValue key = edge.Key; if (this.mappings.Keys2(key) != null && this.mappings.Keys2(key).Count() == 1 && this.mappings[key, this.mappings.Keys2(key).First()] == symbol) { continue; } } Changed = true; return; } }
public bool Equals(SymGraphTerm <TFunc> that) { if (!this.Function.Equals(that.Function) || this.Args.Length != that.Args.Length) { return(false); } for (int i = 0; i < this.Args.Length; i++) { if (!this.Args [i].Equals(that.Args [i])) { return(false); } } return(true); }
public void JoinMultiEdge(SymValue sv1, SymValue sv2, MultiEdge <TFunc, TADomain> edge) { var key = new Tuple <SymValue, SymValue, MultiEdge <TFunc, TADomain> > (sv1, sv2, edge); if (!this.visited_multi_edges.Add(key)) { return; } Sequence <SymValue> list1 = this.Graph1.MultiEdgeMap [sv1, edge]; Sequence <SymValue> list2 = this.Graph2.MultiEdgeMap [sv2, edge]; if (list2.IsEmpty()) { return; } foreach (SymValue v1 in list1.AsEnumerable()) { foreach (SymValue v2 in list2.AsEnumerable()) { if (UpdatePendingCount(v1, v2, edge.Arity)) { SymGraphTerm <TFunc> term1 = this.Graph1.EqualMultiTermsMap [v1]; SymGraphTerm <TFunc> term2 = this.Graph2.EqualMultiTermsMap [v2]; if (term1.Args != null && term2.Args != null) { var resultRoots = new SymValue[term1.Args.Length]; for (int i = 0; i < resultRoots.Length; i++) { resultRoots [i] = this.mappings [term1.Args [i], term2.Args [i]]; } SymValue r = AddJointEdge(v1, v2, edge.Function, resultRoots); if (r != null) { JoinSymbolicValue(sv1, sv2, r); } } else { break; } } } } }
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); }
private bool IsValidMultiTerm(SymGraphTerm <TFunc> term) { return(LookupWithoutManifesting(term.Args, term.Function) != null); }
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); } } }
public SymValue this [SymValue[] args, TFunc function] { get { int len = args.Length; for (int i = 0; i < len; i++) { args [i] = Find(args [i]); } SymValue candidate = FindCandidate(args, function); if (candidate != null) { return(candidate); } candidate = FreshSymbol(); for (int i = 0; i < len; i++) { var edge = new MultiEdge <TFunc, TADomain> (function, i, len); MultiEdgeMap = MultiEdgeMap.Add(args [i], edge, MultiEdgeMap [args [i], edge].Cons(candidate)); } EqualMultiTermsMap = EqualMultiTermsMap.Add(candidate, new SymGraphTerm <TFunc> (function, args)); AddMultiEdgeUpdate(args, function); return(candidate); } set { int len = args.Length; for (int i = 0; i < len; i++) { args [i] = Find(args [i]); } bool isTermEqual = true; SymGraphTerm <TFunc> term = EqualMultiTermsMap [value]; if (term.Args != null) { for (int i = 0; i < len; i++) { if (term.Args [i] != args [i]) { isTermEqual = false; break; } } } for (int i = 0; i < len; i++) { var edge = new MultiEdge <TFunc, TADomain> (function, i, len); Sequence <SymValue> list = MultiEdgeMap [args [i], edge]; if (isTermEqual && !Sequence <SymValue> .Contains(list, value)) { isTermEqual = false; } if (!isTermEqual) { MultiEdgeMap = MultiEdgeMap.Add(args [i], edge, list.Cons(value)); } } if (isTermEqual) { return; } EqualMultiTermsMap = EqualMultiTermsMap.Add(value, new SymGraphTerm <TFunc> (function, args)); AddMultiEdgeUpdate(args, function); } }