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