src/java/isac/bridge/CalcTree.java
author akremp
Tue, 02 Dec 2003 17:47:24 +0100
changeset 1233 44d0d14dbaf9
parent 1218 0f4ed6043f46
child 1240 95c45efd7b28
permissions -rw-r--r--
*** empty log message ***
     1 /*
     2  * Created on Sep 11, 2003
     3  */
     4 package isac.bridge;
     5 
     6 import isac.util.CalcChangedEvent;
     7 import isac.util.Formula;
     8 import isac.util.ICalcIterator;
     9 import isac.util.IToCalc;
    10 import isac.util.IToUser;
    11 import isac.util.Tactic;
    12 import isac.wsdialog.DialogGuide;
    13 
    14 import java.io.Serializable;
    15 import java.rmi.RemoteException;
    16 import java.util.Iterator;
    17 import java.util.Vector;
    18 
    19 /**
    20  * A CalcTree represents a Calculation: It is a tree which consists
    21  * of one CalcHead at the top and abitrarily many Formulas and Tactics.
    22  * SubCalculations (with separate CalcHeads) are also part of CalcTree
    23  * This is the main interface between the Bridge and the Dialog
    24  * The CalcTree calls methods of the Math Engine, which in turn are
    25  * delegated to the BridgeRMI object on the other side of the RMI connection
    26  * The communication with the SML Kernel is completly hidden from
    27  * the Dialog and the Frontend.
    28  * @author rgradisc
    29  */
    30 public class CalcTree implements IToCalc, Serializable {
    31 
    32   private final static int SCOPE_CURRENT_SUBPROBLEM = 1;
    33   private final static int SCOPE_CURRENT_SUBCALCULATION = 2;
    34   private final static int SCOPE_WHOLE_CALCULATION = 3;
    35 
    36   private int id;
    37   private Vector listeners;
    38   private MathEngine mathEngine;
    39   private ICalcIterator hotSpot;
    40 
    41   /**
    42   Start a new calculation. In case of failure, 
    43   the constructor may change the formalization object to hint at incomplete or
    44   contradictory specifications. 
    45   <br> Under normal circumstances, only complete calcHeads should be passed. 
    46   <br> Check every CalcHead for completeness (with the
    47   static method checkcalcHead() before constructing a CalcTree
    48   * @param calcHead The CalcHead for this CalcTree
    49   */
    50   CalcTree(MathEngine mathEngine, int id) {
    51     this.id = id;
    52     this.mathEngine = mathEngine;    
    53     listeners = new Vector();
    54   }
    55 
    56   /**
    57   Attach another dialog to the existing calculation tree. 
    58   * @param dlg The new Dialog to be attached to this CalcTree
    59   */
    60   public void attach(DialogGuide dg) {
    61   	listeners.add(dg);
    62   }
    63 
    64   /**
    65   Get a new iterator referencing the root element of the calculation tree. 
    66   <p> The functionality for navigating the calculation 
    67   is implemented in the CalcIterator object.
    68   * @return new instance of CalcIterator
    69   */
    70   public ICalcIterator iterator() {
    71     return new CalcIterator(this);
    72   }
    73 
    74   /**
    75   Makes the passed formula the active formula, i.e. the formula 
    76   the next tactic is applied to.
    77   * @param newActiveFormula
    78   */
    79   public void moveActiveFormula(ICalcIterator newActiveFormula) {
    80     //String s = sendToBridge("moveActiveFormula 1 1;");
    81     //not implemented in kernel
    82     ((CalcIterator)hotSpot).moveTo((CalcIterator)newActiveFormula);	
    83   }
    84 
    85   /**
    86   Tries to replaces the active formula in the calculation tree by 
    87   the passed formula. This could fail if no valid derivation from 
    88   the preceding formula to the (new) active formula can be found. 
    89   <p>Parts of the calculation after the replaced 
    90   formula are likely to become invalid, listeners will be informed
    91   of this with the update message, which contains the last unchanged 
    92   formula.
    93   * @param newFormula
    94   * @return The method will return 0 on success or a nonzero value 
    95   indicating the status otherwise. 
    96   */
    97   public int replaceFormula(Formula newFormula) {
    98     //String s = sendToBridge("replaceFormula 1 1;");
    99     //Not implemented in kernel
   100 	informListeners((ICalcIterator)hotSpot.clone());
   101     return 0;
   102   }
   103 
   104   /**
   105   Tries to append the passed formula after the active formula. 
   106   This could fail if no valid derivation from the preceding formula 
   107   to the (new) active formula can be found. The method will fail as 
   108   well if the active formula is not the last formula in the (sub)calculation.
   109   Parts of the calculation might become invalid.
   110   * @param newFormula
   111   * @return The method will return 0 on success or a nonzero value 
   112   indicating the status otherwise.
   113   */
   114   public int appendFormula(Formula newFormula) {
   115 	informListeners((ICalcIterator)hotSpot.clone());
   116     return 0;
   117   }
   118 
   119   /**
   120   Set and use a tactic in the next step of calculation.   
   121   * @param tactic the Tactic to be used in the the next step
   122   * @return The return value indicates success, failure or probable
   123   success at a later time.
   124   */
   125   public int setNextTactic(Tactic tactic) {
   126     int result = -1;
   127     try {
   128       result = mathEngine.setNextTactic(this.id, tactic);
   129       if (result == 0) {
   130         hotSpot.moveDown(); // move to the new formula/calcHead
   131 		informListeners((ICalcIterator)hotSpot.clone());
   132       }	  
   133     } catch (RemoteException e) {
   134       // TODO Auto-generated catch block
   135       e.printStackTrace();
   136     }
   137     return -1;
   138   }
   139 
   140   /**
   141   Retrieve the tactic proposed by the SML-Kernel for 
   142   the next step in the calculation.  
   143   * @return proposed tactic.
   144   * Can be null, if the kernel does
   145   * not know what to do next, or if the end 
   146   * of the calculation is reached 
   147   */
   148   public Tactic fetchProposedTactic() {
   149     try {
   150       return mathEngine.fetchProposedTactic(this.id);
   151     } catch (RemoteException e) {
   152       // TODO Auto-generated catch block
   153       e.printStackTrace();
   154     }
   155     return null;
   156   }
   157 
   158   /**
   159   Get a list of tactics applicable to the active formula. 
   160   * @param scope The filter parameter selects the scope of
   161   search for applicable tactics: all tactics / all tactics from the 
   162   current theory / all tactics from the (calculation) method being applied.
   163   * @return Array with applyable tactics
   164   */
   165   public Tactic[] fetchApplicableTactics(int scope) {
   166     Tactic[] result = null;
   167     try {
   168       result = mathEngine.fetchAppliableTactics(this.id, scope);
   169 	} catch (RemoteException e) {
   170       // TODO Auto-generated catch block
   171       e.printStackTrace();
   172     }
   173     return result;
   174   }
   175 
   176   /**
   177   Calculate the next n steps starting from the active formula.   
   178   * @param scope The scope parameter can have following values:
   179   <ul>
   180   <li> 1 .. Stay in the current subproblem
   181   <li> 2 .. Stay in the current subcalculation (e.g. repetitions) 
   182   <li> 3 .. Stay in the current calculation as a whole. 
   183   </ul>
   184   * @param nSteps Specifies the count of steps to be autocalculated. 
   185   Passing 0 for nSteps will calculate until reaching a final result. 
   186   * @return The method returns an unique id to identify the request when 
   187   notifying about updates in the tree.
   188   */
   189   public int autoCalculate(int scope, int nSteps) {
   190     int result = -1;
   191     try {
   192       result = mathEngine.autoCalculate(this.id, scope, nSteps);
   193 	  informListeners((ICalcIterator)hotSpot.clone());
   194     } catch (RemoteException e) {
   195       e.printStackTrace();
   196     }
   197     return result;
   198   }
   199 
   200   /**
   201    * Add a Listener to this CalcTree. Listeners will be informed about any
   202    * changes in the CalcTree.
   203    * @param listener the new Listener, has to implement the interface IToUser
   204    * @return true, if the listener has been added successfully
   205    */
   206   public boolean addListener(IToUser listener) {
   207     if (listeners.contains(listener)) {
   208       return false;
   209     } else {
   210       listeners.add(listener);
   211     }
   212     return true;
   213   }
   214 
   215   /**
   216    * Retrieve the active formula in a CalcTree. This is the formula form
   217    * where the calculation will continue.
   218    * @return Iterator that marks the currently active formula
   219    */
   220   public ICalcIterator getActiveFormula() {    
   221     return (ICalcIterator)hotSpot.clone();
   222   }  
   223 
   224   /**
   225   * Destruct this CalcTree: the sml-Representation of the CalcTree
   226   * is disposed, the id can be used for a new CalcTree
   227   * @return boolean value: success of operation (complete/failed)
   228   */
   229   public boolean destruct() {
   230     try {
   231       return mathEngine.destruct(this.id);
   232     } catch (RemoteException e) {
   233       // TODO Auto-generated catch block
   234       e.printStackTrace();
   235     }
   236     return false;
   237   } 
   238   
   239   // send an update event to the registered listeners
   240   private void informListeners(ICalcIterator firstChangedFormula) {
   241     Iterator it = listeners.iterator();    
   242     DialogGuide dg;
   243     CalcChangedEvent e = new CalcChangedEvent(
   244     0,    // transactionID 
   245     true, // completed    
   246     firstChangedFormula);
   247     while (it.hasNext()) {
   248       dg = (DialogGuide)it.next();
   249       dg.calcChanged(e);
   250     }
   251   }  
   252   
   253   MathEngine getMathEngine() {
   254     return mathEngine;
   255   }
   256 
   257   public int getId() {
   258     return id;
   259   }
   260   
   261   // Special iterator hotSpot: marks the currently active formula of
   262   // the calcTree 
   263   void setHotSpot(ICalcIterator iterator) {
   264     hotSpot = iterator;
   265   }
   266 
   267 }