java: DGuide implements IToCalc NOTANYMORE, DialogGuide cleaned from IToCalc-methods
2 * Created on Sep 11, 2003
7 import isac.util.CalcChanged;
8 import isac.util.CalcChangedEvent;
9 import isac.util.StartSolvingException;
10 import isac.util.formulae.CalcHead;
11 import isac.util.formulae.CalcFormula;
12 import isac.util.formulae.Position;
13 import isac.util.interfaces.ICalcIterator;
14 import isac.util.interfaces.IToCalc;
15 import isac.util.interfaces.IToUser;
16 import isac.util.tactics.Tactic;
17 import isac.wsdialog.DialogGuide;
19 import java.io.Serializable;
20 import java.rmi.RemoteException;
21 import java.util.Iterator;
22 import java.util.Vector;
24 import org.apache.log4j.Logger;
27 * A CalcTree represents a Calculation: It is a tree which consists of one
28 * CalcHead at the top and abitrarily many Formulas and SubCalculations (with
29 * separate CalcHeads). This is the main interface between the Bridge and the
30 * Dialog. The CalcTree calls methods of the Math Engine, which in turn are
31 * delegated to the BridgeRMI object on the other side of the RMI connection
32 * ??????WN0409. The communication with the SML Kernel is completly hided from
33 * the Dialog and the Frontend.
35 * @author Richard Gradischnegg
38 public class CalcTree implements IToCalc, Serializable {
42 private Vector listeners_;
44 private MathEngine mathEngine_;
46 private ICalcIterator hot_spot_;//WN040924 ..delete: control hotSpot --> DG
48 private IBridgeRMI bridgeRMI_;//WN040924 added for completeCalcHead & Co.
50 static Logger logger_ = Logger.getLogger(CalcTree.class.getName());
53 * Start a new calculation. In case of failure, the constructor may change
54 * the formalization object to hint at incomplete or contradictory
55 * specifications. <br>
56 * Only complete calcHeads should be passed. <br>
57 * Check every CalcHead for completeness (with the static method
58 * checkcalcHead() before constructing a CalcTree ..TODO WN040824 shift to
61 * @param identification
62 * for the CalcTree as delivered by the SML-kernel
64 CalcTree(MathEngine me, int id) {
66 this.mathEngine_ = me;
67 this.bridgeRMI_ = me.getBridgeRMI();//WN040924
68 listeners_ = new Vector();
72 * Attach another dialog to the existing calculation tree.
75 * The new Dialog to be attached to this CalcTree
77 public void attach(DialogGuide dg) {
82 * Get a new iterator referencing the root element of the calculation tree.
84 * The functionality for navigating the calculation is implemented in the
85 * CalcIterator object.
87 * @return new instance of CalcIterator
89 public ICalcIterator iterator() {
90 return new CalcIterator(this);
94 * Makes the passed formula the active formula, i.e. the formula the next
95 * tactic is applied to.
97 * @param newActiveFormula
99 public void moveActiveFormula(ICalcIterator cit) {
101 Position p = mathEngine_.moveActiveFormula(id_, cit.getPosition());
102 // if (p == null)//WN0412 message ?!
106 } catch (RemoteException e) {
107 // TODO Auto-generated catch block
113 * @see isac.util.interfaces.IToCalc#startSolving()
115 public void startSolving() throws Exception {
116 Tactic tac = this.fetchProposedTactic();
117 if (tac.getName().compareTo("Apply_Method") == 0)
118 this.autoCalculate(IToCalc.SCOPE_CALCULATION, 1);
120 new StartSolvingException (tac);
124 * @see isac.util.interfaces.IToCalc#modifyCalcHead(isac.util.formulae.CalcHead)
126 public void modifyCalcHead(CalcHead calcHead) {
127 logger_.fatal(" DG->BR: modifyCalcHead(" + calcHead.toSMLString());
128 CalcHead newCalcHead = null;
130 //WN040924 newCalcHead = bridgeRMI.modifyCalcHead(calcHead);
131 bridgeRMI_.modifyCalcHead(calcHead);
132 //WN040924 calcHead.fillValuesfrom(newCalcHead);
133 } catch (RemoteException e) {
139 * @see isac.util.interfaces.IToCalc#completeCalcHead(isac.util.formulae.CalcHead)
141 public void completeCalcHead() {
142 logger_.fatal(" DG->BR: completeCalcHead()");
144 //WN040924 newCalcHead = bridgeRMI.completeCalcHead(calcHead);
145 bridgeRMI_.completeCalcHead(this.id_);
146 //WN040924 calcHead.fillValuesfrom(newCalcHead);
147 } catch (RemoteException e) {
153 * @see isac.util.interfaces.IToCalc#completeCalcHead(isac.util.formulae.CalcHead,
156 * eventually updated by the user
157 * @param completeItem
158 * requested by the DialogGuide
160 * WN040924 copied from MathEngine
163 public void completeCalcHead(CalcHead calcHead, int completeItem) {
164 // CalcHead newCalcHead;
166 // //WN040924 newCalcHead = bridgeRMI.completeCalcHead(calcHead,
168 // bridgeRMI_.completeCalcHead(this.id_, calcHead, completeItem);
169 // //WN040924 calcHead.fillValuesfrom(newCalcHead);
170 // //TODO: Remove the following line!!
171 // calcHead.setCalcHeadStatus(CalcHead.MODEL_ITEM_CORRECT);
173 // } catch (RemoteException e) {
174 // e.printStackTrace();
179 * Calculate the next n steps starting from the active formula. The Tactic
180 * to be applied in this step may be preset by setNextTactic
183 * The scope parameter can have following values:
185 * <li>Stay in the current subproblem
186 * <li>Stay in the current subcalculation (e.g. repetitions)
187 * <li>Stay in the current calculation as a whole.
189 * Constants for this scopes are found in the IToCalc class
191 * Specifies the count of steps to be autocalculated. Passing 0
192 * for nSteps will calculate until reaching a final result.
193 * @return The method returns an unique id to identify the request when
194 * notifying about updates in the tree.
196 * WN0504 see differences to this method completely done by RG !
198 public int autoCalculate(int scope, int nSteps) {
199 logger_.fatal(" DG->BR: autoCalculate(" + scope + ", " + nSteps + ")");
201 int transactionID = -1;
203 cc = mathEngine_.autoCalculate(this.id_, scope, nSteps);
205 hot_spot_ = new CalcIterator(this, cc.getLastGenerated());
206 transactionID = generateTransactionID();
207 informListeners(new CalcIterator(this, cc.getLastUnchanged()),
208 new CalcIterator(this, cc.getLastDeleted()),
209 new CalcIterator(this, cc.getLastGenerated()),
212 } catch (RemoteException e) {
215 return transactionID;
219 * Tries to replaces the active formula in the calculation tree by the
220 * passed formula. This could fail if no valid derivation from the preceding
221 * formula to the (new) active formula can be found.
223 * Parts of the calculation after the replaced formula are likely to become
224 * invalid, listeners will be informed of this with the update message,
225 * which contains the last unchanged formula.
228 * @return The method will return 0 on success or a nonzero value indicating
229 * the status otherwise.
231 public int replaceFormula(CalcFormula f) throws RemoteException {
232 logger_.fatal(" DG->BR: replaceFormula(" + f.toSMLString() + ")");
234 int transactionID = -1;
236 cc = mathEngine_.replaceFormula(this.id_, f);
238 hot_spot_ = new CalcIterator(this, cc.getLastGenerated());
239 transactionID = generateTransactionID();
240 informListeners(new CalcIterator(this, cc.getLastUnchanged()),
241 new CalcIterator(this, cc.getLastDeleted()),
242 new CalcIterator(this, cc.getLastGenerated()),
245 } catch (RemoteException e) {
252 * Tries to append the passed formula after the active formula. This could
253 * fail if no valid derivation from the preceding formula to the (new)
254 * active formula can be found. The method will fail as well if the active
255 * formula is not the last formula in the (sub)calculation. Parts of the
256 * calculation might become invalid.
259 * @return The method will return 0 on success or a nonzero value indicating
260 * the status otherwise.
262 public int appendFormula(CalcFormula f) throws RemoteException {
263 logger_.fatal(" DG->BR: appendFormula(" + f.toSMLString() + ")");
265 int transactionID = -1;
267 cc = mathEngine_.appendFormula(this.id_, f);
269 hot_spot_ = new CalcIterator(this, cc.getLastGenerated());
270 transactionID = generateTransactionID();
271 informListeners(new CalcIterator(this, cc.getLastUnchanged()),
272 new CalcIterator(this, cc.getLastDeleted()),
273 new CalcIterator(this, cc.getLastGenerated()),
276 } catch (RemoteException e) {
283 * @see isac.util.interfaces.IToCalc#intermediateSteps()
285 public int intermediateSteps(ICalcIterator ci) throws RemoteException {
286 logger_.fatal(" DG->BR: intermediateSteps(" + ci.toSMLString() + ")");
288 int transactionID = -1;
290 cc = mathEngine_.intermediateSteps(this.id_, ci);
292 transactionID = generateTransactionID();
293 informListeners(new CalcIterator(this, cc.getLastUnchanged()),
294 new CalcIterator(this, cc.getLastDeleted()),
295 new CalcIterator(this, cc.getLastGenerated()),
298 } catch (RemoteException e) {
305 * Set a tactic for usage by autocalculate.
308 * the Tactic to be used in the the next step
309 * @return The return value indicates success, failure or probable success
312 public int setNextTactic(Tactic tactic) {
313 logger_.fatal(" DG->BR: setNextTactic(" + tactic.toSMLString() + ")");
316 result = mathEngine_.setNextTactic(this.id_, tactic);
318 hot_spot_.moveDown(); // move to the new formula/calcHead
320 informListeners((ICalcIterator) hot_spot_.clone(),
321 // FIXXXME: nothing changed, but if outcommented: subpbl shows
322 // Add_Given etc. ... discuss with LK !
323 (ICalcIterator) hot_spot_.clone(),
324 (ICalcIterator) hot_spot_.clone(),
325 generateTransactionID());
327 } catch (RemoteException e) {
328 // TODO Auto-generated catch block
334 // public int setNextTactic(Tactic tactic) {
335 // logger_.fatal(" DG->BR: setNextTactic(" + tactic.toSMLString() + ")");
339 // result = mathEngine_.setNextTactic(this.id_, tactic);
340 // //^^^^ should be CalcChanged !
341 // if (result == 0) {
342 // //hack before @@@ autoCalculate --->
343 // // isac.wsdialog.DialogGuide#notifyUserAction
344 // //works only if nothing is deleted by use in <Next Step>
345 // it = (ICalcIterator) hot_spot_.clone();
346 // hot_spot_.moveDown();
347 // informListeners((ICalcIterator) it, it,//thus deleted nodes
348 // // are not reported !!!
349 // (ICalcIterator) hot_spot_.clone(),
350 // generateTransactionID());
352 // } catch (RemoteException e) {
353 // // TODO Auto-generated catch block
354 // e.printStackTrace();
360 * Retrieve the tactic proposed by the SML-Kernel for the next step in the
363 * @return proposed tactic. Can be null, if the kernel does not know what to
364 * do next, or if the end of the calculation is reached
366 public Tactic fetchProposedTactic() {
367 logger_.fatal(" DG->BR: fetchProposedTactic()");
369 Tactic tac = mathEngine_.fetchProposedTactic(this.id_);
370 logger_.fatal(" DG<-BR: fetchProposedTactic <- "
371 + tac.toSMLString());
373 } catch (RemoteException e) {
374 // TODO Auto-generated catch block
377 logger_.fatal(" DG<-BR: fetchProposedTactic <- NULL helpless");
382 // * Get a list of tactics applicable to the active formula.
385 // * The filter parameter selects the scope of search for
386 // * applicable tactics: all tactics / all tactics from the current
387 // * theory / all tactics from the (calculation) method being
389 // * @return Array with applyable tactics
391 // public Tactic[] fetchApplicableTactics(int scope) {
392 // logger_.fatal(" DG->BR: fetchApplicableTactics(" + scope + ")");
393 // Tactic[] result = null;
395 // // result = mathEngine_.fetchAppliableTactics(this.id_, scope);
396 // // } catch (RemoteException e) {
397 // // // TODO Auto-generated catch block
398 // // e.printStackTrace();
404 * Add a Listener to this CalcTree. Listeners will be informed about any
405 * changes in the CalcTree.
408 * the new Listener, has to implement the interface IToUser
409 * @return true, if the listener has been added successfully
411 public boolean addDataChangeListener(IToUser listener) {
412 logger_.fatal(" DG->BR: addDataChangeListener(" + listener + ")");
413 if (listeners_.contains(listener)) {
416 listeners_.add(listener);
422 * Retrieve the active formula in a CalcTree. This is the formula form where
423 * the calculation will continue.
425 * @return Iterator that marks the currently active formula
427 public ICalcIterator getActiveFormula() {
428 logger_.fatal(" DG<>BR: getActiveFormula <- "
429 + hot_spot_.toSMLString());
430 return (ICalcIterator) hot_spot_.clone();
434 * Destruct this CalcTree: the sml-Representation of the CalcTree is
435 * disposed, the id can be used for a new CalcTree
437 * @return boolean value: success of operation (complete/failed) TODO
438 * WN040824 call mathEngine.destruct when WS is closed TODO WN040824
439 * call mathEngine.destruct when session is closed
441 public boolean destruct() {
443 return mathEngine_.destruct(this.id_);
444 } catch (RemoteException e) {
445 // TODO Auto-generated catch block
451 // send an update event to the registered listeners
452 private void informListeners(ICalcIterator lastUnchangedFormula,
453 ICalcIterator lastDeletedFormula,
454 ICalcIterator lastGeneratedFormula, int transactionID)
455 throws RemoteException {
456 logger_.fatal(" . . <-BR: informListeners (unc="
457 + lastUnchangedFormula.toSMLString() + ", del="
458 + lastDeletedFormula.toSMLString() + ", gen="
459 + lastGeneratedFormula.toSMLString());
460 Iterator listn_it = listeners_.iterator();
463 CalcChangedEvent e = new CalcChangedEvent(transactionID, true, // completed
464 lastUnchangedFormula, lastDeletedFormula, lastGeneratedFormula);
465 while (listn_it.hasNext()) {
466 dg = (IToUser) listn_it.next();
471 MathEngine getMathEngine() {
479 // Special iterator hotSpot: marks the currently active formula of
481 void setHotSpot(ICalcIterator iterator) {
482 hot_spot_ = iterator;
485 //WN0411 reminiscence to Dinopolis, drop it !?
486 //WN0501 ... _NO_: ... = return-value of autoCalculate,etc. =
487 // = CalcChangedEvent.transaction_id_
488 private int generateTransactionID() {
489 return (int) (Math.random() * 0xFFFF);
495 * @see isac.util.interfaces.IToCalc#getElementsFromTo(isac.util.interfaces.ICalcIterator,
496 * isac.util.interfaces.ICalcIterator, java.lang.Integer, boolean)
498 public Vector getElementsFromTo(ICalcIterator iterator_from,
499 ICalcIterator iterator_to, Integer level,
500 boolean result_includes_tactics) throws RemoteException {
501 logger_.fatal(" DG->BR: getElementsFromTo("
502 + iterator_from.toSMLString() + ", "
503 + iterator_to.toSMLString() + level + ")");
505 return mathEngine_.getElementsFromTo(this.id_, iterator_from,
506 iterator_to, level, result_includes_tactics);
507 } catch (RemoteException e) {