1 changed files with 207 additions and 0 deletions
@ -0,0 +1,207 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2016- |
||||
|
// 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.BitSet; |
||||
|
import java.util.Iterator; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* A data structure storing, for a given NondeterministicModel, |
||||
|
* which of the individual choices should be considered enabled |
||||
|
* or disabled. |
||||
|
* <br> |
||||
|
* This is implemented similar to the sparse data structures: |
||||
|
* A mask BitSet stores a bit where 'true' means that the corresponding |
||||
|
* choice is disabled. |
||||
|
* The indizes are calculated by means of a choiceStart array, |
||||
|
* that stores the overall index of the first choice for each state. |
||||
|
* Given a state s and choice index c, this allows the calculation of |
||||
|
* the index i into the mask via i = choiceStart[s] + c. |
||||
|
*/ |
||||
|
public class ChoicesMask |
||||
|
{ |
||||
|
/** The mask bits (set = choice is disabled) */ |
||||
|
private BitSet mask; |
||||
|
|
||||
|
/** The overall index of the first choice (i.e., index 0) for the given state */ |
||||
|
private int[] choiceStart; |
||||
|
|
||||
|
/** The overall number of states */ |
||||
|
int numStates; |
||||
|
|
||||
|
/** Constructor. Initially, all choices are enabled. */ |
||||
|
public ChoicesMask(NondetModel model) |
||||
|
{ |
||||
|
numStates = model.getNumStates(); |
||||
|
|
||||
|
// initialise choiceStart array |
||||
|
// plus one to allow storing the last choice |
||||
|
// and provide an easy way to determine the end index |
||||
|
// for a given state by looking at choiceStart[s+1] |
||||
|
choiceStart = new int[numStates + 1]; |
||||
|
|
||||
|
// store the global choice index for the first choice |
||||
|
// of each state |
||||
|
int curChoice = 0; |
||||
|
for (int s = 0; s < numStates; s++) { |
||||
|
choiceStart[s] = curChoice; |
||||
|
curChoice += model.getNumChoices(s); |
||||
|
} |
||||
|
// store the last choice index at the end |
||||
|
choiceStart[numStates] = curChoice; |
||||
|
|
||||
|
// initialise the mask to be empty, i.e, all choices are enabled |
||||
|
mask = new BitSet(); |
||||
|
} |
||||
|
|
||||
|
/** Enable all choices */ |
||||
|
public void enableAll() |
||||
|
{ |
||||
|
mask.clear(); |
||||
|
} |
||||
|
|
||||
|
/** Disable all choices */ |
||||
|
public void disableAll() |
||||
|
{ |
||||
|
mask.set(0, getNumChoices()); |
||||
|
} |
||||
|
|
||||
|
private void setChoiceBit(int state, int choice, boolean value) |
||||
|
{ |
||||
|
assert(state < numStates); |
||||
|
int start = choiceStart[state]; |
||||
|
int end = choiceStart[state+1]; |
||||
|
assert(start + choice < end); |
||||
|
|
||||
|
mask.set(start + choice, value); |
||||
|
} |
||||
|
|
||||
|
private boolean getChoiceBit(int state, int choice) |
||||
|
{ |
||||
|
assert(state < numStates); |
||||
|
int start = choiceStart[state]; |
||||
|
int end = choiceStart[state+1]; |
||||
|
assert(start + choice < end); |
||||
|
|
||||
|
return mask.get(start + choice); |
||||
|
} |
||||
|
|
||||
|
/** Enable the given choice for the given state */ |
||||
|
public void enableChoice(int state, int choice) |
||||
|
{ |
||||
|
// set to false => enabled |
||||
|
setChoiceBit(state, choice, false); |
||||
|
} |
||||
|
|
||||
|
/** Disable the given choice for the given state */ |
||||
|
public void disableChoice(int state, int choice) |
||||
|
{ |
||||
|
// set to true => disabled |
||||
|
setChoiceBit(state, choice, true); |
||||
|
} |
||||
|
|
||||
|
/** Return true if the given choice in the given state is enabled */ |
||||
|
public boolean isEnabled(int state, int choice) |
||||
|
{ |
||||
|
// set bit => disabled, so we negate |
||||
|
return !getChoiceBit(state, choice); |
||||
|
} |
||||
|
|
||||
|
/** Return the overall number of choices (enabled and disabled) */ |
||||
|
public int getNumChoices() |
||||
|
{ |
||||
|
return choiceStart[numStates]; |
||||
|
} |
||||
|
|
||||
|
/** Return the number of choices for the given state (enabled and disabled) */ |
||||
|
public int getNumChoices(int state) |
||||
|
{ |
||||
|
assert(state < numStates); |
||||
|
int start = choiceStart[state]; |
||||
|
int end = choiceStart[state+1]; |
||||
|
|
||||
|
return end - start; |
||||
|
} |
||||
|
|
||||
|
/** Return the number of enabled choices for the given state */ |
||||
|
public int getNumEnabledChoices(int state) |
||||
|
{ |
||||
|
int enabled = 0; |
||||
|
for (@SuppressWarnings("unused") int c : enabledChoices(state)) { |
||||
|
enabled++; |
||||
|
} |
||||
|
return enabled; |
||||
|
} |
||||
|
|
||||
|
/** Return true if the given state has enabled choices */ |
||||
|
public boolean hasEnabledChoices(int state) |
||||
|
{ |
||||
|
for (@SuppressWarnings("unused") int c : enabledChoices(state)) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** Provide an Iterable over the indizes (local) that are enabled in the given state */ |
||||
|
public Iterable<Integer> enabledChoices(final int state) |
||||
|
{ |
||||
|
final int start = choiceStart[state]; |
||||
|
final int end = choiceStart[state+1]; |
||||
|
|
||||
|
return new Iterable<Integer>() { |
||||
|
public Iterator<Integer> iterator() { |
||||
|
return new Iterator<Integer>() { |
||||
|
private int cur = start; |
||||
|
|
||||
|
@Override |
||||
|
public boolean hasNext() |
||||
|
{ |
||||
|
cur = mask.nextClearBit(cur); |
||||
|
if (cur >= 0 && cur < end) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Integer next() |
||||
|
{ |
||||
|
cur = mask.nextClearBit(cur); |
||||
|
if (cur >= 0 && cur < end) { |
||||
|
int rv = cur - start; |
||||
|
cur++; |
||||
|
return rv; |
||||
|
} |
||||
|
throw new UnsupportedOperationException(); |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue