Back to index

wims  3.65+svn20090927
Addition.java
Go to the documentation of this file.
00001 /*
00002 $Id: Addition.java,v 1.3 2003/02/18 11:48:47 sander Exp $
00003 */
00004 
00005 
00006 /*
00007 Copyright (C) 2001-2002 Mainline Project (I3S - ESSI - CNRS -UNSA)
00008 
00009 This library is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU Lesser General Public
00011 License as published by the Free Software Foundation; either
00012 version 2.1 of the License, or (at your option) any later version.
00013 
00014 This library is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public
00020 License along with this library; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023 For further information on the GNU Lesser General Public License,
00024 see: http://www.gnu.org/copyleft/lesser.html
00025 For further information on this library, contact: mainline@essi.fr
00026 */
00027 
00028 
00029 package fr.ove.openmath.jome.model;
00030 
00031 import java.util.*;
00032 import fr.ove.openmath.jome.model.*;
00033 import fr.ove.openmath.jome.model.events.*;
00034 import fr.ove.openmath.jome.model.evaluation.*;
00035 
00045 public class Addition extends NaryOperator {
00049     public Addition() {
00050         setResourceIdentifier("ADDITION");
00051         setValue("+");
00052         setAsOperatorPriority(resourcesManager.getAsOperatorPriority("plusPriorities"));
00053         setAsOperandPriority(resourcesManager.getAsOperandPriority("plusPriorities"));
00054         setAreOperandsMovable(true);
00055     }
00056     
00064     public FormulaTreeStructure insert(FormulaTreeStructure current) {
00065         // On cherche la position d'insertion de notre "+"
00066         current = findLocation(current);
00067         int currentAsOperandPriority = current.getAsOperandPriority();
00068         int currentAsOperatorPriority = current.getAsOperatorPriority();
00069 
00070         if (currentAsOperatorPriority == getAsOperandPriority()) {
00071             // On a déjà tapé dans la formule un "+", on va donc insérer un nouveau
00072             // "+" dans le précédent ==> cas particuliers.
00073             if ((currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryPlusPriorities")) || 
00074                 (currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryMinusPriorities"))) {
00075                 // Si on est en précense de ce cas là, la position d'insertion est
00076                 // sur un op. unaire ("+"  ou "-"). Il faut récupérer le père de l'op.
00077                 // en question, i.e. une instance d'Addition que l'on a inséré auparavant
00078                 // dansla FST.
00079                 FormulaTreeStructure father = (FormulaTreeStructure) current.getFather();
00080                 
00081                 if (currentAsOperandPriority == resourcesManager.getAsOperandPriority("unaryPlusPriorities")) {
00082                     FormulaTreeStructure operand = (FormulaTreeStructure) current.getChild(0);
00083                     // si en fait, notre position d'insertion est un "+" unaire, on enlève
00084                     // notre opérateur unaire pour ne garder que son opérande.
00085                     // Ex: on avait +a, on tape "+", on génère a+[?] où [?] est le template.
00086                     int rank = current.getRank();
00087                     
00088                     father.addChild(operand, rank);
00089                     father.removeChild(current);
00090                 }
00091 
00092                 // On insère notre template.
00093                 VariableOrNumber template0 = new VariableOrNumber();
00094                 father.addChild(template0);
00095                 
00096                 // On retourne la reférence de notre dernier point d'insertion.
00097                 return template0;
00098             }
00099             
00100             // On est dans le cas classique de la saisie d'une suite "+", on insère
00101             // notre template dans la FTS.
00102             VariableOrNumber template = new VariableOrNumber();
00103             current.addChild(template);
00104             
00105             // On retourne la reférence de notre dernier point d'insertion.
00106             return template;
00107         }
00108         else {
00109             // On est dans le cas où on commence à saisir une addition.
00110             
00111             // On ajoute l'opérateur "+" comme fils à l'opérateur courant.
00112             // Pour gérer le fait que l'on puisse taper un "+" binaire ou unaire, 
00113             // notre opérateur "+" unaire de notre FTS (UnaryPlus) sera ajouté comme
00114             // fils à l'instance courante. D'où l'ajout systématique suivant à la position
00115             // d'insertion. La distinction de cas singuliers est faite au test suivant.
00116             current.addChild(this);
00117             
00118             // Ce test est nécessaire pour savoir si on est dans le cas du "+" binaire
00119             // ou du "+" unaire.
00120             if (current.getNbChildren() > 1) {
00121                 // Il faut que l'on fasse attention pour savoir si l'on veut entrer un "+" unaire ou pas.
00122                 // Donc on vient d'ajouter notre instance comme fils a current.
00123                 // Si on est là, 2 solutions,  le fils de current qui a pour rank, le rank de l'instance -1 :
00124                 //      * est un template ==> on saisi un plus unaire
00125                 //      * n'est pas un template ==> on saisi une addition
00126                 FormulaTreeStructure fts = (FormulaTreeStructure) current.getChild(getRank() - 1);
00127                 
00128                 // Quelque soit le cas, on enlève fts de current.
00129                 // Dans le cas du plus unaire, (fts est un template) un template sera rajouté avec
00130                 // l'insertion du UnaryPlus
00131                 // Dans le cas de l'addition, fts sera ajouté à notre instance
00132                 current.removeChild(fts);
00133                 
00134                 if ((fts.getAsOperatorPriority() == resourcesManager.getAsOperatorPriority("constantPriorities")) &&
00135                     fts.isTemplate()) {
00136                     // On ajoute un opérateur "+" unaire comme fils à notre instance
00137                     current = this;
00138                     current = (new UnaryPlus()).insert(current);
00139                     
00140                     // On retourne la référence de notre dernier point d'insertion
00141                     return current;
00142                 }
00143                 else {
00144                     addChild(fts);
00145                     
00146                     // On ajoute un template à l'addition
00147                     VariableOrNumber template = new VariableOrNumber();
00148                     addChild(template);
00149                     
00150                     // On retourne la référence de notre dernier point d'insertion
00151                     return template;
00152                 }
00153             }
00154             else { // on est dans le cas du "+" unaire
00155                 // Comme dit précédemment, on ajoute un opérateur "+" unaire comme
00156                 // fils à l'instance courante.
00157                 current = this;
00158                 current = (new UnaryPlus()).insert(current);
00159                 
00160                 // On retourne la référence de notre dernier point d'insertion
00161                 return current;
00162             }
00163         }
00164     }
00165     
00169     public String createLinear(String linear) {
00170         FormulaTreeStructure child;
00171         
00172         for (int i = 0; i < getNbChildren(); i++) {
00173             child = (FormulaTreeStructure) getChild(i);
00174             if (i == 0)
00175                 linear = child.createLinear(linear);
00176             else {
00177                 if (!((child instanceof UnaryPlus) || (child instanceof UnaryMinus)))
00178                     linear += "+";
00179                 linear = child.createLinear(linear);
00180             }
00181         }
00182         return linear;
00183     }
00184     
00188     public String evaluate() {
00189         Vector evaluations = new Vector();
00190         
00191         // On commence par évaluer tous les fils de l'instance
00192         for (Enumeration e = getChildren().elements(); e.hasMoreElements(); )
00193             evaluations.addElement(((FormulaTreeStructure) e.nextElement()).evaluate());
00194     
00195         int nbEvaluations = evaluations.size();
00196         String anEvaluation, currEvaluation;
00197         // Maintenant, on parcourre toutes les évaluations calculées et on essaye de leur appliquer
00198         // l'opérateur courant
00199         for (int i = 1; i < nbEvaluations; i++) {
00200             currEvaluation = (String) evaluations.elementAt(i);
00201             
00202             for (int j = 0; j < i; j++) {
00203                 anEvaluation = (String) evaluations.elementAt(j);
00204                 
00205                 if (Evaluator.type(currEvaluation) == Evaluator.type(anEvaluation)) {
00206                     evaluations.insertElementAt(Evaluator.evaluate(anEvaluation, currEvaluation, "+"), j);
00207                     evaluations.removeElement(anEvaluation);
00208                     evaluations.removeElement(currEvaluation);
00209                     i--;
00210                     nbEvaluations--;
00211                     break;
00212                 }
00213             }
00214         }
00215         
00216         // On a appliqué l'opérateur courant, on retourne maintenant le résultat, en prenant soin
00217         // d'intercaler des opérateur entre les évaluations si nécessaire
00218         String result = (String) evaluations.firstElement();
00219         for (int i = 1; i < nbEvaluations; i++) {
00220             anEvaluation = (String) evaluations.elementAt(i);
00221             if (anEvaluation.charAt(0) == '-')
00222                 result += anEvaluation;
00223             else
00224                 result += "+" + anEvaluation;
00225         }
00226         return result;
00227     }
00228 }