/// <summary> /// Encode this assignment as a single statement /// </summary> /// <param name="model"></param> /// <returns></returns> public override ExpressionBDDEncoding TranslateBoolExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); ExpressionBDDEncoding variableBddEncoding = new PrimitiveApplication(PrimitiveApplication.ARRAYPRIME, this.RecordExpression, this.PropertyExpression).TranslateIntExpToBDD(model); ExpressionBDDEncoding valueBddEncoding = this.RightHandExpression.TranslateIntExpToBDD(model); for (int i = 0; i < variableBddEncoding.Count(); i++) { for (int j = 0; j < valueBddEncoding.Count(); j++) { CUDD.Ref(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); CUDDNode guardDD = CUDD.Function.And(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); if (guardDD.Equals(CUDD.ZERO)) { CUDD.Deref(guardDD); continue; } CUDD.Ref(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); CUDDNode assignmentDD = CUDD.Function.Equal(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); guardDD = CUDD.Function.And(guardDD, assignmentDD); result.AddNodeToGuard(guardDD); } } //remove unused expression variableBddEncoding.DeRef(); valueBddEncoding.DeRef(); return result; }
/// <summary> /// Encode this assignment as a single statement /// </summary> /// <param name="model"></param> /// <returns></returns> public override ExpressionBDDEncoding TranslateBoolExpToBDD(Model model) { ExpressionBDDEncoding result = new ExpressionBDDEncoding(); ExpressionBDDEncoding variableBddEncoding = new PrimitiveApplication(PrimitiveApplication.ARRAYPRIME, this.RecordExpression, this.PropertyExpression).TranslateIntExpToBDD(model); ExpressionBDDEncoding valueBddEncoding = this.RightHandExpression.TranslateIntExpToBDD(model); for (int i = 0; i < variableBddEncoding.Count(); i++) { for (int j = 0; j < valueBddEncoding.Count(); j++) { CUDD.Ref(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); CUDDNode guardDD = CUDD.Function.And(variableBddEncoding.GuardDDs[i], valueBddEncoding.GuardDDs[j]); if (guardDD.Equals(CUDD.ZERO)) { CUDD.Deref(guardDD); continue; } CUDD.Ref(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); CUDDNode assignmentDD = CUDD.Function.Equal(variableBddEncoding.ExpressionDDs[i], valueBddEncoding.ExpressionDDs[j]); guardDD = CUDD.Function.And(guardDD, assignmentDD); result.AddNodeToGuard(guardDD); } } //remove unused expression variableBddEncoding.DeRef(); valueBddEncoding.DeRef(); return(result); }
/// <summary> /// And of more than 1 expression /// </summary> /// <param name="exps"></param> /// <returns></returns> public static Expression AND(params Expression[] exps) { Expression result = exps[0]; for(int i = 1; i < exps.Length; i++) { result = new PrimitiveApplication(PrimitiveApplication.AND, result, exps[i]); } return result; }
/// <summary> /// Return product of more than 1 expression /// </summary> /// <param name="exps"></param> /// <returns></returns> public static Expression TIMES(params Expression[] exps) { Expression result = exps[0]; for (int i = 1; i < exps.Length; i++) { result = new PrimitiveApplication(PrimitiveApplication.TIMES, result, exps[i]); } return(result); }
/// /// <summary> /// Use when the boolen constant is used as expression: a = true /// </summary> /// <param name="model"></param> /// <returns></returns> public override ExpressionBDDEncoding TranslateIntExpToBDD(Model model) { string channelName = Arguments[0].ToString(); string countChannelVariable = Model.GetCountVarChannel(channelName); string topChannelVariable = Model.GetTopVarChannel(channelName); switch (MethodName) { case Constants.cfull: Expression isFull = Expression.EQ(new Variable(countChannelVariable), new IntConstant(model.mapChannelToSize[channelName])); ExpressionBDDEncoding isFullTemp = isFull.TranslateBoolExpToBDD(model); isFullTemp.ExpressionDDs = new List <CUDDNode>(isFullTemp.GuardDDs); isFullTemp.GuardDDs = new List <CUDDNode>() { CUDD.Constant(1) }; return(isFullTemp); case Constants.cempty: Expression isEmpty = Expression.EQ(new Variable(countChannelVariable), new IntConstant(0)); ExpressionBDDEncoding isEmptyTemp = isEmpty.TranslateBoolExpToBDD(model); isEmptyTemp.ExpressionDDs = new List <CUDDNode>(isEmptyTemp.GuardDDs); isEmptyTemp.GuardDDs = new List <CUDDNode>() { CUDD.Constant(1) }; return(isEmptyTemp); case Constants.ccount: return(new Variable(countChannelVariable).TranslateIntExpToBDD(model)); case Constants.csize: return(new IntConstant(model.mapChannelToSize[channelName]).TranslateIntExpToBDD(model)); case Constants.cpeek: //(top_a - count_a) % L Expression popedElementPosition = new PrimitiveApplication(PrimitiveApplication.MOD, Expression.MINUS(new Variable(topChannelVariable), new Variable(countChannelVariable)), new IntConstant(model.mapChannelToSize[channelName])); //a[top_a - count_a % L][i] return(new PrimitiveApplication(PrimitiveApplication.ARRAY, new Variable(channelName), Expression.TIMES( popedElementPosition, new IntConstant(Model.MAX_MESSAGE_LENGTH)) ).TranslateIntExpToBDD(model)); } throw new Exception("Static call can not be encoded in BDD"); }
public Expression GetIndexedExpression() { List<Expression> expressions = new List<Expression>(16); foreach (ParallelDefinition pd in Definitions) { if (pd.GetGlobalVariables().Count > 0) { throw new Exception("Global variable can not be used in the index expression!"); } pd.DomainValues.Sort(); } List<List<Expression>> list = new List<List<Expression>>(); foreach (int v in Definitions[0].DomainValues) { List<Expression> l = new List<Expression>(Definitions.Count); l.Add(new IntConstant(v)); list.Add(l); } for (int i = 1; i < Definitions.Count; i++) { List<List<Expression>> newList = new List<List<Expression>>(); List<int> domain = Definitions[i].DomainValues; for (int j = 0; j < list.Count; j++) { foreach (int i1 in domain) { List<Expression> cList = new List<Expression>(list[j]); cList.Add(new IntConstant(i1)); newList.Add(cList); } } list = newList; } foreach (List<Expression> constants in list) { //Dictionary<string, Expression> constMappingNew = new Dictionary<string, Expression>(constMapping); Dictionary<string, Expression> constMappingNew = new Dictionary<string, Expression>(); for (int i = 0; i < constants.Count; i++) { Expression constant = constants[i]; //constant.BuildVars(); constMappingNew.Add(Definitions[i].Parameter, constant); } Expression newExpression = Expression.ClearConstant(constMappingNew); expressions.Add(newExpression); } if (expressions.Count > 1) { PrimitiveApplication toReturn = new PrimitiveApplication(Operator, expressions[expressions.Count - 2], expressions[expressions.Count - 1]); for (int i = expressions.Count - 3; i >= 0; i--) { toReturn = new PrimitiveApplication(Operator, expressions[i], toReturn); } return toReturn; } throw new Exception("The number of expressions must be greater than 1!"); }
private static ExpressionValue EvalPrimAppl(PrimitiveApplication application, ExpressionValue x1, Expression x2Exp, Valuation env) { try { ExpressionValue x2; switch (application.Operator) { case "<": x2 = Evaluate(x2Exp, env); return new BoolConstant(((IntConstant)x1).Value < ((IntConstant)x2).Value); case "<=": x2 = Evaluate(x2Exp, env); return new BoolConstant(((IntConstant)x1).Value <= ((IntConstant)x2).Value); case ">": x2 = Evaluate(x2Exp, env); return new BoolConstant(((IntConstant)x1).Value > ((IntConstant)x2).Value); case ">=": x2 = Evaluate(x2Exp, env); return new BoolConstant(((IntConstant)x1).Value >= ((IntConstant)x2).Value); case "==": x2 = Evaluate(x2Exp, env); return new BoolConstant(x1.ExpressionID == x2.ExpressionID); case "!=": x2 = Evaluate(x2Exp, env); //return new BoolConstant(((IntConstant)x1).Value != ((IntConstant)x2).Value); return new BoolConstant(x1.ExpressionID != x2.ExpressionID); case "&&": if(((BoolConstant)x1).Value) { x2 = Evaluate(x2Exp, env); return new BoolConstant(((BoolConstant)x2).Value); } else { return new BoolConstant(false); } case "||": if (!((BoolConstant)x1).Value) { x2 = Evaluate(x2Exp, env); return new BoolConstant(((BoolConstant)x2).Value); } else { return new BoolConstant(true); } case "xor": x2 = Evaluate(x2Exp, env); return new BoolConstant(((BoolConstant)x1).Value ^ ((BoolConstant)x2).Value); case "!": return new BoolConstant(!((BoolConstant)x1).Value); case "+": x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value + ((IntConstant)x2).Value); case "-": x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value - ((IntConstant)x2).Value); case "*": x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value * ((IntConstant)x2).Value); case "/": x2 = Evaluate(x2Exp, env); if (((IntConstant)x2).Value == 0) { throw new ArithmeticException("Divide by Zero on " + application.ToString()); } else { return new IntConstant(((IntConstant)x1).Value / ((IntConstant)x2).Value); } case "mod": x2 = Evaluate(x2Exp, env); if (((IntConstant)x2).Value == 0) { throw new ArithmeticException("Modulo by Zero on " + application.ToString()); } else { int int_X1 = ((IntConstant) x1).Value; int int_X2 = ((IntConstant) x2).Value; int tmp = int_X1 % int_X2; return new IntConstant((tmp >= 0) ? tmp : (tmp + int_X2)); } //case "empty" : // return new Value(((RecordValue) x1).Empty); //case "hasproperty": // return new Value(((RecordValue)x1).HasProperty(((PropertyValue)x2).PropertyName)); case ".": RecordValue record = (RecordValue)x1; x2 = Evaluate(x2Exp, env); int index = ((IntConstant)x2).Value; if (index < 0) { throw new NegativeArraySizeException("Access negative index " + index + " for variable " + application.Argument1.ToString() + " in expression " + application.ToString()); } else if (index >= record.Associations.Length) { throw new IndexOutOfBoundsException("Index " + index + " is out of range for variable " + application.Argument1.ToString() + " in expression " + application.ToString()); } return record.Associations[index]; case "~": return new IntConstant(-((IntConstant)x1).Value); //Bitwise operators used by NESC module case "<<"://bitwise left shift x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value << ((IntConstant)x2).Value); case ">>"://bitwise right shift x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value >> ((IntConstant)x2).Value); case "&"://bitwise AND x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value & ((IntConstant)x2).Value); case "^"://bitwise XOR x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value ^ ((IntConstant)x2).Value); case "|"://bitwise OR x2 = Evaluate(x2Exp, env); return new IntConstant(((IntConstant)x1).Value | ((IntConstant)x2).Value); } } catch (InvalidCastException ex) { throw new RuntimeException("Invalid Cast Exception for " + application.ToString() + ": " + ex.Message.Replace("PAT.Common.Classes.Expressions.ExpressionClass.", "")); } //catch (Exception ex1) //{ // throw new RuntimeException("Invalid Primitive Operation: " + application.ToString() + "!"); //} throw new RuntimeException("Invalid Primitive Operation: " +application.ToString() + "!"); }
/// <summary> /// Return guard, update of channel input /// guard: not empty and same size (buffer and received) and guard and expected value in buffer /// update: received = buffer and length of buffer - 1 /// Does not include the update of Event /// </summary> /// <param name="channelName"></param> /// <param name="guard"></param> /// <param name="exps"></param> /// <param name="assignmentExp">null if does not exist</param> /// <param name="model"></param> /// <returns></returns> private static List<Expression> GetGuardUpdateOfChannelInput(string channelName, Expression guard, List<Expression> exps, Expression assignmentExp, Model model) { string topChannelVariable = Model.GetTopVarChannel(channelName); string countChannelVariable = Model.GetCountVarChannel(channelName); string sizeElementArray = Model.GetArrayOfSizeElementChannel(channelName); Expression guardOfChannel, updateOfChannel = null; //Not empty channel buffer: count_a > 0 Expression notEmptyChannel = Expression.GT(new Variable(countChannelVariable), new IntConstant(0)); //The poped element size must have the same size of exps: size_a[top_a - count_a %L] == exps.count //(top_a - count_a) % L Expression popedElementPosition = new PrimitiveApplication(PrimitiveApplication.MOD, Expression.MINUS(new Variable(topChannelVariable), new Variable(countChannelVariable)), new IntConstant(model.mapChannelToSize[channelName])); Expression sameSize = Expression.EQ( new PrimitiveApplication(PrimitiveApplication.ARRAY, new Variable(sizeElementArray), popedElementPosition), new IntConstant(exps.Count)); guardOfChannel = Expression.AND(notEmptyChannel, sameSize); guardOfChannel = Expression.AND(guardOfChannel, guard); //Assign data from buffer to exps //exps[i] = a[top_a - count_a % L][i] for (int i = 0; i < exps.Count; i++) { //Expect value in the channel if (exps[i] is IntConstant) { //a[top_a - count_a % L][i] == exps[i] guardOfChannel = Expression.AND(guardOfChannel, Expression.EQ( new PrimitiveApplication(PrimitiveApplication.ARRAY, new Variable(channelName), Expression.PLUS( Expression.TIMES(popedElementPosition, new IntConstant(Model.MAX_MESSAGE_LENGTH)), new IntConstant(i))), exps[i])); } else { //receive value from buffer updateOfChannel = Expression.CombineProgramBlock(updateOfChannel, new Assignment(exps[i].expressionID, new PrimitiveApplication(PrimitiveApplication.ARRAY, new Variable(channelName), Expression.PLUS( new PrimitiveApplication( PrimitiveApplication.TIMES, popedElementPosition, new IntConstant( Model.MAX_MESSAGE_LENGTH)), new IntConstant(i))))); } } //Update size: count_a = count_a - 1 updateOfChannel = Expression.CombineProgramBlock(updateOfChannel, new Assignment(countChannelVariable, Expression.MINUS(new Variable(countChannelVariable), new IntConstant(1)))); updateOfChannel = Expression.CombineProgramBlock(updateOfChannel, assignmentExp); return new List<Expression>() { guardOfChannel, updateOfChannel }; }
public Expression GetIndexedExpression() { List <Expression> expressions = new List <Expression>(16); foreach (ParallelDefinition pd in Definitions) { if (pd.GetGlobalVariables().Count > 0) { throw new Exception("Global variable can not be used in the index expression!"); } pd.DomainValues.Sort(); } List <List <Expression> > list = new List <List <Expression> >(); foreach (int v in Definitions[0].DomainValues) { List <Expression> l = new List <Expression>(Definitions.Count); l.Add(new IntConstant(v)); list.Add(l); } for (int i = 1; i < Definitions.Count; i++) { List <List <Expression> > newList = new List <List <Expression> >(); List <int> domain = Definitions[i].DomainValues; for (int j = 0; j < list.Count; j++) { foreach (int i1 in domain) { List <Expression> cList = new List <Expression>(list[j]); cList.Add(new IntConstant(i1)); newList.Add(cList); } } list = newList; } foreach (List <Expression> constants in list) { //Dictionary<string, Expression> constMappingNew = new Dictionary<string, Expression>(constMapping); Dictionary <string, Expression> constMappingNew = new Dictionary <string, Expression>(); for (int i = 0; i < constants.Count; i++) { Expression constant = constants[i]; //constant.BuildVars(); constMappingNew.Add(Definitions[i].Parameter, constant); } Expression newExpression = Expression.ClearConstant(constMappingNew); expressions.Add(newExpression); } if (expressions.Count > 1) { PrimitiveApplication toReturn = new PrimitiveApplication(Operator, expressions[expressions.Count - 2], expressions[expressions.Count - 1]); for (int i = expressions.Count - 3; i >= 0; i--) { toReturn = new PrimitiveApplication(Operator, expressions[i], toReturn); } return(toReturn); } throw new Exception("The number of expressions must be greater than 1!"); }