Ejemplo n.º 1
0
        /// <summary>
        /// Converts a term AST to a term, and expands symbolic constants as much as possible.
        /// Returns null if there are errors.
        /// Should only be called after the set has been successfully compiled.
        /// </summary>
        private Term Expand(AST <Node> ast, List <Flag> flags)
        {
            bool gotLock = false;

            try
            {
                termIndexLock.Enter(ref gotLock);

                UserSymbol other;
                var        symTable        = index.SymbolTable;
                var        valParamToValue = new Map <UserCnstSymb, Term>(Symbol.Compare);
                foreach (var kv in valueInputs)
                {
                    valParamToValue.Add(
                        (UserCnstSymb)symTable.Resolve(string.Format("%{0}", kv.Key), out other, symTable.ModuleSpace),
                        kv.Value);
                }

                var nextDcVarId = new MutableTuple <int>(0);
                var success     = new SuccessToken();
                var symbStack   = new Stack <Tuple <Namespace, Symbol> >();
                symbStack.Push(new Tuple <Namespace, Symbol>(index.SymbolTable.Root, null));
                var result = ast.Compute <Tuple <Term, Term> >(
                    x => Expand_Unfold(x, symbStack, nextDcVarId, success, flags),
                    (x, y) => Expand_Fold(x, y, symbStack, valParamToValue, success, flags));
                return(result == null ? null : result.Item1);
            }
            finally
            {
                if (gotLock)
                {
                    termIndexLock.Exit();
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Tries to eliminate the quotations in a module using parser plugins.
        /// It succeeds, then the compiler data of module is set to the simplified
        /// module definition.
        /// </summary>
        private bool EliminateQuotations(bool isQueryContainer, AST <Node> module, List <Flag> flags)
        {
            var configStack = new Stack <Configuration>();
            var success     = new SuccessToken();
            var simplified  = module.Compute <Node>(
                (node) =>
            {
                return(ElimQuoteUnfold(node, configStack, success, flags, cancel));
            },
                (node, folds) =>
            {
                return(ElimQuoteFold(node, folds, configStack));
            },
                cancel);

            if (cancel.IsCancellationRequested)
            {
                return(false);
            }

            if (success.Result)
            {
                var modData = new ModuleData(Env, new Location(module), simplified, isQueryContainer);
                module.Node.CompilerData = modData;
                simplified.CompilerData  = modData;
            }

            return(success.Result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Performs a computation over a Z3 expressions by unfold and fold operations.
        /// If a token is provided and then Failed() during computation, then computation
        /// is immediately canceled and default(S) is returned.
        ///
        /// Compute(t, unfold, fold) =
        /// fold(t, Compute(t_1, unfold, fold), ... , Compute(t_1, unfold, fold))
        ///
        /// where:
        /// t_1 ... t_n are returned by unfold(t)
        /// </summary>
        public static S Compute <S>(
            this Z3Expr expr,
            Func <Z3Expr, SuccessToken, IEnumerable <Z3Expr> > unfold,
            Func <Z3Expr, IEnumerable <S>, SuccessToken, S> fold,
            SuccessToken token = null)
        {
            if (expr == null)
            {
                return(default(S));
            }

            Z3Expr            t;
            Compute1State <S> top;
            var stack = new Stack <Compute1State <S> >();

            stack.Push(new Compute1State <S>(null, expr, unfold(expr, token)));
            if (token != null && !token.Result)
            {
                return(default(S));
            }

            while (stack.Count > 0)
            {
                top = stack.Peek();
                if (top.GetNext(out t))
                {
                    stack.Push(new Compute1State <S>(top, t, unfold(t, token)));
                    if (token != null && !token.Result)
                    {
                        return(default(S));
                    }
                }
                else
                {
                    if (top.Parent == null)
                    {
                        Contract.Assert(stack.Count == 1);
                        return(fold(top.T, top.ChildrenValues, token));
                    }

                    top.Parent.ChildrenValues.AddLast(fold(top.T, top.ChildrenValues, token));
                    stack.Pop();
                    if (token != null && !token.Result)
                    {
                        return(default(S));
                    }
                }
            }

            throw new Impossible();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Tries to match t with pattern and returns true if successfull. CurrentBindings
        /// holds the most recent variable bindings, which may be null if the match failed.
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool TryMatch(Term t)
        {
            Contract.Requires(t != null && t.Groundness == Groundness.Ground);
            Contract.Requires(t.Owner == Pattern.Owner);
            foreach (var v in bindingVars)
            {
                bindings[v] = null;
            }

            var success = new SuccessToken();

            Pattern.Compute <Unit>(t, ExpandMatch, (x, y, ch, s) => default(Unit), success);
            return(success.Result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Applies the visitor to all unfolded terms.
        /// t.Visit(unfold, visitor) = visitor(t); s.Visit(unfold, visitor) for s \in unfold(t).
        /// </summary>
        public void Visit(
            Func <Term, IEnumerable <Term> > unfold,
            Action <Term> visitor,
            SuccessToken token = null)
        {
            IEnumerable <Term> ures;
            var stack = new Stack <IEnumerator <Term> >();

            visitor(this);
            ures = unfold(this);
            if (ures == null || (token != null && !token.Result))
            {
                return;
            }

            stack.Push(ures.GetEnumerator());
            IEnumerator <Term> enm;

            while (stack.Count > 0)
            {
                enm = stack.Peek();
                if (enm != null && enm.MoveNext())
                {
                    visitor(enm.Current);
                    ures = unfold(enm.Current);

                    if (token != null && !token.Result)
                    {
                        return;
                    }
                    else if (ures != null)
                    {
                        stack.Push(ures.GetEnumerator());
                    }
                }
                else
                {
                    if (enm != null)
                    {
                        enm.Dispose();
                    }

                    stack.Pop();
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Performs an AST computation over two terms by unfold and fold operations.
        /// Let A be this term and B be the other term. Let a \in A and b \in B.
        /// If a token is provided and then Failed() during computation, then computation
        /// is immediately canceled and default(S) is returned.
        ///
        /// Then:
        /// Compute(a, b, unfold, fold) =
        /// fold(a, b, Compute(a_1, b_1), ... Compute(a_n, b_n))
        ///
        /// where:
        /// a_1 ... a_n are returned by the first enumerator of unfold(a, b)
        /// b_1 ... b_n are returned by the second enumerator of unfold(a, b).
        ///
        /// If one enumerator enumerates fewer elements, then the remaining
        /// elements are null.
        /// </summary>
        public S Compute <S>(
            Term other,
            Func <Term, Term, SuccessToken, Tuple <IEnumerable <Term>, IEnumerable <Term> > > unfold,
            Func <Term, Term, IEnumerable <S>, SuccessToken, S> fold,
            SuccessToken token = null)
        {
            Term a, b;
            Compute2State <S> top;
            var stack = new Stack <Compute2State <S> >();

            stack.Push(new Compute2State <S>(null, this, other, unfold(this, other, token)));
            if (token != null && !token.Result)
            {
                return(default(S));
            }

            while (stack.Count > 0)
            {
                top = stack.Peek();
                if (top.GetNext(out a, out b))
                {
                    stack.Push(new Compute2State <S>(top, a, b, unfold(a, b, token)));
                    if (token != null && !token.Result)
                    {
                        return(default(S));
                    }
                }
                else
                {
                    if (top.Parent == null)
                    {
                        Contract.Assert(stack.Count == 1);
                        return(fold(top.A, top.B, top.ChildrenValues, token));
                    }

                    top.Parent.ChildrenValues.AddLast(fold(top.A, top.B, top.ChildrenValues, token));
                    stack.Pop();
                    if (token != null && !token.Result)
                    {
                        return(default(S));
                    }
                }
            }

            throw new Impossible();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Tries to eliminate the quotations from the AST using the provided configuration.
        /// </summary>
        internal static Node EliminateQuotations(Configuration config, AST <Node> ast, List <Flag> flags)
        {
            Contract.Requires(config != null && ast != null && flags != null);
            var configStack = new Stack <Configuration>();
            var success     = new SuccessToken();

            configStack.Push(config);
            var simplified = ast.Compute <Node>(
                (node) =>
            {
                return(ElimQuoteUnfold(node, configStack, success, flags, default(CancellationToken)));
            },
                (node, folds) =>
            {
                return(ElimQuoteFold(node, folds, configStack));
            });

            return(success.Result ? simplified : null);
        }
Ejemplo n.º 8
0
        public static bool IsUnifiable(Term tA, Term tB, bool standardize = true)
        {
            Contract.Requires(tA != null && tB != null);
            Contract.Requires(tA.Owner == tB.Owner);

            var eqs           = new EquivalenceRelation <StdTerm>(StdTerm.Compare, 1, 1);
            var success       = new SuccessToken();
            var relabelSymbol = tA.Owner.SymbolTable.GetOpSymbol(ReservedOpKind.Relabel);
            var pending       = new Stack <Tuple <StdTerm, StdTerm> >();

            pending.Push(new Tuple <StdTerm, StdTerm>(tA.Standardize(0), tB.Standardize(standardize ? 1 : 0)));

            int  lblA, lblB;
            Term trmA, trmB;
            Tuple <StdTerm, StdTerm> top;
            Set <StdTerm>            allVars = new Set <StdTerm>(StdTerm.Compare);

            while (pending.Count > 0)
            {
                top = pending.Pop();
                if (StdTerm.Compare(top.Item1, top.Item2) == 0)
                {
                    continue;
                }

                top.GetComponents(out trmA, out lblA, out trmB, out lblB);
                trmA.Compute <Unit>(
                    trmB,
                    (xA, xB, s) =>
                {
                    if (xA.Symbol == relabelSymbol)
                    {
                        xA = EliminateRelabel(xA);
                    }

                    if (xB.Symbol == relabelSymbol)
                    {
                        xB = EliminateRelabel(xB);
                    }

                    if (xA.Groundness == Groundness.Ground && xB.Groundness == Groundness.Ground)
                    {
                        //// If x1 and x2 are ground, then just check equality.
                        if (xA != xB)
                        {
                            success.Failed();
                        }

                        return(null);
                    }
                    else if ((xA.Symbol.IsDataConstructor || xA.Symbol.IsNonVarConstant) &&
                             (xB.Symbol.IsDataConstructor || xB.Symbol.IsNonVarConstant))
                    {
                        //// If x1 and x2 are both data constructors,
                        //// then check symbol equality and unroll.
                        if (xA.Symbol != xB.Symbol)
                        {
                            success.Failed();
                            return(null);
                        }

                        return(new Tuple <IEnumerable <Term>, IEnumerable <Term> >(xA.Args, xB.Args));
                    }
                    else if (xA.Symbol.IsVariable || xA.Symbol == xA.Owner.SelectorSymbol)
                    {
                        Bind(allVars, eqs, pending, xA.Standardize(lblA), xB.Standardize(lblB));
                        return(null);
                    }
                    else
                    {
                        Bind(allVars, eqs, pending, xB.Standardize(lblB), xA.Standardize(lblA));
                        return(null);
                    }
                },
                    (xA, xB, ch, s) =>
                {
                    return(default(Unit));
                },
                    success);
            }

            if (!success.Result)
            {
                return(false);
            }

            return(OccursCheck(allVars, eqs));
        }
Ejemplo n.º 9
0
        private Tuple <IEnumerable <Term>, IEnumerable <Term> > ExpandMatch(Term px, Term ty, SuccessToken success)
        {
            if (px.Groundness == Groundness.Ground)
            {
                if (px != ty)
                {
                    success.Failed();
                }

                return(null);
            }
            else if (px.Symbol.IsVariable)
            {
                var crnt = bindings[px];
                if (crnt == null)
                {
                    bindings[px] = ty;
                }
                else if (crnt != ty)
                {
                    success.Failed();
                }

                return(null);
            }
            else
            {
                Contract.Assert(px.Symbol.IsDataConstructor);
                if (px.Symbol != ty.Symbol)
                {
                    success.Failed();
                    return(null);
                }

                return(new Tuple <IEnumerable <Term>, IEnumerable <Term> >(px.Args, ty.Args));
            }
        }
Ejemplo n.º 10
0
        private static IEnumerable <Node> ElimQuoteUnfold(
            Node n,
            Stack <Configuration> configStack,
            SuccessToken success,
            List <Flag> flags,
            CancellationToken cancel)
        {
            if (n.NodeKind == NodeKind.Config)
            {
                yield break;
            }

            Cnst          value;
            Configuration conf;

            if (n.TryGetConfiguration(out conf))
            {
                configStack.Push(conf);
            }

            if (n.NodeKind != NodeKind.Quote)
            {
                foreach (var c in n.Children)
                {
                    yield return(c);
                }

                yield break;
            }

            Contract.Assert(configStack.Count > 0);
            conf = configStack.Peek();
            if (!conf.TryGetSetting(Configuration.Parse_ActiveParserSetting, out value))
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    n,
                    Constants.QuotationError.ToString("No active parser configured."),
                    Constants.QuotationError.Code);
                flags.Add(flag);
                success.Failed();
                yield break;
            }

            IQuoteParser parser;

            if (!conf.TryGetParserInstance(value.GetStringValue(), out parser))
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    n,
                    Constants.QuotationError.ToString(string.Format("Cannot find a parser named {0}", value.GetStringValue())),
                    Constants.QuotationError.Code);
                flags.Add(flag);
                success.Failed();
                yield break;
            }

            string     unquotePrefix = "";
            bool       parseSuccess  = true;
            AST <Node> result        = null;

            try
            {
                unquotePrefix = parser.UnquotePrefix;
                List <Flag> parseFlags;
                if (!parser.Parse(
                        conf,
                        new QuoteStream((Quote)n, parser.UnquotePrefix, cancel),
                        new SourcePositioner((Quote)n, parser.UnquotePrefix),
                        out result,
                        out parseFlags))
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        n,
                        Constants.QuotationError.ToString(string.Empty),
                        Constants.QuotationError.Code);
                    flags.Add(flag);
                    parseSuccess = false;
                }

                if (parseFlags != null)
                {
                    flags.AddRange(parseFlags);
                }
            }
            catch (Exception e)
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    n,
                    Constants.PluginException.ToString(Configuration.ParsersCollectionName, value.GetStringValue(), e.Message),
                    Constants.PluginException.Code);
                flags.Add(flag);
                parseSuccess = false;
            }

            if (cancel.IsCancellationRequested)
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    n,
                    Constants.QuotationError.ToString("Cancelled quotation parse"),
                    Constants.QuotationError.Code);
                flags.Add(flag);
                parseSuccess = false;
            }

            if (parseSuccess && (result == null || result.FindAny(queryQuote, cancel) != null))
            {
                var flag = new Flag(
                    SeverityKind.Error,
                    n,
                    Constants.QuotationError.ToString("Quotation parser did not eliminate quotations."),
                    Constants.QuotationError.Code);
                flags.Add(flag);
                parseSuccess = false;
            }

            if (!parseSuccess)
            {
                success.Failed();
                yield break;
            }

            Quote qn         = (Quote)n;
            int   childId    = 0;
            var   unquoteMap = new Map <string, AST <Node> >(string.CompareOrdinal);

            foreach (var c in qn.Contents)
            {
                if (c.NodeKind != NodeKind.QuoteRun)
                {
                    unquoteMap.Add(string.Format("{0}{1}", unquotePrefix, childId), Factory.Instance.ToAST(c));
                    ++childId;
                }
            }

            if (childId == 0)
            {
                yield return(result.Node);
            }
            else
            {
                yield return(SubstituteEscapes(result, unquoteMap, cancel).Root);
            }
        }
Ejemplo n.º 11
0
        private Tuple <Term, Term> Expand_Fold(
            Node n,
            IEnumerable <Tuple <Term, Term> > args,
            Stack <Tuple <Namespace, Symbol> > symbStack,
            Map <UserCnstSymb, Term> valParamToValue,
            SuccessToken success,
            List <Flag> flags)
        {
            bool wasAdded;
            var  space = symbStack.Peek().Item1;
            var  symb  = symbStack.Pop().Item2;

            if (symb == null)
            {
                return(null);
            }
            if (symb.IsNonVarConstant)
            {
                var cnst = symb as UserCnstSymb;
                if (cnst != null && cnst.IsSymbolicConstant)
                {
                    var expDef = valParamToValue[cnst];
                    Contract.Assert(expDef != null);
                    return(new Tuple <Term, Term>(expDef, index.MkDataWidenedType(expDef)));
                }
                else
                {
                    var valTerm = index.MkApply(symb, TermIndex.EmptyArgs, out wasAdded);
                    return(new Tuple <Term, Term>(valTerm, valTerm));
                }
            }
            else if (symb.IsVariable)
            {
                var varTerm = index.MkApply(symb, TermIndex.EmptyArgs, out wasAdded);
                return(new Tuple <Term, Term>(varTerm, varTerm));
            }
            else if (symb.IsDataConstructor)
            {
                var con  = (UserSymbol)symb;
                var sort = symb.Kind == SymbolKind.ConSymb ? ((ConSymb)con).SortSymbol : ((MapSymb)con).SortSymbol;

                var i     = 0;
                var vargs = new Term[con.Arity];
                var typed = true;
                foreach (var a in args)
                {
                    if (a == null)
                    {
                        //// If an arg is null, then it already has errors,
                        //// so skip it an check the rest.
                        typed = false;
                        continue;
                    }
                    else if (a.Item2.Symbol.IsNonVarConstant)
                    {
                        if (!sort.DataSymbol.CanonicalForm[i].AcceptsConstant(a.Item2.Symbol))
                        {
                            flags.Add(new Flag(
                                          SeverityKind.Error,
                                          n,
                                          Constants.BadArgType.ToString(i + 1, sort.DataSymbol.FullName),
                                          Constants.BadArgType.Code));
                            success.Failed();
                            typed = false;
                            continue;
                        }
                    }
                    else if (a.Item2.Symbol.Kind == SymbolKind.UserSortSymb)
                    {
                        if (!sort.DataSymbol.CanonicalForm[i].Contains(a.Item2.Symbol))
                        {
                            flags.Add(new Flag(
                                          SeverityKind.Error,
                                          n,
                                          Constants.BadArgType.ToString(i + 1, sort.DataSymbol.FullName),
                                          Constants.BadArgType.Code));
                            success.Failed();
                            typed = false;
                            continue;
                        }
                    }
                    else if (!a.Item2.Symbol.IsVariable)
                    {
                        //// Only don't care variables are allowed, which always type check.
                        throw new NotImplementedException();
                    }

                    vargs[i] = a.Item1;
                    ++i;
                }

                if (!typed)
                {
                    success.Failed();
                    return(null);
                }

                return(new Tuple <Term, Term>(
                           index.MkApply(con, vargs, out wasAdded),
                           index.MkApply(sort, TermIndex.EmptyArgs, out wasAdded)));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 12
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();
            }
        }
Ejemplo n.º 13
0
        public bool Validate(List <Flag> flags, CancellationToken cancel, bool isCompilerAction = false)
        {
            var success   = new SuccessToken();
            var symbStack = new Stack <Tuple <Namespace, Symbol> >();

            symbStack.Push(new Tuple <Namespace, Symbol>(Index.SymbolTable.Root, null));
            var head = Factory.Instance.ToAST(Head).Compute <Tuple <Term, Term> >(
                x => CreateHeadTerm_Unfold(x, symbStack, success, flags),
                (x, y) => CreateHeadTerm_Fold(x, y, symbStack, success, flags),
                cancel);

            if (head == null)
            {
                success.Failed();
            }
            else if (head != null)
            {
                HeadTerm = head.Item1;
                HeadType = head.Item2;
            }

            if (myComprData == null && head != null)
            {
                head.Item2.Visit(
                    x => x.Symbol == theUnnSymbol ? x.Args : null,
                    x =>
                {
                    if (x.Symbol.IsNewConstant)
                    {
                        var flag = new Flag(
                            SeverityKind.Error,
                            Head,
                            Constants.DerivesError.ToString(string.Format("the new constant {0}", x.Symbol.PrintableName), "it is illegal to derive new-kind constants"),
                            Constants.DerivesError.Code);
                        flags.Add(flag);
                        success.Failed();
                    }
                    else if (x.Symbol.Kind == SymbolKind.BaseSortSymb)
                    {
                        var flag = new Flag(
                            SeverityKind.Error,
                            Head,
                            Constants.DerivesError.ToString(string.Format("values of type {0}", x.Symbol.PrintableName), "it is illegal to derive base constants"),
                            Constants.DerivesError.Code);
                        flags.Add(flag);
                        success.Failed();
                    }
                    else if (!isCompilerAction && Index.SymbolTable.IsProtectedHeadSymbol(x.Symbol))
                    {
                        var flag = new Flag(
                            SeverityKind.Error,
                            Head,
                            Constants.DerivesError.ToString(string.Format("values of the form {0}", x.Symbol.PrintableName), "user-defined rules cannot derive these values"),
                            Constants.DerivesError.Code);
                        flags.Add(flag);
                        success.Failed();
                    }
                });
            }

            return(success.Result);
        }
Ejemplo n.º 14
0
        private Tuple <Term, Term> CreateHeadTerm_Fold(
            Node n,
            IEnumerable <Tuple <Term, Term> > args,
            Stack <Tuple <Namespace, Symbol> > symbStack,
            SuccessToken success,
            List <Flag> flags)
        {
            bool wasAdded;
            Term valTerm, typTerm;
            var  space = symbStack.Peek().Item1;
            var  symb  = symbStack.Pop().Item2;

            if (symb == null && space == null)
            {
                return(null);
            }
            else if (symb == null)
            {
                var data = args.First <Tuple <Term, Term> >();
                if (data == null)
                {
                    return(null);
                }

                return(SmpIdentity(space, data.Item1, data.Item2, n, flags));
            }
            if (symb.IsNonVarConstant)
            {
                valTerm = Index.MkApply(symb, TermIndex.EmptyArgs, out wasAdded);
                return(new Tuple <Term, Term>(valTerm, valTerm));
            }
            else if (symb.IsVariable)
            {
                valTerm = MkSelectors((Id)n, symb);
                if (!Body.TryGetType(valTerm, out typTerm))
                {
                    flags.Add(new Flag(
                                  SeverityKind.Error,
                                  n,
                                  Constants.UnorientedError.ToString(((Id)n).Name),
                                  Constants.UnorientedError.Code));

                    return(null);
                }
                else
                {
                    //// return new Tuple<Term, Term>(valTerm, Index.MkDataWidenedType(typTerm));
                    return(new Tuple <Term, Term>(valTerm, typTerm));
                }
            }
            else if (symb.IsDataConstructor)
            {
                var con  = (UserSymbol)symb;
                var sort = symb.Kind == SymbolKind.ConSymb ? ((ConSymb)con).SortSymbol : ((MapSymb)con).SortSymbol;

                var vargs = new Term[con.Arity];
                var targs = new Term[con.Arity];

                var i     = 0;
                var typed = true;
                Tuple <Term, Term> coerced;
                foreach (var a in args)
                {
                    if (a == null)
                    {
                        //// If an arg is null, then it already has errors,
                        //// so skip it an check the rest.
                        typed = false;
                        continue;
                    }

                    coerced = Coerce(
                        sort.DataSymbol.CanonicalForm[i],
                        a.Item1,
                        a.Item2,
                        i,
                        n,
                        sort.PrintableName,
                        flags);

                    if (coerced == null)
                    {
                        ++i;
                        typed = false;
                        continue;
                    }

                    vargs[i] = coerced.Item1;
                    targs[i] = coerced.Item2;
                    ++i;
                }

                if (!typed)
                {
                    success.Failed();
                    return(null);
                }

                return(new Tuple <Term, Term>(
                           Index.MkApply(con, vargs, out wasAdded),
                           Index.MkApply(con, targs, out wasAdded)));
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 15
0
        private IEnumerable <Node> CreateHeadTerm_Unfold(Node n,
                                                         Stack <Tuple <Namespace, Symbol> > symbStack,
                                                         SuccessToken success,
                                                         List <Flag> flags)
        {
            var        space = symbStack.Peek().Item1;
            UserSymbol other;

            switch (n.NodeKind)
            {
            case NodeKind.Cnst:
            {
                if (myComprData == null && symbStack.Count == 1)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        n,
                        Constants.BadSyntax.ToString(string.Format("A rule cannot produce the base constant {0}", ((Cnst)n).Raw)),
                        Constants.BadSyntax.Code);
                    flags.Add(flag);
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }

                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 (myComprData == null &&
                         id.Fragments.Length == 1 &&
                         (symb = Index.SymbolTable.Resolve(id.Fragments[0], out other, Index.SymbolTable.ModuleSpace, x => x.IsDerivedConstant)) != null &&
                         other == null &&
                         symb.Namespace == Index.SymbolTable.ModuleSpace)
                {
                    symbStack.Push(new Tuple <Namespace, Symbol>(symb.Namespace, symb));
                    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);
                }

                if (symb.Kind == SymbolKind.UserCnstSymb && ((UserCnstSymb)symb).IsSymbolicConstant)
                {
                    symb = (UserSymbol)Index.MkScVar(((UserCnstSymb)symb).FullName, false).Symbol;
                }

                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 (ASTSchema.Instance.IsId(ftid.Name, true, false, false, true) &&
                        ftid.Fragments[ftid.Fragments.Length - 1] == ASTSchema.Instance.DontCareName)
                    {
                        var nsName = ftid.Fragments.Length == 1
                                             ? string.Empty
                                             : ftid.Name.Substring(0, ftid.Name.Length - 2);
                        Namespace ns, ons;
                        ns = Index.SymbolTable.Resolve(nsName, out ons, space);
                        if (!AddNamespaceErrors(n, nsName, ns, ons, flags))
                        {
                            symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                            success.Failed();
                            return(null);
                        }
                        else
                        {
                            symbStack.Push(new Tuple <Namespace, Symbol>(ns, null));
                        }
                    }
                    else if (ValidateUse_UserFunc(ft, space, out symb, flags))
                    {
                        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
                {
                    string opName;
                    if (ft.Function is RelKind)
                    {
                        opName = ASTSchema.Instance.ToString((RelKind)ft.Function);
                    }
                    else if (ft.Function is OpKind)
                    {
                        OpStyleKind kind;
                        opName = ASTSchema.Instance.ToString((OpKind)ft.Function, out kind);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    var flag = new Flag(
                        SeverityKind.Error,
                        ft,
                        Constants.BadSyntax.ToString(string.Format("The function {0} cannot appear here; considering moving it to the right-hand side.", opName)),
                        Constants.BadSyntax.Code);
                    flags.Add(flag);
                    symbStack.Push(new Tuple <Namespace, Symbol>(null, null));
                    success.Failed();
                    return(null);
                }
            }

            default:
                throw new NotImplementedException();
            }
        }