Beispiel #1
0
        protected void ProcessDefinition(IExpression expr, IVariableDeclaration targetVar, bool isLhs)
        {
            bool targetIsPointMass       = false;
            IMethodInvokeExpression imie = expr as IMethodInvokeExpression;

            if (imie != null)
            {
                // TODO: consider using a method attribute for this
                if (Recognizer.IsStaticGenericMethod(imie, new Models.FuncOut <PlaceHolder, PlaceHolder, PlaceHolder>(Clone.VariablePoint))
                    )
                {
                    targetIsPointMass = true;
                }
                else
                {
                    FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, imie);
                    targetIsPointMass = info.IsDeterministicFactor && (
                        (info.ReturnedInAllElementsParameterIndex != -1 && ArgumentIsPointMass(imie.Arguments[info.ReturnedInAllElementsParameterIndex])) ||
                        imie.Arguments.All(ArgumentIsPointMass)
                        );
                }
                if (targetIsPointMass)
                {
                    // do this immediately so all uses are updated
                    if (!context.InputAttributes.Has <ForwardPointMass>(targetVar))
                    {
                        context.OutputAttributes.Set(targetVar, new ForwardPointMass());
                    }
                    // the rest is done later
                    List <IMethodInvokeExpression> list;
                    if (!variablesDefinedPointMass.TryGetValue(targetVar, out list))
                    {
                        list = new List <IMethodInvokeExpression>();
                        variablesDefinedPointMass.Add(targetVar, list);
                    }
                    // this code needs to be synchronized with MessageTransform.ConvertMethodInvoke
                    if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, int, PlaceHolder[]>(Clone.Replicate)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItems)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItems)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <IReadOnlyList <int> > >, PlaceHolder[][][]>(Collection.GetDeepJaggedItems)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromJagged)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <IReadOnlyList <IReadOnlyList <PlaceHolder> > >, IReadOnlyList <int>, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromDeepJagged)) ||
                        Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <IReadOnlyList <int> >, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItemsFromJagged))
                        )
                    {
                        list.Add(imie);
                    }
                }
            }
            if (!targetIsPointMass && !(expr is IArrayCreateExpression))
            {
                variablesDefinedNonPointMass.Add(targetVar);
                if (variablesDefinedPointMass.ContainsKey(targetVar))
                {
                    variablesDefinedPointMass.Remove(targetVar);
                    context.OutputAttributes.Remove <ForwardPointMass>(targetVar);
                }
            }
        }
        /// <summary>
        /// Convert random assignments to derived variables
        /// </summary>
        /// <param name="iae"></param>
        /// <returns></returns>
        protected override IExpression ConvertAssign(IAssignExpression iae)
        {
            iae = (IAssignExpression)base.ConvertAssign(iae);
            IStatement ist = context.FindAncestor <IStatement>();

            if (!context.InputAttributes.Has <Models.Constraint>(ist) &&
                (iae.Expression is IMethodInvokeExpression))
            {
                IMethodInvokeExpression imie = (IMethodInvokeExpression)iae.Expression;
                IVariableDeclaration    ivd  = Recognizer.GetVariableDeclaration(iae.Target);
                if (ivd != null)
                {
                    bool isDerived = context.InputAttributes.Has <DerivedVariable>(ivd);
                    if (isDerived)
                    {
                        FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, imie);
                        if (!info.IsDeterministicFactor)
                        {
                            // The variable is derived, but this definition is not derived.
                            // Thus we must convert
                            //   y = sample()
                            // into
                            //   y_random = sample()
                            //   y = Copy(y_random)
                            // where y_random is not derived.
                            VariableInformation varInfo = VariableInformation.GetVariableInformation(context, ivd);
                            IList <IStatement>  stmts   = Builder.StmtCollection();
                            string name = ivd.Name + "_random" + (Count++);
                            List <IList <IExpression> > indices  = Recognizer.GetIndices(iae.Target);
                            IVariableDeclaration        cloneVar = varInfo.DeriveIndexedVariable(stmts, context, name, indices, copyInitializer: true);
                            context.OutputAttributes.Remove <DerivedVariable>(cloneVar);
                            stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(cloneVar), iae.Expression));
                            int ancIndex = context.FindAncestorIndex <IStatement>();
                            context.AddStatementsBeforeAncestorIndex(ancIndex, stmts);
                            Type tp = iae.Target.GetExpressionType();
                            if (tp == null)
                            {
                                Error("Could not determine type of expression: " + iae.Target);
                                return(iae);
                            }
                            IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp },
                                                                           Builder.VarRefExpr(cloneVar));
                            iae = Builder.AssignExpr(iae.Target, copy);
                        }
                    }
                }
            }
            return(iae);
        }
        private NodeInfo GetNodeInfo(IExpression factor)
        {
            IExpression             target = null;
            IMethodInvokeExpression imie;

            if (factor is IAssignExpression iae)
            {
                target = iae.Target;
                if (target is IVariableDeclarationExpression)
                {
                    IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(target);
                    target = Builder.VarRefExpr(ivd);
                }
                imie = (IMethodInvokeExpression)iae.Expression;
            }
            else
            {
                imie = (IMethodInvokeExpression)factor;
            }
            NodeInfo info = new NodeInfo(imie)
            {
                info = CodeRecognizer.GetFactorInfo(context, imie)
            };

            if (target != null)
            {
                info.isReturnOrOut.Add(true);
                info.arguments.Add(target);
            }
            if (!info.info.Method.IsStatic)
            {
                info.isReturnOrOut.Add(false);
                info.arguments.Add(imie.Method.Target);
            }
            foreach (IExpression arg in imie.Arguments)
            {
                bool isOut = (arg is IAddressOutExpression);
                info.isReturnOrOut.Add(isOut);
                info.arguments.Add(isOut ? ((IAddressOutExpression)arg).Expression : arg);
            }
            return(info);
        }
        protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
        {
            CheckMethodArgumentCount(imie);
            if (CodeRecognizer.IsInfer(imie))
            {
                inferCount++;
                object decl = Recognizer.GetDeclaration(imie.Arguments[0]);
                if (decl != null && !context.InputAttributes.Has <IsInferred>(decl))
                {
                    context.InputAttributes.Set(decl, new IsInferred());
                }
                // the arguments must not be substituted for their values, so we don't call ConvertExpression
                var newArgs = imie.Arguments.Select(CodeRecognizer.RemoveCast);
                IMethodInvokeExpression infer = Builder.MethodInvkExpr();
                infer.Method = imie.Method;
                infer.Arguments.AddRange(newArgs);
                context.InputAttributes.CopyObjectAttributesTo(imie, context.OutputAttributes, infer);
                return(infer);
            }
            IExpression converted = base.ConvertMethodInvoke(imie);

            if (converted is IMethodInvokeExpression mie)
            {
                foreach (IExpression arg in mie.Arguments)
                {
                    if (arg is IAddressOutExpression iaoe)
                    {
                        IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iaoe.Expression);
                        if (ivd != null)
                        {
                            FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, mie);
                            if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd))
                            {
                                context.InputAttributes.Set(ivd, new DerivedVariable());
                            }
                        }
                    }
                }
            }
            return(converted);
        }
 /// <summary>
 /// Attach DerivedVariable attributes to newly created variables
 /// </summary>
 /// <param name="iae"></param>
 /// <returns></returns>
 protected override IExpression ConvertAssign(IAssignExpression iae)
 {
     iae = (IAssignExpression)base.ConvertAssign(iae);
     if (iae.Expression is IMethodInvokeExpression imie)
     {
         IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iae.Target);
         if (ivd != null)
         {
             bool isDerived = context.InputAttributes.Has <DerivedVariable>(ivd);
             if (!isDerived)
             {
                 FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, imie);
                 if (info.IsDeterministicFactor)
                 {
                     context.InputAttributes.Set(ivd, new DerivedVariable());
                 }
             }
         }
     }
     return(iae);
 }
