private static void addStatusToChildInstance(ParentInstance parentInstance, ChildInstance childSmvInstance) { //copy status variable and add custom activation case. Variable status = module.Status; Variable childStatus = new Variable(status.Name); childStatus.Behaviour = VariableBehaviour.DIVISION; childStatus.Type = status.Type; foreach (var caseLine in status.Next.CaseStatement.CaseLines) { childStatus.Next.CaseStatement.CaseLines.Add(caseLine); } // add custom case (parent._status = willDivide) & (next( parent._status) = DIVIDED) CaseLine newCase = new CaseLine(); string parentStatus = parentInstance.Name + "." + status.Name; Expression left = new Expression(); left.Exp = parentStatus; Expression right = new Expression(StatusStates.WILLDIVIDE);//I changed here for willDivide BoolExp condition1 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); left = new Expression(); left.Exp = SMVKeys.NEXT + "( " + parentStatus + ")"; right = new Expression(StatusStates.DIVIDED); BoolExp condition2 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); CompoundBoolExpression compound = new CompoundBoolExpression(condition1, NuSMV.BinaryOperator.AND, condition2); Expression result = new Expression(StatusStates.ACTIVE); newCase.Rule.Condition = compound; newCase.Result = result; //insert at the beginning childStatus.Next.CaseStatement.CaseLines.Insert(0, newCase); childSmvInstance.DivisionStatus = childStatus; }
internal static void assignLastCasesToDivisionVars(Module module) { if (module.HasDivisionRule) { if (module.Instance is ChildInstance) { ChildInstance childInstance = (ChildInstance)module.Instance; // childInstance.DivisionStatus.Next.CaseStatement.CaseLines.Add(trueCaseLine(childInstance.DivisionStatus)); foreach (var variable in module.Variables) { if (variable.Behaviour == VariableBehaviour.DIVISION) { //Copy all rules of division variable which are added after division value calculation in BDivision name space. Variable divisionVar = (Variable)childInstance.DivisionVariables.First(item => item.Name.Equals(variable.Name)); if (variable is Variable) { foreach (var caseLine in (variable as Variable).Next.CaseStatement.CaseLines) { if (!BRulesComVar.ruleExist(divisionVar.Next, caseLine as CaseLine)) { divisionVar.Next.addCaseLine(caseLine); } } } } } } } }
/// <summary> Insert the caseline at the beginning of child status' next, If parent divides then child will activate /// case (parent._status = willDivide) & (next( parent._status) = DIVIDED) : _ACTIVE; </summary> <param /// name="childSMVInstance"></param> private static void updateChildModuleStatus(ChildInstance childSMVInstance) { //copy status variable and add custom activation case. Variable status = module.Status; status.Behaviour = VariableBehaviour.DIVISION; // add custom case (parent._status = willDivide) & (next( parent._status) = DIVIDED) CaseLine newCase = new CaseLine(); string parentStatus = childSMVInstance.ParentInstance.Name + "." + status.Name; Expression left = new Expression(); left.Exp = parentStatus; Expression right = new Expression(StatusStates.WILLDIVIDE); BoolExp condition1 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); left = new Expression(); left.Exp = SMVKeys.NEXT + "( " + parentStatus + ")"; right = new Expression(StatusStates.DIVIDED); BoolExp condition2 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); CompoundBoolExpression compound = new CompoundBoolExpression(condition1, BinaryOperator.AND, condition2); Expression result = new Expression(StatusStates.ACTIVE); newCase.Rule.Condition = compound; newCase.Result = result; //insert at the beginning status.Next.CaseStatement.CaseLines.Insert(0, newCase); childSMVInstance.DivisionStatus = status; }
/// <summary> /// Add the rule which defines the values of division variables. Remained rules will be added later in /// BRulesStandardVar.assignLastCasesToDivisionVars /// </summary> /// <param name="childSmvInstance"></param> /// <param name="variable"></param> /// <param name="totalValue"></param> private static void addRuleChildDivisionVariables(ChildInstance childSmvInstance, Variable variable, int totalValue) { CaseLine newCase = new CaseLine(); string childActivation = childSmvInstance.Name + "." + childSmvInstance.DivisionStatus.Name; Expression left = new Expression(); left.Exp = childActivation; Expression right = new Expression(StatusStates.NONEXIST); BoolExp condition1 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); //next(child.status)=ACTIVE left = new Expression(); left.Exp = SMVKeys.NEXT + "(" + childActivation + ")"; right = new Expression(StatusStates.ACTIVE); BoolExp condition2 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); CompoundBoolExpression compound = new CompoundBoolExpression(condition1, NuSMV.BinaryOperator.AND, condition2); newCase.Rule.Condition = compound; Expression result = new Expression(); result.Exp = totalValue.ToString(); newCase.Result = result; variable.Next.CaseStatement.CaseLines.Insert(0, newCase); }
internal static string WriteChildDivisionVariablesNext(ChildInstance childInstance) { string op = ""; foreach (var variable in childInstance.DivisionVariables) { op += "next (" + childInstance.Name + "." + variable.Name + ") := case\n"; bool firstRule = true;// first rule related with parent, so, its rule shouldn't be named with child instances foreach (var caseLine in variable.Next.CaseStatement.CaseLines) { string temp = "\t"; if (!firstRule) { // add child name as prefix temp += insertInstanceName(caseLine.Rule.Condition, childInstance); } else { temp += caseLine.Rule.Condition; } temp += " : "; temp += insertInstanceName2Expression(caseLine.Result, childInstance); temp += ";\n"; op += temp; firstRule = false; } op += "esac;\n"; } return(op); }
/// <summary> /// For each MInstance (KP instance) generate a SMV instance. /// </summary> /// <param name="nuSMV"></param> /// <param name="module"></param> /// <param name="type"></param> /// <param name="kpInstance"></param> public static void generateSMVInstances(SMVModel nuSMV, Module module, MType type, MInstance kpInstance) { Instance smvInstance = null; //If module has division rule then being child or parent becomes matter, otherwise they are default SMV instances if (module.HasDivisionRule) { //Define module behaviour based on whether the instance is a parent or a child //Status parameter, parents start in ACTIVE; child instances start in NONEXIST state ParameterVar statusParam = new ParameterVar(); //A Child instance if (kpInstance is KPChildInstance) { // generate SMV Child Instance smvInstance = new ChildInstance(); smvInstance.DivisionType = DIVISIONTYPE.CHILD; //Start Status parameter in NONEXISTS state statusParam.Name = CustomVariables.STATUS; statusParam.Behaviour = VariableBehaviour.CUSTOM; statusParam.Init = StatusStates.NONEXIST; smvInstance.Parameters.Add(statusParam); //add this instance to its parent children crossReferChild2ParentInstance(nuSMV, type, kpInstance, smvInstance as ChildInstance); } // A Parent instance else { // generate SMV Parent Instance smvInstance = new ParentInstance(); smvInstance.DivisionType = DIVISIONTYPE.PARENT; //Start Status parameter in Active state statusParam.Name = CustomVariables.STATUS; statusParam.Behaviour = VariableBehaviour.CUSTOM; statusParam.Init = StatusStates.ACTIVE; smvInstance.Parameters.Add(statusParam); } //set parameter to module as well. module.Parameters.Add(statusParam); } //Default instance else { smvInstance = new Instance(); smvInstance.DivisionType = DIVISIONTYPE.NODIVISION; } smvInstance.Name = kpInstance.Name; //join custom parameters, e.g., status, with model parameters smvInstance.Parameters.UnionWith(getInstanceParameters(module, type, kpInstance)); //cross reference module and its instance smvInstance.Module = module; module.Instance = smvInstance; }
private static void calculateValuesOfDivisionVariables(List <KpCore.Rule> divisionRules, List <InstanceBlueprint> result) { //Get the instance of the module ChildInstance childSMVInstance = (module.Instance as ChildInstance); updateStatusAndAddDivisionVars2ChildModule(childSMVInstance); foreach (var variable in childSMVInstance.DivisionVariables) { int totalValue = getTotalAmountOfDivisionVar(variable, divisionRules, result); addRuleChildDivisionVariables(childSMVInstance, variable, totalValue); } }
private static void formDivisionInstance(ParentInstance parentInstance, List <KpCore.Rule> divisionRules, List <InstanceBlueprint> result) { MType type = result.ElementAt(0).Type; MInstance instance = new MInstance(); ChildInstance childSmvInstance = new ChildInstance(); addChildInstance2Module(type, instance, parentInstance, childSmvInstance); foreach (var variable in childSmvInstance.DivisionVariables) { int totalValue = getTotalAmountOfDivisionVar(variable, divisionRules, result); addRuleChildDivisionVariables(childSmvInstance, variable, totalValue); } }
/// <summary> /// Creates an extra variable for each division rule. /// </summary> /// <param name="childSmvInstance"></param> private static void addDivisionVariable2ChildModule(ChildInstance childSmvInstance) { //copy division rules to child instance. foreach (var variable in module.Variables) { if (variable.Behaviour == VariableBehaviour.DIVISION) { Variable divVar = new Variable(variable.Name); divVar.Behaviour = VariableBehaviour.DIVISION; divVar.Type = variable.Type; if (variable is Variable) { foreach (var caseLine in (variable as Variable).Next.CaseStatement.CaseLines) { divVar.Next.CaseStatement.CaseLines.Add(caseLine); } childSmvInstance.DivisionVariables.Add(divVar); } } } }
/// <summary> /// Print status rules of each child instance /// </summary> internal static string WriteChildStatusNext(NuSMV.Module module, ChildInstance childInstance) { string op = ""; Variable status = childInstance.DivisionStatus; op = "next (" + childInstance.Name + "." + status.Name + ") := case\n"; bool firstRule = true;// first rule related with parent, so, its rule shouldn't be named with child instances foreach (var caseLine in status.Next.CaseStatement.CaseLines) { string temp = ""; if (!firstRule) { // add child name as prefix temp += TVariables.insertInstanceName(caseLine.Rule.Condition, childInstance); } else { temp += caseLine.Rule.Condition; firstRule = false; } temp += " : "; // for last true case if (caseLine.Rule.Condition is TruthValue) { temp += childInstance.Name + "." + caseLine.Result; } else { temp += caseLine.Result; } temp += ";\n"; op += temp; } op += "esac;\n"; return(op); }
/// <summary> /// Update status variable and For each variable inside InstanceBlueprint, create a new variable so called division /// variable and add them to division variable list of child instance, i.e., DivisionVariables /// </summary> /// <param name="childSMVInstance"></param> private static void updateStatusAndAddDivisionVars2ChildModule(ChildInstance childSMVInstance) { updateChildModuleStatus(childSMVInstance); addDivisionVariable2ChildModule(childSMVInstance); }
/// <summary> /// Cross reference child instance to its parent, and vice versa /// </summary> /// <param name="type"></param> /// <param name="kpInstance"></param> private static void crossReferChild2ParentInstance(SMVModel nuSMV, MType type, MInstance kpInstance, ChildInstance childSMVInstance) { //Access its parent KP instance MInstance parentKPInstance = (kpInstance as KPChildInstance).ParentKPInstance; ParentInstance parentSMVInstance = getSMVInstance(nuSMV, parentKPInstance); if (childSMVInstance.ParentInstance == null) { childSMVInstance.ParentInstance = parentSMVInstance; } else { throw new Exception("Error: Cross reference error with child and parent SMV instance..."); } if (!parentSMVInstance.ChildInstances.Contains(childSMVInstance)) { parentSMVInstance.ChildInstances.Add(childSMVInstance); } }
private static void addChildSMVInstance(Module module, Instance parentSMVInstance, ChildInstance childSmvInstance) { childSmvInstance.ConnectedTo = parentSMVInstance.ConnectedTo; //build cross relation foreach (var target in parentSMVInstance.ConnectedTo) { //if it is not added already, then add if (!target.ConnectedTo.Contains(childSmvInstance)) { target.ConnectedTo.Add(childSmvInstance); } } childSmvInstance.DivisionType = DIVISIONTYPE.CHILD; childSmvInstance.Module = parentSMVInstance.Module; childSmvInstance.Name = SMVUtil.generateAnInstanceName(childSmvInstance); foreach (var parameter in parentSMVInstance.Parameters) { if (parameter is ParameterVar) { ParameterVar childParam = new ParameterVar(); ParameterVar parentParam = (ParameterVar)parameter; // if status variable, set NONEXIST if (parentParam.Behaviour == VariableBehaviour.CUSTOM) { if (parentParam.Name == CustomVariables.STATUS) { childParam.Behaviour = parentParam.Behaviour; childParam.Name = parentParam.Name; childParam.Init = StatusStates.NONEXIST; } else if (parentParam.Name == CustomVariables.TURN) { childParam.Behaviour = parentParam.Behaviour; childParam.Name = parentParam.Name; childParam.Init = TurnStates.READY; } else if (parameter.Name == CustomVariables.SYNCH) { childParam = parentParam; } } else //set remained parameters as zero { childParam.Behaviour = parentParam.Behaviour; childParam.Name = parentParam.Name; childParam.Init = "0"; } childSmvInstance.Parameters.Add(childParam); } else { //if there is something else just take as it is. childSmvInstance.Parameters.Add(parameter); } } module.ChildInstances.Add(childSmvInstance); }
private static void addChildInstance2Module(MType type, MInstance newInstance, ParentInstance parentInstance, ChildInstance childSmvInstance) { childSmvInstance.ParentInstance = parentInstance; parentInstance.ChildInstances.Add(childSmvInstance); addChildSMVInstance(module, parentInstance, childSmvInstance); addDivisionVariableToChildInstance(childSmvInstance); addStatusToChildInstance(parentInstance, childSmvInstance); }
/// <summary> /// Add the rule which defines the values of division variables. Remained rules will be added later in /// BRulesStandardVar.assignLastCasesToDivisionVars /// </summary> /// <param name="childSmvInstance"></param> /// <param name="variable"></param> /// <param name="totalValue"></param> private static void addRuleChildDivisionVariables(ChildInstance childSmvInstance, Variable variable, int totalValue) { CaseLine newCase = new CaseLine(); string childActivation = childSmvInstance.Name + "." + childSmvInstance.DivisionStatus.Name; Expression left = new Expression(); left.Exp = childActivation; Expression right = new Expression(StatusStates.NONEXIST); BoolExp condition1 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); //next(child.status)=ACTIVE left = new Expression(); left.Exp = SMVKeys.NEXT + "(" + childActivation + ")"; right = new Expression(StatusStates.ACTIVE); BoolExp condition2 = new BoolExp(left, NuSMV.RelationalOperator.EQUAL, right); CompoundBoolExpression compound = new CompoundBoolExpression(condition1, NuSMV.BinaryOperator.AND, condition2); newCase.Rule.Condition = compound; Expression result = new Expression(); //inherit the parent's remained multiset objects //result.Exp = SMVKeys.NEXT + "(" + childSmvInstance.ParentInstance.Name + "." + variable.Name + ") + " + totalValue.ToString(); //newCase.Rule.AppendBoolExpression(BRulesStandardVar.getBoundCondition(variable, result), BinaryOperator.AND); result.Exp = totalValue.ToString(); newCase.Result = result; variable.Next.CaseStatement.CaseLines.Insert(0, newCase); ////((((_status = _willDISSOLVE) | (_status = _willDIVIDE))) & (_sync = _EXCH)) : 0; //CaseLine caseLine2 = new CaseLine(); //ICondition willDissolve = null; //ICondition willDivide = null; //ICondition willDissolveOrDivide = null; //if (module.HasDissolutionRule) //{ // willDissolve = BRulesComVar.getInstancedStatus(module, StatusStates.WILLDISSOLVE); //} //if (module.HasDivisionRule) //{ // willDivide = BRulesComVar.getInstancedStatus(module, StatusStates.WILLDIVIDE); //} //willDissolveOrDivide = new CompoundBoolExpression(willDissolve, BinaryOperator.OR, willDivide); //// this is non-instanced _sync = _EXCH //BoolExp synchIsExch = new BoolExp(); //synchIsExch.Left = new Expression(CustomVariables.SYNCH); //synchIsExch.RelationalOperator.Operator = NuSMV.RelationalOperator.EQUAL; //synchIsExch.Right = new Expression(SynchStates.EXCHANGE); //CompoundBoolExpression statusAndSync = new CompoundBoolExpression(willDissolveOrDivide, BinaryOperator.AND, synchIsExch); //caseLine2.Rule.Condition = statusAndSync; //caseLine2.Result = new Expression("0"); //variable.Next.CaseStatement.CaseLines.Insert(1, caseLine2); ////((_status = _DISSOLVED) | (_status = _DIVIDED)) : 0; //CaseLine caseLine3 = new CaseLine(); //ICondition dissolved = null; //ICondition divided = null; //ICondition dissolvedOrDivided= null; //if (module.HasDissolutionRule) //{ // dissolved = BRulesComVar.getInstancedStatus(module, StatusStates.DISSOLVED); //} //if (module.HasDivisionRule) //{ // divided = BRulesComVar.getInstancedStatus(module, StatusStates.DIVIDED); //} //dissolvedOrDivided = new CompoundBoolExpression(dissolved, BinaryOperator.OR, divided); //caseLine3.Rule.Condition = dissolvedOrDivided; //caseLine3.Result = new Expression("0"); //variable.Next.CaseStatement.CaseLines.Insert(2, caseLine3); }