Exemplo n.º 1
0
 public ActionSet(ComprehensionData comprData)
 {
     Contract.Requires(comprData != null);
     AST             = Factory.Instance.ToAST(comprData.Node);
     Index           = comprData.Owner.Index;
     myComprData     = comprData;
     TypeEnvironment = comprData.Owner.TypeEnvironment.AddChild(comprData.Node);
     IsCompiled      = LiftedBool.Unknown;
 }
Exemplo n.º 2
0
        private bool RecordValidationResult(bool result)
        {
            if (!result)
            {
                IsCompiled = LiftedBool.False;
            }

            return(result);
        }
Exemplo n.º 3
0
        public ActionSet(AST <Node> ast, TermIndex index)
        {
            Contract.Requires(index != null && ast != null);
            Contract.Requires(ast.Node.NodeKind == NodeKind.Rule || ast.Node.NodeKind == NodeKind.ContractItem);
            //// TODO: Accept contract specifications too.

            AST             = ast;
            Index           = index;
            myComprData     = null;
            TypeEnvironment = new TypeEnvironment(ast.Node, index);
            IsCompiled      = LiftedBool.Unknown;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Compiles the action set into a set of rules. Should not be called if validation failed.
        /// </summary>
        public bool Compile(RuleTable rules, List <Flag> flags, CancellationToken cancel)
        {
            bool result = true;

            if (IsCompiled != LiftedBool.Unknown)
            {
                return((bool)IsCompiled);
            }
            else if (myComprData == null)
            {
                foreach (var a in actions)
                {
                    result = a.Compile(rules, flags, cancel) && result;
                }

                return((bool)(IsCompiled = result));
            }

            //// For a comprehension need to compile the bodies of the actions
            //// before compiling the actions, so a representation for the comprehension is known.
            FindData[] parts;
            var        bodies = new LinkedList <Term>();

            foreach (var a in actions)
            {
                result = a.Body.Compile(rules, out parts, flags, cancel) && result;
                if (result)
                {
                    bodies.AddLast(rules.MkBodyTerm(parts));
                }
            }

            if (!result)
            {
                return((bool)(IsCompiled = result));
            }

            bool wasAdded;
            Term reads       = Index.TrueValue;
            var  comprSymbol = Index.SymbolTable.GetOpSymbol(ReservedOpKind.Compr);
            var  conjSymbol  = Index.SymbolTable.GetOpSymbol(ReservedOpKind.Conj);

            foreach (var kv in myComprData.ReadVars.Reverse)
            {
                reads = Index.MkApply(conjSymbol, new Term[] { kv.Key, reads }, out wasAdded);
            }

            var headSet = new Set <Term>(Term.Compare);

            foreach (var a in actions)
            {
                headSet.Add(a.HeadTerm);
            }

            Term heads = Index.TrueValue;

            foreach (var h in headSet.Reverse)
            {
                heads = Index.MkApply(conjSymbol, new Term[] { h, heads }, out wasAdded);
            }

            myComprData.Representation = Index.MkApply(comprSymbol, new Term[] { heads, reads, rules.MkBodiesTerm(bodies) }, out wasAdded);
            foreach (var a in actions)
            {
                result = a.Compile(rules, flags, cancel) && result;
            }

            return((bool)(IsCompiled = result));
        }
Exemplo n.º 5
0
        /// <summary>
        /// If arg : argType must be a subtype of acceptingType, then returns
        /// a possibly coerced term satisfying the property. The type of the
        /// coerced term is also returned.
        ///
        /// Returns null and generates errors of if the term cannot be
        /// coerced.
        ///
        /// If computeType is false, then the type of the coerced
        /// term is not returned.
        /// </summary>
        private Tuple <Term, Term> Coerce(AppFreeCanUnn acceptingType,
                                          Term arg,
                                          Term argType,
                                          int argIndex,
                                          Node appNode,
                                          string appFun,
                                          List <Flag> flags)
        {
            bool             wasAdded;
            Set <Namespace>  spaces;
            Namespace        maxPrefix   = null;
            LiftedBool       isCoercable = LiftedBool.True;
            Set <UserSymbol> dataSorts   = null;
            Term             resultType  = null;
            UserSymbol       us;
            UserSortSymb     uss;

            //// Step 1. Check that all constants are accepted, and all data sorts
            //// can potentially be coerced.
            //// After this loop, resultType contains all constants.
            argType.Visit(
                x => x.Symbol == theUnnSymbol ? x.Args : null,
                t =>
            {
                if (t.Symbol == theUnnSymbol)
                {
                    return;
                }
                else if (t.Symbol.Kind == SymbolKind.UserSortSymb ||
                         t.Symbol.IsDataConstructor ||
                         t.Symbol.IsDerivedConstant ||
                         (t.Symbol.Kind == SymbolKind.UserCnstSymb && ((UserCnstSymb)t.Symbol).IsTypeConstant))
                {
                    if (t.Symbol.Kind == SymbolKind.UserSortSymb)
                    {
                        uss = (UserSortSymb)t.Symbol;
                        us  = uss.DataSymbol;
                    }
                    else if (t.Symbol.IsDataConstructor)
                    {
                        us  = (UserSymbol)t.Symbol;
                        uss = us.Kind == SymbolKind.ConSymb ? ((ConSymb)us).SortSymbol : ((MapSymb)us).SortSymbol;
                    }
                    else
                    {
                        uss = null;
                        us  = (UserSymbol)t.Symbol;
                    }

                    if (maxPrefix == null)
                    {
                        maxPrefix = us.Namespace;
                    }
                    else
                    {
                        us.Namespace.TryGetPrefix(maxPrefix, out maxPrefix);
                    }

                    if (dataSorts == null)
                    {
                        dataSorts = new Set <UserSymbol>(Symbol.Compare);
                    }

                    dataSorts.Add(us);
                    if (!acceptingType.Contains(uss == null ? (Symbol)us : uss))
                    {
                        if (!acceptingType.TryGetRenamings(us.Name, out spaces))
                        {
                            var flag = new Flag(
                                SeverityKind.Error,
                                appNode,
                                Constants.UnsafeArgType.ToString(
                                    argIndex + 1,
                                    appFun,
                                    t.Symbol.PrintableName),
                                Constants.UnsafeArgType.Code);
                            flags.Add(flag);
                            isCoercable = LiftedBool.False;
                        }
                        else if (isCoercable == LiftedBool.True)
                        {
                            isCoercable = LiftedBool.Unknown;
                        }
                    }
                }
                else if (!acceptingType.AcceptsConstants(t))
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        appNode,
                        Constants.UnsafeArgType.ToString(
                            argIndex + 1,
                            appFun,
                            t.Symbol != theRngSymbol ? t.Symbol.PrintableName : (t.Args[0].Symbol.PrintableName + ".." + t.Args[1].Symbol.PrintableName)),
                        Constants.UnsafeArgType.Code);
                    flags.Add(flag);
                    isCoercable = LiftedBool.False;
                }
                else
                {
                    resultType = resultType == null
                                        ? t
                                        : Index.MkApply(theUnnSymbol, new Term[] { t, resultType }, out wasAdded);
                }
            });

            if (isCoercable == false)
            {
                return(null);
            }
            else if (isCoercable == true)
            {
                return(new Tuple <Term, Term>(arg, argType));
            }

            //// Step 2. Check that there is a unique coercion from the user sorts.
            Contract.Assert(dataSorts != null && maxPrefix != null);
            Set <Namespace> rnmgs = null, cndts;
            Namespace       prefix;

            string[] suffix;

            foreach (var s in dataSorts)
            {
                suffix = s.Namespace.Split(maxPrefix);
                Contract.Assert(suffix != null);

                acceptingType.TryGetRenamings(s.Name, out spaces);
                cndts = new Set <Namespace>(Namespace.Compare);
                foreach (var ns in spaces)
                {
                    if (ns.Split(suffix, out prefix))
                    {
                        cndts.Add(prefix);
                    }
                }

                if (rnmgs == null)
                {
                    rnmgs = cndts;
                }
                else
                {
                    rnmgs.IntersectWith(cndts);
                }

                if (rnmgs.Count == 0)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        appNode,
                        Constants.UncoercibleArgType.ToString(
                            argIndex + 1,
                            appFun,
                            s.PrintableName),
                        Constants.UncoercibleArgType.Code);
                    flags.Add(flag);
                    return(null);
                }
            }

            if (rnmgs.Count != 1)
            {
                foreach (var ns in rnmgs)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        appNode,
                        Constants.AmbiguousCoercibleArg.ToString(
                            argIndex + 1,
                            appFun,
                            maxPrefix.FullName,
                            ns.FullName),
                        Constants.AmbiguousCoercibleArg.Code);
                    flags.Add(flag);
                }

                return(null);
            }

            var    from = maxPrefix;
            var    to   = rnmgs.GetSomeElement();
            Symbol coerced;

            foreach (var ds in dataSorts)
            {
                if (ds.Kind == SymbolKind.UserCnstSymb)
                {
                    if (!Index.SymbolTable.IsCoercible(ds, from, to, out coerced))
                    {
                        coerced = null;
                    }
                }
                else
                {
                    uss = ds.Kind == SymbolKind.ConSymb ? ((ConSymb)ds).SortSymbol : ((MapSymb)ds).SortSymbol;
                    if (!Index.SymbolTable.IsCoercible(uss, from, to, out coerced))
                    {
                        coerced = null;
                    }
                }

                if (coerced == null)
                {
                    var flag = new Flag(
                        SeverityKind.Error,
                        appNode,
                        Constants.UncoercibleArgType.ToString(
                            argIndex + 1,
                            appFun,
                            ds.PrintableName),
                        Constants.UncoercibleArgType.Code);
                    flags.Add(flag);
                    return(null);
                }
                else
                {
                    resultType = resultType == null
                                    ? Index.MkApply(coerced, TermIndex.EmptyArgs, out wasAdded)
                                    : Index.MkApply(
                        theUnnSymbol,
                        new Term[] { Index.MkApply(coerced, TermIndex.EmptyArgs, out wasAdded), resultType },
                        out wasAdded);
                }
            }

            typeEnvironment.AddCoercion(appNode, argIndex, from.FullName, to.FullName);
            var coercedArg = Index.MkApply(
                Index.SymbolTable.GetOpSymbol(ReservedOpKind.Relabel),
                new Term[] {
                Index.MkCnst(from.FullName, out wasAdded),
                Index.MkCnst(to.FullName, out wasAdded),
                arg
            },
                out wasAdded);

            return(new Tuple <Term, Term>(coercedArg, resultType));
        }