コード例 #1
0
        internal Containers Where(Predicate <IStatement> predicate)
        {
            Containers result = new Containers();

            for (int i = 0; i < inputs.Count; i++)
            {
                IStatement container = inputs[i];
                if (predicate(container))
                {
                    result.inputs.Add(container);
                    result.outputs.Add(outputs[i]);
                }
            }
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Get the minimal set of containers needed to evaluate an expression, along with the first index in the context stack at which the expression's variables are all declared.
        /// </summary>
        /// <param name="context">The transform context</param>
        /// <param name="expr">Any expression</param>
        /// <param name="ancIndex">On exit, the first index in the context stack at which the expression's variables are all declared.</param>
        /// <returns>The minimal set of containers needed to evaluate expr</returns>
        internal static Containers GetContainersNeededForExpression(BasicTransformContext context, IExpression expr, out int ancIndex)
        {
            Containers containers = GetContainersNeededForExpression(context, expr);

            if (containers == null)
            {
                ancIndex = -1;
                return(null);
            }
            ancIndex = containers.GetMatchingAncestorIndex(context);
            // append any conditionals with constant conditions
            //List<IStatement> loopsMissing = Containers.GetLoopsNeededForExpression(context, expr, ancIndex-1, true);
            //containers = Containers.Append(containers, loopsMissing);
            //containers.OrderByContext(context);
            return(containers);
        }
コード例 #3
0
        internal static Containers InsideOf(BasicTransformContext context, int exclude)
        {
            Containers containers = new Containers();

            for (int i = exclude + 1; i < context.InputStack.Count; i++)
            {
                TransformInfo ti           = context.InputStack[i];
                IStatement    inputElement = ti.inputElement as IStatement;
                if (IsContainer(inputElement) && !context.InputAttributes.Has <ConvergenceLoop>(inputElement))
                {
                    containers.inputs.Add(CreateContainer(inputElement));
                    containers.outputs.Add((IStatement)ti.PrimaryOutput);
                }
            }
            return(containers);
        }
コード例 #4
0
        /// <summary>
        /// Collect all containers that are not in the context at the given index.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ancestorIndex">If 0, all containers are returned.</param>
        /// <returns></returns>
        internal Containers GetContainersNotInContext(BasicTransformContext context, int ancestorIndex)
        {
            Containers result = new Containers();

            for (int i = 0; i < inputs.Count; i++)
            {
                IStatement container = inputs[i];
                int        index     = GetAncestorIndex(context, container);
                if (index == -1 || index >= ancestorIndex)
                {
                    result.inputs.Add(container);
                    result.outputs.Add(outputs[i]);
                }
            }
            return(result);
        }
コード例 #5
0
        internal static Containers Append(Containers containers, Containers extraContainers)
        {
            Containers result = new Containers();

            result.inputs  = new List <IStatement>(containers.inputs);
            result.outputs = new List <IStatement>(containers.outputs);
            for (int i = 0; i < extraContainers.inputs.Count; i++)
            {
                IStatement input = extraContainers.inputs[i];
                if (!containers.Contains(input))
                {
                    result.inputs.Add(input);
                    result.outputs.Add(extraContainers.outputs[i]);
                }
            }
            return(result);
        }
コード例 #6
0
        internal Containers Replace(Func <IStatement, IStatement> getReplacement)
        {
            Containers result = new Containers();

            for (int i = 0; i < inputs.Count; i++)
            {
                IStatement container   = inputs[i];
                IStatement replacement = getReplacement(container);
                result.inputs.Add(replacement);
                if (!ContainersAreEqual(outputs[i], inputs[i]))
                {
                    throw new Exception("outputs[i] != inputs[i]");
                }
                result.outputs.Add(replacement);
            }
            return(result);
        }
コード例 #7
0
        /// <summary>
        /// Returns the outermost container in the context that is not in this.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        internal int GetMatchingAncestorIndex(BasicTransformContext context)
        {
            int ancIndex = context.FindAncestorIndex <IStatement>();

            foreach (IStatement container in Containers.FindContainers(context))
            {
                if (context.InputAttributes.Has <ConvergenceLoop>(container))
                {
                    continue;
                }
                if (!this.Contains(container))
                {
                    // found a container unique to the current context.
                    // statements must be added here.
                    ancIndex = context.GetAncestorIndex(container);
                    break;
                }
            }
            return(ancIndex);
        }
コード例 #8
0
        internal static Containers RemoveStochasticConditionals(Containers containers, BasicTransformContext context)
        {
            Containers result = new Containers();

            for (int i = 0; i < containers.inputs.Count; i++)
            {
                IStatement container = containers.inputs[i];
                if (container is IConditionStatement)
                {
                    IConditionStatement ics = (IConditionStatement)container;
                    if (CodeRecognizer.IsStochastic(context, ics.Condition))
                    {
                        continue;
                    }
                }
                result.inputs.Add(container);
                result.outputs.Add(containers.outputs[i]);
            }
            return(result);
        }
コード例 #9
0
ファイル: VariableInformation.cs プロジェクト: dotnet/infer
 /// <summary>
 /// Check that the replacements are safe.
 /// </summary>
 /// <param name="context"></param>
 /// <param name="expr"></param>
 /// <param name="replacedIndexVars"></param>
 private static void CheckReplacements(BasicTransformContext context, IExpression expr, Dictionary <IVariableDeclaration, IExpression> replacedIndexVars)
 {
     foreach (var v in Recognizer.GetVariables(expr))
     {
         Containers containers = context.InputAttributes.Get <Containers>(v);
         if (containers != null && !replacedIndexVars.ContainsKey(v))
         {
             foreach (IStatement container in containers.inputs)
             {
                 if (container is IForStatement ifs)
                 {
                     IVariableDeclaration loopVar = Recognizer.LoopVariable(ifs);
                     if (replacedIndexVars.TryGetValue(loopVar, out IExpression actualIndex))
                     {
                         context.Error($"Cannot index {expr} by {loopVar.Name}={actualIndex} since {v.Name} has an implicit dependency on {loopVar.Name}. Try making the dependency explicit by putting {v.Name} into an array indexed by {loopVar.Name}");
                     }
                 }
             }
         }
     }
 }
コード例 #10
0
        /// <summary>
        /// Returns the containers common to both, preserving the order in the first argument.
        /// </summary>
        /// <param name="containers"></param>
        /// <param name="containers2"></param>
        /// <param name="allowBrokenLoops"></param>
        /// <param name="ignoreLoopDirection"></param>
        /// <returns></returns>
        internal static Containers Intersect(Containers containers, Containers containers2, bool allowBrokenLoops = false, bool ignoreLoopDirection = false)
        {
            Containers result = new Containers();

            for (int i = 0; i < containers.inputs.Count; i++)
            {
                IStatement container = containers.inputs[i];
                for (int j = 0; j < containers2.inputs.Count; j++)
                {
                    IStatement container2  = containers2.inputs[j];
                    IStatement intersected = Intersect(container, container2, allowBrokenLoops, ignoreLoopDirection);
                    if (intersected != null)
                    {
                        result.inputs.Add(intersected);
                        var intersectedOutput = Intersect(containers.outputs[i], containers2.outputs[j], allowBrokenLoops, ignoreLoopDirection);
                        result.outputs.Add(intersectedOutput);
                    }
                }
            }
            return(result);
        }
コード例 #11
0
        internal Containers RemoveOneRepeat(IRepeatStatement irs)
        {
            bool       found  = false;
            Containers result = new Containers();

            for (int i = 0; i < inputs.Count; i++)
            {
                IStatement container = inputs[i];
                if (!found && container is IRepeatStatement rs)
                {
                    if (rs.Count.Equals(irs.Count))
                    {
                        found = true;
                        continue;
                    }
                }
                result.inputs.Add(container);
                result.outputs.Add(outputs[i]);
            }
            return(result);
        }
コード例 #12
0
 private Containers(Containers c)
 {
     inputs.AddRange(c.inputs);
     outputs.AddRange(c.outputs);
 }
コード例 #13
0
        /// <summary>
        /// Remove loops (and their dependent containers) that are not needed to evaluate the expression.
        /// </summary>
        /// <param name="containers"></param>
        /// <param name="context"></param>
        /// <param name="needed"></param>
        /// <returns></returns>
        internal static Containers RemoveUnusedLoops(Containers containers, BasicTransformContext context, Containers needed)
        {
            Containers result = new Containers();
            Set <IVariableDeclaration> allowedVars = Containers.GetConditionedLoopVariables(context);

            allowedVars.Clear(); // for ReplicateWithConditionedIndexTest
            for (int i = 0; i < containers.inputs.Count; i++)
            {
                IStatement container = containers.inputs[i];
                if (container is IForStatement)
                {
                    IForStatement        ifs     = container as IForStatement;
                    IVariableDeclaration loopVar = Recognizer.LoopVariable(ifs);
                    if (!allowedVars.Contains(loopVar) && !needed.Contains(container))
                    {
                        continue;
                    }
                }
                result.inputs.Add(container);
                result.outputs.Add(containers.outputs[i]);
            }
            // Removing unused loops may have left us with containers that refer to the removed loop index.  We must remove these also.
            // Note this routine could be merged with RemoveUnusedLoops.
            result = Containers.RemoveInvalidConditions(result, context);
            return(result);
        }
コード例 #14
0
        /// <summary>
        /// Remove loops (and their dependent containers) that are not needed to evaluate the expression.
        /// </summary>
        /// <param name="containers"></param>
        /// <param name="context"></param>
        /// <param name="expr"></param>
        /// <returns></returns>
        internal static Containers RemoveUnusedLoops(Containers containers, BasicTransformContext context, IExpression expr)
        {
            Containers needed = Containers.GetContainersNeededForExpression(context, expr);

            return(RemoveUnusedLoops(containers, context, needed));
        }
コード例 #15
0
        internal static Containers RemoveInvalidConditions(Containers containers, BasicTransformContext context)
        {
            Containers result = new Containers();

            for (int i = 0; i < containers.inputs.Count; i++)
            {
                IStatement container = containers.inputs[i];
                if (container is IConditionStatement)
                {
                    IConditionStatement ics       = (IConditionStatement)container;
                    IExpression         condition = ics.Condition;
                    if (condition is IBinaryExpression && ((IBinaryExpression)condition).Operator == BinaryOperator.BooleanAnd)
                    {
                        // split the condition into conjuncts
                        List <IExpression> conditions   = new List <IExpression>();
                        IExpression        newCondition = null;
                        bool changed = false;
                        ForEachConjunct(condition, delegate(IExpression expr)
                        {
                            if (ContainsExpression(containers.inputs, context, expr))
                            {
                                if (newCondition == null)
                                {
                                    newCondition = expr;
                                }
                                else
                                {
                                    newCondition = Builder.BinaryExpr(BinaryOperator.BooleanAnd, newCondition, expr);
                                }
                            }
                            else
                            {
                                changed = true;
                            }
                        });
                        if (changed)
                        {
                            if (newCondition != null)
                            {
                                IConditionStatement cs = Builder.CondStmt(newCondition, Builder.BlockStmt());
                                result.inputs.Add(cs);
                                result.outputs.Add(cs);
                            }
                            continue;
                        }
                    }
                    else
                    {
                        if (!ContainsExpression(containers.inputs, context, condition))
                        {
                            continue;
                        }
                    }
                }
                else if (container is IRepeatStatement)
                {
                    IRepeatStatement irs = (IRepeatStatement)container;
                    if (!ContainsExpression(containers.inputs, context, irs.Count))
                    {
                        continue;
                    }
                }
                result.inputs.Add(container);
                result.outputs.Add(containers.outputs[i]);
            }
            return(result);
        }
コード例 #16
0
 internal Containers Remove(Containers containers)
 {
     return(Remove(containers.inputs));
 }
コード例 #17
0
 internal bool SetEquals(Containers c)
 {
     return(Contains(c) && c.Contains(this));
 }