コード例 #1
0
        public Term MkFindTerm(TermIndex index)
        {
            if (IsNull)
            {
                return(index.FalseValue);
            }
            else if (Binding.Symbol.IsReservedOperation)
            {
                //// In this case, do not create a find(...) term.
                return(Binding);
            }

            bool wasAdded;

            return(index.MkApply(
                       index.SymbolTable.GetOpSymbol(ReservedOpKind.Find),
                       new Term[] { Binding, Pattern, index.MkApply(index.TypeRelSymbol, new Term[] { Pattern, Type }, out wasAdded) },
                       out wasAdded));
        }
コード例 #2
0
ファイル: AppFreeCanUnn.cs プロジェクト: thisiscam/formula
        /// <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);
        }
コード例 #3
0
ファイル: CoreSubRule.cs プロジェクト: thisiscam/formula
        public override CoreRule Clone(int ruleId, Predicate <Symbol> isCompr, TermIndex index, Map <Term, Term> bindingReificationCache, Map <UserSymbol, UserSymbol> symbolTransfer, string renaming)
        {
            Contract.Assert(isCompr == null && index != null && bindingReificationCache == null && string.IsNullOrEmpty(renaming));

            bool wasAdded;
            var  newHeadArgs = new Term[Head.Symbol.Arity];
            var  newHeadCon  = symbolTransfer[(UserSymbol)Head.Symbol];

            for (int i = 0; i < newHeadArgs.Length; ++i)
            {
                newHeadArgs[i] = index.MkVar(((UserSymbol)Head.Args[i].Symbol).Name, true, out wasAdded);
            }

            var newHead = index.MkApply(newHeadCon, newHeadArgs, out wasAdded);

            return(new CoreSubRule(
                       ruleId,
                       newHead,
                       index.MkVar(((UserSymbol)Find1.Binding.Symbol).Name, true, out wasAdded),
                       Matcher.Clone(index)));
        }
コード例 #4
0
ファイル: ApplyResult.cs プロジェクト: thisiscam/formula
        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();
            }
        }
コード例 #5
0
ファイル: SolveResult.cs プロジェクト: thisiscam/formula
        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));
                }
            }
        }
コード例 #6
0
        public SubtermMatcher(TermIndex index, bool onlyNewKinds, Term[] pattern)
        {
            Contract.Requires(pattern != null && pattern.Length > 0);
            //// Appears that Requires is triggering bug in Code Contracts 1.9.10714.2
            Contract.Assert(index != null);

            this.pattern        = pattern;
            IsMatchOnlyNewKinds = onlyNewKinds;
            matchingUnions      = new AppFreeCanUnn[pattern.Length];

            bool wasAdded;
            Term type, intr;
            Term levelTypes = null;

            IsSatisfiable = true;
            IsTriggerable = false;
            Stack <Term> pending          = new Stack <Term>();
            Set <Term>   pendingOrVisited = new Set <Term>(Term.Compare);

            for (int i = pattern.Length - 1; i >= 0; --i)
            {
                if (!IsSatisfiable)
                {
                    return;
                }

                if (i == pattern.Length - 1)
                {
                    intr = pattern[pattern.Length - 1];
                }
                else if (!index.MkIntersection(pattern[i], levelTypes, out intr))
                {
                    IsSatisfiable = false;
                    return;
                }

                levelTypes    = null;
                IsSatisfiable = false;
                pendingOrVisited.Clear();
                foreach (var t in intr.Enumerate(x => x.Symbol == index.TypeUnionSymbol ? x.Args : null))
                {
                    if (t.Symbol == index.TypeUnionSymbol)
                    {
                        continue;
                    }
                    else if (IsPermitted(index, onlyNewKinds, t))
                    {
                        IsSatisfiable = true;
                        GetMatchingSet(i, t).Add(CanMatch);
                        pending.Push(t);
                        pendingOrVisited.Add(t);
                        levelTypes = levelTypes == null ? t : index.MkApply(index.TypeUnionSymbol, new Term[] { t, levelTypes }, out wasAdded);
                        if (i == 0 && (t.Symbol.Kind == SymbolKind.UserSortSymb || t.Symbol.IsDerivedConstant))
                        {
                            IsTriggerable = true;
                        }
                    }
                }

                if (!IsSatisfiable)
                {
                    return;
                }
                else
                {
                    matchingUnions[i] = new AppFreeCanUnn(levelTypes);
                }

                while (pending.Count > 0)
                {
                    type = pending.Pop();
                    foreach (var tup in index.GetTypeUses(type))
                    {
                        if (tup.Item1.Kind == SymbolKind.ConSymb)
                        {
                            type = index.MkApply(((ConSymb)tup.Item1).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                        }
                        else if (tup.Item1.Kind == SymbolKind.MapSymb)
                        {
                            type = index.MkApply(((MapSymb)tup.Item1).SortSymbol, TermIndex.EmptyArgs, out wasAdded);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }

                        if (IsPermitted(index, onlyNewKinds, type))
                        {
                            GetMatchingSet(i, type).Add(tup.Item2);
                            if (!pendingOrVisited.Contains(type))
                            {
                                pending.Push(type);
                                pendingOrVisited.Add(type);
                                levelTypes = levelTypes == null ? type : index.MkApply(index.TypeUnionSymbol, new Term[] { type, levelTypes }, out wasAdded);
                                if (i == 0 && (type.Symbol.Kind == SymbolKind.UserSortSymb || type.Symbol.IsDerivedConstant))
                                {
                                    IsTriggerable = true;
                                }
                            }
                        }
                    }
                }
            }

            if (IsTriggerable)
            {
                var level0 = matcher[0];
                levelTypes = null;
                foreach (var kv in level0)
                {
                    if (kv.Key.Symbol.Kind == SymbolKind.UserSortSymb || kv.Key.Symbol.IsDerivedConstant)
                    {
                        levelTypes = levelTypes == null ? kv.Key : index.MkApply(index.TypeUnionSymbol, new Term[] { kv.Key, levelTypes }, out wasAdded);
                    }
                }

                Trigger = levelTypes;
            }
        }