5 import isac.util.formulae.*;
6 import isac.util.interfaces.*;
7 import isac.util.tactics.*;
9 import java.io.Serializable;
10 import java.net.MalformedURLException;
12 import java.rmi.registry.LocateRegistry;
13 import java.rmi.server.UnicastRemoteObject;
14 import java.util.Vector;
18 * * recognize CalcHead in Changed Formula -> switch to DILAOGPAHSE_SPECIFY_SUBPROBLEM
19 * * differentiate CalcHeads
25 * The DialogGuide moderates the communication between two instances working on
26 * the same CalcTree object. One of these instances is the user, the other a
27 * math engine. Most probably, the user's GUI, the DialogGuide and the math
28 * engine reside on different machines and communicate with each other by means
31 * @author Alan Krempler
33 public class DialogGuide extends UnicastRemoteObject implements DGuide,
34 IToUser, Serializable {
36 protected CalcTree calc_tree_;
38 protected CalcHead calc_head_;
40 protected CalcHead calc_head_sub_;
42 protected MathEngine math_engine_;
46 private Vector datachange_listeners_;
48 private IToWorksheet ui_control_listener_;
52 * URL of the math engine to be used
53 * @throws RemoteException
55 public DialogGuide(String ME_path) throws RemoteException {
58 datachange_listeners_ = new Vector();
59 MathEngine.init(ME_path);
60 math_engine_ = MathEngine.getMathEngine();
61 phase_ = DIALOGPHASE_IDLE;
66 * at the beginning of a calculation as well as of a subproblem
69 * empty (formalization stored invisibly in the calcTree)
70 * @return calc_head with viestyle set
72 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
73 // and like trymatch etc. see below
74 CalcHead startSpecifying(CalcHead calc_head) {
76 // WN040825 if (start_from == STARTFROM_EXAMPLE) { <---startSpecifying ?
78 int calchead_view = CalcHead.VIEWSTYLE_SINGLELINE;
79 //WN040824 VIEWSTYLE_IN_CALC depends on UserModel
80 //WN040824 VIEWSTYLE_IN_CALC is appropriate for equations, not for
82 //WN040825 appropriate for pbl-class [univatiate,equation]
83 //WN040825 NOT -"- for maximum-expl
84 calc_head.setCalcHeadStatus(calchead_view);
85 math_engine_.completeCalcHead(calc_head);
87 phase_ = DIALOGPHASE_SPECIFY;
88 return calc_head; //WN040906 this is NOT completed !!!
89 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
92 // FIXME.WN040906 do NOT return calc_head, like Formula in solve-phase
93 public CalcHead startCalculation(int user_id, Formalization f,
94 int start_from, int requested_calchead_view) {
96 calc_head_ = math_engine_.startCalculation(f);
98 // for the moment, all requests for a view are honored
99 // WN040825 calc_head_.setViewStyle(requested_calchead_view);
100 // --->startSpecifying
102 // for testing purposes: if starting an example from the collection,
103 // have everything filled in by the KI
104 // WN040825 if (start_from == STARTFROM_EXAMPLE) { --->startSpecifying ?
106 // old-style filling the fields of the calc-head by setting
108 // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
111 // test code; this protocol is now controlled by the presentation layer
114 // } while (false); // status != ok
115 // newCalculation(calc_head_);
116 //WN040825 phase_ = DIALOGPHASE_SPECIFY; --->startSpecifying
117 //WN040825 return calc_head_;
118 return startSpecifying(calc_head_);
121 public void newCalculation(CalcHead calcHead) {
123 calc_tree_ = math_engine_.startSolving(calcHead);
124 } catch (Exception e) {
125 // TODO Auto-generated catch block
128 // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
129 calc_tree_.addDataChangeListener(this);
130 phase_ = DIALOGPHASE_SOLVE;
136 * @see isac.wsdialog.IToUser#calcChanged(isac.wsdialog.CalcChangedEvent)
138 public void calcChanged(CalcChangedEvent event) {
140 ICalcElement calc_elem;
142 for (int i = 0; i < datachange_listeners_.size(); i++) {
143 ((IToUser) datachange_listeners_.elementAt(i)).calcChanged(event);
145 ICalcIterator last_formula = event.getFirstChangedFormula();
146 // while searching for last formula, mark intermediate CalcHeads as not
149 while (!last_formula.isLast()) {
150 if (last_formula.getElement().getType() == ICalcElement.CALCEL_CALCHEAD) {
151 last_formula.getElement().setViewStyle(
152 CalcHead.VIEWSTYLE_IN_CALC);
154 last_formula.moveDown();
155 //TODO last_formula.moveDown.. WN040824 DG may limit the level down
158 // for now, do not specify the CalcHead, just display it.
159 calc_elem = last_formula.getElement();
161 if (calc_elem.getType() == ICalcElement.CALCEL_CALCHEAD) {
162 //WN040826 phase_ = DIALOGPHASE_SPECIFY; --->startSpecifying
164 // calc_elem.setViewStyle(CalcHead.VIEWSTYLE_SINGLELINE);--->startSpecifying
166 //WN040826calc_head = startSpecifying((CalcHead) calc_elem);
167 // --->startSpecifying
168 startSpecifying((CalcHead) calc_elem);
169 //WN040826 math_engine_.completeCalcHead(calc_head);
170 // --->startSpecifying
172 phase_ = DIALOGPHASE_SOLVE;
174 } catch (Exception e) {
180 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
182 public void modifyCalcHead(CalcHead calc_head) {
183 // MathEngine.getMathEngine().modifyCalcHead(calc_head);
184 math_engine_.modifyCalcHead(calc_head);
190 * @see isac.wsdialog.IToCalc#iterator()
192 public ICalcIterator iterator() {
194 return new DialogIterator((CalcIterator) calc_tree_.iterator());
195 } catch (Exception e){
204 * @see isac.wsdialog.IToCalc#addListener(isac.wsdialog.IToUser)
206 public boolean addDataChangeListener(IToUser listener) {
207 if (datachange_listeners_.contains(listener)) {
210 datachange_listeners_.add(listener);
215 public boolean registerUIControlListener(IToWorksheet listener) {
216 if (ui_control_listener_ != null) {
217 ui_control_listener_.doUIAction(new UserAction(UI_DO_DETACH));
219 ui_control_listener_ = listener;
223 public Tactic fetchProposedTactic() {
224 return calc_tree_.fetchProposedTactic();
227 public Tactic[] fetchApplicableTactics(int scope) {
228 return calc_tree_.fetchApplicableTactics(scope);
232 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
234 public int setNextTactic(Tactic tactic) {
235 return calc_tree_.setNextTactic(tactic);
239 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
241 public int autoCalculate(int scope, int nSteps) {
242 return calc_tree_.autoCalculate(scope, nSteps);
246 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
248 public void tryMatch(CalcHead ch, CalcHeadCompoundID problemID)
249 throws NotInSpecificationPhaseException {
251 // MathEngine.getMathEngine().tryMatch(ch, problemID);
252 math_engine_.tryMatch(ch, problemID);
256 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
258 public void tryRefine(CalcHead ch, CalcHeadCompoundID problemID)
259 throws NotInSpecificationPhaseException {
261 // MathEngine.getMathEngine().tryRefine(ch , problemID);
262 math_engine_.tryRefine(ch, problemID);
265 public ICalcIterator getActiveFormula() {
266 return calc_tree_.getActiveFormula();
270 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
272 public int replaceFormula(Formula newFormula) {
273 return calc_tree_.replaceFormula(newFormula);
277 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
279 public int appendFormula(Formula newFormula) {
280 return calc_tree_.appendFormula(newFormula);
284 * @deprecated Use {@link #notifyUserAction(IUserAction)}instead
286 public void moveActiveFormula(ICalcIterator newActiveFormula) {
287 calc_tree_.moveActiveFormula(newActiveFormula);
291 * Notify the Dialog Guide about interaction from the User
294 * @return true, if the action has been processed, false if the processing
295 * the action has been denied
298 public boolean notifyUserAction(IUserAction action)
299 throws DialogProtocolException {
300 int request = action.getActionID();
303 case DIALOGPHASE_IDLE:
304 throw new DialogProtocolException(request, phase_);
305 //case DIALOGPHASE_SPECIFY: WN040826
306 case DIALOGPHASE_SPECIFY: //_SUBPROBLEM WN040826
307 if (request < UI_DUMMY_FIRST_SPECIFY
308 || request > UI_DUMMY_LAST_SPECIFY)
309 throw new DialogProtocolException(request, phase_);
311 case DIALOGPHASE_SOLVE:
312 if (request < UI_DUMMY_FIRST_SOLVE || request > UI_DUMMY_LAST_SOLVE)
313 throw new DialogProtocolException(request, phase_);
318 case UI_SPECIFY_TRY_MATCH:
320 tryMatch(calc_head_, ((UserActionOnCalcHeadCompoundID) action)
322 } catch (NotInSpecificationPhaseException e) {
323 throw new DialogMathException(request, phase_, e);
327 case UI_SPECIFY_TRY_REFINE:
329 tryRefine(calc_head_, ((UserActionOnCalcHeadCompoundID) action)
331 } catch (NotInSpecificationPhaseException e) {
332 throw new DialogMathException(request, phase_, e);
336 case UI_SPECIFY_CHANGE_VIEW:
337 calc_head_.setViewStyle(((UserActionOnInt) action).getInt());
340 case UI_SPECIFY_COMPLETE_CALCHEAD:
341 math_engine_.completeCalcHead(calc_head_);
342 // old-style filling the fields of the calc-head by setting
344 // calc_head_.setCalcHeadStatus(CalcHead.CALCHEAD_HELP_ME);
345 // modifyCalcHead(calc_head_);
348 case UI_SPECIFY_COMPLETE_METHOD:
349 case UI_SPECIFY_COMPLETE_THEORY:
350 case UI_SPECIFY_COMPLETE_PROBLEM:
351 case UI_SPECIFY_COMPLETE_GIVEN:
352 case UI_SPECIFY_COMPLETE_FIND:
353 case UI_SPECIFY_COMPLETE_RELATE:
354 throw new DialogNotImplementedException(request, phase_);
356 case UI_SPECIFY_CHECK_CALCHEAD:
357 modifyCalcHead(calc_head_);
360 // was: newCalculation()
361 case UI_SPECIFY_CALCULATE_1:
362 case UI_SPECIFY_CALCULATE_ALL:
363 modifyCalcHead(calc_head_);
364 if (calc_head_.getCalcHeadStatus() != CalcHead.CALCHEAD_CORRECT)
368 calc_tree_ = math_engine_.startSolving(calc_head_);
369 } catch (Exception e) {
370 // TODO Auto-generated catch block
373 // calc_tree_ = MathEngine.getMathEngine().startSolving(calcHead);
374 calc_tree_.addDataChangeListener(this);
375 phase_ = DIALOGPHASE_SOLVE;
376 // fall through to calculate
378 case UI_SOLVE_CALCULATE_1:
379 case UI_SOLVE_CALCULATE_ALL:
381 case UI_SPECIFY_CALCULATE_ALL:
382 case UI_SOLVE_CALCULATE_ALL:
383 autoCalculate(SCOPE_CALCULATION, 0);
385 case UI_SPECIFY_CALCULATE_1:
388 autoCalculate(SCOPE_CALCULATION, 1);
393 case UI_SOLVE_CALCULATE_SUBPROBLEM:
394 autoCalculate(SCOPE_SUBPROBLEM, 0);
397 case UI_SOLVE_EDIT_ACTIVE_FORMULA:
398 ui_control_listener_.doUIAction(new UserAction(UI_DO_EDIT_FORMULA));
401 case UI_SOLVE_EDIT_ACTIVE_FORMULA_COMPLETE:
402 replaceFormula((Formula) ((UserActionOnCalcElement) action)
406 case UI_SOLVE_APPEND_USER_FORMULA:
407 // appendFormula((Formula) ((UserActionOnCalcElement)
408 // action).getCalcElement());
410 .doUIAction(new UserAction(UI_DO_APPEND_FORMULA));
413 case UI_SOLVE_MOVE_ACTIVE_FORMULA:
414 moveActiveFormula(((UserActionOnIterator) action).getPosition());
417 case UI_SOLVE_GET_PROPOSED_TACTIC:
418 throw new DialogNotImplementedException(request, phase_);
420 case UI_SOLVE_GET_APPLICABLE_TACTICS:
421 throw new DialogNotImplementedException(request, phase_);
423 case UI_SOLVE_SET_NEXT_TACTIC:
424 setNextTactic((Tactic) ((UserActionOnCalcElement) action)
428 case UI_SOLVE_HELP_ENTERING_FORMULA:
429 throw new DialogNotImplementedException(request, phase_);
431 case UI_SOLVE_SHOW_ASSUMPTIONS:
432 throw new DialogNotImplementedException(request, phase_);
434 case UI_SOLVE_SHOW_DETAILS:
435 throw new DialogNotImplementedException(request, phase_);
438 throw new DialogUnknownActionException(request, phase_);
443 private void rmiBind() {
444 if (System.getSecurityManager() == null) {
445 System.setSecurityManager(new RMISecurityManager());
449 LocateRegistry.createRegistry(1099);
450 } catch (java.rmi.RemoteException exc2) {
451 System.err.println("can not create registry: " + exc2.getMessage());
454 String name = "//localhost/isac-DialogGuide";
456 System.out.println("try to bind as " + name);
457 Naming.rebind(name, this);
458 System.out.println("Dialog Guide bound to " + name);
459 //WN040906 was Object Manager ...
460 } catch (java.rmi.ConnectException e) {
461 System.err.println("failed to contact as " + name
462 + " (creating RMI-Server on localhost: 1099)");
463 } catch (RemoteException e) {
464 // TODO Auto-generated catch block
466 } catch (MalformedURLException e) {
467 // TODO Auto-generated catch block
472 public static void main(String[] args) {
474 new DialogGuide(args[0]);
475 } catch (RemoteException e) {