gt:             if (j != (probability_functions[i].values.length - 1))
context: /**
   * BayesNet.java
   * @author Fabio G. Cozman 
   * Copyright 1996 - 1999, Fabio G. Cozman,
   *          Carnergie Mellon University, Universidade de Sao Paulo
   * fgcozman@usp.br, http://www.cs.cmu.edu/~fgcozman/home.html
   *
   * The JavaBayes distribution 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), 
   * provided that this notice and the name of the author appear in all 
   * copies. Upon request to the author, some of the packages in the 
   * JavaBayes distribution can be licensed under the GNU Lesser General
   * Public License as published by the Free Software Foundation (either
   * version 2 of the License, or (at your option) any later version).
   * If you're using the software, please notify fgcozman@usp.br so
   * that you can receive updates and patches. JavaBayes is distributed
   * "as is", 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 the JavaBayes distribution. If not, write to the Free
   * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  
  package edu.cmu.cs.in.ml.bayesiannet.BayesianNetworks;
  
  import edu.cmu.cs.in.ml.bayesiannet.*;
  import edu.cmu.cs.in.ml.bayesiannet.InterchangeFormat.IFException;
  import edu.cmu.cs.in.ml.bayesiannet.InterchangeFormat.InterchangeFormat;
  
  import java.io.*;
  import java.net.URL;
  import java.util.Vector;
  import java.util.Enumeration;
  import java.util.Date;
  
  /* ************************************************************************ */
  
  public class BayesNet {
    protected String name;
    protected Vector properties;
    protected ProbabilityVariable probability_variables[];
    protected ProbabilityFunction probability_functions[];
    protected DiscreteFunction utility_function;
  
    public final static int INVALID_INDEX = -1;
  
    public final static int BIF = 1;
    public final static int XML = 2;
    public final static int BUGS = 3;
  
    /**
     * Default constructor for a BayesNet.
     */
    public BayesNet() {
    }
  
    /**
     * Simple constructor for a BayesNet.
     * @param n_n Name of the network.
     * @param n_v Number of variables in the network.
     * @param n_f Number of probability distributions in the network.
     */
    public BayesNet(String n_n, int n_v, int n_f) {
      this();
      name = n_n;
      probability_variables = new ProbabilityVariable[n_v];
      probability_functions = new ProbabilityFunction[n_f];
    }
  
    /**
     * Simple constructor for a BayesNet.
     * @param n_n Name of network.
     * @param p Properties of the network.
     */
    public BayesNet(String n_n, Vector p) {
      this();
      name = n_n;
      properties = p;
    }
  
    /**
     * Simple constructor for a BayesNet; creates a copy of a given
     * network.
     * @param bn Network to be copied.
     */
    public BayesNet(BayesNet bn) {
      this(bn.name, bn.probability_variables.length,
           bn.probability_functions.length);
  
      for (int i=0; i<bn.probability_variables.length; i++)
          probability_variables[i] = bn.probability_variables[i];
      for (int i=0; i<bn.probability_functions.length; i++)
          probability_functions[i] = bn.probability_functions[i];
  
      properties = bn.properties;
    }
  
    /**
     * Construct a BayesNet from a textual description in a string.
     */
    public BayesNet(String s) throws IFException {
      this();
      StringBufferInputStream istream = new StringBufferInputStream(s);
      // Read the BayesNet from the stream
      InterchangeFormat ifo = new InterchangeFormat(istream);
      ifo.CompilationUnit();
      // Transfer information from the parser
      translate(ifo);
    }
  
    /**
     * Construct a BayesNet from a textual description in a stream.
     */
    public BayesNet(InputStream istream) throws IFException {
      this();
  
      // Read the BayesNet from the stream
      InterchangeFormat ifo = new InterchangeFormat(istream);    
      ifo.CompilationUnit();
  
      // Now transfer information from the parser
      translate(ifo);
    }
  
    /**
     * Construct a BayesNet from a textual description
     * in an URL.
     * @param context The URL context as defined in the Java libraries.
     * @param spec The URL spec as defined in the Java libraries.
     */
    public BayesNet(URL context, String spec) throws IFException, IOException {
      this();
      URL url = new URL(context, spec);
      InputStream istream = url.openStream();
      // Read the BayesNet from the stream
      InterchangeFormat ifo = new InterchangeFormat(istream);
      ifo.CompilationUnit();
      // Now transfer information from the parser
      translate(ifo);
      istream.close();
    }
  
    /**
     * Construct a BayesNet from a textual description in an URL.
     */
    public BayesNet(URL url) throws IFException, IOException {
      this();
      InputStream istream = url.openStream();
      // Read the BayesNet from the stream
      InterchangeFormat ifo = new InterchangeFormat(istream);
      ifo.CompilationUnit();
      // Now transfer information from the parser
      translate(ifo);
      istream.close();
    }
  
    /*
     * Translate the contents of a
     * IFBayesNet object into a BayesNet object.
     *
     * This method makes modifications to the basic objects
     * supported by the InterchangeFormat, so that the full
     * functionality of the BayesianNetworks package can be used.
     * As the InterchangeFormat evolves, probably some of the
     * objects created through extensions will be created directly
     * by the parser as it parses an InterchangeFormat stream.
     * Right now the extensions involve:
     * 1) Detecting observed variables.
     * 2) Detecting explanation variables.
     */
    protected void translate(InterchangeFormat ifo) {
      ConvertInterchangeFormat cbn = new ConvertInterchangeFormat(ifo);
      name = cbn.get_name();
      properties = cbn.get_properties();
      probability_variables = cbn.get_probability_variables(this);
      probability_functions = cbn.get_probability_functions(this);
  
      // Process BayesNet properties
      process_properties();
  
      // Process ProbabilityVariable properties
      for (int i=0; i<probability_variables.length; i++)
        process_probability_variable_properties(i);
  
      // Process ProbabilityFunction properties
      for (int i=0; i<probability_functions.length; i++)
        process_probability_function_properties(i);
    }
  
    /*
     * Make modifications to a BayesNet based on the properties of
     * the BayesNet.
     */
    protected void process_properties() { }
  
    /*
     * Process the properties of a ProbabilityVariable.
     */
    protected void process_probability_variable_properties(int index) {
      probability_variables[index].process_properties();
    }
  
    /*
     * Process the properties of a ProbabilityFunction.
     */
    protected void process_probability_function_properties(int index) {
      probability_functions[index].process_properties();
    }
  
    /**
     * Find the ProbabilityFunction that corresponds to a
     * given ProbabilityVariable.
     * Note: the index of a variable is used by the function, as it
     * is the only reference to the variable that is guaranteed to identify
     * the variable uniquely.
     */
    public ProbabilityFunction get_function(ProbabilityVariable p_v) {
      for (int i=0; i<probability_functions.length; i++)
          if (p_v.index == probability_functions[i].variables[0].index)
              return(probability_functions[i]);
  
      return(null);
    }
  
    /**
     * Save a BayesNet object in a stream, in the BIF InterchangeFormat.
     */
    public void save_bif(PrintStream out) {
      int i;
      String property;
  
      out.println("// Bayesian network ");
      if (name != null)
        out.print("network \"" + name + "\" {");
      if (probability_variables != null)
        out.print(" //" + probability_variables.length + " variables");
      if (probability_functions != null)
        out.print(" and " + probability_functions.length +
  		       " probability distributions");
  
      out.println();
      if ((properties != null) && (properties.size() > 0)) {
        for (Enumeration e = properties.elements(); e.hasMoreElements(); ) {
  	property = (String)(e.nextElement());
  	out.println("\tproperty \"" + property + "\" ;");
        }
      }
      out.println("}");
      if (probability_variables != null)
        for (i=0; i<probability_variables.length; i++)
  	if (probability_variables[i] != null)
  	  probability_variables[i].print(out);
      if (probability_functions != null)
        for (i=0; i<probability_functions.length; i++)
  	if (probability_functions[i] != null)
  	  probability_functions[i].print(out);
    }
  
    /**
     * Save a BayesNet object in a stream for the EBayes engine.
     */
    public void save_embayes(PrintStream out) {
      int i, j;
      out.println("import ebayes.data.*");
      out.println("class " + name + " extends BayesNet {");
      out.println("\tpublic " + name + "() {");
      out.println("\tsetName(\"" + name + "\");");
  
      for (i=0; i<probability_variables.length; i++) {
          out.println("\tCategoricalVariable " + 
                      probability_variables[i].name + " = ");
          out.println("\t\tnew CategoricalVariable(\"" + 
                      probability_variables[i].name + "\",");
          out.print("\t\t\tnew String[] {");
          for (j=0; j<probability_variables[i].values.length; j++) {
              out.print("\"" + probability_variables[i].values[j] + "\"");
              if (j != (probability_variables[i].values.length - 1))
                  out.print(",");
          }
          out.println("});\n");
      }
      out.println("\n\n");
      for (i=0; i<probability_functions.length; i++) {
          out.println("\tCategoricalProbability p" + i + " = ");
          out.println("\t\tnew CategoricalProbability(" +
                      probability_functions[i].variables[0].get_name() + ",");
          if (probability_functions[i].variables.length > 1) {
              out.print("\t\t\tnew CategoricalVariable[] {");
              for (j=1; j<probability_functions[i].variables.length; j++) {
                  out.print(probability_functions[i].variables[j].get_name());
                  if (j != (probability_functions[i].variables.length - 1))
                      out.print(", ");
              }
              out.println("}, ");
          }
          out.print("\t\t\tnew double[] {");
          for (j=0; j<probability_functions[i].values.length; j++) {
              out.print(probability_functions[i].values[j]);
  