Ejemplo n.º 1
0
            private void Add(Term t)
            {
                if (t.Symbol == unnSymb)
                {
                    return;
                }

                bool       wasAdded;
                Set <Term> bin;

                switch (t.Symbol.Kind)
                {
                case SymbolKind.ConSymb:
                case SymbolKind.MapSymb:
                {
                    if (!binMap.TryFindValue(t.Symbol, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(t.Symbol, bin);
                    }

                    Term max = null;
                    if (t.Symbol.Kind == SymbolKind.ConSymb)
                    {
                        max = index.MkApply(((ConSymb)t.Symbol).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                    }
                    else
                    {
                        max = index.MkApply(((MapSymb)t.Symbol).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                    }

                    if (bin.Contains(max))
                    {
                        return;
                    }
                    else
                    {
                        bin.Add(t);
                    }

                    break;
                }

                case SymbolKind.UserSortSymb:
                {
                    if (!binMap.TryFindValue(((UserSortSymb)t.Symbol).DataSymbol, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(((UserSortSymb)t.Symbol).DataSymbol, bin);
                        bin.Add(t);
                    }
                    else if (!bin.Contains(t))
                    {
                        bin.Clear();
                        bin.Add(t);
                    }

                    break;
                }

                case SymbolKind.UserCnstSymb:
                {
                    Contract.Assert(t.Symbol.IsNonVarConstant);
                    if (!binMap.TryFindValue(trueSymb, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(trueSymb, bin);
                    }

                    bin.Add(t);
                    break;
                }

                case SymbolKind.BaseSortSymb:
                {
                    var baseSort = ((BaseSortSymb)t.Symbol);
                    var binName  = baseSort.SortKind == BaseSortKind.String ? stringSymb : realSymb;
                    if (!binMap.TryFindValue(binName, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(binName, bin);
                    }

                    switch (baseSort.SortKind)
                    {
                    case BaseSortKind.String:
                        if (!bin.Contains(t))
                        {
                            bin.Clear();
                            bin.Add(t);
                        }

                        break;

                    case BaseSortKind.Real:
                        if (!bin.Contains(t))
                        {
                            bin.Clear();
                            bin.Add(t);
                            intervals = null;
                        }

                        break;

                    case BaseSortKind.Integer:
                        if (!bin.Contains(t) &&
                            !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)))
                        {
                            bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded));
                            bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded));
                            bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded));
                            bin.Add(t);
                            intervals = null;
                        }

                        break;

                    case BaseSortKind.Natural:
                        if (!bin.Contains(t) &&
                            !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) &&
                            !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)))
                        {
                            bin.Remove(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded));
                            bin.Add(t);
                            if (intervals != null && intervals.Count > 0)
                            {
                                BigInteger min, max;
                                intervals.GetExtrema(out min, out max);
                                intervals.Remove(BigInteger.Zero, BigInteger.Max(BigInteger.Zero, max));
                            }
                        }

                        break;

                    case BaseSortKind.PosInteger:
                        if (!bin.Contains(t) &&
                            !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)) &&
                            !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) &&
                            !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)))
                        {
                            bin.Add(t);
                            if (intervals != null && intervals.Count > 0)
                            {
                                BigInteger min, max;
                                intervals.GetExtrema(out min, out max);
                                intervals.Remove(BigInteger.One, BigInteger.Max(BigInteger.One, max));
                            }
                        }

                        break;

                    case BaseSortKind.NegInteger:
                        if (!bin.Contains(t) &&
                            !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)) &&
                            !bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)))
                        {
                            bin.Add(t);
                            if (intervals != null && intervals.Count > 0)
                            {
                                BigInteger min, max;
                                intervals.GetExtrema(out min, out max);
                                intervals.Remove(BigInteger.Min(min, BigInteger.MinusOne), BigInteger.MinusOne);
                            }
                        }

                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    break;
                }

                case SymbolKind.BaseCnstSymb:
                {
                    var baseCnst = (BaseCnstSymb)t.Symbol;
                    var binName  = baseCnst.CnstKind == CnstKind.String ? stringSymb : realSymb;
                    if (!binMap.TryFindValue(binName, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(binName, bin);
                    }

                    switch (baseCnst.CnstKind)
                    {
                    case CnstKind.String:
                        if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.String), TermIndex.EmptyArgs, out wasAdded)))
                        {
                            bin.Add(t);
                        }

                        break;

                    case CnstKind.Numeric:
                    {
                        var rat = (Rational)baseCnst.Raw;
                        if (bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)))
                        {
                        }
                        else if (!rat.IsInteger)
                        {
                            bin.Add(t);
                        }
                        else if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)))
                        {
                        }
                        else if (rat.Sign < 0)
                        {
                            if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded)))
                            {
                                intervals = intervals == null ? new IntIntervals() : intervals;
                                intervals.Add(rat.Numerator, rat.Numerator);
                            }
                        }
                        else if (rat.Sign == 0)
                        {
                            if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)))
                            {
                                intervals = intervals == null ? new IntIntervals() : intervals;
                                intervals.Add(rat.Numerator, rat.Numerator);
                            }
                        }
                        else
                        {
                            if (!bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)) &&
                                !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded)))
                            {
                                intervals = intervals == null ? new IntIntervals() : intervals;
                                intervals.Add(rat.Numerator, rat.Numerator);
                            }
                        }

                        break;
                    }

                    default:
                        throw new NotImplementedException();
                    }

                    break;
                }

                case SymbolKind.BaseOpSymb:
                {
                    Contract.Assert(t.Symbol == rngSymb);
                    if (!binMap.TryFindValue(realSymb, out bin))
                    {
                        bin = new Set <Term>(Term.Compare);
                        binMap.Add(realSymb, bin);
                    }

                    if (!bin.Contains(index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded)) &&
                        !bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded)))
                    {
                        var end1 = ((Rational)((BaseCnstSymb)t.Args[0].Symbol).Raw).Numerator;
                        var end2 = ((Rational)((BaseCnstSymb)t.Args[1].Symbol).Raw).Numerator;
                        intervals = intervals == null ? new IntIntervals() : intervals;
                        intervals.Add(end1, end2);
                        BigInteger min, max;
                        intervals.GetExtrema(out min, out max);

                        if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded)))
                        {
                            intervals.Remove(BigInteger.Zero, BigInteger.Max(BigInteger.Zero, max));
                        }
                        else if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded)))
                        {
                            intervals.Remove(BigInteger.One, BigInteger.Max(BigInteger.One, max));
                        }

                        if (bin.Contains(index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded)))
                        {
                            intervals.Remove(BigInteger.Min(BigInteger.MinusOne, min), BigInteger.MinusOne);
                        }
                    }

                    break;
                }

                default:
                    throw new InvalidOperationException();
                }
            }
Ejemplo n.º 2
0
            private void IntersectNumerics(Set <Term> s1, IntIntervals i1, Set <Term> s2, IntIntervals i2, BinnedUnion result)
            {
                bool wasAdded;
                var  realTrm = index.MkApply(realSymb, TermIndex.EmptyArgs, out wasAdded);
                var  intTrm  = index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Integer), TermIndex.EmptyArgs, out wasAdded);
                var  natTrm  = index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.Natural), TermIndex.EmptyArgs, out wasAdded);
                var  posTrm  = index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.PosInteger), TermIndex.EmptyArgs, out wasAdded);
                var  negTrm  = index.MkApply(index.SymbolTable.GetSortSymbol(BaseSortKind.NegInteger), TermIndex.EmptyArgs, out wasAdded);

                //// Handle the case where one side contains Real
                if (s1.Contains(realTrm))
                {
                    foreach (var t in s2)
                    {
                        result.Add(t);
                    }

                    if (i2 != null)
                    {
                        foreach (var kv in i2.CanonicalForm)
                        {
                            result.Add(index.MkApply(
                                           rngSymb,
                                           new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                        index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                           out wasAdded));
                        }
                    }

                    return;
                }
                else if (s2.Contains(realTrm))
                {
                    foreach (var t in s1)
                    {
                        result.Add(t);
                    }

                    if (i1 != null)
                    {
                        foreach (var kv in i1.CanonicalForm)
                        {
                            result.Add(index.MkApply(
                                           rngSymb,
                                           new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                        index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                           out wasAdded));
                        }
                    }

                    return;
                }
                else
                {
                    //// Need to keep all real constants common to both sets.
                    var sA = s1.Count <= s2.Count ? s1 : s2;
                    var sB = s2.Count >= s1.Count ? s2 : s1;
                    foreach (var t in sA)
                    {
                        if (t.Symbol.Kind == SymbolKind.BaseCnstSymb && sB.Contains(t))
                        {
                            result.Add(t);
                        }
                    }
                }

                //// Handle the case where one side contains Integer.
                if (s1.Contains(intTrm))
                {
                    foreach (var t in s2)
                    {
                        if (t.Symbol.Kind != SymbolKind.BaseCnstSymb ||
                            s1.Contains(t))
                        {
                            result.Add(t);
                        }
                    }

                    if (i2 != null)
                    {
                        foreach (var kv in i2.CanonicalForm)
                        {
                            result.Add(index.MkApply(
                                           rngSymb,
                                           new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                        index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                           out wasAdded));
                        }
                    }

                    return;
                }
                else if (s2.Contains(intTrm))
                {
                    foreach (var t in s1)
                    {
                        if (t.Symbol.Kind != SymbolKind.BaseCnstSymb ||
                            s2.Contains(t))
                        {
                            result.Add(t);
                        }

                        result.Add(t);
                    }

                    if (i1 != null)
                    {
                        foreach (var kv in i1.CanonicalForm)
                        {
                            result.Add(index.MkApply(
                                           rngSymb,
                                           new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                        index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                           out wasAdded));
                        }
                    }

                    return;
                }

                //// Neither set contains all reals or all integers.
                //// First take intersections of intervals: O(n)
                if (i1 != null && i2 != null)
                {
                    BigInteger aS, aE, bS, bE, s, e;
                    using (var itA = i1.CanonicalForm.GetEnumerator())
                    {
                        using (var itB = i2.CanonicalForm.GetEnumerator())
                        {
                            var cont = itA.MoveNext() && itB.MoveNext();
                            while (cont)
                            {
                                aS = itA.Current.Key;
                                aE = itA.Current.Value;

                                bS = itB.Current.Key;
                                bE = itB.Current.Value;

                                s    = aS > bS ? aS : bS;
                                e    = aE < bE ? aE : bE;
                                cont = aE <= bE?itA.MoveNext() : itB.MoveNext();

                                if (s <= e)
                                {
                                    result.Add(index.MkApply(
                                                   rngSymb,
                                                   new Term[] { index.MkCnst(new Rational(s, BigInteger.One), out wasAdded),
                                                                index.MkCnst(new Rational(e, BigInteger.One), out wasAdded) },
                                                   out wasAdded));
                                }
                            }
                        }
                    }
                }

                //// Next consider intervals intersecting with Nat, Pos, and Neg.
                if (i2 != null)
                {
                    bool hasNat = s1.Contains(natTrm);
                    bool hasPos = s1.Contains(posTrm);
                    bool hasNeg = s1.Contains(negTrm);
                    if (hasNat || hasPos || hasNeg)
                    {
                        var nonNegLB = hasNat ? BigInteger.Zero : BigInteger.One;
                        foreach (var kv in i2.CanonicalForm)
                        {
                            if (hasNeg)
                            {
                                if (kv.Key < BigInteger.Zero)
                                {
                                    result.Add(index.MkApply(
                                                   rngSymb,
                                                   new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                                index.MkCnst(new Rational(BigInteger.Min(kv.Value, BigInteger.MinusOne), BigInteger.One), out wasAdded) },
                                                   out wasAdded));
                                }
                            }

                            if (hasNat || hasPos)
                            {
                                if (kv.Value >= nonNegLB)
                                {
                                    result.Add(index.MkApply(
                                                   rngSymb,
                                                   new Term[] { index.MkCnst(new Rational(BigInteger.Max(kv.Key, nonNegLB), BigInteger.One), out wasAdded),
                                                                index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                                   out wasAdded));
                                }
                            }
                        }
                    }
                }

                if (i1 != null)
                {
                    bool hasNat = s2.Contains(natTrm);
                    bool hasPos = s2.Contains(posTrm);
                    bool hasNeg = s2.Contains(negTrm);
                    if (hasNat || hasPos || hasNeg)
                    {
                        var nonNegLB = hasNat ? BigInteger.Zero : BigInteger.One;
                        foreach (var kv in i1.CanonicalForm)
                        {
                            if (hasNeg)
                            {
                                if (kv.Key < BigInteger.Zero)
                                {
                                    result.Add(index.MkApply(
                                                   rngSymb,
                                                   new Term[] { index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded),
                                                                index.MkCnst(new Rational(BigInteger.Min(kv.Value, BigInteger.MinusOne), BigInteger.One), out wasAdded) },
                                                   out wasAdded));
                                }
                            }

                            if (hasNat || hasPos)
                            {
                                if (kv.Value >= nonNegLB)
                                {
                                    result.Add(index.MkApply(
                                                   rngSymb,
                                                   new Term[] { index.MkCnst(new Rational(BigInteger.Max(kv.Key, nonNegLB), BigInteger.One), out wasAdded),
                                                                index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded) },
                                                   out wasAdded));
                                }
                            }
                        }
                    }
                }

                //// Finally, consider intersections between the sorts Nat, Pos, Neg.
                if (s1.Contains(natTrm))
                {
                    if (s2.Contains(natTrm))
                    {
                        result.Add(natTrm);
                    }
                    else if (s2.Contains(posTrm))
                    {
                        result.Add(posTrm);
                    }
                }
                else if (s2.Contains(natTrm))
                {
                    if (s1.Contains(natTrm))
                    {
                        result.Add(natTrm);
                    }
                    else if (s1.Contains(posTrm))
                    {
                        result.Add(posTrm);
                    }
                }
                else if (s1.Contains(posTrm) && s2.Contains(posTrm))
                {
                    result.Add(posTrm);
                }

                if (s1.Contains(negTrm) && s2.Contains(negTrm))
                {
                    result.Add(negTrm);
                }
            }