Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: exptree/expressionTree.java


1   /* Evolvo - Image Generator
2    * Copyright (C) 2000 Andrew Molloy
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU General Public License
6    * as published by the Free Software Foundation; either version 2
7    * of the License, or (at your option) any later version.
8   
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13  
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17   */
18  
19  /*
20   * @(#)exptressionTree.java   0.1   08/19/2000
21   */
22  
23  package exptree;
24  
25  import java.lang.ref.*;
26  import java.io.*;
27  import exptree.operators.*;
28  import exptree.utilities.*;
29  
30  /**
31   * Handles mathematic expressions in a tree structure, including
32   * storage, evaluation, and display.  Will eventually provide the
33   * functionality to manipulate the tree as well.
34   *
35   * @version 1.1 08/19/2000
36   * @author Andy Molloy
37   */
38  public class expressionTree implements Serializable
39  {
40     /** Holds parameters to this node's operator. */
41     expressionTree[] params;
42     /** Holds the operator for this node of the tree. */
43     operatorInterface operator;
44     /** Holds the cached value for this branch.  */
45     double cachedValue;
46     boolean cacheable = false;
47  
48     /** Creates a new expressionTree */
49     public expressionTree() {}
50  
51     /** Creates a new expressionTree with operator op and parameters prms[] */
52     public expressionTree(expressionTree[] prms, operatorInterface op)
53     {
54        params = prms;
55        operator = op;
56     }
57  
58     /** Convenience method to retrieve a clone of expressionTree as type expressionTree. */
59     public expressionTree getClone(variablePackage v)
60     {
61        int counter;
62  
63        expressionTree[] newParams = new expressionTree[operator.getNumberOfParameters()]; // create a new array of expressionTrees
64        for (counter = 0; counter < operator.getNumberOfParameters(); counter++ )
65        {
66           newParams[counter] = params[counter].getClone(v);  // and fill it with clones of our current parameters.
67        }                                                    // This recurses until it reaches terminal nodes.
68        
69        expressionTree newET = new expressionTree(newParams, operator); // create a new expressionTree using this new array
70  
71        return newET;
72     }
73  
74     /** Evaluate the expressionTree, returning the result as a double. */
75     public double evaluate()
76     {
77        if (cacheable)
78        {
79           return cachedValue;
80        }
81        else
82        {
83           return operator.evaluate(params);
84        }
85     }
86  
87     /** Returns a (sort of) human readable string representation of the expression.
88       * The resulting string contains the expression written in prefix notation.  For example,
89       * The simple equation "1+1" would be written as "+(1, 1)".  This notation is
90       * somewhat unusual, but is the closest written notation to this class' internal representation
91       * of the expression. */
92     public String toString()
93     {
94        int count;
95        int len = operator.getNumberOfParameters();
96        StringBuffer theString = new StringBuffer();
97  
98        theString.append(operator.getName() + "(");
99  
100       for(count = 0; count < len; count++)
101       {
102          theString.append(params[count].toString());  // Recurse into the params array
103          if(count < (len - 1))
104          {
105             theString.append(", ");
106          }
107       }
108 
109       theString.append(")");
110 
111       return theString.toString();
112    }
113 
114    /** Returns the name of this node's operator. */
115    public String getName()
116    {
117       return(operator.getName());
118    }
119 
120    /** Returns the number of parameter's this node's operator expects. */
121    public int getParamLength()
122    {
123       return(operator.getNumberOfParameters());
124    }
125 
126    /** Set this node's parameters. 
127      * <B>Note:</B> Currently does not check that p[] has the correct number of
128      * elements.  If p[] has too many elements, the extras are simply thrown out.
129      * If, however, there are too few, the results are unpredicatable.
130      *
131      * This behavior should be modified in future versions to be more robust.
132      */
133    public void setParams(expressionTree p[])
134    {
135       int count;
136       int len = operator.getNumberOfParameters();
137 
138       params = new expressionTree[len];
139 
140       for(count = 0; count < len; count++)
141       {
142          params[count] = p[count];
143       }
144    }
145 
146    /** Returns the number of parameters this node expects. */
147    public int getNumParams()
148    {
149       return operator.getNumberOfParameters();
150    }
151 
152    /** Returns the parameters this node is holding. */
153    public expressionTree[] getParams()
154    {
155       return params;
156    }
157 
158    /** Returns the operator this node holds. */
159    public operatorInterface getOperator()
160    {
161       return operator;
162    }
163 
164    /** Sets this node's operator.
165      * <B>Note:</B> If the new operator expects more parameters than
166      * the current operator, results are unpredicatable.
167      *
168      * This behaviour should be modified in future version to be more robust. */
169    public void setOperator(operatorInterface o)
170    {
171       operator = o;
172    }
173 
174    /** Determines if this branch of the tree is cacheable (ie, the value never changes).
175      * A side effect of calling this function is that a cache is built.
176      */
177    public boolean isCacheable()
178    {
179       boolean canBeCached = true;
180 
181       for (int i = 0; i < operator.getNumberOfParameters(); i++)
182       {
183          canBeCached &= params[i].isCacheable();
184       }
185 
186       if (canBeCached)
187       {
188          cachedValue = evaluate();
189       }
190       
191       cacheable = canBeCached;
192 
193       return cacheable;
194    }
195 
196    /** Builds a cache for this branch.  Simply calls the isCacheable() method, throwing away its
197      * return value.
198      */
199    public void buildCache()
200    {
201       cacheable = false;
202       boolean trash = isCacheable();
203    }
204 }