예제 #1
0
        /// <summary>
        /// Create a type term from this union. An optional renaming may be applied
        /// to its elements.
        /// </summary>
        internal Term MkTypeTerm(TermIndex index)
        {
            Contract.Assert(elements.Count > 0 || intervals.Count > 0);
            Term t       = null;
            var  tunSymb = index.SymbolTable.GetOpSymbol(ReservedOpKind.TypeUnn);
            var  noArgs  = new Term[0];
            bool wasAdded;

            //// Step 1. Create an enum of all non-integral constants.
            foreach (var e in elements)
            {
                t = t == null?index.MkApply(e, noArgs, out wasAdded)
                        : index.MkApply(tunSymb, new Term[] { index.MkApply(e, noArgs, out wasAdded), t }, out wasAdded);
            }

            //// Step 2. Create an enum of all integer intervals
            var  rngSymb = index.SymbolTable.GetOpSymbol(ReservedOpKind.Range);
            Term beg, end;

            foreach (var kv in intervals.CanonicalForm)
            {
                beg = index.MkCnst(new Rational(kv.Key, BigInteger.One), out wasAdded);
                end = index.MkCnst(new Rational(kv.Value, BigInteger.One), out wasAdded);
                t   = t == null?index.MkApply(rngSymb, new Term[] { beg, end }, out wasAdded)
                          : index.MkApply(tunSymb, new Term[] { index.MkApply(rngSymb, new Term[] { beg, end }, out wasAdded), t }, out wasAdded);
            }

            return(t);
        }
예제 #2
0
        private IEnumerable <Node> Expand_Unfold(Node n,
                                                 Stack <Tuple <Namespace, Symbol> > symbStack,
                                                 MutableTuple <int> nextDcVarId,
                                                 SuccessToken success,
                                                 List <Flag> flags)
        {
            var space = symbStack.Peek().Item1;

            switch (n.NodeKind)
            {
            case NodeKind.Cnst:
            {
                bool         wasAdded;
                var          cnst = (Cnst)n;
                BaseCnstSymb symb;
                switch (cnst.CnstKind)
                {
                case CnstKind.Numeric:
                    symb = (BaseCnstSymb)index.MkCnst((Rational)cnst.Raw, out wasAdded).Symbol;
                    break;

                case CnstKind.String:
                    symb = (BaseCnstSymb)index.MkCnst((string)cnst.Raw, out wasAdded).Symbol;
                    break;

                default:
                    throw new NotImplementedException();
                }

                symbStack.Push(new Tuple <Namespace, Symbol>(space, symb));
                return(null);
            }

            case NodeKind.Id:
            {
                var        id = (Id)n;
                UserSymbol symb;
                if (index.SymbolTable.HasRenamingPrefix(id))
                {
                    if (!Resolve(id.Name, "constant", id, space, x => x.IsNonVarConstant, out symb, flags))
                    {
                        symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                        success.Failed();
                        return(null);
                    }
                }
                else if (id.Fragments.Length == 1 && id.Name == API.ASTQueries.ASTSchema.Instance.DontCareName)
                {
                    bool wasAdded;
                    var  fresh = index.MkVar(string.Format("{0}{1}{2}", SymbolTable.ManglePrefix, "dc", nextDcVarId.Item1), true, out wasAdded);
                    ++nextDcVarId.Item1;
                    symbStack.Push(new Tuple <Namespace, Symbol>(space, fresh.Symbol));
                    return(null);
                }
                else if (!Resolve(id.Fragments[0], "variable or constant", id, space, x => x.Kind == SymbolKind.UserCnstSymb, out symb, flags))
                {
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }
                else if (id.Fragments.Length > 1 && symb.IsNonVarConstant)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        id,
                        Constants.BadSyntax.ToString("constants do not have fields"),
                        Constants.BadSyntax.Code);
                    flags.Add(flag);
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }
                else if (symb.IsVariable)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        id,
                        Constants.BadSyntax.ToString("Variables cannot appear here."),
                        Constants.BadSyntax.Code);
                    flags.Add(flag);
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }

                symbStack.Push(new Tuple <Namespace, Symbol>(symb.Namespace, symb));
                return(null);
            }

            case NodeKind.FuncTerm:
            {
                var ft = (FuncTerm)n;
                if (ft.Function is Id)
                {
                    UserSymbol symb;
                    var        ftid = (Id)ft.Function;
                    if (ValidateUse_UserFunc(ft, space, out symb, flags, true))
                    {
                        symbStack.Push(new Tuple <Namespace, Symbol>(symb.Namespace, symb));
                    }
                    else
                    {
                        symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                        success.Failed();
                        return(null);
                    }

                    return(ft.Args);
                }
                else
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        ft,
                        Constants.BadSyntax.ToString("Only data constructors can appear here."),
                        Constants.BadSyntax.Code);
                    flags.Add(flag);
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }
            }

            default:
                throw new NotImplementedException();
            }
        }
