/// <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); }
/// <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); } }
/// <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); } }
public Scope CreateChildScope(IRepeatStatement repeat) { if (repeat.IncrementVariable == null) { return(this); } return(new Scope( DeclaredIdentifiers.SetItem(repeat.IncrementVariable.Name, repeat.IncrementVariable), DeclaredDataTypes)); }
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)); }
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); }
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); }
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); }
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); }