/**
   * Compute the min/max probability, from the initial state, of reaching a set of target locations.
   */
  private double computeProbabilisticReachability(BitSet targetLocs, boolean min)
      throws PrismException {
    // Determine which method to use for computation
    String ptaMethod = prism.getSettings().getString(PrismSettings.PRISM_PTA_METHOD);

    // Do probability computation through abstraction/refinement/stochastic games
    if (ptaMethod.equals("Stochastic games")) {
      PTAAbstractRefine ptaAR;
      ptaAR = new PTAAbstractRefine();
      String arOptions = prism.getSettings().getString(PrismSettings.PRISM_AR_OPTIONS);
      ptaAR.setLog(mainLog);
      ptaAR.parseOptions(arOptions.split(","));
      return ptaAR.forwardsReachAbstractRefine(pta, targetLocs, null, min);
    }

    // Do probability computation by first constructing a bisimulation
    else if (ptaMethod.equals("Bisimulation minimisation")) {
      // Not supported yet
      throw new PrismException("Not yet supported");
    } else throw new PrismException("Unknown PTA solution method");
  }
  /** Constructor. */
  public PTAModelChecker(Prism prism, ModulesFile modulesFile, PropertiesFile propertiesFile)
      throws PrismException {
    this.prism = prism;
    mainLog = prism.getMainLog();
    this.modulesFile = modulesFile;
    this.propertiesFile = propertiesFile;

    // Get combined constant values from model/properties
    constantValues = new Values();
    constantValues.addValues(modulesFile.getConstantValues());
    if (propertiesFile != null) constantValues.addValues(propertiesFile.getConstantValues());

    // Build a combined label list and expand any constants
    // (note labels in model are ignored (removed) during PTA translation so need to store here)
    labelList = new LabelList();
    for (int i = 0; i < modulesFile.getLabelList().size(); i++) {
      labelList.addLabel(
          modulesFile.getLabelList().getLabelNameIdent(i),
          modulesFile.getLabelList().getLabel(i).deepCopy());
    }
    for (int i = 0; i < propertiesFile.getLabelList().size(); i++) {
      labelList.addLabel(
          propertiesFile.getLabelList().getLabelNameIdent(i),
          propertiesFile.getLabelList().getLabel(i).deepCopy());
    }
    labelList = (LabelList) labelList.replaceConstants(constantValues);

    // Build mapping from all (original model) variables to non-clocks only
    int numVars = modulesFile.getNumVars();
    nonClockVarMap = new int[numVars];
    int count = 0;
    for (int i = 0; i < numVars; i++) {
      if (modulesFile.getVarType(i) instanceof TypeClock) {
        nonClockVarMap[i] = -1;
      } else {
        nonClockVarMap[i] = count++;
      }
    }
  }