Browse Source
imported patch rewardcounter-ProductWithProductStates.patch
tud-infrastructure-2018-10-12
imported patch rewardcounter-ProductWithProductStates.patch
tud-infrastructure-2018-10-12
1 changed files with 264 additions and 0 deletions
@ -0,0 +1,264 @@ |
|||
//============================================================================== |
|||
// |
|||
// Copyright (c) 2015- |
|||
// Authors: |
|||
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden) |
|||
// |
|||
//------------------------------------------------------------------------------ |
|||
// |
|||
// 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 explicit; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.BitSet; |
|||
import java.util.HashMap; |
|||
import java.util.HashSet; |
|||
import java.util.Iterator; |
|||
import java.util.LinkedList; |
|||
import java.util.Vector; |
|||
import java.util.Map.Entry; |
|||
|
|||
import common.IterableStateSet; |
|||
|
|||
import parser.State; |
|||
import prism.PrismException; |
|||
|
|||
/** |
|||
* Provides functionality for generating a Product via a |
|||
* DTMCProductOperator / MDPProductOperator. |
|||
* |
|||
* @param <M> the model type |
|||
*/ |
|||
public class ProductWithProductStates<M extends Model> extends Product<M> { |
|||
/** Mapping index to ProductState */ |
|||
protected Vector<ProductState> prod_states = new Vector<ProductState>(); |
|||
/** States of interest in the product */ |
|||
protected BitSet statesOfInterestInProduct = new BitSet(); |
|||
|
|||
/** Constructor */ |
|||
protected ProductWithProductStates(M originalModel) |
|||
{ |
|||
super(originalModel); |
|||
} |
|||
|
|||
/** Get the product state information for a given state index in the product */ |
|||
public ProductState getState(int index) |
|||
{ |
|||
return prod_states.get(index); |
|||
} |
|||
|
|||
@Override |
|||
public int getModelState(int productState) |
|||
{ |
|||
return getState(productState).getFirstState(); |
|||
} |
|||
|
|||
@Override |
|||
public int getAutomatonState(int productState) |
|||
{ |
|||
return getState(productState).getSecondState(); |
|||
} |
|||
|
|||
@Override |
|||
public BitSet getTransformedStatesOfInterest() |
|||
{ |
|||
return statesOfInterestInProduct; |
|||
} |
|||
|
|||
/** |
|||
* Generates the DTMC for a {@code ProductWithProductStates<DTMC>} |
|||
* using the operator {@code op}, storing the result in |
|||
* {@product}. |
|||
* @param op the ProductOperator |
|||
* @param product for storing the result |
|||
* @param statesOfInterest the states of interest in the DTMC, null = all states |
|||
*/ |
|||
static public void generate(final DTMCProductOperator op, final ProductWithProductStates<DTMC> product, BitSet statesOfInterest) throws PrismException |
|||
{ |
|||
final DTMC dtmc = op.getGraph(); |
|||
final DTMCSimple dtmcProduct = new DTMCSimple(); |
|||
final ArrayList<State> statesList = new ArrayList<State>(); |
|||
final Vector<ProductState> prod_states = new Vector<ProductState>(); |
|||
|
|||
@SuppressWarnings("serial") |
|||
class ProductStateMap extends HashMap<ProductState, Integer> |
|||
{ |
|||
public Integer findOrAdd(ProductState state) throws PrismException |
|||
{ |
|||
Integer index = get(state); |
|||
if (index == null) { |
|||
index = Integer.valueOf(dtmcProduct.addState()); |
|||
put(state, index); |
|||
if (index != prod_states.size()) { |
|||
throw new PrismException("Implementation error in product construction!"); |
|||
} |
|||
prod_states.add(state); |
|||
statesList.add(dtmc.getStatesList().get(state.getFirstState())); |
|||
|
|||
// notify operator of the index |
|||
op.notify(state, index); |
|||
} |
|||
return index; |
|||
} |
|||
}; |
|||
|
|||
ProductStateMap mapping = new ProductStateMap(); |
|||
HashSet<ProductState> expanded = new HashSet<ProductState>(); |
|||
LinkedList<ProductState> todo = new LinkedList<ProductState>(); |
|||
|
|||
for (int index : new IterableStateSet(statesOfInterest, dtmc.getNumStates())) { |
|||
ProductState prod_initial = op.getInitialState(index); |
|||
Integer s = mapping.findOrAdd(prod_initial); |
|||
todo.add(prod_initial); |
|||
dtmcProduct.addInitialState(s); |
|||
product.statesOfInterestInProduct.set(s); |
|||
} |
|||
|
|||
while (!todo.isEmpty()) { |
|||
ProductState cur = todo.remove(0); |
|||
if (expanded.contains(cur)) { |
|||
// cur has been expanded in the time between insertion into todo and now |
|||
continue; |
|||
} |
|||
// mark as expanded |
|||
expanded.add(cur); |
|||
|
|||
Integer from_index = mapping.get(cur); |
|||
|
|||
// expand cur |
|||
Iterator<Entry<Integer, Double>> transitions = dtmc.getTransitionsIterator(cur.getFirstState()); |
|||
while (transitions.hasNext()) { |
|||
Entry<Integer, Double> transition = transitions.next(); |
|||
|
|||
ProductState to_state = op.getSuccessor(cur, transition.getKey()); |
|||
if (!expanded.contains(to_state)) { |
|||
todo.add(to_state); |
|||
} |
|||
Integer to_index = mapping.findOrAdd(to_state); |
|||
|
|||
dtmcProduct.addToProbability(from_index.intValue(), to_index.intValue(), transition.getValue()); |
|||
} |
|||
} |
|||
|
|||
op.finish(); |
|||
|
|||
dtmcProduct.setStatesList(statesList); |
|||
product.productModel = dtmcProduct; |
|||
product.prod_states = prod_states; |
|||
|
|||
// lift labels |
|||
for (String label : dtmc.getLabels()) { |
|||
dtmcProduct.addLabel(label, product.liftFromModel(dtmc.getLabelStates(label))); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Generates the MDP for a {@code ProductWithProductStates<MDP>} |
|||
* using the operator {@code op}, storing the result in |
|||
* {@product}. |
|||
* @param op the ProductOperator |
|||
* @param product for storing the result |
|||
* @param statesOfInterest the states of interest in the MDP, null = all states |
|||
*/ |
|||
static public void generate(final MDPProductOperator op, final ProductWithProductStates<MDP> product, BitSet statesOfInterest) throws PrismException |
|||
{ |
|||
final MDP mdp = op.getGraph(); |
|||
final MDPSimple mdpProduct = new MDPSimple(); |
|||
final ArrayList<State> statesList = new ArrayList<State>(); |
|||
final Vector<ProductState> prod_states = new Vector<ProductState>(); |
|||
|
|||
@SuppressWarnings("serial") |
|||
class ProductStateMap extends HashMap<ProductState, Integer> |
|||
{ |
|||
public Integer findOrAdd(ProductState state) throws PrismException |
|||
{ |
|||
Integer index = get(state); |
|||
if (index == null) { |
|||
index = Integer.valueOf(mdpProduct.addState()); |
|||
put(state, index); |
|||
if (index != prod_states.size()) { |
|||
throw new PrismException("Implementation error in product construction!"); |
|||
} |
|||
prod_states.add(state); |
|||
statesList.add(mdp.getStatesList().get(state.getFirstState())); |
|||
|
|||
// notify operator of the index |
|||
op.notify(state, index); |
|||
} |
|||
return index; |
|||
} |
|||
}; |
|||
|
|||
ProductStateMap mapping = new ProductStateMap(); |
|||
HashSet<ProductState> expanded = new HashSet<ProductState>(); |
|||
LinkedList<ProductState> todo = new LinkedList<ProductState>(); |
|||
|
|||
for (int index : new IterableStateSet(statesOfInterest, mdp.getNumStates())) { |
|||
ProductState prod_initial = op.getInitialState(index); |
|||
Integer s = mapping.findOrAdd(prod_initial); |
|||
todo.add(prod_initial); |
|||
mdpProduct.addInitialState(s); |
|||
product.statesOfInterestInProduct.set(s); |
|||
} |
|||
|
|||
while (!todo.isEmpty()) { |
|||
ProductState cur = todo.remove(0); |
|||
if (expanded.contains(cur)) { |
|||
// cur has been expanded in the time between insertion into todo and now |
|||
continue; |
|||
} |
|||
// mark as expanded |
|||
expanded.add(cur); |
|||
|
|||
Integer from_index = mapping.get(cur); |
|||
|
|||
// expand cur |
|||
int choices = mdp.getNumChoices(cur.getFirstState()); |
|||
for (int choice_i = 0; choice_i<choices; choice_i++) { |
|||
Distribution successors = new Distribution(); |
|||
Iterator<Entry<Integer, Double>> transitions = mdp.getTransitionsIterator(cur.getFirstState(), choice_i); |
|||
while (transitions.hasNext()) { |
|||
Entry<Integer, Double> transition = transitions.next(); |
|||
|
|||
ProductState to_state = op.getSuccessor(cur, choice_i, transition.getKey()); |
|||
if (!expanded.contains(to_state)) { |
|||
todo.add(to_state); |
|||
} |
|||
Integer to_index = mapping.findOrAdd(to_state); |
|||
|
|||
successors.add(to_index.intValue(), transition.getValue()); |
|||
} |
|||
|
|||
mdpProduct.addChoice(from_index.intValue(), successors); |
|||
} |
|||
} |
|||
|
|||
op.finish(); |
|||
|
|||
mdpProduct.setStatesList(statesList); |
|||
product.productModel = mdpProduct; |
|||
product.prod_states = prod_states; |
|||
|
|||
// lift labels |
|||
for (String label : mdp.getLabels()) { |
|||
mdpProduct.addLabel(label, product.liftFromModel(mdp.getLabelStates(label))); |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue