Source code: com/hartmath/initial/Programming.java
1 /*
2 * Programming.java
3 * Copyright (C) 2000 Klaus Hartlage
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 package com.hartmath.initial;
20 import com.hartmath.util.*;
21 import com.hartmath.mapping.*;
22 import com.hartmath.patternmatching.*;
23
24 //import java.net.URL;
25 import java.lang.*;
26 import java.util.Enumeration;
27 import java.io.*;
28 import java.util.*;
29 import com.hartmath.lib.C;
30 import com.hartmath.expression.HObject;
31 import com.hartmath.expression.HString;
32 import com.hartmath.expression.HSymbol;
33 import com.hartmath.expression.HFunction;
34 import com.hartmath.expression.HInteger;
35 import com.hartmath.exceptions.HThrowException;
36 import com.hartmath.lib.Session;
37
38 /**
39 * Description of the Class
40 *
41 *@author khartlage
42 *@created 16. Juli 2001
43 */
44 class ECheck extends SFunctionEvaluator {
45 /**
46 * Constructor for the ECheck object
47 */
48 public ECheck() {
49 }
50
51
52 /**
53 *@param vect the function, which should be evaluated
54 *@param session Description of Parameter
55 *@return <code>null</code> or the evaluated object
56 */
57 public HObject evaluate(HFunction vect, Session session) {
58 if ((vect.size() == 1) || (vect.size() == 2)) {
59 if (session.EV(vect.get(0)) != C.True) {
60 throw new MatchingFailed();
61 }
62
63 if (vect.size() == 2) {
64 return vect.get(1);
65 }
66
67 return C.Null;
68 }
69
70 throw new MatchingFailed();
71 }
72
73 }
74
75 /**
76 * Class Declaration.
77 *
78 *@author Klaus Hartlage <A HREF="mailto:khartlage@t-online.de">
79 * khartlage@t-online.de</A>
80 *@created 16. Juli 2001
81 *@see
82 *@version %I%, %G%
83 */
84 class EN extends SFunctionEvaluator {
85
86
87 /**
88 * Description of the Method
89 *
90 *@param f Description of Parameter
91 *@param session Description of Parameter
92 *@return Description of the Returned Value
93 */
94 public HObject evaluate(HFunction f, Session session) {
95 if (f.size() == 1) {
96 return session.NEV(f.get(0));
97 }
98 if (f.size() == 2) {
99 if (f.get(1) instanceof HInteger) {
100 int digits = ((HInteger) f.get(1)).intValue();
101 if (digits > 0) {
102 int old_digits = session.getDigits();
103 session.setDigits(digits);
104 HObject temp = session.NEV(f.get(0));
105 session.setDigits(old_digits);
106 return temp;
107 }
108 }
109 }
110 return null;
111 }
112
113 }
114
115 /**
116 * Class Declaration.
117 *
118 *@author
119 *@created 16. Juli 2001
120 *@see
121 *@version %I%, %G%
122 */
123 class ESet extends SFunctionEvaluator implements FunctionOpEvaluator {
124
125
126 /**
127 *@param vect the function, which should be evaluated
128 *@param session Description of Parameter
129 *@return <code>null</code> or the evaluated object
130 */
131 public HObject evaluate(HFunction vect, Session session) {
132 if (vect.size() == 2) {
133 HObject a0 = (HObject) vect.get(0);
134 HObject arg2 = session.EV((HObject) vect.get(1));
135
136 if (a0 instanceof HSymbol) {
137 ((HSymbol) a0).putDownRule(session, HRule.SET, a0, arg2);
138
139 return arg2;
140 }
141
142 if (a0 instanceof HFunction) {
143 HFunction fun = ((HFunction) a0);
144 // special: if lhs, has the form a[i] =...
145 if (fun.head().equals(C.Part) &&
146 (fun.get(0) instanceof HSymbol) &&
147 (fun.get(1) instanceof HInteger) &&
148 fun.size() == 2) {
149 // HObject v1 = C.EV(fun.get(1));
150 HSymbol sym = (HSymbol) fun.get(0);
151 HObject result;
152 Object temp;
153 if (!sym.hasNoLocalVar(session)) {
154 result = sym.deleteLocalVar(session);
155 temp = execute(result, (HInteger) fun.get(1), arg2);
156 if (temp != null) {
157 sym.createLocalVar(session, (HObject) temp);
158 return arg2;
159 }
160 sym.createLocalVar(session, result);
161 return null;
162 }
163 result = sym.getDownRule(sym, session);
164 if (result != null) {
165 temp = execute(result, (HInteger) fun.get(1), arg2);
166 if (temp != null) {
167 sym.putDownRule(session, HRule.SET, sym, (HObject) temp);
168 return arg2;
169 }
170 }
171 StringBuffer buf = new StringBuffer("index ");
172 buf.append(((HInteger) fun.get(1)).toString());
173 buf.append(" out of range [..] in expression: ");
174 buf.append(fun.get(0).toString());
175 throw new HThrowException(C.OutOfRangeError, C.Part,
176 new HString(buf.toString()));
177 }
178 fun = fun.evaluateLHSAttr(session);
179 if (fun == null) {
180 fun = ((HFunction) a0);
181 }
182 ((HFunction) a0).head().putDownRule(session, HRule.SET, fun, arg2);
183
184 return arg2;
185 }
186 }
187
188 return null;
189 }
190
191
192 /**
193 * Description of the Method
194 *
195 *@param first Description of Parameter
196 *@param hi Description of Parameter
197 *@param second Description of Parameter
198 *@return Description of the Returned Value
199 */
200 public HObject execute(HObject first, HInteger hi, HObject second) {
201 int sz = 0;
202 if (first instanceof HFunction) {
203 HFunction fun = (HFunction) ((HFunction) first).clone();
204 sz = fun.size();
205 if (hi.checkRange(1L, fun.size())) {
206 int indx = hi.intValue();
207 fun.set(indx - 1, second);
208 return fun;
209 }
210 }
211 StringBuffer buf = new StringBuffer("index ");
212
213 buf.append(hi.toString());
214 buf.append(" out of range [1..");
215 buf.append(new Integer(sz).toString());
216 buf.append("] in expression: ");
217 buf.append(first.toString());
218
219 throw new HThrowException(C.OutOfRangeError, C.Part,
220 new HString(buf.toString()));
221 }
222
223
224 /**
225 * Method Declaration.
226 *
227 *@param fun
228 *@param session Description of Parameter
229 *@return
230 *@see
231 */
232 public String toOpString(HFunction fun, Session session) {
233 return E2SArg.operatorString(fun, "=", C.SET_PRECEDENCE, session);
234 }
235
236
237 /**
238 * Method Declaration.
239 *
240 *@return
241 *@see
242 */
243 public int precedence() {
244 return C.SET_PRECEDENCE;
245 }
246
247 }
248
249 /**
250 * Class Declaration.
251 *
252 *@author
253 *@created 16. Juli 2001
254 *@see
255 *@version %I%, %G%
256 */
257 class ESetDelayed extends SFunctionEvaluator implements FunctionOpEvaluator {
258
259
260 /**
261 *@param vect the function, which should be evaluated
262 *@param session Description of Parameter
263 *@return <code>null</code> or the evaluated object
264 */
265 public HObject evaluate(HFunction vect, Session session) {
266 if (vect.size() == 2) {
267 HObject a0 = (HObject) vect.get(0);
268
269 if (a0 instanceof HSymbol) {
270
271 // ((HSymbol)a0).setProperties(HSymbol.SETDELAYED);
272
273 ((HSymbol) a0).putDownRule(session, HRule.SETDELAYED, a0,
274 vect.get(1));
275
276 return C.Null;
277 }
278
279 if (a0 instanceof HFunction) {
280 HFunction fun = ((HFunction) a0).evaluateLHSAttr(session);
281
282 if (fun == null) {
283 fun = ((HFunction) a0);
284 }
285
286 // fun.setProperties(HSymbol.SETDELAYED);
287
288 ((HFunction) a0).head().putDownRule(session, HRule.SETDELAYED, fun,
289 vect.get(1));
290
291 return C.Null;
292 }
293 }
294
295 return null;
296 }
297
298
299 /**
300 * Method Declaration.
301 *
302 *@param fun
303 *@param session Description of Parameter
304 *@return
305 *@see
306 */
307 public String toOpString(HFunction fun, Session session) {
308 return E2SArg.operatorString(fun, ":=", C.SETDELAYED_PRECEDENCE, session);
309 }
310
311
312 /**
313 * Method Declaration.
314 *
315 *@return
316 *@see
317 */
318 public int precedence() {
319 return C.SETDELAYED_PRECEDENCE;
320 }
321
322 }
323
324 /**
325 * Class Declaration.
326 *
327 *@author
328 *@created 16. Juli 2001
329 *@see
330 *@version %I%, %G%
331 */
332 class EStatement extends SFunctionEvaluator implements FunctionOpEvaluator {
333
334
335 /**
336 *@param vect the function, which should be evaluated
337 *@param session Description of Parameter
338 *@return <code>null</code> or the evaluated object
339 */
340 public HObject evaluate(HFunction vect, Session session) {
341 if (vect.size() > 0) {
342 for (int i = 0; i < vect.size() - 1; i++) {
343 session.EV(vect.get(i));
344 }
345
346 return session.EV(vect.get(vect.size() - 1));
347 }
348
349 return C.Null;
350 }
351
352
353 /**
354 * Method Declaration.
355 *
356 *@param fun
357 *@param session Description of Parameter
358 *@return
359 *@see
360 */
361 public String toOpString(HFunction fun, Session session) {
362 return E2SArg.operatorString(fun, ";", C.STATEMENT_PRECEDENCE, session);
363 }
364
365
366 /**
367 * Method Declaration.
368 *
369 *@return
370 *@see
371 */
372 public int precedence() {
373 return C.STATEMENT_PRECEDENCE;
374 }
375
376 }
377
378 /**
379 * Class Declaration.
380 *
381 *@author
382 *@created 16. Juli 2001
383 *@see
384 *@version %I%, %G%
385 */
386 /*
387 * class ETraceRule implements FunctionEvaluator
388 * {
389 * public HObject evaluate(HFunction vect)
390 * {
391 * if (vect.size() == 1)
392 * {
393 * if (vect.get(0).equals(C.True))
394 * {
395 * C.traceRuleFlag = true;
396 * return C.True;
397 * }
398 * if (vect.get(0).equals(C.False))
399 * {
400 * C.traceRuleFlag = false;
401 * return C.False;
402 * }
403 * }
404 * return null;
405 * }
406 * }
407 */
408 /**
409 * Class Declaration.
410 *
411 * Class Declaration. Class Declaration. Class Declaration. Class Declaration.
412 * Class Declaration.
413 *
414 *@author
415 *@author
416 *@author
417 *@author
418 *@author
419 *@author
420 *@created 16. Juli 2001
421 *@created 16. Juli 2001
422 *@created 16. Juli 2001
423 *@created 16. Juli 2001
424 *@created 16. Juli 2001
425 *@see
426 *@version %I%, %G%
427 */
428 class EUpSet extends SFunctionEvaluator implements FunctionOpEvaluator {
429
430
431 /**
432 *@param vect the function, which should be evaluated
433 *@param session Description of Parameter
434 *@return <code>null</code> or the evaluated object
435 */
436 public HObject evaluate(HFunction vect, Session session) {
437 if (vect.size() == 2) {
438 HObject a0 = (HObject) vect.get(0);
439 HObject arg2 = session.EV((HObject) vect.get(1));
440
441 if (a0 instanceof HSymbol) {
442
443 // ((HSymbol)a0).setProperties(HSymbol.UPSET);
444
445 ((HSymbol) a0).putUpRule(session, HRule.UPSET, a0, arg2);
446
447 return arg2;
448 }
449
450 if (a0 instanceof HFunction) {
451 HFunction fun = ((HFunction) a0).evaluateLHSAttr(session);
452 if (fun == null) {
453 fun = ((HFunction) a0);
454 }
455
456 // fun.setProperties(HSymbol.UPSET);
457
458 if (fun.size() > 0) {
459 if (fun.get(0) instanceof HSymbol) {
460 ((HSymbol) fun.get(0)).putUpRule(session, HRule.UPSET, fun, arg2);
461 }
462 else {
463 fun.get(0).head().putUpRule(session, HRule.UPSET, fun, arg2);
464 }
465 }
466 else {
467 fun.head().putUpRule(session, HRule.UPSET, fun, arg2);
468 }
469
470 return arg2;
471 }
472 }
473
474 return null;
475 }
476
477
478 /**
479 * Method Declaration.
480 *
481 *@param fun
482 *@param session Description of Parameter
483 *@return
484 *@see
485 */
486 public String toOpString(HFunction fun, Session session) {
487 return E2SArg.operatorString(fun, "^=", C.UPSET_PRECEDENCE, session);
488 }
489
490
491 /**
492 * Method Declaration.
493 *
494 *@return
495 *@see
496 */
497 public int precedence() {
498 return C.UPSET_PRECEDENCE;
499 }
500
501 }
502
503 /**
504 * Class Declaration.
505 *
506 *@author
507 *@created 16. Juli 2001
508 *@see
509 *@version %I%, %G%
510 */
511 class EUpSetDelayed extends SFunctionEvaluator implements FunctionOpEvaluator {
512
513
514 /**
515 *@param vect the function, which should be evaluated
516 *@param session Description of Parameter
517 *@return <code>null</code> or the evaluated object
518 */
519 public HObject evaluate(HFunction vect, Session session) {
520 if (vect.size() == 2) {
521 HObject a0 = (HObject) vect.get(0);
522
523 if (a0 instanceof HSymbol) {
524
525 // ((HSymbol)a0).setProperties(HSymbol.UPSETDELAYED);
526
527 ((HSymbol) a0).putUpRule(session, HRule.UPSETDELAYED, a0,
528 vect.get(1));
529
530 return C.Null;
531 }
532
533 if (a0 instanceof HFunction) {
534 HFunction fun = ((HFunction) a0).evaluateLHSAttr(session);
535
536 if (fun == null) {
537 fun = ((HFunction) a0);
538 }
539
540 // fun.setProperties(HSymbol.UPSETDELAYED);
541
542 if (fun.size() > 0) {
543 if (fun.get(0) instanceof HSymbol) {
544 ((HSymbol) fun.get(0)).putUpRule(session, HRule.UPSETDELAYED, fun,
545 vect.get(1));
546 }
547 else {
548 fun.get(0).head().putUpRule(session, HRule.UPSETDELAYED, fun,
549 vect.get(1));
550 }
551 }
552 else {
553 fun.head().putUpRule(session, HRule.UPSETDELAYED, fun,
554 vect.get(1));
555 }
556
557 return C.Null;
558 }
559 }
560
561 return null;
562 }
563
564
565 /**
566 * Method Declaration.
567 *
568 *@param fun
569 *@param session Description of Parameter
570 *@return
571 *@see
572 */
573 public String toOpString(HFunction fun, Session session) {
574 return E2SArg.operatorString(fun, "^:=", C.UPSETDELAYED_PRECEDENCE, session);
575 }
576
577
578 /**
579 * Method Declaration.
580 *
581 *@return
582 *@see
583 */
584 public int precedence() {
585 return C.UPSETDELAYED_PRECEDENCE;
586 }
587
588 }
589
590 class E_Function_Head_ extends SFunctionEvaluator implements FunctionOpEvaluator {
591 public HObject evaluate(HFunction hmFunction, Session hmSession) {
592 if (hmFunction.size()>=2 &&
593 hmFunction.get(0) instanceof HSymbol &&
594 hmFunction.get(1) instanceof HFunction) {
595 HSymbol arg1 = (HSymbol) hmFunction.get(0);
596 HFunction arg2 = (HFunction) hmFunction.get(1);
597
598 if ( arg2.head().equals(C._Function_Body_) ) {
599 HFunction temp = new HFunction(arg2, arg1, 0, arg2.size(), true);
600 HFunction fun;
601 if (hmFunction.size()==2) {
602 return temp;
603 }
604 fun = (HFunction) hmFunction.clone();
605 fun.remove(0);
606 fun.set(0, temp);
607 return fun;
608 }
609 }
610 return null;
611 }
612 public String toOpString(HFunction fun, Session session) {
613
614 if (fun.size()==0) {
615 return "()";
616 }
617
618 StringBuffer buf = new StringBuffer();
619 fun.get(0).toStringBuffer(buf, session);
620 for (int i=1;i<fun.size();i++) {
621 fun.get(i).toStringBuffer(buf, session);
622 }
623 return buf.toString();
624
625 }
626
627 public int precedence() {
628 return C.MINIMUM_PRECEDENCE;
629 }
630 }
631
632 class E_Function_Body_ extends SFunctionEvaluator implements FunctionOpEvaluator {
633 public HObject evaluate(HFunction hmFunction, Session hmSession) {
634 return null;
635 }
636 public String toOpString(HFunction fun, Session session) {
637
638 if (fun.size()==0) {
639 return "()";
640 }
641
642 StringBuffer buf = new StringBuffer();
643 buf.append('(');
644 fun.argumentsToString(buf,0,false,session);
645 buf.append(')');
646 return buf.toString();
647
648 }
649
650 public int precedence() {
651 return C.MINIMUM_PRECEDENCE;
652 }
653 }
654
655 class EPureFunction extends SFunctionEvaluator {
656 /**
657 * Constructor for the ELambda object
658 */
659 public EPureFunction() {
660 }
661
662
663 /**
664 * Method Declaration.
665 *
666 *@param vect
667 *@param session Description of Parameter
668 *@return
669 *@see
670 */
671 public HObject evaluate(HFunction vect, Session session) {
672 if (vect.size() >= 3) {
673 // && vect.get(1) instanceof HFunction
674 HObject obj = vect.get(1);
675
676 if (vect.get(0).equals(C.Null)) {
677 for (int i = 2; i < vect.size(); i++) {
678 obj = substitute(obj, C.Slot.f(HInteger.valueOf(i - 1)),
679 session.EV(vect.get(i)));
680 }
681
682 return session.EV(obj);
683 }
684
685 if (vect.get(0) instanceof HSymbol) {
686 // HSymbol sym = (HSymbol) vect.get(0);
687
688 obj = substitute(obj, vect.get(0), session.EV(vect.get(2)));
689
690 return session.EV(obj);
691 }
692
693 if (vect.get(0).isList()) {
694 HFunction lst = (HFunction) vect.get(0);
695
696 if (vect.size() - 2 >= lst.size()) {
697 for (int i = 0; i < lst.size(); i++) {
698 if (!(lst.get(i) instanceof HSymbol)) {
699 return null;
700 }
701 }
702
703 for (int i = 0; i < lst.size(); i++) {
704 obj = substitute(obj, (lst.get(i)),
705 session.EV(vect.get(2 + i)));
706 }
707
708 return session.EV(obj);
709 }
710 }
711 }
712
713 return null;
714 }
715
716
717 /**
718 * Description of the Method
719 *
720 *@param fun Description of Parameter
721 *@param obj Description of Parameter
722 *@param subst Description of Parameter
723 *@return Description of the Returned Value
724 */
725 public HObject substitute(HObject fun, HObject obj, HObject subst) {
726 if (fun instanceof HFunction) {
727 HFunction f = (HFunction) fun;
728 // local variables are necessary:
729 if (f.head().equals(C.PureFunction)) {
730 return f;
731 }
732 //---
733 boolean evaled = false;
734
735 if (f.equals(obj)) {
736 return subst;
737 }
738 HFunction temp;
739 if (f.head().equals(obj) && (subst instanceof HSymbol)) {
740 temp = new HFunction((HSymbol) subst);
741 // temp.symbol = (HSymbol) subst;
742 temp.addAll(0, f);
743 evaled = true;
744 }
745 else {
746 temp = (HFunction) ((HFunction) f).clone();
747 }
748
749 HObject tempi;
750
751 for (int i = 0; i < f.size(); i++) {
752 tempi = substitute(f.get(i), obj, subst);
753
754 if (tempi != f.get(i)) {
755 temp.set(i, tempi);
756
757 evaled = true;
758 }
759 }
760
761 if (evaled) {
762 return temp;
763 }
764
765 return f;
766 }
767 return fun.substitute(obj, subst);
768 }
769 }
770 /**
771 * Implementation of programming functions
772 *
773 */
774 public class Programming implements FunctionEvaluator {
775
776
777 /**
778 * Description of the Method
779 *
780 *@param vect Description of Parameter
781 *@return Description of the Returned Value
782 */
783 public HObject evaluate(HFunction vect) {
784 C.Check.setEval(new ECheck());
785 C.N.setEval(new EN());
786 C.Set.setEval(new ESet());
787 C.SetDelayed.setEval(new ESetDelayed());
788 C.Statement.setEval(new EStatement());
789 C.UpSet.setEval(new EUpSet());
790 C.UpSetDelayed.setEval(new EUpSetDelayed());
791 C.PureFunction.setEval(new EPureFunction());
792
793 C._Function_Head_.setEval(new E_Function_Head_());
794 C._Function_Body_.setEval(new E_Function_Body_());
795
796 return C.Null;
797 }
798
799 }
800