예제 #1
0
        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);
        }
예제 #2
0
        public IEnumerable <SymGraphTerm <TFunc> > EqMultiTerms(SymValue sv)
        {
            SymGraphTerm <TFunc> term = EqualMultiTermsMap [sv];

            if (term.Args != null && IsValidMultiTerm(term))
            {
                yield return(term);
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
                        }
                    }
                }
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
 private bool IsValidMultiTerm(SymGraphTerm <TFunc> term)
 {
     return(LookupWithoutManifesting(term.Args, term.Function) != null);
 }
예제 #8
0
        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);
                }
            }
        }
예제 #9
0
        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);
            }
        }