/// <summary> /// [ REFS: '', DEREFS:] /// </summary> /// <param name="allProb"></param> /// <param name="state"></param> public double GetMinProb(CUDDNode allProb, CUDDNode filter) { double result = 0; CUDD.Ref(filter, reach); CUDDNode newFilter = CUDD.Function.And(filter, reach); if (newFilter.Equals(CUDD.ZERO)) { result = double.MaxValue; } else { CUDD.Ref(newFilter, allProb); CUDDNode tmp = CUDD.Function.ITE(newFilter, allProb, CUDD.PlusInfinity()); result = CUDD.FindMin(tmp); CUDD.Deref(tmp); } CUDD.Deref(newFilter); return(result); }
/// <summary> /// Calculate state rewards and store in stateRewards /// Transition rewards are prepared and stored in sysDDs /// </summary> /// <param name="sysDDs"></param> private void ComputeRewards(SystemDDs sysDDs) { int numRewardStructs = modules.rewardStructs.Count; //Initialize reward of State and the resulted SystemDDs sysDDs for (int j = 0; j < numRewardStructs; j++) { stateRewards.Add(CUDD.Constant(0)); sysDDs.ind.rewards.Add(CUDD.Constant(0)); for (int i = 0; i < synchs.Count; i++) { sysDDs.synchs[i].rewards.Add(CUDD.Constant(0)); } } // for each reward structure... for (int j = 0; j < numRewardStructs; j++) { // get reward struct RewardStruct rs = modules.rewardStructs[j]; // work through list of items in reward struct foreach (var rewardItem in rs.items) { // translate states predicate and reward expression CUDDNode guard = EncodeExpression(rewardItem.guard); CUDDNode rewards = EncodeExpression(rewardItem.reward); CUDDNode rewardDD; string synch = rewardItem.synch; if (synch == null) { // first case: item corresponds to state rewards // restrict rewards to relevant states rewardDD = CUDD.Function.Times(guard, rewards); // check for negative rewards if (CUDD.FindMin(rewardDD) < 0) { throw new Exception("Reward structure item with guard " + rewardItem.guard + " contains negative rewards"); } // add to state rewards stateRewards[j] = CUDD.Function.Plus(stateRewards[j], rewardDD); } else { // second case: item corresponds to transition rewards //find the corresponding component to update the reward ComponentDDs compDDs; // work out which (if any) action this is for if (synch == string.Empty) { compDDs = sysDDs.ind; } else if (synchs.Contains(synch)) { int k = synchs.IndexOf(synch); compDDs = sysDDs.synchs[k]; } else { throw new Exception("Invalid action name \"" + synch + "\" in reward structure item"); } // identify corresponding transitions // (for dtmcs/ctmcs, keep actual values - need to weight rewards; for mdps just store 0/1) CUDD.Ref(compDDs.trans); rewardDD = (modules.modelType == ModelType.MDP)? (CUDD.Convert.GreaterThan(compDDs.trans, 0)): compDDs.trans; // restrict to relevant states rewardDD = CUDD.Function.Times(rewardDD, guard); // multiply by reward values rewardDD = CUDD.Function.Times(rewardDD, rewards); // check for negative rewards if (CUDD.FindMin(rewardDD) < 0) { throw new Exception("Reward structure item with guard " + rewardItem.guard + " contains negative rewards"); } // add result to rewards compDDs.rewards[j] = CUDD.Function.Plus(compDDs.rewards[j], rewardDD); } } } }