Beispiel #6
0
        protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
        {
            if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, ICompilerAttribute, PlaceHolder>(Attrib.Var)))
            {
                IVariableReferenceExpression ivre   = imie.Arguments[0] as IVariableReferenceExpression;
                IVariableDeclaration         target = ivre.Variable.Resolve();
                IExpression expr = CodeRecognizer.RemoveCast(imie.Arguments[1]);
                AddAttribute(target, expr);
                return(null);
            }
            else if (Recognizer.IsStaticMethod(imie, new Action <object, object>(Attrib.InitialiseTo)))
            {
                IVariableReferenceExpression ivre   = CodeRecognizer.RemoveCast(imie.Arguments[0]) as IVariableReferenceExpression;
                IVariableDeclaration         target = ivre.Variable.Resolve();
                context.OutputAttributes.Set(target, new InitialiseTo(imie.Arguments[1]));
                return(null);
            }
            else if (CodeRecognizer.IsInfer(imie))
            {
                inferCount++;
                object decl = Recognizer.GetDeclaration(imie.Arguments[0]);
                if (decl != null && !context.InputAttributes.Has <IsInferred>(decl))
                {
                    context.InputAttributes.Set(decl, new IsInferred());
                }
                // the arguments must not be substituted for their values, so we don't call ConvertExpression
                List <IExpression> newArgs = new List <IExpression>();
                foreach (var arg in imie.Arguments)
                {
                    newArgs.Add(CodeRecognizer.RemoveCast(arg));
                }
                IMethodInvokeExpression mie = Builder.MethodInvkExpr();
                mie.Method = imie.Method;
                mie.Arguments.AddRange(newArgs);
                context.InputAttributes.CopyObjectAttributesTo(imie, context.OutputAttributes, mie);
                return(mie);
            }
            IExpression converted = base.ConvertMethodInvoke(imie);

            if (converted is IMethodInvokeExpression)
            {
                var  mie   = (IMethodInvokeExpression)converted;
                bool isAnd = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.And));
                bool isOr  = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.Or));
                bool anyArgumentIsLiteral = mie.Arguments.Any(arg => arg is ILiteralExpression);
                if (anyArgumentIsLiteral)
                {
                    if (isAnd)
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(false)))
                        {
                            return(Builder.LiteralExpr(false));
                        }
                        // any remaining literals must be true, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(true));
                        }
                    }
                    else if (isOr)
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(true)))
                        {
                            return(Builder.LiteralExpr(true));
                        }
                        // any remaining literals must be false, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(false));
                        }
                    }
                    else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool>(Factors.Factor.Not)))
                    {
                        bool allArgumentsAreLiteral = mie.Arguments.All(arg => arg is ILiteralExpression);
                        if (allArgumentsAreLiteral)
                        {
                            return(Builder.LiteralExpr(evaluator.Evaluate(mie)));
                        }
                    }
                }
                foreach (IExpression arg in mie.Arguments)
                {
                    if (arg is IAddressOutExpression)
                    {
                        IAddressOutExpression iaoe = (IAddressOutExpression)arg;
                        IVariableDeclaration  ivd  = Recognizer.GetVariableDeclaration(iaoe.Expression);
                        if (ivd != null)
                        {
                            FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, mie);
                            if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd))
                            {
                                context.InputAttributes.Set(ivd, new DerivedVariable());
                            }
                        }
                    }
                }
            }
            return(converted);
        }
Beispiel #7
0
        protected override IExpression ConvertAssign(IAssignExpression iae)
        {
            IParameterDeclaration ipd = null;
            IVariableDeclaration  ivd = Recognizer.GetVariableDeclaration(iae.Target);
            object decl = ivd;

            if (ivd == null)
            {
                ipd = Recognizer.GetParameterDeclaration(iae.Target);
                if (ipd == null)
                {
                    return(base.ConvertAssign(iae));
                }
                decl = ipd;
            }
            if (iae.Target is IArrayIndexerExpression)
            {
                // Gather index variables from the left-hand side of the assignment
                VariableInformation vi = VariableInformation.GetVariableInformation(context, decl);
                try
                {
                    List <IVariableDeclaration[]> indVars = new List <IVariableDeclaration[]>();
                    Recognizer.AddIndexers(context, indVars, iae.Target);
                    int depth = Recognizer.GetIndexingDepth(iae.Target);
                    // if this statement is actually a constraint, then we don't need to enforce matching of index variables
                    bool isConstraint = context.InputAttributes.Has <Models.Constraint>(context.FindAncestor <IStatement>());
                    for (int i = 0; i < depth; i++)
                    {
                        vi.SetIndexVariablesAtDepth(i, indVars[i], allowMismatch: isConstraint);
                    }
                }
                catch (Exception ex)
                {
                    Error(ex.Message, ex);
                }
            }
            IAssignExpression ae = (IAssignExpression)base.ConvertAssign(iae);

            if (ipd == null)
            {
                // assignment to a local variable
                if (ae.Expression is IMethodInvokeExpression)
                {
                    IMethodInvokeExpression imie = (IMethodInvokeExpression)ae.Expression;
                    // this unfortunately duplicates some of the work done by SetStoch and IsStoch.
                    FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, imie);
                    if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd))
                    {
                        context.InputAttributes.Set(ivd, new DerivedVariable());
                    }
                }
                if (ae.Expression is ILiteralExpression)
                {
                    bool isLoopInitializer = (Recognizer.GetAncestorIndexOfLoopBeingInitialized(context) != -1);
                    if (!isLoopInitializer)
                    {
                        Type valueType = ae.Expression.GetExpressionType();
                        if (Quoter.ShouldInlineType(valueType))
                        {
                            // inline all future occurrences of this variable with the rhs expression
                            conditionContext.Add(new ConditionBinding(ae.Target, ae.Expression));
                        }
                    }
                }
            }
            else
            {
                // assignment to a method parameter
                IStatement ist = context.FindAncestor <IStatement>();
                if (!context.InputAttributes.Has <Models.Constraint>(ist))
                {
                    // mark this statement as a constraint
                    context.OutputAttributes.Set(ist, new Models.Constraint());
                }
            }
            // a FactorAlgorithm attribute on a variable turns into an Algorithm attribute on its right hand side.
            var attr = context.InputAttributes.Get <FactorAlgorithm>(decl);

            if (attr != null)
            {
                context.OutputAttributes.Set(ae.Expression, new Algorithm(attr.algorithm));
            }
            context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(decl, context.OutputAttributes, ae.Expression);
            return(ae);
        }