示例#1
0
        /// <summary>
        /// Get a statement for the entire block, and a pointer to its body.
        /// </summary>
        /// <param name="innerBlock">On return, a pointer to the body of the block.</param>
        /// <returns></returns>
        internal override IStatement GetStatement(out IList <IStatement> innerBlock)
        {
            IRepeatStatement rs = CodeBuilder.Instance.RepeatStmt(countVar.GetExpression());

            innerBlock = rs.Body.Statements;
            return(rs);
        }
示例#2
0
 /// <summary>
 /// Create a clone of prototype with an empty body.
 /// </summary>
 /// <param name="prototype"></param>
 /// <returns></returns>
 internal static IStatement CreateContainer(IStatement prototype)
 {
     if (prototype is IForStatement)
     {
         IForStatement loop = (IForStatement)prototype;
         IForStatement ifs  = Builder.ForStmt(loop);
         ifs.Initializer = loop.Initializer;
         ifs.Condition   = loop.Condition;
         ifs.Increment   = loop.Increment;
         ifs.Body        = Builder.BlockStmt();
         return(ifs);
     }
     else if (prototype is IConditionStatement)
     {
         IConditionStatement cond = (IConditionStatement)prototype;
         return(Builder.CondStmt(cond.Condition, Builder.BlockStmt()));
     }
     else if (prototype is IRepeatStatement)
     {
         IRepeatStatement irs = (IRepeatStatement)prototype;
         return(Builder.RepeatStmt(irs.Count));
     }
     else
     {
         throw new NotImplementedException("unrecognized container: " + prototype);
     }
 }
示例#3
0
 /// <summary>
 /// True if the containers match, ignoring the statements in their bodies.
 /// </summary>
 /// <param name="st1"></param>
 /// <param name="st2"></param>
 /// <param name="allowBrokenLoops"></param>
 /// <param name="ignoreLoopDirection"></param>
 /// <returns></returns>
 internal static bool ContainersAreEqual(IStatement st1, IStatement st2, bool allowBrokenLoops = false, bool ignoreLoopDirection = false)
 {
     if (ReferenceEquals(st1, st2))
     {
         return(true);
     }
     if (st1 is IForStatement)
     {
         IForStatement ifs1 = (IForStatement)st1;
         if (st2 is IForStatement)
         {
             IForStatement ifs2 = (IForStatement)st2;
             if (ignoreLoopDirection && Recognizer.IsForwardLoop(ifs1) != Recognizer.IsForwardLoop(ifs2))
             {
                 ifs2 = (IForStatement)CreateContainer(ifs2);
                 Recognizer.ReverseLoopDirection(ifs2);
             }
             return(ifs1.Initializer.Equals(ifs2.Initializer) &&
                    ifs1.Condition.Equals(ifs2.Condition) &&
                    ifs1.Increment.Equals(ifs2.Increment) &&
                    (allowBrokenLoops || ((ifs1 is IBrokenForStatement) == (ifs2 is IBrokenForStatement))));
         }
         else
         {
             return(false);
         }
     }
     else if (st1 is IConditionStatement)
     {
         IConditionStatement ics1 = (IConditionStatement)st1;
         if (st2 is IConditionStatement)
         {
             IConditionStatement ics2 = (IConditionStatement)st2;
             return(ics1.Condition.Equals(ics2.Condition));
         }
         else
         {
             return(false);
         }
     }
     else if (st1 is IRepeatStatement)
     {
         IRepeatStatement irs1 = (IRepeatStatement)st1;
         if (st2 is IRepeatStatement)
         {
             IRepeatStatement irs2 = (IRepeatStatement)st2;
             return(irs1.Count.Equals(irs2.Count));
         }
         else
         {
             return(false);
         }
     }
     else
     {
         return(st1 == st2);
     }
 }
示例#4
0
        public Scope CreateChildScope(IRepeatStatement repeat)
        {
            if (repeat.IncrementVariable == null)
            {
                return(this);
            }

            return(new Scope(
                       DeclaredIdentifiers.SetItem(repeat.IncrementVariable.Name, repeat.IncrementVariable),
                       DeclaredDataTypes));
        }
