STORM_LOG_THROW(automata.size()==this->model.getNumberOfAutomata(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model whose system composition refers to a subset of automata.");
// Then, check that the model does not contain unbounded integer or non-transient real variables.
STORM_LOG_THROW(!this->model.getGlobalVariables().containsUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains global unbounded integer variables.");
STORM_LOG_THROW(!automaton.getVariables().containsUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains unbounded integer variables in automaton '"<<automaton.getName()<<"'.");
}
// Then, check that the model does not contain non-transient unbounded integer or non-transient real variables.
STORM_LOG_THROW(!this->model.getGlobalVariables().containsNonTransientUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains non-transient global unbounded integer variables.");
STORM_LOG_THROW(!this->model.getGlobalVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains global non-transient real variables.");
STORM_LOG_THROW(!automaton.getVariables().containsNonTransientUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains non-transient unbounded integer variables in automaton '"<<automaton.getName()<<"'.");
STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains non-transient real variables in automaton '"<<automaton.getName()<<"'.");
// Check that the model does not contain unbounded integer or non-real transient variables.
STORM_LOG_THROW(!model.getGlobalVariables().containsUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains global unbounded integer variables.");
// Check that the model does not contain non-transient unbounded integer or non-transient real variables.
STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build model from JANI model that contains global non-transient real variables.");
STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build model from JANI model that contains non-transient unbounded integer variables.");
for(autoconst&automaton:model.getAutomata()){
STORM_LOG_THROW(!automaton.getVariables().containsUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains unbounded integer variables in automaton '"<<automaton.getName()<<"'.");
}
STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains global non-transient real variables.");
for(autoconst&automaton:model.getAutomata()){
STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build symbolic model from JANI model that contains non-transient real variables in automaton '"<<automaton.getName()<<"'.");
STORM_LOG_THROW(!automaton.getVariables().containsNonTransientUnboundedIntegerVariables(),storm::exceptions::InvalidArgumentException,"Cannot build model from JANI model that contains non-transient unbounded integer variables in automaton '"<<automaton.getName()<<"'.");
STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(),storm::exceptions::InvalidArgumentException,"Cannot build model from JANI model that contains non-transient real variables in automaton '"<<automaton.getName()<<"'.");
// STORM_LOG_THROW(variableStructure.at("type").count("kind") == 1, storm::exceptions::InvalidJaniException, "For complex type as in variable " << name << "(scope: " << scopeDescription << ") kind must be given");
// std::string kind = getString(variableStructure.at("type").at("kind"), "kind for complex type as in variable " + name + "(scope: " + scopeDescription + ") ");
// if(kind == "bounded") {
// // First do the bounds, that makes the code a bit more streamlined
// STORM_LOG_THROW(variableStructure.at("type").count("lower-bound") == 1, storm::exceptions::InvalidJaniException, "For bounded type as in variable " << name << "(scope: " << scopeDescription << ") lower-bound must be given");
// storm::expressions::Expression lowerboundExpr = parseExpression(variableStructure.at("type").at("lower-bound"), "Lower bound for variable "+ name + " (scope: " + scopeDescription + ")");
// assert(lowerboundExpr.isInitialized());
// STORM_LOG_THROW(variableStructure.at("type").count("upper-bound") == 1, storm::exceptions::InvalidJaniException, "For bounded type as in variable " << name << "(scope: " << scopeDescription << ") upper-bound must be given");
// storm::expressions::Expression upperboundExpr = parseExpression(variableStructure.at("type").at("upper-bound"), "Upper bound for variable "+ name + " (scope: " + scopeDescription + ")");
// assert(upperboundExpr.isInitialized());
// STORM_LOG_THROW(variableStructure.at("type").count("base") == 1, storm::exceptions::InvalidJaniException, "For bounded type as in variable " << name << "(scope: " << scopeDescription << ") base must be given");
// std::string basictype = getString(variableStructure.at("type").at("base"), "base for bounded type as in variable " + name + "(scope: " + scopeDescription + ") ");
// if(basictype == "int") {
// STORM_LOG_THROW(lowerboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Lower bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed");
// STORM_LOG_THROW(upperboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Upper bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed");
initVal=parseExpression(variableStructure.at("initial-value"),"Initial value for variable "+name+" (scope: "+scopeDescription+") ");
STORM_LOG_THROW(initVal.get().hasRationalType()||initVal.get().hasIntegerType(),storm::exceptions::InvalidJaniException,"Initial value for rational variable "+name+"(scope "+scopeDescription+") should be a rational");
STORM_LOG_THROW(initVal.get().hasRationalType(),storm::exceptions::InvalidJaniException,"Initial value for integer variable "+name+"(scope "+scopeDescription+") should be a rational");
STORM_LOG_THROW(locEntry.count("name")==1,storm::exceptions::InvalidJaniException,"Locations for automaton '"<<name<<"' must have exactly one name");
std::stringlocName=getString(locEntry.at("name"),"location of automaton "+name);
STORM_LOG_THROW(locIds.count(locName)==0,storm::exceptions::InvalidJaniException,"Location with name '"+locName+"' already exists in automaton '"+name+"'");
STORM_LOG_THROW(locEntry.count("time-progress")==0,storm::exceptions::InvalidJaniException,"Time progress conditions in locations as in '"+locName+"' in automaton '"+name+"' are not supported");
STORM_LOG_THROW(locEntry.count("invariant")==0,storm::exceptions::InvalidJaniException,"Invariants in locations as in '"+locName+"' in automaton '"+name+"' are not supported");
//STORM_LOG_THROW(locEntry.count("invariant") > 0 && !supportsInvariants(parentModel.getModelType()), storm::exceptions::InvalidJaniException, "Invariants are not supported in the model type " + to_string(parentModel.getModelType()));
STORM_LOG_THROW(transientValueEntry.count("ref")==1,storm::exceptions::InvalidJaniException,"Transient values in location "<<locName<<" need exactly one ref that is assigned to");
STORM_LOG_THROW(transientValueEntry.count("value")==1,storm::exceptions::InvalidJaniException,"Transient values in location "<<locName<<" need exactly one assigned value");
storm::jani::Variableconst&lhs=getLValue(transientValueEntry.at("ref"),parentModel.getGlobalVariables(),automaton.getVariables(),"LHS of assignment in location "+locName+" (automaton '"+name+"')");
STORM_LOG_THROW(lhs.isTransient(),storm::exceptions::InvalidJaniException,"Assigned non-transient variable "+lhs.getName()+" in location "+locName+" (automaton: '"+name+"')");
storm::expressions::Expressionrhs=parseExpression(transientValueEntry.at("value"),"Assignment of variable "+lhs.getName()+" in location "+locName+" (automaton: '"+name+"')");
STORM_LOG_THROW(transientValueEntry.count("ref")==1,storm::exceptions::InvalidJaniException,"Transient values in location "<<locName<<" need exactly one ref that is assigned to");
STORM_LOG_THROW(transientValueEntry.count("value")==1,storm::exceptions::InvalidJaniException,"Transient values in location "<<locName<<" need exactly one assigned value");
storm::jani::Variableconst&lhs=getLValue(transientValueEntry.at("ref"),parentModel.getGlobalVariables(),automaton.getVariables(),"LHS of assignment in location "+locName+" (automaton '"+name+"')");
STORM_LOG_THROW(lhs.isTransient(),storm::exceptions::InvalidJaniException,"Assigned non-transient variable "+lhs.getName()+" in location "+locName+" (automaton: '"+name+"')");
storm::expressions::Expressionrhs=parseExpression(transientValueEntry.at("value"),"Assignment of variable "+lhs.getName()+" in location "+locName+" (automaton: '"+name+"')");
STORM_LOG_THROW(edgeEntry.count("rate")<2,storm::exceptions::InvalidJaniException,"Edge from '"<<sourceLoc<<"' in automaton '"<<name<<"' has multiple rates");
storm::expressions::ExpressionrateExpr;
if(edgeEntry.count("rate")>0){
STORM_LOG_THROW(edgeEntry.at("rate").count("exp")==1,storm::exceptions::InvalidJaniException,"Rate in edge from '"<<sourceLoc<<"' in automaton '"<<name<<"' has no expression");
rateExpr=parseExpression(edgeEntry.at("rate").at("exp"),"Rate expression in edge from '"+sourceLoc+"' in automaton '"+name+"'");
rateExpr=parseExpression(edgeEntry.at("rate"),"rate expression in edge from '"+sourceLoc+"' in automaton '"+name+"'");
STORM_LOG_THROW(rateExpr.hasNumericalType(),storm::exceptions::InvalidJaniException,"Rate '"<<rateExpr<<"' has not a numerical type");
STORM_LOG_THROW(edgeEntry.count("location")==1,storm::exceptions::InvalidJaniException,"Each destination in edge from '"<<sourceLoc<<"' in automaton '"<<name<<"' must have a target location");
std::stringtargetLoc=getString(edgeEntry.at("location"),"target location for edge from '"+sourceLoc+"' in automaton '"+name+"'");
std::stringtargetLoc=getString(destEntry.at("location"),"target location for edge from '"+sourceLoc+"' in automaton '"+name+"'");
STORM_LOG_THROW(locIds.count(targetLoc)==1,storm::exceptions::InvalidJaniException,"Target of edge has unknown location '"<<targetLoc<<"' in automaton '"<<name<<"'.");
STORM_LOG_THROW(compositionStructure.count("elements")>0,storm::exceptions::InvalidJaniException,"Elements of a composition must be given.");
STORM_LOG_THROW(compositionStructure.count("elements")<2,storm::exceptions::InvalidJaniException,"Elements of a composition must be given at most once.");
STORM_LOG_THROW(compositionStructure.count("elements")==1,storm::exceptions::InvalidJaniException,"Elements of a composition must be given");