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
        /// <summary>
        /// Attempts to compute the canonical form.
        /// </summary>
        internal bool Canonize(string myName, List <Flag> flags, CancellationToken cancel, Symbol myself = null)
        {
            if (typeExpr == null)
            {
                return(true);
            }

            //// Step 1. Replace all unions with their expansions and all
            //// Con/Map symbols with their corresponding sorts.
            var processed = new Set <Symbol>(Symbol.Compare);
            var stack     = new Stack <UserSymbol>();

            if (myself != null)
            {
                elements.Remove(myself);
                processed.Add(myself);
            }

            foreach (var s in elements)
            {
                if (s.Kind == SymbolKind.ConSymb ||
                    s.Kind == SymbolKind.MapSymb ||
                    s.Kind == SymbolKind.UnnSymb)
                {
                    processed.Add(s);
                    stack.Push((UserSymbol)s);
                }
            }

            AppFreeCanUnn otherCanUnn;
            UserSymbol    n;

            while (stack.Count > 0)
            {
                n = stack.Pop();
                elements.Remove(n);

                if (n.Kind == SymbolKind.ConSymb)
                {
                    elements.Add(((ConSymb)n).SortSymbol);
                }
                else if (n.Kind == SymbolKind.MapSymb)
                {
                    elements.Add(((MapSymb)n).SortSymbol);
                }
                else if (n.CanonicalForm != null)
                {
                    elements.UnionWith(n.CanonicalForm[0].elements);
                    intervals.UnionWith(n.CanonicalForm[0].intervals);
                }
                else
                {
                    otherCanUnn = (AppFreeCanUnn)n.Definitions.First <AST <Node> >().Node.CompilerData;
                    intervals.UnionWith(otherCanUnn.intervals);
                    foreach (var sp in otherCanUnn.elements)
                    {
                        if (processed.Contains(sp))
                        {
                            continue;
                        }

                        if (sp.Kind == SymbolKind.ConSymb ||
                            sp.Kind == SymbolKind.MapSymb ||
                            sp.Kind == SymbolKind.UnnSymb)
                        {
                            processed.Add(sp);
                            stack.Push((UserSymbol)sp);
                        }
                        else
                        {
                            elements.Add(sp);
                        }
                    }
                }
            }

            //// Step 2. Apply a set of simplification rules to canonize combinations of base sorts
            var realSort = table.GetSortSymbol(BaseSortKind.Real);
            var intSort  = table.GetSortSymbol(BaseSortKind.Integer);
            var natSort  = table.GetSortSymbol(BaseSortKind.Natural);
            var negSort  = table.GetSortSymbol(BaseSortKind.NegInteger);
            var posSort  = table.GetSortSymbol(BaseSortKind.PosInteger);
            var strSort  = table.GetSortSymbol(BaseSortKind.String);

            //// PosInteger + {0} = Natural
            if (elements.Contains(posSort) && intervals.Contains(BigInteger.Zero, BigInteger.Zero))
            {
                elements.Add(natSort);
            }

            //// Natural + NegInteger = Integer
            if (elements.Contains(negSort) && elements.Contains(natSort))
            {
                elements.Add(intSort);
            }

            //// Removed subsumed sorts.
            if (elements.Contains(realSort))
            {
                intervals.Clear();
                elements.Remove(intSort);
                elements.Remove(natSort);
                elements.Remove(negSort);
                elements.Remove(posSort);
            }
            else if (elements.Contains(intSort))
            {
                intervals.Clear();
                elements.Remove(natSort);
                elements.Remove(negSort);
                elements.Remove(posSort);
            }

            if (elements.Contains(natSort))
            {
                BigInteger min, max;
                if (intervals.GetExtrema(out min, out max))
                {
                    intervals.Remove(BigInteger.Zero, BigInteger.Max(BigInteger.Zero, max));
                }

                elements.Remove(posSort);
            }
            else if (elements.Contains(posSort))
            {
                BigInteger min, max;
                if (intervals.GetExtrema(out min, out max))
                {
                    intervals.Remove(BigInteger.One, BigInteger.Max(BigInteger.One, max));
                }
            }

            if (elements.Contains(negSort))
            {
                BigInteger min, max;
                if (intervals.GetExtrema(out min, out max))
                {
                    intervals.Remove(BigInteger.Min(BigInteger.MinusOne, min), BigInteger.MinusOne);
                }
            }

            if (elements.Contains(strSort))
            {
                var dropList = new List <Symbol>();
                foreach (var e in elements)
                {
                    if (e.Kind == SymbolKind.BaseCnstSymb && ((BaseCnstSymb)e).CnstKind == CnstKind.String)
                    {
                        dropList.Add(e);
                    }
                }

                foreach (var e in dropList)
                {
                    elements.Remove(e);
                }
            }

            if (elements.Count == 0 && intervals.Count == 0)
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    typeExpr.Node,
                    Constants.BadTypeDecl.ToString(myName, "it has no members"),
                    Constants.BadTypeDecl.Code);
                flags.Add(flag);
                return(false);
            }
            else
            {
                if (intervals.Count > 0)
                {
                    ContainsConstants = true;
                }
                else
                {
                    foreach (var e in elements)
                    {
                        if (e.Kind == SymbolKind.BaseCnstSymb ||
                            e.Kind == SymbolKind.UserCnstSymb ||
                            e.Kind == SymbolKind.BaseSortSymb)
                        {
                            ContainsConstants = true;
                            break;
                        }
                    }
                }
            }

            return(true);
        }