View Javadoc

1   /*
2   $Id: Addition.java 710 2005-03-21 16:34:22Z guest $
3   */
4   
5   
6   /*
7   Copyright (C) 2001-2002 Mainline Project (I3S - ESSI - CNRS -UNSA)
8   
9   This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13  
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  Lesser General Public License for more details.
18  
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  
23  For further information on the GNU Lesser General Public License,
24  see: http://www.gnu.org/copyleft/lesser.html
25  For further information on this library, contact: mainline@essi.fr
26  */
27  
28  
29  package fr.ove.openmath.jome.model;
30  
31  import java.util.*;
32  import fr.ove.openmath.jome.model.*;
33  import fr.ove.openmath.jome.model.events.*;
34  import fr.ove.openmath.jome.model.evaluation.*;
35  
36  /***
37  * The operator "+".<BR>
38  *
39  * <CODE>Addition</CODE> represents a node in the formula tree.
40  * Its children are the operands of the operation.
41  *
42  * @author © 1999 DIRAT Laurent
43  * @version 2.0  25/06/1999
44  */
45  public class Addition extends NaryOperator {
46      /***
47      * The Constructor.
48      */
49      public Addition() {
50          setResourceIdentifier("ADDITION");
51          setValue("+");
52          setAsOperatorPriority(resourcesManager.getAsOperatorPriority("plusPriorities"));
53          setAsOperandPriority(resourcesManager.getAsOperandPriority("plusPriorities"));
54          setAreOperandsMovable(true);
55      }
56      
57      /***
58      * Inserts the operator instance in the formula tree, from the current insertion position.
59      * (checks the priorities and goes up in the tree if necessary).
60      *
61      * @param current the current insertion position.
62      * @return the new insertion position.
63      */
64      public FormulaTreeStructure insert(FormulaTreeStructure current) {
65          // On cherche la position d'insertion de notre "+"
66          current = findLocation(current);
67          int currentAsOperandPriority = current.getAsOperandPriority();
68          int currentAsOperatorPriority = current.getAsOperatorPriority();
69  
70          if (currentAsOperatorPriority == getAsOperandPriority()) {
71              // On a dÈj? tapÈ dans la formule un "+", on va donc insÈrer un nouveau
72              // "+" dans le prÈcÈdent ==> cas particuliers.
73              if ((currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryPlusPriorities")) || 
74                  (currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryMinusPriorities"))) {
75                  // Si on est en prÈcense de ce cas l?, la position d'insertion est
76                  // sur un op. unaire ("+"  ou "-"). Il faut rÈcupÈrer le pËre de l'op.
77                  // en question, i.e. une instance d'Addition que l'on a insÈrÈ auparavant
78                  // dansla FST.
79                  FormulaTreeStructure father = (FormulaTreeStructure) current.getFather();
80                  
81                  if (currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryPlusPriorities")) {
82                      FormulaTreeStructure operand = (FormulaTreeStructure) current.getChild(0);
83                      // si en fait, notre position d'insertion est un "+" unaire, on enlËve
84                      // notre opÈrateur unaire pour ne garder que son opÈrande.
85                      // Ex: on avait +a, on tape "+", on gÈnËre a+[?] o? [?] est le template.
86                      int rank = current.getRank();
87                      
88                      father.addChild(operand, rank);
89                      father.removeChild(current);
90                  }
91  
92                  // On insËre notre template.
93                  VariableOrNumber template0 = new VariableOrNumber();
94                  father.addChild(template0);
95                  
96                  // On retourne la refÈrence de notre dernier point d'insertion.
97                  return template0;
98              }
99              
100             // On est dans le cas classique de la saisie d'une suite "+", on insËre
101             // notre template dans la FTS.
102             VariableOrNumber template = new VariableOrNumber();
103             current.addChild(template);
104             
105             // On retourne la refÈrence de notre dernier point d'insertion.
106             return template;
107         }
108         else {
109             // On est dans le cas o? on commence ? saisir une addition.
110             
111             // On ajoute l'opÈrateur "+" comme fils ? l'opÈrateur courant.
112             // Pour gÈrer le fait que l'on puisse taper un "+" binaire ou unaire, 
113             // notre opÈrateur "+" unaire de notre FTS (UnaryPlus) sera ajoutÈ comme
114             // fils ? l'instance courante. D'o? l'ajout systÈmatique suivant ? la position
115             // d'insertion. La distinction de cas singuliers est faite au test suivant.
116             current.addChild(this);
117             
118             // Ce test est nÈcessaire pour savoir si on est dans le cas du "+" binaire
119             // ou du "+" unaire.
120             if (current.getNbChildren() > 1) {
121                 // Il faut que l'on fasse attention pour savoir si l'on veut entrer un "+" unaire ou pas.
122                 // Donc on vient d'ajouter notre instance comme fils a current.
123                 // Si on est l?, 2 solutions,  le fils de current qui a pour rank, le rank de l'instance -1 :
124                 //      * est un template ==> on saisi un plus unaire
125                 //      * n'est pas un template ==> on saisi une addition
126                 FormulaTreeStructure fts = (FormulaTreeStructure) current.getChild(getRank() - 1);
127                 
128                 if(fts.getFather() instanceof Function2){
129 					current.removeChild(fts);
130 					fts = (FormulaTreeStructure) current.getChild(fts.getRank() - 1);
131                 }
132                 
133                 // Quelque soit le cas, on enlËve fts de current.
134                 // Dans le cas du plus unaire, (fts est un template) un template sera rajoutÈ avec
135                 // l'insertion du UnaryPlus
136                 // Dans le cas de l'addition, fts sera ajoutÈ ? notre instance
137                 current.removeChild(fts);
138                 
139                 if ((fts.getAsOperatorPriority() == resourcesManager.getAsOperatorPriority("constantPriorities")) &&
140                     fts.isTemplate()) {
141                     // On ajoute un opÈrateur "+" unaire comme fils ? notre instance
142                     current = this;
143                     current = (new UnaryPlus()).insert(current);
144                     
145                     // On retourne la rÈfÈrence de notre dernier point d'insertion
146                     return current;
147                 }
148                 else {
149                    	addChild(fts);
150                     
151                     // On ajoute un template ? l'addition
152                     VariableOrNumber template = new VariableOrNumber();
153                     addChild(template);
154                     
155                     // On retourne la rÈfÈrence de notre dernier point d'insertion
156                     return template;
157                 }
158             }
159             else { // on est dans le cas du "+" unaire
160                 // Comme dit prÈcÈdemment, on ajoute un opÈrateur "+" unaire comme
161                 // fils ? l'instance courante.
162                 current = this;
163                 current = (new UnaryPlus()).insert(current);
164                 
165                 // On retourne la rÈfÈrence de notre dernier point d'insertion
166                 return current;
167             }
168         }
169     }
170     
171     /***
172     * The Creation of the corresponding linear expression of the formula.
173     */
174     public String createLinear(String linear) {
175         FormulaTreeStructure child;
176         
177         for (int i = 0; i < getNbChildren(); i++) {
178             child = (FormulaTreeStructure) getChild(i);
179             if (i == 0)
180                 linear = child.createLinear(linear);
181             else {
182                 if (!((child instanceof UnaryPlus) || (child instanceof UnaryMinus)))
183                     linear += "+";
184                 linear = child.createLinear(linear);
185             }
186         }
187         return linear;
188     }
189     
190     /***
191     * Evaluates the instance.
192     */
193     public String evaluate() {
194         Vector evaluations = new Vector();
195         
196         // On commence par Èvaluer tous les fils de l'instance
197         for (Enumeration e = getChildren().elements(); e.hasMoreElements(); )
198             evaluations.addElement(((FormulaTreeStructure) e.nextElement()).evaluate());
199     
200         int nbEvaluations = evaluations.size();
201         String anEvaluation, currEvaluation;
202         // Maintenant, on parcourre toutes les Èvaluations calculÈes et on essaye de leur appliquer
203         // l'opÈrateur courant
204         for (int i = 1; i < nbEvaluations; i++) {
205             currEvaluation = (String) evaluations.elementAt(i);
206             
207             for (int j = 0; j < i; j++) {
208                 anEvaluation = (String) evaluations.elementAt(j);
209                 
210                 if (Evaluator.type(currEvaluation) == Evaluator.type(anEvaluation)) {
211                     evaluations.insertElementAt(Evaluator.evaluate(anEvaluation, currEvaluation, "+"), j);
212                     evaluations.removeElement(anEvaluation);
213                     evaluations.removeElement(currEvaluation);
214                     i--;
215                     nbEvaluations--;
216                     break;
217                 }
218             }
219         }
220         
221         // On a appliquÈ l'opÈrateur courant, on retourne maintenant le rÈsultat, en prenant soin
222         // d'intercaler des opÈrateur entre les Èvaluations si nÈcessaire
223         String result = (String) evaluations.firstElement();
224         for (int i = 1; i < nbEvaluations; i++) {
225             anEvaluation = (String) evaluations.elementAt(i);
226             if (anEvaluation.charAt(0) == '-')
227                 result += anEvaluation;
228             else
229                 result += "+" + anEvaluation;
230         }
231         return result;
232     }
233 }