Esempio n. 1
0
 public DelayedIntersection(BinnedUnion tA, Term tB)
 {
     Contract.Requires(tA != null && tB != null);
     OuterSymbol = null;
     parent      = null;
     AUnions     = new BinnedUnion[1];
     BUnions     = new BinnedUnion[1];
     Results     = new BinnedUnion[1];
     AUnions[0]  = tA;
     BUnions[0]  = new BinnedUnion(tB);
     Results[0]  = new BinnedUnion(tA.index);
 }
Esempio n. 2
0
                public DelayedIntersection(Symbol s, ImmutableArray <Term> tAs, ImmutableArray <Term> tBs, DelayedIntersection parent)
                {
                    Contract.Requires(s != null && tAs != null && tBs != null && parent != null);
                    Contract.Requires(tAs.Length > 0 && tBs.Length > 0 && tAs.Length == tBs.Length);
                    Contract.Requires(s.Arity == tAs.Length);

                    OuterSymbol = s;
                    AUnions     = new BinnedUnion[tAs.Length];
                    BUnions     = new BinnedUnion[tAs.Length];
                    Results     = new BinnedUnion[tAs.Length];
                    var owner = tAs[0].Owner;

                    for (int i = 0; i < tAs.Length; ++i)
                    {
                        AUnions[i] = new BinnedUnion(tAs[i]);
                        BUnions[i] = new BinnedUnion(tBs[i]);
                        Results[i] = new BinnedUnion(owner);
                    }

                    this.parent = parent;
                }
Esempio n. 3
0
            internal bool MkIntersection(Term t, out Term tintr)
            {
                Contract.Assert(t != null && t.Owner == Term.Owner);
                if (t == Term)
                {
                    tintr = t;
                    return(true);
                }

                var result    = new DelayedIntersection(this, t);
                var intrStack = new Stack <DelayedIntersection>();

                intrStack.Push(result);

                //// Uses a depth-first expansion to compute
                //// f(t1,...,tn) /\ f(t1',...,tn') as
                //// f(t1 /\ t1',..., tn /\ tn').
                int                 pos;
                Term                max;
                bool                wasAdded;
                Set <Term>          binA, binB;
                BinnedUnion         unnA = null, unnB = null, intr = null;
                DelayedIntersection top;

                while (intrStack.Count > 0)
                {
                    top = intrStack.Peek();
                    if (top.MoveBin(out pos))
                    {
                        unnA = top.AUnions[pos];
                        unnB = top.BUnions[pos];
                        intr = top.Results[pos];
                    }
                    else
                    {
                        intrStack.Pop();
                        continue;
                    }

                    foreach (var kv in unnA.binMap)
                    {
                        binA = kv.Value;
                        if (!unnB.binMap.TryFindValue(kv.Key, out binB))
                        {
                            continue;
                        }

                        if (kv.Key.Kind == SymbolKind.ConSymb)
                        {
                            max = index.MkApply(((ConSymb)kv.Key).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                        }
                        else if (kv.Key.Kind == SymbolKind.MapSymb)
                        {
                            max = index.MkApply(((MapSymb)kv.Key).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                        }
                        else if (kv.Key == stringSymb)
                        {
                            IntersectStrings(binA, binB, top.Results[pos]);
                            continue;
                        }
                        else if (kv.Key == trueSymb)
                        {
                            IntersectUsrConsts(binA, binB, top.Results[pos]);
                            continue;
                        }
                        else if (kv.Key == realSymb)
                        {
                            IntersectNumerics(
                                binA,
                                top.AUnions[pos].intervals,
                                binB,
                                top.BUnions[pos].intervals,
                                top.Results[pos]);
                            continue;
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }

                        if (binA.Contains(max))
                        {
                            foreach (var b in binB)
                            {
                                intr.Add(b);
                            }

                            continue;
                        }
                        else if (binB.Contains(max))
                        {
                            foreach (var a in binA)
                            {
                                intr.Add(a);
                            }

                            continue;
                        }

                        //// Now both bins only contain terms starting with f(....)
                        foreach (var a in binA)
                        {
                            if (binB.Contains(a))
                            {
                                intr.Add(a);
                                continue;
                            }
                            else if (a.Groundness == Groundness.Ground)
                            {
                                foreach (var b in binB)
                                {
                                    if (index.IsGroundMember(b, a))
                                    {
                                        intr.Add(a);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                foreach (var b in binB)
                                {
                                    if (b.Groundness == Groundness.Ground)
                                    {
                                        if (index.IsGroundMember(a, b))
                                        {
                                            intr.Add(b);
                                        }
                                    }
                                    else
                                    {
                                        intrStack.Push(new DelayedIntersection(a.Symbol, a.Args, b.Args, top));
                                    }
                                }
                            }
                        }
                    }
                }

                if (result.Results[0].binMap.Count == 0)
                {
                    tintr = null;
                    return(false);
                }
                else
                {
                    tintr = result.Results[0].Term;
                    return(true);
                }
            }