示例#5
0
        protected override IStatement ConvertRepeat(IRepeatStatement irs)
        {
            var loopSize = irs.Count;

            if (!((loopSize is IVariableReferenceExpression) || (loopSize is IArrayIndexerExpression) ||
                  (loopSize is IArgumentReferenceExpression) || (loopSize is ILiteralExpression) ||
                  (loopSize is IPropertyReferenceExpression)))
            {
                Error("Invalid expression type for the count of a repeat block (" + loopSize.GetType().Name + "): " + loopSize);
                return(irs);
            }
            var body = ConvertBlock(irs.Body);

            context.AddStatementsAfterCurrent(body.Statements);
            return(null);
        }
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            IRepeatStatement statement = obj as IRepeatStatement;

            if (statement == null)
            {
                return(false);
            }

            return
                (Body.Equals(statement.Body) &&
                 Count.Equals(statement.Count));
        }
示例#7
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);
        }
示例#8
0
        protected IExpression ConvertWithReplication(IExpression expr)
        {
            IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(expr);

            // Check if this is an index local variable
            if (baseVar == null)
            {
                return(expr);
            }
            // Check if the variable is stochastic
            if (!CodeRecognizer.IsStochastic(context, baseVar))
            {
                return(expr);
            }
            if (cutVariables.Contains(baseVar))
            {
                return(expr);
            }

            // Get the repeat context for this variable
            RepeatContext lc = context.InputAttributes.Get <RepeatContext>(baseVar);

            if (lc == null)
            {
                Error("Repeat context not found for '" + baseVar.Name + "'.");
                return(expr);
            }

            // Get the reference loop context for this expression
            var rlc = lc.GetReferenceRepeatContext(context);

            // If the reference is in the same loop context as the declaration, do nothing.
            if (rlc.repeats.Count == 0)
            {
                return(expr);
            }

            // Determine if this expression is being defined (is on the LHS of an assignment)
            bool isDef = Recognizer.IsBeingMutated(context, expr);

            Containers containers = context.InputAttributes.Get <Containers>(baseVar);

            for (int currentRepeat = 0; currentRepeat < rlc.repeatCounts.Count; currentRepeat++)
            {
                IExpression      repeatCount = rlc.repeatCounts[currentRepeat];
                IRepeatStatement repeat      = rlc.repeats[currentRepeat];

                // must replicate across this loop.
                if (isDef)
                {
                    Error("Cannot re-define a variable in a repeat block.");
                    continue;
                }
                // are we replicating the argument of Gate.Cases?
                IMethodInvokeExpression imie = context.FindAncestor <IMethodInvokeExpression>();
                if (imie != null)
                {
                    if (Recognizer.IsStaticMethod(imie, typeof(Gate), "Cases"))
                    {
                        Error("'if(" + expr + ")' should be placed outside 'repeat(" + repeatCount + ")'");
                    }
                    if (Recognizer.IsStaticMethod(imie, typeof(Gate), "CasesInt"))
                    {
                        Error("'case(" + expr + ")' or 'switch(" + expr + ")' should be placed outside 'repeat(" + repeatCount + ")'");
                    }
                }

                VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                IList <IStatement>  stmts   = Builder.StmtCollection();

                List <IList <IExpression> > inds   = Recognizer.GetIndices(expr);
                IVariableDeclaration        repVar = varInfo.DeriveIndexedVariable(stmts, context, VariableInformation.GenerateName(context, varInfo.Name + "_rpt"), inds);
                if (!context.InputAttributes.Has <DerivedVariable>(repVar))
                {
                    context.OutputAttributes.Set(repVar, new DerivedVariable());
                }
                if (context.InputAttributes.Has <ChannelInfo>(baseVar))
                {
                    VariableInformation repVarInfo = VariableInformation.GetVariableInformation(context, repVar);
                    ChannelInfo         ci         = ChannelInfo.UseChannel(repVarInfo);
                    ci.decl = repVar;
                    context.OutputAttributes.Set(repVar, ci);
                }
                // set the RepeatContext of repVar to include all repeats up to this one (so that it doesn't get Entered again)
                List <IRepeatStatement> repeats = new List <IRepeatStatement>(lc.repeats);
                for (int i = 0; i <= currentRepeat; i++)
                {
                    repeats.Add(rlc.repeats[i]);
                }
                context.OutputAttributes.Remove <RepeatContext>(repVar);
                context.OutputAttributes.Set(repVar, new RepeatContext(repeats));

                // Create replicate factor
                Type returnType = Builder.ToType(repVar.VariableType);
                IMethodInvokeExpression powerPlateMethod = Builder.StaticGenericMethod(
                    new Func <PlaceHolder, double, PlaceHolder>(PowerPlate.Enter),
                    new Type[] { returnType }, expr, repeatCount);

                IExpression assignExpression = Builder.AssignExpr(Builder.VarRefExpr(repVar), powerPlateMethod);
                // Copy attributes across from variable to replication expression
                context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, powerPlateMethod);
                context.InputAttributes.CopyObjectAttributesTo <DivideMessages>(baseVar, context.OutputAttributes, powerPlateMethod);
                context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(baseVar, context.OutputAttributes, powerPlateMethod);
                stmts.Add(Builder.ExprStatement(assignExpression));

                // add any containers missing from context.
                containers = new Containers(context);
                // remove inner repeats
                for (int i = currentRepeat + 1; i < rlc.repeatCounts.Count; i++)
                {
                    containers = containers.RemoveOneRepeat(rlc.repeats[i]);
                }
                context.OutputAttributes.Set(repVar, containers);
                containers = containers.RemoveOneRepeat(repeat);
                containers = Containers.RemoveUnusedLoops(containers, context, powerPlateMethod);
                if (context.InputAttributes.Has <DoNotSendEvidence>(baseVar))
                {
                    containers = Containers.RemoveStochasticConditionals(containers, context);
                }
                //Containers shouldBeEmpty = containers.GetContainersNotInContext(context, context.InputStack.Count);
                //if (shouldBeEmpty.inputs.Count > 0) { Error("Internal: Variable is out of scope"); return expr; }
                int        ancIndex = containers.GetMatchingAncestorIndex(context);
                Containers missing  = containers.GetContainersNotInContext(context, ancIndex);
                stmts = Containers.WrapWithContainers(stmts, missing.inputs);
                // must convert the output since it may contain 'if' conditions
                context.AddStatementsBeforeAncestorIndex(ancIndex, stmts, true);
                baseVar = repVar;
                expr    = Builder.VarRefExpr(repVar);
            }

            return(expr);
        }
