protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { context.InputAttributes.Remove <Containers>(ivde.Variable); context.InputAttributes.Set(ivde.Variable, new Containers(context)); IVariableDeclaration ivd = ivde.Variable; if (!CodeRecognizer.IsStochastic(context, ivd)) { ProcessConstant(ivd); if (!context.InputAttributes.Has <DescriptionAttribute>(ivd)) { context.OutputAttributes.Set(ivd, new DescriptionAttribute("The constant '" + ivd.Name + "'")); } return(ivde); } VariableInformation vi = VariableInformation.GetVariableInformation(context, ivd); // Ensure the marginal prototype is set. MarginalPrototype mpa = Context.InputAttributes.Get <MarginalPrototype>(ivd); try { vi.SetMarginalPrototypeFromAttribute(mpa); } catch (ArgumentException ex) { Error(ex.Message); } return(ivde); }
protected override IStatement ConvertExpressionStatement(IExpressionStatement ies) { if (parent == null) { return(ies); } bool keepIfStatement = false; // Only keep the surrounding if statement when a factor or constraint is being added. IExpression expr = ies.Expression; if (expr is IMethodInvokeExpression) { keepIfStatement = true; if (CodeRecognizer.IsInfer(expr)) { keepIfStatement = false; } } else if (expr is IAssignExpression) { keepIfStatement = false; IAssignExpression iae = (IAssignExpression)expr; IMethodInvokeExpression imie = iae.Expression as IMethodInvokeExpression; if (imie != null) { keepIfStatement = true; if (imie.Arguments.Count > 0) { // Statements that copy evidence variables should not send evidence messages. IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iae.Target); IVariableDeclaration ivdArg = Recognizer.GetVariableDeclaration(imie.Arguments[0]); if (ivd != null && context.InputAttributes.Has <DoNotSendEvidence>(ivd) && ivdArg != null && context.InputAttributes.Has <DoNotSendEvidence>(ivdArg)) { keepIfStatement = false; } } } else { expr = iae.Target; } } if (expr is IVariableDeclarationExpression) { IVariableDeclarationExpression ivde = (IVariableDeclarationExpression)expr; IVariableDeclaration ivd = ivde.Variable; keepIfStatement = CodeRecognizer.IsStochastic(context, ivd) && !context.InputAttributes.Has <DoNotSendEvidence>(ivd); } if (!keepIfStatement) { return(ies); } IConditionStatement cs = Builder.CondStmt(parent.Condition, Builder.BlockStmt()); cs.Then.Statements.Add(ies); return(cs); }
protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { bool isDef = Recognizer.IsBeingMutated(context, ivde); if (isDef) { RegisterDepth(ivde, isDef); } return(ivde); }
public override bool Equals(object obj) { if (this == obj) { return(true); } IVariableDeclarationExpression expressionDecl = obj as IVariableDeclarationExpression; if (expressionDecl == null) { return(false); } return(this.Variable.Resolve().Equals(expressionDecl.Variable.Resolve())); }
protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { HoistingInfo info; if (analysis.infoOfVariable.TryGetValue(ivde.Variable, out info) && info.newVariable != null) { IStatement newDeclStmt = Builder.ExprStatement(ivde); IStatement declStmt = context.FindAncestor <IStatement>(); context.InputAttributes.CopyObjectAttributesTo(declStmt, context.OutputAttributes, newDeclStmt); context.AddStatementBeforeCurrent(newDeclStmt); return(Builder.VarDeclExpr(info.newVariable)); } else { return(base.ConvertVariableDeclExpr(ivde)); } }
protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivde); VariableInformation vi = VariableInformation.GetVariableInformation(context, ivd); if (vi.IsStochastic) { UsageInfo info = new UsageInfo(); info.containers = new Containers(context); usageInfo[ivd] = info; } if (Recognizer.GetAncestorIndexOfLoopBeingInitialized(context) != -1) { loopVars.Add(ivd); } return(base.ConvertVariableDeclExpr(ivde)); }
public static IVariableDeclaration GetVariable(IExpression exp) { IVariableDeclarationExpression exp_var_decl = exp as IVariableDeclarationExpression; if (exp_var_decl != null) { return(exp_var_decl.Variable); } IVariableReferenceExpression exp_var_ref = exp as IVariableReferenceExpression; if (exp_var_ref != null) { return(exp_var_ref.Variable.Resolve()); } return(null); }
private static void WriteAssign(LanguageWriter w, IAssignExpression exp) { #if EXTRA_TEMP // 無駄な変数の除去 // 之はその内に StatementAnalyze に引っ越した方が分かりやすいかも知れない // 但し、その場合には式内で代入を行う場合には対応出来ない (例: (i=j)==0 等) IVariableDeclarationExpression target = exp.Target as IVariableDeclarationExpression; IVariableReferenceExpression target2 = exp.Target as IVariableReferenceExpression; IVariableReferenceExpression right = exp.Expression as IVariableReferenceExpression; if (w.ExtraTemporaries != null) { // 無駄変数の宣言 if (target != null) { for (int i = 0; i < w.ExtraTemporaries.Length; i++) { if (!w.EssentialTemporaries[i] && target.Variable.Name == w.ExtraTemporaries[i]) { return; } } } // 無駄変数から無駄変数への受け渡し if (target2 != null && right != null) { int iTarget = -1; int iRight = -1; for (int j = 0; j < w.ExtraTemporaries.Length; j++) { if (target2.Variable.ToString() == w.ExtraTemporaries[j]) { iTarget = j; w.VerifyCorrectBlock(j); } if (right.Variable.ToString() == w.ExtraTemporaries[j]) { iRight = j; w.VerifyCorrectBlock(j); } } if (iTarget >= 0 && !w.EssentialTemporaries[iTarget]) { string str; if (iRight >= 0 && !w.EssentialTemporaries[iRight]) { if (w.ExtraMappings[iRight] == null) { w.EssentialTemporaries[iRight] = true; str = null; } else { str = w.ExtraMappings[iRight]; } } else { str = right.Variable.ToString(); } if (str != null && target2.Variable.ToString()[0] == str[0]) { w.ExtraMappings[iTarget] = str; return; } } } } #endif WriteExpression(w, exp.Target, false); w.Write(" = "); WriteExpression(w, exp.Expression, false); }
public virtual void VisitVariableDeclarationExpression(IVariableDeclarationExpression value) { VisitVariableDeclaration(value.Variable); }
public virtual void VisitVariableDeclarationExpression(IVariableDeclarationExpression value) { this.VisitVariableDeclaration(value.Variable); }
/// <summary> /// Converts a variable declaration by creating definition, marginal and uses channel variables. /// </summary> protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { IVariableDeclaration ivd = ivde.Variable; VariableInformation vi = VariableInformation.GetVariableInformation(context, ivd); // If the variable is deterministic, return bool isInferred = context.InputAttributes.Has <IsInferred>(ivd); if (!vi.IsStochastic) { return(ivde); } bool suppressVariableFactor = context.InputAttributes.Has <SuppressVariableFactor>(ivd); bool isDerived = context.InputAttributes.Has <DerivedVariable>(ivd); bool isStochastic = vi.IsStochastic; int useCount; ChannelAnalysisTransform.UsageInfo info; if (!analysis.usageInfo.TryGetValue(ivd, out info)) { useCount = 0; } else { useCount = info.NumberOfUsesOld; } if (!(algorithm is Algorithms.GibbsSampling) && isStochastic && !suppressVariableFactor && (useCount <= 1) && !isInferred && isDerived) { // this is optional suppressVariableFactor = true; context.InputAttributes.Set(ivd, new SuppressVariableFactor()); } context.InputAttributes.Remove <LoopContext>(ivd); context.InputAttributes.Set(ivd, new LoopContext(context)); // Create variable-to-channel information for the variable. VariableToChannelInformation vtci = new VariableToChannelInformation(); vtci.shareAllUses = (useCount <= 1); Context.InputAttributes.Set(ivd, vtci); // Create the definition channel vtci.defChannel = ChannelInfo.DefChannel(vi); vtci.defChannel.decl = ivd; // Always create a variable factor for a stochastic variable if (isInferred || (isStochastic && !suppressVariableFactor)) { vi.DefineAllIndexVars(context); IList <IStatement> stmts = Builder.StmtCollection(); // Create marginal channel CreateMarginalChannel(vi, vtci, stmts); if (algorithm is GibbsSampling && ((GibbsSampling)algorithm).UseSideChannels) { CreateSamplesChannel(vi, vtci, stmts); CreateConditionalsChannel(vi, vtci, stmts); } else { vtci.samplesChannel = vtci.marginalChannel; vtci.conditionalsChannel = vtci.marginalChannel; } if (isStochastic) { // Create uses channel CreateUsesChannel(vi, useCount, vtci, stmts); } //setAllGroupRoots(context, ivd, false); context.AddStatementsBeforeCurrent(stmts); // Append usageDepth indices to def/marginal/use expressions IExpression defExpr = Builder.VarRefExpr(ivd); IExpression marginalExpr = Builder.VarRefExpr(vtci.marginalChannel.decl); IExpression countExpr = Builder.LiteralExpr(useCount); // Add clone factor tying together all of the channels IMethodInvokeExpression variableFactorExpr; Type[] genArgs = new Type[] { vi.varType }; if (algorithm is GibbsSampling && ((GibbsSampling)algorithm).UseSideChannels) { GibbsSampling gs = (GibbsSampling)algorithm; IExpression burnInExpr = Builder.LiteralExpr(gs.BurnIn); IExpression thinExpr = Builder.LiteralExpr(gs.Thin); IExpression samplesExpr = Builder.VarRefExpr(vtci.samplesChannel.decl); IExpression conditionalsExpr = Builder.VarRefExpr(vtci.conditionalsChannel.decl); if (isDerived) { Delegate d = new FuncOut3 <PlaceHolder, int, int, int, PlaceHolder, PlaceHolder, PlaceHolder, PlaceHolder[]>(Clone.ReplicateWithMarginalGibbs); variableFactorExpr = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, burnInExpr, thinExpr, marginalExpr, samplesExpr, conditionalsExpr); } else { Delegate d = new FuncOut3 <PlaceHolder, int, int, int, PlaceHolder, PlaceHolder, PlaceHolder, PlaceHolder[]>(Clone.UsesEqualDefGibbs); variableFactorExpr = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, burnInExpr, thinExpr, marginalExpr, samplesExpr, conditionalsExpr); } } else { Delegate d; if (isDerived) { d = new FuncOut <PlaceHolder, int, PlaceHolder, PlaceHolder[]>(Clone.ReplicateWithMarginal <PlaceHolder>); } else { d = new FuncOut <PlaceHolder, int, PlaceHolder, PlaceHolder[]>(Clone.UsesEqualDef <PlaceHolder>); } variableFactorExpr = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, marginalExpr); } if (isDerived) { context.OutputAttributes.Set(variableFactorExpr, new DerivedVariable()); // used by Gibbs } // Mark this as a pseudo-factor context.OutputAttributes.Set(variableFactorExpr, new IsVariableFactor()); if (useCount <= 1) { context.OutputAttributes.Set(variableFactorExpr, new DivideMessages(false)); } else { context.InputAttributes.CopyObjectAttributesTo <DivideMessages>(ivd, context.OutputAttributes, variableFactorExpr); } context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(ivd, context.OutputAttributes, variableFactorExpr); if (vtci.usageChannel != null) { IExpression usageExpr = Builder.VarRefExpr(vtci.usageChannel.decl); IAssignExpression assignExpr = Builder.AssignExpr(usageExpr, variableFactorExpr); // Copy attributes across from input to output Context.InputAttributes.CopyObjectAttributesTo <Algorithm>(ivd, context.OutputAttributes, assignExpr); context.OutputAttributes.Remove <InitialiseTo>(ivd); if (vi.ArrayDepth == 0) { // Insert the UsesEqualDef statement after the declaration. // Note the variable will not have been defined yet. context.AddStatementAfterCurrent(Builder.ExprStatement(assignExpr)); } else { // For an array, the UsesEqualDef statement should be inserted after the array is allocated. // Store the statement for later use by ConvertArrayCreate. context.InputAttributes.Remove <LoopContext>(ivd); context.InputAttributes.Set(ivd, new LoopContext(context)); context.InputAttributes.Remove <Containers>(ivd); context.InputAttributes.Set(ivd, new Containers(context)); vtci.usesEqualDefsStatements = Builder.StmtCollection(); vtci.usesEqualDefsStatements.Add(Builder.ExprStatement(assignExpr)); } } } // These must be set after the above or they will be copied to the other channels if (isStochastic) { context.OutputAttributes.Set(ivd, vtci.defChannel); } if (!context.InputAttributes.Has <DescriptionAttribute>(vtci.defChannel.decl)) { context.OutputAttributes.Set(vtci.defChannel.decl, new DescriptionAttribute("definition of '" + ivd.Name + "'")); } return(ivde); }
//=========================================================== // Expression 分岐 //=========================================================== public virtual void WriteExpression(IExpression expression) { if (expression == null) { return; } mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, false); #if FALSE #pragma warning disable 612 IMemberInitializerExpression expression3 = expression as IMemberInitializerExpression; if (expression3 != null) { this.WriteMemberInitializerExpression(expression3); return; } IAddressOutExpression expression27 = expression as IAddressOutExpression; if (expression27 != null) { this.WriteAddressOutExpression(expression27); return; } IAddressReferenceExpression expression26 = expression as IAddressReferenceExpression; if (expression26 != null) { this.WriteAddressReferenceExpression(expression26); return; } IDelegateCreateExpression iDelegateCreateExpression = expression as IDelegateCreateExpression; if (iDelegateCreateExpression != null) { this.WriteDelegateCreateExpression(iDelegateCreateExpression); return; } IMethodInvokeExpression iMethodInvokeExpression = expression as IMethodInvokeExpression; if (iMethodInvokeExpression != null) { this.WriteMethodInvokeExpression(iMethodInvokeExpression); return; } IVariableDeclarationExpression expression15 = expression as IVariableDeclarationExpression; if (expression15 != null) { this.WriteVariableDeclaration(expression15.Variable); return; } ITypeOfExpression iTypeOfExpression = expression as ITypeOfExpression; if (iTypeOfExpression != null) { this.WriteTypeOfExpression(iTypeOfExpression); return; } ISnippetExpression iSnippetExpression = expression as ISnippetExpression; if (iSnippetExpression != null) { this.WriteSnippetExpression(iSnippetExpression); return; } IUnaryExpression iUnaryExpression = expression as IUnaryExpression; if (iUnaryExpression != null) { this.WriteUnaryExpression(iUnaryExpression); return; } IObjectCreateExpression iObjectCreateExpression = expression as IObjectCreateExpression; if (iObjectCreateExpression != null) { this.WriteObjectCreateExpression(iObjectCreateExpression); return; } IVariableReferenceExpression iVariableReferenceExpression = expression as IVariableReferenceExpression; if (iVariableReferenceExpression != null) { this.WriteVariableReferenceExpression(iVariableReferenceExpression); return; } IThisReferenceExpression expression12 = expression as IThisReferenceExpression; if (expression12 != null) { this.WriteThisReferenceExpression(expression12); return; } ITryCastExpression iTryCastExpression = expression as ITryCastExpression; if (iTryCastExpression != null) { this.WriteTryCastExpression(iTryCastExpression); return; } IConditionExpression expression9 = expression as IConditionExpression; if (expression9 != null) { this.WriteConditionExpression(expression9); return; } IFieldReferenceExpression iFieldReferenceExpression = expression as IFieldReferenceExpression; if (iFieldReferenceExpression != null) { this.WriteFieldReferenceExpression(iFieldReferenceExpression); return; } IPropertyIndexerExpression iPropertyIndexerExpression = expression as IPropertyIndexerExpression; if (iPropertyIndexerExpression != null) { this.WritePropertyIndexerExpression(iPropertyIndexerExpression); return; } ITypeReferenceExpression iTypeReferenceExpression = expression as ITypeReferenceExpression; if (iTypeReferenceExpression != null) { this.WriteTypeReferenceExpression(iTypeReferenceExpression); return; } IMethodReferenceExpression iMethodReferenceExpression = expression as IMethodReferenceExpression; if (iMethodReferenceExpression != null) { this.WriteMethodReferenceExpression(iMethodReferenceExpression); return; } IPropertyReferenceExpression iPropertyReferenceExpression = expression as IPropertyReferenceExpression; if (iPropertyReferenceExpression != null) { this.WritePropertyReferenceExpression(iPropertyReferenceExpression); return; } ICastExpression expression5 = expression as ICastExpression; if (expression5 != null) { this.WriteCastExpression(expression5); return; } ICanCastExpression iCanCastExpression = expression as ICanCastExpression; if (iCanCastExpression != null) { this.WriteCanCastExpression(iCanCastExpression); return; } ICastExpression iCastExpression = expression as ICastExpression; if (iCastExpression != null) { this.WriteCastExpression(iCastExpression); return; } ILiteralExpression literalExpression = expression as ILiteralExpression; if (literalExpression != null) { this.WriteLiteralExpression(literalExpression); return; } IBinaryExpression iBinaryExpression = expression as IBinaryExpression; if (iBinaryExpression != null) { mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, true); //this.WriteBinaryExpression(iBinaryExpression); return; } IArrayIndexerExpression expression30 = expression as IArrayIndexerExpression; if (expression30 != null) { this.WriteArrayIndexerExpression(expression30); return; } IAddressDereferenceExpression expression29 = expression as IAddressDereferenceExpression; if (expression29 != null) { this.WriteAddressDereferenceExpression(expression29); return; } IAddressOfExpression expression28 = expression as IAddressOfExpression; if (expression28 != null) { this.WriteAddressOfExpression(expression28); return; } IArgumentListExpression expression25 = expression as IArgumentListExpression; if (expression25 != null) { this.WriteArgumentListExpression(expression25); return; } IBaseReferenceExpression iBaseReferenceExpression = expression as IBaseReferenceExpression; if (iBaseReferenceExpression != null) { this.WriteBaseReferenceExpression(iBaseReferenceExpression); return; } IArgumentReferenceExpression expression13 = expression as IArgumentReferenceExpression; if (expression13 != null) { this.WriteArgumentReferenceExpression(expression13); return; } IArrayCreateExpression expression10 = expression as IArrayCreateExpression; if (expression10 != null) { this.WriteArrayCreateExpression(expression10); return; } IAssignExpression iAssignExpression = expression as IAssignExpression; if (iAssignExpression != null) { this.WriteAssignExpression(iAssignExpression); return; } IBlockExpression expression2 = expression as IBlockExpression; if (expression2 != null) { this.WriteBlockExpression(expression2); return; } #pragma warning restore 612 this.Write(expression.ToString()); #endif }
//=========================================================== // using の変換 //=========================================================== /// <summary> /// Using 文を他の構文に変換して、yields に変換後の Statement を書き込みます。 /// </summary> /// <param name="yields">変換後の Statement の書き込み先を指定します。</param> /// <param name="state">using 構文を表現する Statement を指定します。</param> /// <param name="last">state が Statements の中で最後の Statement か否かを指定します。</param> public static void TransformUsingStatement(Gen::List <IStatement> yields, IUsingStatement state, bool last) { // 変数の宣言の場合 IAssignExpression assig = state.Expression as IAssignExpression; if (assig != null) { do { IVariableDeclarationExpression var_decl_x = assig.Target as IVariableDeclarationExpression; if (var_decl_x == null) { continue; } IVariableDeclaration var_decl = var_decl_x.Variable as IVariableDeclaration; if (var_decl == null) { continue; } IObjectCreateExpression exp_create = assig.Expression as IObjectCreateExpression; if (exp_create != null) { LocalRefVariableStatement s_lr = new LocalRefVariableStatement(var_decl, assig.Expression, state.Body); s_lr.noblock = last; yields.Add(s_lr); } else { //yields.Add(new ExpressionStatement(assig)); //yields.Add(state.Body); //yields.Add(new DeleteStatement(new VariableReferenceExpression(var_decl))); //↑ 中で例外が起こったときのことを考えていない。 // 宣言部分と代入部分を分離 IStatement s_decl = new ExpressionStatement(var_decl_x); IStatement s_asgn = new ExpressionStatement( new AssignExpression( new VariableReferenceExpression(var_decl), assig.Expression ) ); IStatement s_delete = new DeleteStatement(new VariableReferenceExpression(var_decl)); // 宣言 yields.Add(s_decl); // try-finally BlockStatement try_block = new BlockStatement(); try_block.Statements.Add(s_asgn); try_block.Statements.AddRange(state.Body.Statements); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(try_block); s_tcf.Finally = finally_block; yields.Add(s_tcf); } return; }while(false); throw new InterfaceNotImplementedException("×実装中×", typeof(IVariableDeclarationExpression), assig.Target); } // 変数の参照の場合 IVariableReferenceExpression varref = state.Expression as IVariableReferenceExpression; if (varref != null) { IStatement s_delete = new DeleteStatement(varref); // try-finally TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(state.Body); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); s_tcf.Finally = finally_block; yields.Add(s_tcf); return; } throw new InterfaceNotImplementedException( "Unexpected using-statement expression interface (expects IAssignExpression or IVariableReferenceExpression)", typeof(IAssignExpression), state.Expression); }
private void WriteVariableList(IVariableDeclarationExpression expression, IFormatter formatter, ref bool hasvar) { if (expression != null) WriteVariableListEntry(expression.Variable, formatter, ref hasvar); }
private void WriteVariableDeclarationExpression(IVariableDeclarationExpression expression, IFormatter formatter) { // this.WriteVariableDeclaration(formatter, expression.Variable); // this is for C# // // no variable declaration expression in Delphi. Convert this to a variable reference only! this.WriteVariableReference(expression.Variable, formatter); }
/// <summary> /// Converts a variable declaration by creating definition, marginal and uses channel variables. /// </summary> protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { IVariableDeclaration ivd = ivde.Variable; VariableInformation vi = VariableInformation.GetVariableInformation(context, ivd); // If the variable is deterministic, return if (!vi.IsStochastic) { ProcessConstant(ivd); context.OutputAttributes.Set(ivd, new DescriptionAttribute("The constant '" + ivd.Name + "'")); return(ivde); } bool suppressVariableFactor = context.InputAttributes.Has <SuppressVariableFactor>(ivd); bool isDerived = context.InputAttributes.Has <DerivedVariable>(ivd); bool isConstant = false; bool isInferred = context.InputAttributes.Has <IsInferred>(ivd); int useCount; ChannelAnalysisTransform.UsageInfo info; if (!analysis.usageInfo.TryGetValue(ivd, out info)) { useCount = 0; } else { useCount = info.NumberOfUsesOld; } if (!(algorithm is Algorithms.GibbsSampling) && !isConstant && !suppressVariableFactor && (useCount == 1) && !isInferred && isDerived) { // this is optional suppressVariableFactor = true; context.InputAttributes.Set(ivd, new SuppressVariableFactor()); } context.InputAttributes.Remove <LoopContext>(ivd); context.InputAttributes.Set(ivd, new LoopContext(context)); // Create variable-to-channel information for the variable. VariableToChannelInformation vtc = new VariableToChannelInformation(); vtc.shareAllUses = (useCount == 1); Context.InputAttributes.Set(ivd, vtc); // Ensure the marginal prototype is set. MarginalPrototype mpa = Context.InputAttributes.Get <MarginalPrototype>(ivd); try { vi.SetMarginalPrototypeFromAttribute(mpa); } catch (ArgumentException ex) { Error(ex.Message); } // Create the definition channel vtc.defChannel = ChannelInfo.DefChannel(vi); vtc.defChannel.decl = ivd; // Always create a variable factor for a stochastic variable if (!isConstant && !suppressVariableFactor) { vi.DefineAllIndexVars(context); IList <IStatement> stmts = Builder.StmtCollection(); // Create marginal channel vtc.marginalChannel = ChannelInfo.MarginalChannel(vi); vtc.marginalChannel.decl = vi.DeriveIndexedVariable(stmts, context, vi.Name + "_marginal"); context.InputAttributes.CopyObjectAttributesTo <InitialiseTo>(vi.declaration, context.OutputAttributes, vtc.marginalChannel.decl); context.OutputAttributes.Set(vtc.marginalChannel.decl, vtc.marginalChannel); context.OutputAttributes.Set(vtc.marginalChannel.decl, new DescriptionAttribute("marginal of '" + ivd.Name + "'")); SetMarginalPrototype(vtc.marginalChannel.decl); if (algorithm is GibbsSampling && ((GibbsSampling)algorithm).UseSideChannels) { Type marginalType = MessageTransform.GetDistributionType(vi.varType, vi.InnermostElementType, vi.marginalPrototypeExpression.GetExpressionType(), true); Type domainType = ivd.VariableType.DotNetType; vtc.samplesChannel = ChannelInfo.MarginalChannel(vi); vtc.samplesChannel.decl = vi.DeriveIndexedVariable(stmts, context, vi.Name + "_samples"); context.OutputAttributes.Remove <InitialiseTo>(vtc.samplesChannel.decl); context.OutputAttributes.Set(vtc.samplesChannel.decl, vtc.samplesChannel); context.OutputAttributes.Set(vtc.samplesChannel.decl, new DescriptionAttribute("samples of '" + ivd.Name + "'")); Type samplesType = typeof(List <>).MakeGenericType(domainType); IExpression samples_mpe = Builder.NewObject(samplesType); VariableInformation samples_vi = VariableInformation.GetVariableInformation(context, vtc.samplesChannel.decl); samples_vi.marginalPrototypeExpression = samples_mpe; vtc.conditionalsChannel = ChannelInfo.MarginalChannel(vi); vtc.conditionalsChannel.decl = vi.DeriveIndexedVariable(stmts, context, vi.Name + "_conditionals"); context.OutputAttributes.Remove <InitialiseTo>(vtc.conditionalsChannel.decl); context.OutputAttributes.Set(vtc.conditionalsChannel.decl, vtc.conditionalsChannel); context.OutputAttributes.Set(vtc.conditionalsChannel.decl, new DescriptionAttribute("conditionals of '" + ivd.Name + "'")); Type conditionalsType = typeof(List <>).MakeGenericType(marginalType); IExpression conditionals_mpe = Builder.NewObject(conditionalsType); VariableInformation conditionals_vi = VariableInformation.GetVariableInformation(context, vtc.conditionalsChannel.decl); conditionals_vi.marginalPrototypeExpression = conditionals_mpe; } else { vtc.samplesChannel = vtc.marginalChannel; vtc.conditionalsChannel = vtc.marginalChannel; } // Create uses channel vtc.usageChannel = ChannelInfo.UseChannel(vi); vtc.usageChannel.decl = vi.DeriveArrayVariable(stmts, context, vi.Name + "_uses", Builder.LiteralExpr(useCount), Builder.VarDecl("_ind", typeof(int)), useLiteralIndices: true); context.InputAttributes.CopyObjectAttributesTo <InitialiseTo>(vi.declaration, context.OutputAttributes, vtc.usageChannel.decl); context.OutputAttributes.Set(vtc.usageChannel.decl, vtc.usageChannel); context.OutputAttributes.Set(vtc.usageChannel.decl, new DescriptionAttribute("uses of '" + ivd.Name + "'")); SetMarginalPrototype(vtc.usageChannel.decl); //setAllGroupRoots(context, ivd, false); context.AddStatementsBeforeCurrent(stmts); // Append usageDepth indices to def/marginal/use expressions IExpression defExpr = Builder.VarRefExpr(ivd); IExpression marginalExpr = Builder.VarRefExpr(vtc.marginalChannel.decl); IExpression usageExpr = Builder.VarRefExpr(vtc.usageChannel.decl); IExpression countExpr = Builder.LiteralExpr(useCount); // Add clone factor tying together all of the channels IMethodInvokeExpression usesEqualDefExpression; Type[] genArgs = new Type[] { vi.varType }; if (algorithm is GibbsSampling && ((GibbsSampling)algorithm).UseSideChannels) { GibbsSampling gs = (GibbsSampling)algorithm; IExpression burnInExpr = Builder.LiteralExpr(gs.BurnIn); IExpression thinExpr = Builder.LiteralExpr(gs.Thin); IExpression samplesExpr = Builder.VarRefExpr(vtc.samplesChannel.decl); IExpression conditionalsExpr = Builder.VarRefExpr(vtc.conditionalsChannel.decl); if (isDerived) { Delegate d = new FuncOut3 <PlaceHolder, int, int, int, PlaceHolder, PlaceHolder, PlaceHolder, PlaceHolder[]>(Factor.ReplicateWithMarginalGibbs); usesEqualDefExpression = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, burnInExpr, thinExpr, marginalExpr, samplesExpr, conditionalsExpr); } else { Delegate d = new FuncOut3 <PlaceHolder, int, int, int, PlaceHolder, PlaceHolder, PlaceHolder, PlaceHolder[]>(Factor.UsesEqualDefGibbs); usesEqualDefExpression = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, burnInExpr, thinExpr, marginalExpr, samplesExpr, conditionalsExpr); } } else { Delegate d; if (isDerived) { d = new FuncOut <PlaceHolder, int, PlaceHolder, PlaceHolder[]>(Factor.ReplicateWithMarginal <PlaceHolder>); } else { d = new FuncOut <PlaceHolder, int, PlaceHolder, PlaceHolder[]>(Factor.UsesEqualDef <PlaceHolder>); } usesEqualDefExpression = Builder.StaticGenericMethod(d, genArgs, defExpr, countExpr, marginalExpr); } if (isDerived) { context.OutputAttributes.Set(usesEqualDefExpression, new DerivedVariable()); // used by Gibbs } // Mark this as a pseudo-factor context.OutputAttributes.Set(usesEqualDefExpression, new IsVariableFactor()); if (useCount == 1) { context.OutputAttributes.Set(usesEqualDefExpression, new DivideMessages(false)); } else { context.InputAttributes.CopyObjectAttributesTo <DivideMessages>(ivd, context.OutputAttributes, usesEqualDefExpression); } context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(ivd, context.OutputAttributes, usesEqualDefExpression); IAssignExpression assignExpr = Builder.AssignExpr(usageExpr, usesEqualDefExpression); // Copy attributes across from input to output Context.InputAttributes.CopyObjectAttributesTo <Algorithm>(ivd, context.OutputAttributes, assignExpr); context.OutputAttributes.Remove <InitialiseTo>(ivd); if (vi.ArrayDepth == 0) { // Insert the UsesEqualDef statement after the declaration. // Note the variable will not have been defined yet. context.AddStatementAfterCurrent(Builder.ExprStatement(assignExpr)); } else { // For an array, the UsesEqualDef statement should be inserted after the array is allocated. // Store the statement for later use by ConvertArrayCreate. context.InputAttributes.Remove <LoopContext>(ivd); context.InputAttributes.Set(ivd, new LoopContext(context)); context.InputAttributes.Remove <Containers>(ivd); context.InputAttributes.Set(ivd, new Containers(context)); vtc.usesEqualDefsStatements = Builder.StmtCollection(); vtc.usesEqualDefsStatements.Add(Builder.ExprStatement(assignExpr)); } } // These must be set after the above or they will be copied to the other channels context.OutputAttributes.Set(ivd, vtc.defChannel); context.OutputAttributes.Set(vtc.defChannel.decl, new DescriptionAttribute("definition of '" + ivd.Name + "'")); return(ivde); }
/// <summary> /// Converts variable declarations inside loops into array declarations at the top level. /// </summary> /// <param name="ivde"></param> /// <returns></returns> protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { IVariableDeclaration ivd = ivde.Variable; bool isLoneDeclaration = (context.FindAncestorIndex <IExpressionStatement>() == context.Depth - 2); List <IForStatement> loops = context.FindAncestors <IForStatement>(); if (loops.Count == 0) { List <IConditionStatement> ifs = context.FindAncestors <IConditionStatement>(); if (ifs.Count == 0) { return(ivde); } // Add declaration outside the if IStatement outermostContainer = ifs[0]; int ancIndex = context.GetAncestorIndex(outermostContainer); var defaultExpr = Builder.DefaultExpr(ivd.VariableType); var assignSt = Builder.AssignStmt(ivde, defaultExpr); context.OutputAttributes.Set(assignSt, new Initializer()); context.AddStatementBeforeAncestorIndex(ancIndex, assignSt); if (isLoneDeclaration) { return(null); } else { return(Builder.VarRefExpr(ivd)); } } // ignore declaration of a loop variable if (Recognizer.LoopVariable(loops[loops.Count - 1]) == ivd) { return(ivde); } // Declaration is inside one or more loops, find their sizes and index variables Type type = Builder.ToType(ivd.VariableType); Type arrayType = type; LoopVarInfo lvi = new LoopVarInfo(loops); for (int i = 0; i < loops.Count; i++) { IForStatement loop = loops[i]; lvi.indexVarRefs[i] = Builder.VarRefExpr(Recognizer.LoopVariable(loop)); arrayType = Util.MakeArrayType(arrayType, 1); } Predicate <int> isPartitionedAtDepth = (depth => context.InputAttributes.Has <Partitioned>(Recognizer.GetVariableDeclaration(lvi.indexVarRefs[depth]))); Type messageType = Distributions.Distribution.IsDistributionType(type) ? MessageTransform.GetDistributionType(arrayType, type, type, 0, loops.Count, isPartitionedAtDepth) : MessageTransform.GetArrayType(arrayType, type, 0, isPartitionedAtDepth); lvi.arrayvd = Builder.VarDecl(ivd.Name, messageType); loopVarInfos[ivd] = lvi; MessageArrayInformation mai = context.InputAttributes.Get <MessageArrayInformation>(ivd); if (mai != null) { mai.loopVarInfo = lvi; } context.InputAttributes.CopyObjectAttributesTo(ivd, context.OutputAttributes, lvi.arrayvd); context.InputAttributes.Remove <VariableInformation>(lvi.arrayvd); VariableInformation vi = VariableInformation.GetVariableInformation(context, ivd); VariableInformation vi2 = VariableInformation.GetVariableInformation(context, lvi.arrayvd); vi2.IsStochastic = vi.IsStochastic; // Initialise the array to the appropriate sizes // TODO: change to work over loop brackets not loops IExpression expr = Builder.VarDeclExpr(lvi.arrayvd); for (int i = 0; i < loops.Count; i++) { IForStatement loop = loops[i]; IExpression loopSize = Recognizer.LoopSizeExpression(loop); IExpressionStatement assignSt = Builder.AssignStmt(expr, MessageTransform.GetArrayCreateExpression(expr, expr.GetExpressionType(), new IExpression[] { loopSize })); context.OutputAttributes.Set(assignSt.Expression, new DescriptionAttribute("Create array for replicates of '" + ivd.Name + "'")); context.OutputAttributes.Set(assignSt, new Initializer()); if (expr is IVariableDeclarationExpression) { expr = Builder.VarRefExpr(lvi.arrayvd); } expr = Builder.ArrayIndex(expr, lvi.indexVarRefs[i]); vi2.indexVars.Add(new IVariableDeclaration[] { Recognizer.GetVariableDeclaration(lvi.indexVarRefs[i]) }); vi2.sizes.Add(new IExpression[] { loopSize }); // Add declaration outside the loop int ancIndex = context.GetAncestorIndex(loop); context.AddStatementBeforeAncestorIndex(ancIndex, assignSt); } vi2.indexVars.AddRange(vi.indexVars); vi2.sizes.AddRange(vi.sizes); // If the variable declaration was a statement by itself, then return null (i.e. delete the statement). if (isLoneDeclaration) { return(null); } // Return a reference to the newly created array else { return(expr); } }
/// <summary> /// Add the definition of a random variable to the MSL, inside of the necessary containers. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="variable"></param> /// <remarks> /// A scalar variable is declared and defined in one line such as: <c>int x = factor(...);</c>. /// An array variable is first declared with an initializer such as: <c>int[] array = new int[4];</c>. /// Then it is defined either with a bulk factor such as: <c>array = factor(...);</c>, /// or it is defined via its item variable. /// An item variable is defined by 'for' loop whose body is: <c>array[i] = factor(...);</c>. /// </remarks> protected void BuildRandVar <T>(Variable <T> variable) { if (!variable.IsDefined) { throw new InferCompilerException("Variable '" + variable + "' has no definition"); } if (variable.IsArrayElement) { for (int initType = 0; initType < 2; initType++) { IModelExpression init = (initType == 0) ? variable.initialiseTo : variable.initialiseBackwardTo; if (init != null) { IExpression initExpr = init.GetExpression(); // find the base variable Variable parent = variable; while (parent.ArrayVariable != null) { IVariableDeclaration[] indexVars = new IVariableDeclaration[parent.indices.Count]; for (int i = 0; i < indexVars.Length; i++) { IModelExpression expr = parent.indices[i]; if (!(expr is Range)) { throw new Exception(parent + ".InitializeTo is not allowed since the indices are not ranges"); } indexVars[i] = ((Range)expr).GetIndexDeclaration(); } initExpr = VariableInformation.MakePlaceHolderArrayCreate(initExpr, indexVars); parent = (Variable)parent.ArrayVariable; } IVariableDeclaration parentDecl = (IVariableDeclaration)parent.GetDeclaration(); ICompilerAttribute attr; if (initType == 0) { attr = new InitialiseTo(initExpr); } else { attr = new InitialiseBackwardTo(initExpr); } Attributes.Set(parentDecl, attr); } } return; } IVariableDeclaration ivd = (IVariableDeclaration)variable.GetDeclaration(); if (variable.initialiseTo != null) { Attributes.Set(ivd, new InitialiseTo(variable.initialiseTo.GetExpression())); } if (variable.initialiseBackwardTo != null) { Attributes.Set(ivd, new InitialiseBackwardTo(variable.initialiseBackwardTo.GetExpression())); } List <IStatementBlock> stBlocks = new List <IStatementBlock>(); stBlocks.AddRange(variable.Containers); IVariableDeclarationExpression ivde = Builder.VarDeclExpr(ivd); if (variable is IVariableArray iva) { IList <IStatement> sc = Builder.StmtCollection(); IList <IVariableDeclaration[]> jaggedIndexVars; IList <IExpression[]> jaggedSizes; GetJaggedArrayIndicesAndSizes(iva, out jaggedIndexVars, out jaggedSizes); // check that containers are all unique and distinct from jaggedIndexVars Set <IVariableDeclaration> loopVars = new Set <IVariableDeclaration>(); foreach (IStatementBlock stBlock in stBlocks) { if (stBlock is ForEachBlock fb) { IVariableDeclaration loopVar = fb.Range.GetIndexDeclaration(); if (loopVars.Contains(loopVar)) { throw new InvalidOperationException("Variable '" + ivd.Name + "' uses range '" + loopVar.Name + "' twice. Use a cloned range instead."); } loopVars.Add(loopVar); } } foreach (IVariableDeclaration[] bracket in jaggedIndexVars) { foreach (IVariableDeclaration indexVar in bracket) { if (loopVars.Contains(indexVar)) { throw new InvalidOperationException("Variable '" + ivd.Name + "' uses range '" + indexVar.Name + "' twice. Use a cloned range instead."); } } } Builder.NewJaggedArray(sc, ivd, jaggedIndexVars, jaggedSizes); if (!variable.Inline) { BuildStatementBlocks(stBlocks, true); foreach (IStatement stmt in sc) { AddStatement(stmt); } BuildStatementBlocks(stBlocks, false); } ivde = null; // prevent re-declaration } if (ivde != null) { if (!variable.Inline) { BuildStatementBlocks(stBlocks, true); AddStatement(Builder.ExprStatement(ivde)); BuildStatementBlocks(stBlocks, false); } ivde = null; } if (ivde != null) { throw new InferCompilerException("Variable '" + variable + "' has no definition"); } }
/// <summary> /// Record the containers that a variable is created in, for use by HoistingTransform. /// </summary> /// <param name="ivde"></param> /// <returns></returns> protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde) { context.InputAttributes.Remove <Containers>(ivde.Variable); context.InputAttributes.Set(ivde.Variable, new Containers(context)); return(ivde); }
public virtual IExpression TransformVariableDeclarationExpression(IVariableDeclarationExpression value) { value.Variable = this.TransformVariableDeclaration(value.Variable); return value; }