public void testSampling3() {
    BayesianNetwork network = new BayesianNetwork();
    BayesianEvent a = network.createEvent("a");
    BayesianEvent x1 = network.createEvent("x1");
    BayesianEvent x2 = network.createEvent("x2");
    BayesianEvent x3 = network.createEvent("x3");

    network.createDependancy(a, x1, x2, x3);
    network.finalizeStructure();

    a.getTable().addLine(0.5, true); // P(A) = 0.5
    x1.getTable().addLine(0.2, true, true); // p(x1|a) = 0.2
    x1.getTable().addLine(0.6, true, false); // p(x1|~a) = 0.6
    x2.getTable().addLine(0.2, true, true); // p(x2|a) = 0.2
    x2.getTable().addLine(0.6, true, false); // p(x2|~a) = 0.6
    x3.getTable().addLine(0.2, true, true); // p(x3|a) = 0.2
    x3.getTable().addLine(0.6, true, false); // p(x3|~a) = 0.6
    network.validate();

    SamplingQuery query = new SamplingQuery(network);
    query.defineEventType(x1, EventType.Evidence);
    query.defineEventType(x3, EventType.Outcome);
    query.setEventValue(x1, true);
    query.setEventValue(x3, true);
    query.execute();
    testPercent(query.getProbability(), 50);
  }
  /** {@inheritDoc} */
  @Override
  public final Object read(final InputStream is) {
    final BayesianNetwork result = new BayesianNetwork();
    final EncogReadHelper in = new EncogReadHelper(is);
    EncogFileSection section;
    String queryType = "";
    String queryStr = "";
    String contentsStr = "";

    while ((section = in.readNextSection()) != null) {
      if (section.getSectionName().equals("BAYES-NETWORK")
          && section.getSubSectionName().equals("BAYES-PARAM")) {
        final Map<String, String> params = section.parseParams();
        queryType = params.get("queryType");
        queryStr = params.get("query");
        contentsStr = params.get("contents");
      }
      if (section.getSectionName().equals("BAYES-NETWORK")
          && section.getSubSectionName().equals("BAYES-TABLE")) {

        result.setContents(contentsStr);

        // first, define relationships (1st pass)
        for (String line : section.getLines()) {
          result.defineRelationship(line);
        }

        result.finalizeStructure();

        // now define the probabilities (2nd pass)
        for (String line : section.getLines()) {
          result.defineProbability(line);
        }
      }
      if (section.getSectionName().equals("BAYES-NETWORK")
          && section.getSubSectionName().equals("BAYES-PROPERTIES")) {
        final Map<String, String> params = section.parseParams();
        result.getProperties().putAll(params);
      }
    }

    // define query, if it exists
    if (queryType.length() > 0) {
      BayesianQuery query = null;
      if (queryType.equals("EnumerationQuery")) {
        query = new EnumerationQuery(result);
      } else {
        query = new SamplingQuery(result);
      }

      if (query != null && queryStr.length() > 0) {
        result.setQuery(query);
        result.defineClassificationStructure(queryStr);
      }
    }

    return result;
  }
  public void testSampling1() {
    BayesianNetwork network = new BayesianNetwork();
    BayesianEvent a = network.createEvent("a");
    BayesianEvent b = network.createEvent("b");

    network.createDependancy(a, b);
    network.finalizeStructure();
    a.getTable().addLine(0.5, true); // P(A) = 0.5
    b.getTable().addLine(0.2, true, true); // p(b|a) = 0.2
    b.getTable().addLine(0.8, true, false); // p(b|~a) = 0.8	
    network.validate();

    SamplingQuery query = new SamplingQuery(network);
    query.defineEventType(a, EventType.Evidence);
    query.defineEventType(b, EventType.Outcome);
    query.setEventValue(b, true);
    query.setEventValue(a, true);
    query.execute();
    testPercent(query.getProbability(), 20);
  }
  /**
   * Define the structure of the Bayesian network as a string.
   *
   * @param line The string to define events and relations.
   */
  public void setContents(String line) {
    List<ParsedProbability> list = ParseProbability.parseProbabilityList(this, line);
    List<String> labelList = new ArrayList<String>();

    // ensure that all events are there
    for (ParsedProbability prob : list) {
      ParsedEvent parsedEvent = prob.getChildEvent();
      String eventLabel = parsedEvent.getLabel();
      labelList.add(eventLabel);

      // create event, if not already here
      BayesianEvent e = getEvent(eventLabel);
      if (e == null) {
        List<BayesianChoice> cl = new ArrayList<BayesianChoice>();

        for (ParsedChoice c : parsedEvent.getList()) {
          cl.add(new BayesianChoice(c.getLabel(), c.getMin(), c.getMax()));
        }

        createEvent(eventLabel, cl);
      }
    }

    // now remove all events that were not covered
    for (int i = 0; i < events.size(); i++) {
      BayesianEvent event = this.events.get(i);
      if (!labelList.contains(event.getLabel())) {
        removeEvent(event);
      }
    }

    // handle dependencies
    for (ParsedProbability prob : list) {
      ParsedEvent parsedEvent = prob.getChildEvent();
      String eventLabel = parsedEvent.getLabel();

      BayesianEvent event = requireEvent(eventLabel);

      // ensure that all "givens" are present
      List<String> givenList = new ArrayList<String>();
      for (ParsedEvent given : prob.getGivenEvents()) {
        if (!event.hasGiven(given.getLabel())) {
          BayesianEvent givenEvent = requireEvent(given.getLabel());
          this.createDependency(givenEvent, event);
        }
        givenList.add(given.getLabel());
      }

      // now remove givens that were not covered
      for (int i = 0; i < event.getParents().size(); i++) {
        BayesianEvent event2 = event.getParents().get(i);
        if (!givenList.contains(event2.getLabel())) {
          removeDependency(event2, event);
        }
      }
    }

    // finalize the structure
    finalizeStructure();
    if (this.query != null) {
      this.query.finalizeStructure();
    }
  }