Browse Source
prism/ModelVariablesDD: for handling the MTBDD variable related logic for symbolic models
prism/ModelVariablesDD: for handling the MTBDD variable related logic for symbolic models
git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@11823 bbc10eb1-c90d-0410-af57-cb519fbb1720master
1 changed files with 208 additions and 0 deletions
@ -0,0 +1,208 @@ |
|||
//============================================================================== |
|||
// |
|||
// 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 prism; |
|||
|
|||
import java.util.Vector; |
|||
|
|||
import jdd.JDD; |
|||
import jdd.JDDNode; |
|||
import jdd.JDDVars; |
|||
|
|||
/** |
|||
* Management and information storage about the DD variables |
|||
* used by a symbolic model. |
|||
* <br> |
|||
* After use, the variable references should be cleared by |
|||
* calling {@code clear()}. |
|||
*/ |
|||
public class ModelVariablesDD |
|||
{ |
|||
/** Vector of DD variable names for the allocated variables */ |
|||
private Vector<String> ddVarNames = new Vector<String>(); |
|||
/** The allocated variables */ |
|||
private JDDVars ddVariables = new JDDVars(); |
|||
/** The next free variable index */ |
|||
private int nextDDVarIndex = 0; |
|||
|
|||
/** Storage for the preallocated extra state variables */ |
|||
private JDDVars extraStateVariables = new JDDVars(); |
|||
|
|||
/** Constructor */ |
|||
public ModelVariablesDD() |
|||
{ |
|||
} |
|||
|
|||
/** |
|||
* Create a copy of this ModelVariablesDD. |
|||
* All variable information is copied, i.e., the |
|||
* result has to be cleared after use. |
|||
*/ |
|||
public ModelVariablesDD copy() |
|||
{ |
|||
ModelVariablesDD result = new ModelVariablesDD(); |
|||
result.ddVarNames = new Vector<String>(ddVarNames); |
|||
result.ddVariables = ddVariables.copy(); |
|||
result.extraStateVariables = extraStateVariables.copy(); |
|||
result.nextDDVarIndex = nextDDVarIndex; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/** Clear all variable references */ |
|||
public void clear() |
|||
{ |
|||
ddVariables.derefAll(); |
|||
extraStateVariables.derefAll(); |
|||
} |
|||
|
|||
/** Return the vector with variable names for a given variable index */ |
|||
public Vector<String> getDDVarNames() |
|||
{ |
|||
return ddVarNames; |
|||
} |
|||
|
|||
/** |
|||
* Allocate a new variable for the model. |
|||
* <br>[ REFS: <i>result</i> ] |
|||
* @param name a name for the variable |
|||
*/ |
|||
public JDDNode allocateVariable(String name) |
|||
{ |
|||
JDDNode v = JDD.Var(nextDDVarIndex); |
|||
nextDDVarIndex++; |
|||
|
|||
ddVariables.addVar(v.copy()); |
|||
|
|||
ddVarNames.add(name); |
|||
return v; |
|||
} |
|||
|
|||
/** Preallocate the given number of state variables */ |
|||
public void preallocateExtraStateVariables(int count) |
|||
{ |
|||
for (int i=0; i<count; i++) { |
|||
JDDNode v = allocateVariable(""); |
|||
extraStateVariables.addVar(v); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Allocate a new state variable from the pool of |
|||
* preallocated state variables. |
|||
* <br> |
|||
* If the pool is empty, allocate a new variable |
|||
* at the end. |
|||
* <br> [ REFS: <i>result</i> ] |
|||
* @param name the name for the variable |
|||
*/ |
|||
public JDDNode allocateExtraStateVariable(String name) |
|||
{ |
|||
JDDNode v; |
|||
if (extraStateVariables.getNumVars() > 0) { |
|||
v = extraStateVariables.getVar(0); |
|||
extraStateVariables.removeVar(v); |
|||
|
|||
ddVarNames.set(v.getIndex(), name); |
|||
} else { |
|||
// allocate at the end |
|||
v = allocateVariable(name); |
|||
} |
|||
return v; |
|||
} |
|||
|
|||
/** |
|||
* Returns true if there are enough preallocated state variables |
|||
* such that {@code 2*bits} variables can be allocated from the pool |
|||
*/ |
|||
public boolean canPrependExtraStateVariable(int bits) |
|||
{ |
|||
return (bits*2 <= extraStateVariables.getNumVars()); |
|||
} |
|||
|
|||
/** |
|||
* Allocate {@code bits} pairs of row and col variables. |
|||
* <br> |
|||
* If {@code prepend} is true and there is not enough space |
|||
* in the preallocated state variable pool, throws an exception. |
|||
* <br>[ REFS: <i>result</i> ] |
|||
* @param bits number of state variable pairs |
|||
* @param name the name of the variable |
|||
* @param prepend should the variables be allocated from the preallocated pool? |
|||
*/ |
|||
public JDDVars allocateExtraStateVariable(int bits, String name, boolean prepend) throws PrismException |
|||
{ |
|||
int newVarCount = 2*bits; |
|||
|
|||
JDDVars result = new JDDVars(); |
|||
if (newVarCount == 0) return result; |
|||
|
|||
if (prepend) { |
|||
if (!canPrependExtraStateVariable(bits)) { |
|||
throw new PrismException("Can not prepend "+(newVarCount)+" extra row/col variables"); |
|||
} |
|||
|
|||
// take the bottom nVarCount extra variables from the |
|||
// extraStateVariables array, starting with index v |
|||
int v = extraStateVariables.getNumVars() - newVarCount; |
|||
for (int i=0; i < bits; i++) { |
|||
// transfer row, col from extraStateVariables to result, |
|||
// no need to ref again |
|||
JDDNode row_var = extraStateVariables.getVar(v++); |
|||
JDDNode col_var = extraStateVariables.getVar(v++); |
|||
|
|||
result.addVar(row_var); |
|||
result.addVar(col_var); |
|||
|
|||
ddVarNames.set(row_var.getIndex(), name+"."+i); |
|||
ddVarNames.set(col_var.getIndex(), name+"'."+i); |
|||
} |
|||
|
|||
// remove variables from extraStateVariables |
|||
extraStateVariables.removeVars(result); |
|||
|
|||
return result; |
|||
} else { |
|||
for (int i=0; i < bits; i++) { |
|||
result.addVar(allocateVariable(name+"."+i)); |
|||
result.addVar(allocateVariable(name+"'."+i)); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* Get the extra state variables. |
|||
* This is not a copy. |
|||
* |
|||
* <br>[ REFs: <i>none</i>, DEREFs: <i>none</i> ] |
|||
*/ |
|||
public JDDVars getExtraStateVariables() { |
|||
return extraStateVariables; |
|||
} |
|||
|
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue