Ejemplo n.º 1
0
        /// <summary>
        /// Throws an exception if an index expression is not valid for subscripting an array.
        /// </summary>
        /// <param name="index">Index expression</param>
        /// <param name="array">Array that the expression is indexing</param>
        /// <exclude/>
        internal void CheckCompatible(IModelExpression index, IVariableArray array)
        {
            if (IsCompatibleWith(index))
            {
                return;
            }
            string message = StringUtil.TypeToString(array.GetType()) + " " + array + " cannot be indexed by " + index + ".";

            if (index is Range)
            {
                string constructorName = "the constructor";
                message += " Perhaps you omitted " + index + " as an argument to " + constructorName + "?";
            }
            throw new ArgumentException(message, "index");
        }
Ejemplo n.º 2
0
        protected void GetJaggedArrayIndicesAndSizes(IVariableArray array, out IList <IVariableDeclaration[]> jaggedIndexVars, out IList <IExpression[]> jaggedSizes)
        {
            Set <IVariableDeclaration> allVars = new Set <IVariableDeclaration>(ReferenceEqualityComparer <IVariableDeclaration> .Instance);

            jaggedIndexVars = new List <IVariableDeclaration[]>();
            jaggedSizes     = new List <IExpression[]>();
            while (true)
            {
                Type arrayType   = array.GetExpression().GetExpressionType();
                Type elementType = Util.GetElementType(arrayType, out int rank);
                if (!arrayType.IsAssignableFrom(Util.MakeArrayType(elementType, rank)))
                {
                    break;
                }
                GetArrayIndicesAndSizes(array, out IVariableDeclaration[] indexVars, out IExpression[] sizes);
Ejemplo n.º 3
0
        protected void GetArrayIndicesAndSizes(IVariableArray array, out IVariableDeclaration[] indexVars, out IExpression[] sizes)
        {
            IList <Range> ranges = array.Ranges;

            sizes     = new IExpression[ranges.Count];
            indexVars = new IVariableDeclaration[ranges.Count];
            int i = 0;

            foreach (Range r in ranges)
            {
                SearchRange(r);
                indexVars[i] = r.GetIndexDeclaration();
                sizes[i]     = r.GetSizeExpression();
                i++;
            }
        }
Ejemplo n.º 4
0
        protected void GetJaggedArrayIndicesAndSizes(IVariableArray array, out IList <IVariableDeclaration[]> jaggedIndexVars, out IList <IExpression[]> jaggedSizes)
        {
            Set <IVariableDeclaration> allVars = new Set <IVariableDeclaration>(new IdentityComparer <IVariableDeclaration>());

            jaggedIndexVars = new List <IVariableDeclaration[]>();
            jaggedSizes     = new List <IExpression[]>();
            while (true)
            {
                Type arrayType   = array.GetExpression().GetExpressionType();
                Type elementType = Util.GetElementType(arrayType, out int rank);
                if (!arrayType.IsAssignableFrom(Util.MakeArrayType(elementType, rank)))
                {
                    break;
                }
                IVariableDeclaration[] indexVars;
                IExpression[]          sizes;
                GetArrayIndicesAndSizes(array, out indexVars, out sizes);
                foreach (IVariableDeclaration ivd in indexVars)
                {
                    if (allVars.Contains(ivd))
                    {
                        throw new CompilationFailedException("Array '" + array.Name + "' is indexed by range '" + ivd.Name +
                                                             "' on multiple dimensions, which is not allowed.  Use range cloning instead.");
                    }
                    allVars.Add(ivd);
                }
                jaggedIndexVars.Add(indexVars);
                jaggedSizes.Add(sizes);
                if (array is IVariableJaggedArray variableJaggedArray)
                {
                    IVariable itemPrototype = variableJaggedArray.ItemPrototype;
                    if (itemPrototype is IVariableArray variableArray)
                    {
                        array = variableArray;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
        }
Ejemplo n.º 5
0
 private static IModelExpression ReplaceExpressions(IModelExpression expr, Dictionary <IModelExpression, IModelExpression> replacements)
 {
     if (replacements.ContainsKey(expr))
     {
         return(replacements[expr]);
     }
     if (expr is Range)
     {
         return(ReplaceExpressions((Range)expr, replacements));
     }
     else if (expr is Variable)
     {
         Variable v = (Variable)expr;
         if (v.IsArrayElement)
         {
             bool           changed  = false;
             IVariableArray newArray = (IVariableArray)ReplaceExpressions(v.ArrayVariable, replacements);
             if (!ReferenceEquals(newArray, v.ArrayVariable))
             {
                 changed = true;
             }
             IModelExpression[] newIndices = new IModelExpression[v.indices.Count];
             for (int i = 0; i < newIndices.Length; i++)
             {
                 newIndices[i] = ReplaceExpressions(v.indices[i], replacements);
                 if (!ReferenceEquals(newIndices[i], v.indices[i]))
                 {
                     changed = true;
                 }
             }
             if (changed)
             {
                 return
                     ((IModelExpression)
                      Invoker.InvokeMember(newArray.GetType(), "get_Item", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, newArray, newIndices));
             }
         }
     }
     return(expr);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Define a variable in the MSL.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="variable"></param>
        ///
        private void SearchVariable <T>(Variable <T> variable)
        {
            if (searched.Contains(variable))
            {
                return;
            }
            if (variable.IsBase && variable.NameInGeneratedCode != null)
            {
                string name = variable.NameInGeneratedCode;
                foreach (IModelExpression expr in searched)
                {
                    if (name.Equals(expr.Name))
                    {
                        throw new InferCompilerException("Model contains multiple items with the name '" + name + "'.  Names must be unique.");
                    }
                }
            }
            if (variable.IsLoopIndex)
            {
                return;             // do nothing
            }
            searched.Add(variable); // must do this first to prevent re-entry
            SearchContainers(variable.Containers);
            List <IStatementBlock> stBlocks = new List <IStatementBlock>();

            if (variable.IsArrayElement)
            {
                SearchItem(variable);
            }
            else
            {
                // base variable
                // Process dependencies
                if (variable.initialiseTo != null)
                {
                    toSearch.Push(variable.initialiseTo);
                }
                if (variable.initialiseBackwardTo != null)
                {
                    toSearch.Push(variable.initialiseBackwardTo);
                }

                if (!variable.Inline)
                {
                    // Determine if the variable should be inlined
                    bool inline;
                    if (variable.definition != null)
                    {
                        inline = variable.definition.CanBeInlined();
                    }
                    else
                    {
                        inline = (variable.conditionalDefinitions.Values.Count == 1);
                        foreach (MethodInvoke condDef in variable.conditionalDefinitions.Values)
                        {
                            inline = inline && condDef.CanBeInlined();
                        }
                        if (variable is HasItemVariables)
                        {
                            ICollection <IVariable> items = ((HasItemVariables)variable).GetItemsUntyped().Values;
                            if (items.Count > 0)
                            {
                                inline = false;
                            }
                        }
                    }
                    variable.Inline = inline;
                }

                if (variable is IVariableArray)
                {
                    IVariableArray iva = (IVariableArray)variable;
                    IList <IVariableDeclaration[]> jaggedIndexVars;
                    IList <IExpression[]>          jaggedSizes;
                    GetJaggedArrayIndicesAndSizes(iva, out jaggedIndexVars, out jaggedSizes);
                }
                // ivde is null if randVar has been declared at this point.
                if (variable.definition != null)
                {
                    SearchMethodInvoke(variable.definition);
                }

                foreach (var attr in variable.GetAttributes <ICompilerAttribute>())
                {
                    if (attr is ValueRange)
                    {
                        ValueRange vr = (ValueRange)attr;
                        SearchRange(vr.Range);
                    }
                    else if (attr is DistributedCommunication)
                    {
                        DistributedCommunication dc = (DistributedCommunication)attr;
                        toSearch.Push(dc.arrayIndicesToSendExpression);
                        toSearch.Push(dc.arrayIndicesToReceiveExpression);
                        var attr2 = new DistributedCommunicationExpression(dc.arrayIndicesToSendExpression.GetExpression(), dc.arrayIndicesToReceiveExpression.GetExpression());
                        // find the base variable
                        Variable parent = variable;
                        while (parent.ArrayVariable != null)
                        {
                            parent = (Variable)parent.ArrayVariable;
                        }
                        var parentDecl = parent.GetDeclaration();
                        if (Attributes.Has <DistributedCommunicationExpression>(parentDecl))
                        {
                            throw new Exception($"{parent} has multiple DistributedCommunication attributes");
                        }
                        Attributes.Set(parentDecl, attr2);
                    }
                }
            }
            foreach (MethodInvoke condDef in variable.conditionalDefinitions.Values)
            {
                SearchMethodInvoke(condDef);
            }

            if (variable is HasItemVariables)
            {
                // fill the array via the definition of its item variable, if any.
                ICollection <IVariable> ie = ((HasItemVariables)variable).GetItemsUntyped().Values;
                foreach (IVariable irv in ie)
                {
                    toSearch.Push(irv);
                }
            }

            foreach (MethodInvoke constraint in variable.constraints)
            {
                SearchMethodInvoke(constraint);
            }
            foreach (MethodInvoke factor in variable.childFactors)
            {
                SearchMethodInvoke(factor);
            }
        }