You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
9.3 KiB
361 lines
9.3 KiB
//==============================================================================
|
|
//
|
|
// Copyright (c) 2013-
|
|
// Authors:
|
|
// * Ernst Moritz Hahn <emhahn@cs.ox.ac.uk> (University of Oxford)
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// This file is part of PRISM.
|
|
//
|
|
// PRISM is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// PRISM is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with PRISM; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//==============================================================================
|
|
|
|
package param;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.BitSet;
|
|
import java.util.LinkedList;
|
|
import java.util.ListIterator;
|
|
|
|
/**
|
|
* Representation of mutable parametric Markov chain.
|
|
* This class is intended to be used in combination with the
|
|
* {@code StateEliminator}, which uses this class to compute values of
|
|
* parametric Markov models.
|
|
*
|
|
* @author Ernst Moritz Hahn <emhahn@cs.ox.ac.uk> (University of Oxford)
|
|
* @see StateEliminator
|
|
*/
|
|
final class MutablePMC {
|
|
/** function factory to which functions in this object belong */
|
|
private FunctionFactory functionFactory;
|
|
/** assignment of rewards to each state */
|
|
private Function[] rewards;
|
|
/** assignment of time to each state */
|
|
private Function[] times;
|
|
/** for each state, provides list of leaving transition probabilities */
|
|
ArrayList<LinkedList<Function>> transitionProbs;
|
|
/** for each state, provides list of leaving transition targets */
|
|
ArrayList<LinkedList<Integer>> transitionTargets;
|
|
/** for each state, provides list of states which have transitions to this state */
|
|
ArrayList<LinkedList<Integer>> incoming;
|
|
/** true iff uses a reward structure */
|
|
private boolean useRewards;
|
|
/** true iff uses time reward structure */
|
|
private boolean useTime;
|
|
/** initial states */
|
|
private BitSet initStates;
|
|
/** target states */
|
|
private BitSet targetStates;
|
|
/** total number of states */
|
|
private int numStates;
|
|
|
|
/**
|
|
* Constructs a new mutable parametric Markov chain.
|
|
*
|
|
* @param functionFactory function factory used to maintain rational functions
|
|
* @param numStates total number of states this parametric Markov chain shall have
|
|
* @param useRewards true iff parametric Markov chain constructed shall use rewards
|
|
* @param useTime true iff parametric Markov chain constructed needs time entry
|
|
*/
|
|
MutablePMC(FunctionFactory functionFactory, int numStates, boolean useRewards, boolean useTime) {
|
|
this.numStates = numStates;
|
|
this.functionFactory = functionFactory;
|
|
transitionProbs = new ArrayList<LinkedList<Function>>(numStates);
|
|
transitionTargets = new ArrayList<LinkedList<Integer>>(numStates);
|
|
incoming = new ArrayList<LinkedList<Integer>>(numStates);
|
|
for (int state = 0; state < numStates; state++) {
|
|
transitionTargets.add(new LinkedList<Integer>());
|
|
transitionProbs.add(new LinkedList<Function>());
|
|
incoming.add(new LinkedList<Integer>());
|
|
}
|
|
this.useRewards = useRewards;
|
|
this.useTime = useTime;
|
|
initStates = new BitSet(numStates);
|
|
targetStates = new BitSet(numStates);
|
|
if (useRewards) {
|
|
rewards = new Function[numStates];
|
|
for (int i = 0; i < numStates; i++) {
|
|
rewards[i] = functionFactory.getZero();
|
|
}
|
|
}
|
|
if (useTime) {
|
|
times = new Function[numStates];
|
|
for (int i = 0; i < numStates; i++) {
|
|
times[i] = functionFactory.getZero();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns function factory maintaining functions used in this object.
|
|
*
|
|
* @return function factory maintaining functions
|
|
*/
|
|
FunctionFactory getFunctionFactory()
|
|
{
|
|
return functionFactory;
|
|
}
|
|
|
|
/**
|
|
* Adds a probabilistic transition.
|
|
*
|
|
* @param from state transition starts from
|
|
* @param to state transition leads to
|
|
* @param prob probability of transition
|
|
*/
|
|
void addTransition(int from, int to, Function prob)
|
|
{
|
|
ListIterator<Integer> toIter = transitionTargets.get(from).listIterator();
|
|
ListIterator<Function> valIter = transitionProbs.get(from).listIterator();
|
|
boolean alreadyThere = false;
|
|
while (toIter.hasNext() && !alreadyThere) {
|
|
int succ = toIter.next();
|
|
Function succProb = valIter.next();
|
|
if (succ == to) {
|
|
valIter.set(succProb.add(prob));
|
|
alreadyThere = true;
|
|
}
|
|
}
|
|
if (!alreadyThere) {
|
|
transitionTargets.get(from).add(to);
|
|
transitionProbs.get(from).add(prob);
|
|
incoming.get(to).add(from);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the probability of a given transition
|
|
*
|
|
* @param from source state of transition
|
|
* @param to target state of transition
|
|
* @return probability to move from given state to given state
|
|
*/
|
|
Function getTransProb(int from, int to)
|
|
{
|
|
Function prob = null;
|
|
ListIterator<Integer> toIter = transitionTargets.get(from).listIterator();
|
|
ListIterator<Function> valIter = transitionProbs.get(from).listIterator();
|
|
while (toIter.hasNext()) {
|
|
int succ = toIter.next();
|
|
Function succProb = valIter.next();
|
|
if (succ == to) {
|
|
prob = succProb;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (prob == null) {
|
|
prob = functionFactory.getZero();
|
|
}
|
|
|
|
return prob;
|
|
}
|
|
|
|
/**
|
|
* Returns probability of the self-loop in a given state.
|
|
*
|
|
* @param state state to return self-loop probability of
|
|
* @return self-loop probability of given state
|
|
*/
|
|
Function getSelfLoopProb(int state)
|
|
{
|
|
Function loopProb = null;
|
|
|
|
ListIterator<Integer> toIter = transitionTargets.get(state).listIterator();
|
|
ListIterator<Function> valIter = transitionProbs.get(state).listIterator();
|
|
while (toIter.hasNext()) {
|
|
int to = toIter.next();
|
|
Function val = valIter.next();
|
|
if (to == state) {
|
|
loopProb = val;
|
|
break;
|
|
}
|
|
}
|
|
if (loopProb == null) {
|
|
loopProb = functionFactory.getZero();
|
|
}
|
|
|
|
return loopProb;
|
|
}
|
|
|
|
/**
|
|
* Makes a given state absorbing.
|
|
* This means removing all leaving transitions and adding a self-loop
|
|
* with probability one.
|
|
*
|
|
* @param state state to make absorbing
|
|
*/
|
|
void makeAbsorbing(int state)
|
|
{
|
|
LinkedList<Integer> loop = new LinkedList<Integer>();
|
|
loop.add(state);
|
|
LinkedList<Function> one = new LinkedList<Function>();
|
|
one.add(functionFactory.getOne());
|
|
transitionTargets.set(state, loop);
|
|
transitionProbs.set(state, one);
|
|
}
|
|
|
|
/**
|
|
* Sets whether given state shall be an initial state
|
|
*
|
|
* @param state state which shall or shall not be an initial state
|
|
* @param targetState true iff given state shall be an initial state
|
|
*/
|
|
void setInitState(int state, boolean targetState)
|
|
{
|
|
initStates.set(state, targetState);
|
|
}
|
|
|
|
/**
|
|
* Sets whether given state shall be a target state
|
|
*
|
|
* @param state state which shall or shall not be a target state
|
|
* @param targetState true iff given state shall be a target state
|
|
*/
|
|
void setTargetState(int state, boolean targetState)
|
|
{
|
|
targetStates.set(state, targetState);
|
|
}
|
|
|
|
/**
|
|
* Set reward of a given state.
|
|
*
|
|
* @param state state to set reward of
|
|
* @param reward reward to set for given state
|
|
*/
|
|
void setReward(int state, Function reward)
|
|
{
|
|
rewards[state] = reward;
|
|
}
|
|
|
|
/**
|
|
* Set time of a given state.
|
|
*
|
|
* @param state state to set reward of
|
|
* @param time time to set for given state
|
|
*/
|
|
void setTime(int state, Function time)
|
|
{
|
|
times[state] = time;
|
|
}
|
|
|
|
/**
|
|
* Get time of a given state.
|
|
*
|
|
* @param state state to get time of
|
|
* @return time of given state
|
|
*/
|
|
Function getTime(int state)
|
|
{
|
|
return times[state];
|
|
}
|
|
|
|
/**
|
|
* Checks whether given state is a target state.
|
|
*
|
|
* @param state state to check whether it is a target state
|
|
* @return true iff given state is a target state
|
|
*/
|
|
boolean isTargetState(int state)
|
|
{
|
|
return targetStates.get(state);
|
|
}
|
|
|
|
/**
|
|
* Checks whether there are some target states
|
|
*
|
|
* @return true iff there are some target states
|
|
*/
|
|
boolean hasTargetStates()
|
|
{
|
|
return targetStates.cardinality() != 0;
|
|
}
|
|
|
|
/**
|
|
* Checks whether given state is an initial state.
|
|
*
|
|
* @param state state to check whether it is an initial state
|
|
* @return true iff given state is an initial state
|
|
*/
|
|
boolean isInitState(int state)
|
|
{
|
|
return initStates.get(state);
|
|
}
|
|
|
|
/**
|
|
* Gets the reward of a given state.
|
|
*
|
|
* @param state state to get reward of
|
|
* @return reward of given state
|
|
*/
|
|
Function getReward(int state)
|
|
{
|
|
return rewards[state];
|
|
}
|
|
|
|
/**
|
|
* Returns number of states.
|
|
*
|
|
* @return number of states
|
|
*/
|
|
int getNumStates()
|
|
{
|
|
return numStates;
|
|
}
|
|
|
|
/**
|
|
* Returns whether pmc uses rewards.
|
|
*
|
|
* @return true iff rewards are used
|
|
*/
|
|
boolean isUseRewards()
|
|
{
|
|
return useRewards;
|
|
}
|
|
|
|
/**
|
|
* Returns whether pmc uses time.
|
|
*
|
|
* @return true iff uses time
|
|
*/
|
|
boolean isUseTime()
|
|
{
|
|
return useTime;
|
|
}
|
|
|
|
/*
|
|
@Override
|
|
public String toString()
|
|
{
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
for (int state = 0; state < numStates; state++) {
|
|
result.append("state " + state);
|
|
if (useRewards) {
|
|
result.append(" " + rewards[state]);
|
|
}
|
|
if (useTime) {
|
|
result.append(" " + times[state]);
|
|
}
|
|
result.append("\n");
|
|
}
|
|
|
|
return result.toString();
|
|
}
|
|
*/
|
|
}
|