示例#9
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);
        }
示例#10
0
 internal static IStatement Intersect(IStatement st1, IStatement st2, bool allowBrokenLoops = false, bool ignoreLoopDirection = false)
 {
     if (ReferenceEquals(st1, st2))
     {
         return(st1);
     }
     if (st1 is IForStatement)
     {
         IForStatement ifs1      = (IForStatement)st1;
         bool          isForward = Recognizer.IsForwardLoop(ifs1);
         bool          isBroken  = ifs1 is IBrokenForStatement;
         if (st2 is IForStatement)
         {
             IForStatement ifs2 = (IForStatement)st2;
             if (ignoreLoopDirection && isForward != Recognizer.IsForwardLoop(ifs2))
             {
                 ifs2 = (IForStatement)CreateContainer(ifs2);
                 Recognizer.ReverseLoopDirection(ifs2);
             }
             bool isBroken2 = ifs2 is IBrokenForStatement;
             if (ifs1.Initializer.Equals(ifs2.Initializer) &&
                 ifs1.Condition.Equals(ifs2.Condition) &&
                 ifs1.Increment.Equals(ifs2.Increment) &&
                 (allowBrokenLoops || (isBroken == isBroken2)))
             {
                 return(isBroken ? st1 : st2);
             }
             // fall through
         }
         // fall through
     }
     else if (st1 is IConditionStatement)
     {
         IConditionStatement ics1 = (IConditionStatement)st1;
         if (st2 is IConditionStatement)
         {
             IConditionStatement ics2 = (IConditionStatement)st2;
             if (ics1.Condition.Equals(ics2.Condition))
             {
                 return(st1);
             }
             // fall through
         }
         // fall through
     }
     else if (st1 is IRepeatStatement)
     {
         IRepeatStatement irs1 = (IRepeatStatement)st1;
         if (st2 is IRepeatStatement)
         {
             IRepeatStatement irs2 = (IRepeatStatement)st2;
             if (irs1.Count.Equals(irs2.Count))
             {
                 return(st1);
             }
             // fall through
         }
         // fall through
     }
     else if (st1 == st2)
     {
         return(st1);
     }
     return(null);
 }