예제 #3
0
        private static Term Parse(string t, int start, TermIndex index, out int end)
        {
            Contract.Requires(!string.IsNullOrEmpty(t) && start < t.Length);
            end = -1;
            bool wasAdded, result;
            var  tstart = t[start];

            while (char.IsWhiteSpace(tstart))
            {
                ++start;
                tstart = t[start];
            }

            if (tstart == '\"')
            {
                end = start;
                do
                {
                    end = t.IndexOf('\"', end + 1);
                    Contract.Assert(end >= 0);
                }while (t[end - 1] == '\\');

                if (end == start + 1)
                {
                    return(index.MkCnst(string.Empty, out wasAdded));
                }
                else
                {
                    return(index.MkCnst(t.Substring(start + 1, end - start - 1).Replace("\\\"", "\""), out wasAdded));
                }
            }
            else if (char.IsDigit(tstart) || tstart == '+' || tstart == '-' || tstart == '.')
            {
                var end1 = t.IndexOf(',', start);
                var end2 = t.IndexOf(')', start);
                end = (end1 >= 0 && end2 >= 0) ? Math.Min(end1, end2) : Math.Max(end1, end2);
                Rational r;
                if (end < 0)
                {
                    result = Rational.TryParseDecimal(t.Substring(start).Trim(), out r);
                    Contract.Assert(result);
                    end = t.Length - 1;
                }
                else
                {
                    --end;
                    result = Rational.TryParseDecimal(t.Substring(start, end - start + 1).Trim(), out r);
                    Contract.Assert(result);
                }

                return(index.MkCnst(r, out wasAdded));
            }
            else
            {
                Contract.Assert(char.IsLetter(tstart) || tstart == '_');
                UserSymbol us, other;

                var end1 = t.IndexOf(',', start);
                var end2 = t.IndexOf(')', start);
                var end3 = t.IndexOf('(', start);
                end = (end1 >= 0 && end2 >= 0) ? Math.Min(end1, end2) : Math.Max(end1, end2);
                end = (end >= 0 && end3 >= 0) ? Math.Min(end, end3) : Math.Max(end, end3);
                if (end < 0)
                {
                    us = index.SymbolTable.Resolve(t.Substring(start).Trim(), out other);
                    Contract.Assert(us != null && other == null && us.Kind == SymbolKind.UserCnstSymb);
                    end = t.Length - 1;
                    return(index.MkApply(us, TermIndex.EmptyArgs, out wasAdded));
                }
                else if (end == end1 || end == end2)
                {
                    --end;
                    us = index.SymbolTable.Resolve(t.Substring(start, end - start + 1).Trim(), out other);
                    Contract.Assert(us != null && other == null && us.Kind == SymbolKind.UserCnstSymb);
                    return(index.MkApply(us, TermIndex.EmptyArgs, out wasAdded));
                }
                else
                {
                    us = index.SymbolTable.Resolve(t.Substring(start, end - start).Trim(), out other);
                    Contract.Assert(us != null && other == null && us.IsDataConstructor);
                    var args = new Term[us.Arity];
                    for (int i = 0; i < us.Arity; ++i)
                    {
                        ++end;
                        args[i] = Parse(t, end, index, out end);
                        if (i < us.Arity - 1)
                        {
                            end = t.IndexOf(',', end + 1);
                        }
                        else
                        {
                            end = t.IndexOf(')', end + 1);
                        }

                        Contract.Assert(end >= 0);
                    }

                    return(index.MkApply(us, args, out wasAdded));
                }
            }
        }