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