00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package jpl;
00029
00030 import java.util.Hashtable;
00031 import java.util.Iterator;
00032 import java.util.Map;
00033 import jpl.fli.DoubleHolder;
00034 import jpl.fli.Int64Holder;
00035 import jpl.fli.IntHolder;
00036 import jpl.fli.Prolog;
00037 import jpl.fli.StringHolder;
00038 import jpl.fli.term_t;
00039
00040
00041
00067 public abstract class Term {
00068
00069
00070
00071
00072
00073
00074
00075
00080 protected Term() {
00081 }
00082
00083
00084
00085
00086
00093 public abstract Term arg(int ano);
00094
00102 public abstract Term[] args();
00103
00110 public abstract boolean hasFunctor(String name, int arity);
00111
00118 public abstract boolean hasFunctor(int value, int arity);
00125 public abstract boolean hasFunctor(double value, int arity);
00126
00133 public String name() {
00134 throw new JPLException("jpl." + this.typeName() + ".name() is undefined");
00135 };
00136
00143 public int arity() {
00144 throw new JPLException("jpl." + this.typeName() + ".arity() is undefined");
00145 };
00146
00153 public int intValue() {
00154 throw new JPLException("jpl." + this.typeName() + ".intValue() is undefined");
00155 }
00162 public long longValue() {
00163 throw new JPLException("jpl." + this.typeName() + ".longValue() is undefined");
00164 }
00171 public float floatValue() {
00172 throw new JPLException("jpl." + this.typeName() + ".floatValue() is undefined");
00173 }
00174
00181 public double doubleValue() {
00182 throw new JPLException("jpl." + this.typeName() + ".doubleValue() is undefined");
00183 }
00184
00185
00186
00187
00188
00194 public abstract int type();
00195
00201 public abstract String typeName();
00202
00208 public boolean isAtom() {
00209 return this instanceof Atom;
00210 }
00211
00217 public boolean isCompound() {
00218 return this instanceof Compound;
00219 }
00220
00226 public boolean isFloat() {
00227 return this instanceof Float;
00228 }
00229
00235 public boolean isInteger() {
00236 return this instanceof Integer;
00237 }
00238
00244 public boolean isVariable() {
00245 return this instanceof Variable;
00246 }
00247
00253 public boolean isJFalse() {
00254 return false;
00255 }
00256
00262 public boolean isJTrue() {
00263 return false;
00264 }
00265
00271 public boolean isJNull() {
00272 return false;
00273 }
00274
00280 public boolean isJVoid() {
00281 return false;
00282 }
00283
00289 public boolean isJObject() {
00290 return false;
00291 }
00292
00298 public boolean isJRef() {
00299 return false;
00300 }
00301
00302 public abstract Object jrefToObject();
00303
00304
00308 public static Term objectToJRef(Object obj) {
00309 return new Compound( "@", new Term[]{new Atom(Prolog.object_to_tag(obj))});
00310 }
00311
00312 public Term putParams(Term[] ps) {
00313 IntHolder next = new IntHolder();
00314 next.value = 0;
00315 Term t2 = this.putParams1(next, ps);
00316 if (next.value != ps.length) {
00317 throw new JPLException("Term.putParams: more actual params than formal");
00318 }
00319 return t2;
00320 }
00321
00322 public Term putParams(Term plist) {
00323 Term[] ps = plist.toTermArray();
00324 return putParams(ps);
00325 }
00326
00327 protected Term putParams1(IntHolder next, Term[] ps) {
00328 switch (this.type()) {
00329 case Prolog.COMPOUND :
00330 return new Compound(this.name(), putParams2(this.args(), next, ps));
00331 case Prolog.ATOM :
00332 if (this.name().equals("?")) {
00333 if (next.value >= ps.length) {
00334 throw new JPLException("Term.putParams: fewer actual params than formal params");
00335 }
00336 return ps[next.value++];
00337 }
00338 default :
00339 return this;
00340 }
00341 }
00342
00343 static protected Term[] putParams2(Term[] ts, IntHolder next, Term[] ps) {
00344 int n = ts.length;
00345 Term[] ts2 = new Term[n];
00346 for (int i = 0; i < n; i++) {
00347 ts2[i] = ts[i].putParams1(next, ps);
00348 }
00349 return ts2;
00350 }
00351
00358 public int listLength() {
00359 if (this.hasFunctor(".", 2)) {
00360 return 1 + this.arg(2).listLength();
00361 } else if (this.hasFunctor("[]", 0)) {
00362 return 0;
00363 } else {
00364 throw new JPLException("Term.listLength: term is not a list");
00365 }
00366 }
00367
00373 public Term[] toTermArray() {
00374 try {
00375 int len = this.listLength();
00376 Term[] ts = new Term[len];
00377 Term t = this;
00378
00379 for (int i = 0; i < len; i++) {
00380 ts[i] = t.arg(1);
00381 t = t.arg(2);
00382 }
00383 return ts;
00384 } catch (JPLException e) {
00385 throw new JPLException("Term.toTermArray: term is not a proper list");
00386 }
00387 }
00388
00389
00390
00391
00392
00399 public abstract String debugString();
00400
00407 public static String debugString(Term arg[]) {
00408 String s = "[";
00409
00410 for (int i = 0; i < arg.length; ++i) {
00411 s += arg[i].debugString();
00412 if (i != arg.length - 1) {
00413 s += ", ";
00414 }
00415 }
00416 return s + "]";
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 public void put( term_t term){
00445 put( new Hashtable(), term);
00446 }
00456 protected abstract void put(Map varnames_to_vars, term_t term);
00457
00470 protected static term_t putTerms(Map varnames_to_vars, Term[] args) {
00471
00472
00473
00474
00475
00476
00477 term_t term0 = Prolog.new_term_refs(args.length);
00478
00479
00480
00481
00482 long ith_term_t = term0.value;
00483 for (int i = 0; i < args.length; ++i, ++ith_term_t) {
00484 term_t term = new term_t();
00485 term.value = ith_term_t;
00486 args[i].put(varnames_to_vars, term);
00487 }
00488
00489 return term0;
00490 }
00491
00492
00493 public static void putTerm( Object obj, term_t termref){
00494 if (obj instanceof Term){
00495 ((Term)obj).put(termref);
00496 } else {
00497 throw new JPLException("not a Term");
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00587 protected static Term getTerm1(Map vars_to_Vars, term_t term) {
00588 int type = Prolog.term_type(term);
00589
00590 switch (type) {
00591 case Prolog.VARIABLE :
00592 return Variable.getTerm(vars_to_Vars, term);
00593 case Prolog.ATOM :
00594 return Atom.getTerm(vars_to_Vars, term);
00595 case Prolog.STRING :
00596 return Atom.getString(vars_to_Vars, term);
00597 case Prolog.INTEGER :
00598 return Integer.getTerm(vars_to_Vars, term);
00599 case Prolog.FLOAT :
00600 return Float.getTerm(vars_to_Vars, term);
00601 case Prolog.COMPOUND :
00602 return Compound.getTerm(vars_to_Vars, term);
00603 default :
00604
00605 throw new JPLException("Term.from_term_t: unknown term type=" + type);
00606 }
00607 }
00608
00609 protected static Term getTerm(Map vars_to_Vars, term_t term) {
00610 StringHolder hString;
00611 IntHolder hInt;
00612 Int64Holder hInt64;
00613
00614 switch (Prolog.term_type(term)) {
00615 case Prolog.VARIABLE:
00616 for (Iterator i = vars_to_Vars.keySet().iterator(); i.hasNext();) {
00617 term_t varX = (term_t) i.next();
00618 if (Prolog.compare(varX, term) == 0) {
00619 return (Term) vars_to_Vars.get(varX);
00620 }
00621 }
00622
00623 Variable Var = new Variable();
00624 Var.term_ = term;
00625 vars_to_Vars.put(term, Var);
00626 return Var;
00627 case Prolog.ATOM:
00628 hString = new StringHolder();
00629 Prolog.get_atom_chars(term, hString);
00630 return new Atom(hString.value);
00631 case Prolog.STRING:
00632 hString = new StringHolder();
00633 Prolog.get_string_chars(term, hString);
00634 return new Atom(hString.value);
00635 case Prolog.INTEGER:
00636 hInt64 = new Int64Holder();
00637 Prolog.get_integer(term, hInt64);
00638 return new jpl.Integer(hInt64.value);
00639 case Prolog.FLOAT:
00640 DoubleHolder hFloatValue = new DoubleHolder();
00641 Prolog.get_float(term, hFloatValue);
00642 return new jpl.Float(hFloatValue.value);
00643 case Prolog.COMPOUND:
00644 hString = new StringHolder();
00645 hInt = new IntHolder();
00646 Prolog.get_name_arity(term, hString, hInt);
00647 Term args[] = new Term[hInt.value];
00648
00649 for (int i = 1; i <= hInt.value; i++) {
00650 term_t termi = Prolog.new_term_ref();
00651 Prolog.get_arg(i, term, termi);
00652 args[i - 1] = Term.getTerm(vars_to_Vars, termi);
00653 }
00654 return new Compound(hString.value, args);
00655 default:
00656
00657 throw new JPLException("Term.from_term_t: unknown term type=" + Prolog.term_type(term));
00658 }
00659 }
00660
00661 protected static Term getTerm( term_t term){
00662 return getTerm( new Hashtable(), term);
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00704 protected abstract void getSubst(Map varnames_to_Terms, Map vars_to_Vars);
00705
00706
00707
00715 protected static void getSubsts(Map varnames_to_Terms, Map vars_to_Vars, Term[] args) {
00716 for (int i = 0; i < args.length; ++i) {
00717 args[i].getSubst(varnames_to_Terms, vars_to_Vars);
00718 }
00719 }
00720
00721
00722
00732 protected static boolean terms_equals(Term[] t1, Term[] t2) {
00733 if (t1.length != t2.length) {
00734 return false;
00735 }
00736
00737 for (int i = 0; i < t1.length; ++i) {
00738 if (!t1[i].equals(t2[i])) {
00739 return false;
00740 }
00741 }
00742 return true;
00743 }
00744
00745
00746
00753 public static String toString(Term[] args) {
00754 String s = "";
00755
00756 for (int i = 0; i < args.length; ++i) {
00757 s += args[i].toString();
00758 if (i != args.length - 1) {
00759 s += ", ";
00760 }
00761 }
00762
00763 return s;
00764 }
00765
00766 }
00767
00768