public static IndependenceFactsModel loadFacts(Reader reader) throws IOException {
    IndependenceFactsModel facts = new IndependenceFactsModel();
    Set<String> names = new HashSet<String>();
    Map<String, Node> nodes = new HashMap<String, Node>();

    BufferedReader in = new BufferedReader(reader);
    String line;

    while ((line = in.readLine()) != null) {
      String[] tokens = line.split("[ ,;_|]+");

      if (tokens.length == 0) continue;
      if (tokens.length < 2)
        throw new IllegalArgumentException(
            "Must specify at least two variables--e.g. X1 X2, for X1 _||_ X2.");

      for (String token : tokens) {
        names.add(token);

        if (!nodes.containsKey(token)) {
          nodes.put(token, new GraphNode(token));
        }
      }

      List<Node> z = new ArrayList<Node>();

      for (int i = 2; i < tokens.length; i++) {
        z.add(nodes.get(tokens[i]));
      }

      facts.add(new IndependenceFact(nodes.get(tokens[0]), nodes.get(tokens[1]), z));
    }

    return facts;
  }
  /**
   * Constructs a wrapper for the given DataWrapper. The DatWrapper must contain a DataSet that is
   * either a DataSet or a DataSet or a DataList containing either a DataSet or a DataSet as its
   * selected model.
   *
   * @param knowledgeBoxModel
   */
  public AbstractAlgorithmRunner(
      DataWrapper dataWrapper,
      Parameters params,
      KnowledgeBoxModel knowledgeBoxModel,
      IndependenceFactsModel facts) {
    if (dataWrapper == null) {
      throw new NullPointerException();
    }
    if (params == null) {
      throw new NullPointerException();
    }

    this.params = params;
    this.sourceGraph = dataWrapper.getSourceGraph();

    DataModel dataSource = getSelectedDataModel(dataWrapper);

    this.dataWrapper = dataWrapper;

    // temporary workaround to get the knowledge box to coexist with the dataWrapper's knowledge
    if (knowledgeBoxModel == null) {
      getParams().set("knowledge", dataWrapper.getKnowledge());
    } else {
      getParams().set("knowledge", knowledgeBoxModel.getKnowledge());
    }

    getParams().set("independenceFacts", facts.getFacts());
    List names = dataSource.getVariableNames();
    transferVarNamesToParams(names);
  }
  public AbstractAlgorithmRunner(
      IndependenceFactsModel model, Parameters params, KnowledgeBoxModel knowledgeBoxModel) {
    if (model == null) {
      throw new NullPointerException();
    }
    if (params == null) {
      throw new NullPointerException();
    }

    this.params = params;

    DataModel dataSource = model.getFacts();

    if (knowledgeBoxModel != null) {
      getParams().set("knowledge", knowledgeBoxModel.getKnowledge());
    }

    List names = dataSource.getVariableNames();
    transferVarNamesToParams(names);
    this.dataModel = dataSource;
  }