C:/Users/Dennis/src/lang/Life_start/Life/life-1.02/source/bi_type.c

Go to the documentation of this file.
00001 /*                                                                      tab:4
00002  *
00003  * bi_type.c - builtins for doing type heierachy stuff
00004  *
00005  * Copyright (c) 1992 Digital Equipment Corporation
00006  * All Rights Reserved.
00007  *
00008  * The standard digital prl copyrights exist and where compatible
00009  * the below also exists.
00010  * Permission to use, copy, modify, and distribute this
00011  * software and its documentation for any purpose and without
00012  * fee is hereby granted, provided that the above copyright
00013  * notice appear in all copies.  Copyright holder(s) make no
00014  * representation about the suitability of this software for
00015  * any purpose. It is provided "as is" without express or
00016  * implied warranty.
00017  *
00018  */
00019 /*      $Id: bi_type.c,v 1.2 1994/12/08 23:08:52 duchier Exp $   */
00020 
00021 #ifndef lint
00022 static char vcid[] = "$Id: bi_type.c,v 1.2 1994/12/08 23:08:52 duchier Exp $";
00023 #endif /* lint */
00024 
00025 #include "extern.h"
00026 #include "trees.h"
00027 #include "login.h"
00028 #include "parser.h"
00029 #include "copy.h"
00030 #include "token.h"
00031 #include "print.h"
00032 #include "lefun.h"
00033 #include "memory.h"
00034 #include "modules.h"
00035 #ifndef OS2_PORT
00036 #include "built_ins.h"
00037 #else
00038 #include "built_in.h"
00039 #endif
00040 
00041 #include "error.h"
00042 
00043 #ifdef X11
00044 #include "xpred.h"
00045 #endif
00046 
00047 /******** C_CHILDREN
00048   Return a list of roots of the children types of T (except bottom).
00049 */
00050 static long c_children()   /*  RM: Dec 14 1992  Re-wrote most of the routine */
00051 {
00052   long success=TRUE;
00053   ptr_psi_term funct,result,arg1,arg2,t,p1;
00054   ptr_int_list p;
00055   
00056   funct=aim->a;
00057   deref_ptr(funct);
00058   result=aim->b;
00059   get_two_args(funct->attr_list,&arg1,&arg2);
00060   
00061   if (!arg1) {
00062     curry();
00063     return success;
00064   }
00065 
00066   deref(arg1);
00067   deref_args(funct,set_1);
00068   resid_aim=NULL;
00069   
00070   if (arg1->type==top)
00071     t=collect_symbols(greatest_sel); /*  RM: Feb  3 1993  */
00072   else {
00073     p=arg1->type->children;
00074 
00075     /* Hack: check there's enough memory to build the list */
00076     /*  RM: Jul 22 1993  */
00077     /*
00078       { int count=0;
00079       while(p) {
00080       count++;
00081       p=p->next;
00082       }
00083       if (heap_pointer-stack_pointer < 3*count*sizeof(psi_term)) {
00084       goal_stack=aim;
00085       garbage();
00086       return success;
00087       }
00088       */
00089     
00090     t=stack_nil();
00091     if (!(arg1->type==real && arg1->value)) /* PVR 15.2.94 */
00092       while (p) {
00093         ptr_definition ptype;
00094 
00095         ptype = (ptr_definition) p->value;
00096         if (hidden_type(ptype)) { p=p->next; continue; }
00097         p1 = stack_psi_term(0);
00098         p1->type = ptype;
00099         t=stack_cons(p1,t);
00100         p = p->next;
00101       }
00102   }
00103   push_goal(unify,result,t,NULL);
00104 
00105   return success;
00106 }
00107 
00108 
00109 
00110 /******** C_PARENTS
00111   Return a list of roots of the parent types of T.
00112 */
00113 static long c_parents()
00114 {
00115   long success=TRUE;
00116   ptr_psi_term funct,result,arg1,arg2,t,p1;
00117   ptr_int_list p;
00118 
00119   funct=aim->a;
00120   deref_ptr(funct);
00121   result=aim->b;
00122   get_two_args(funct->attr_list,&arg1,&arg2);
00123   if (arg1) {
00124     deref(arg1);
00125     deref_args(funct,set_1);
00126     resid_aim=NULL;
00127     t=stack_nil();  /*  RM: Dec 14 1992  */
00128     p = arg1->type->parents;
00129     if (arg1->type!=top && p==NULL) {
00130       /* Top is the only parent */
00131       p1 = stack_psi_term(4);
00132       p1->type = (ptr_definition) top;
00133       t=stack_cons(p1,t); /*  RM: Dec 14 1992  */
00134     }
00135     else {
00136       if ((arg1->type==quoted_string || arg1->type==integer ||
00137           arg1->type==real) && arg1->value!=NULL) {
00138         /* arg1 is a string, long or real: return a list with arg1 as
00139            argument, where arg1->value = NULL, MH */
00140         p1 = stack_psi_term(4);
00141         p1->type = arg1->type;
00142         t=stack_cons(p1,t); /*  RM: Dec 14 1992  */
00143       }
00144       else {
00145         /* Look at the parents list */
00146         while (p) {
00147           ptr_definition ptype;
00148 
00149           ptype = (ptr_definition) p->value;
00150           if (hidden_type(ptype)) { p=p->next; continue; }
00151           p1 = stack_psi_term(4);
00152           p1->type = ptype;
00153           t=stack_cons(p1,t); /*  RM: Dec 14 1992  */
00154           p = p->next;
00155         }
00156       }
00157     }
00158     push_goal(unify,result,t,NULL);
00159   }
00160   else
00161     curry();
00162 
00163   return success;
00164 }
00165 
00166 
00167 
00168 
00169 /******** C_SMALLEST
00170   Return the parents of bottom.
00171   This function has no arguments.
00172 */
00173 static long c_smallest()
00174 {
00175   long success=TRUE;
00176   ptr_psi_term result, g, t;
00177 
00178   g=aim->a;
00179   deref_args(g,set_empty);
00180   result=aim->b;
00181   t=collect_symbols(least_sel); /*  RM: Feb  3 1993  */
00182   push_goal(unify,result,t,NULL);
00183   
00184   return success;
00185 }
00186 
00187 isSubTypeValue(arg1, arg2)
00188 ptr_psi_term arg1, arg2;
00189 {
00190   long ans=TRUE;
00191   
00192   /* we already know that either arg1->type == arg2->type or that at both
00193    * of the two are either long or real
00194    */
00195   
00196   if (arg2->value) {
00197     if (arg1->value) {
00198       if (arg1->type==real || arg1->type==integer) {
00199         ans=( *(REAL *)arg1->value == *(REAL *)arg2->value);
00200       }
00201       else if (arg1->type==quoted_string) {
00202         ans=strcmp((char *)arg1->value,(char *)arg2->value)==0;
00203       }
00204     }
00205     else
00206       ans=FALSE;
00207   }
00208   else {
00209     if (arg1->value && (arg1->type==real || arg1->type==integer)) {
00210       if (arg2->type==integer)
00211         ans=(*(REAL *)arg1->value == floor(*(REAL *)arg1->value));
00212       else
00213         ans=TRUE;
00214     }
00215   }
00216   return ans;
00217 }
00218 
00219 /* Boolean utility function that implements isa */
00220 static long isa(arg1,arg2)
00221 ptr_psi_term arg1, arg2;
00222 {
00223   long ans;
00224 
00225   if (  arg1->type==arg2->type
00226      || (  (arg1->type==real || arg1->type==integer)
00227         && (arg2->type==real || arg2->type==integer)
00228         && (arg1->value || arg2->value)
00229         )
00230      ) {
00231 
00232     if(arg1->type==cut) /*  RM: Jan 21 1993  */
00233       ans=TRUE;
00234     else
00235       ans=isSubTypeValue(arg1, arg2);
00236   }
00237   else {
00238     matches(arg1->type, arg2->type, &ans);
00239   }
00240 
00241   /*Errorline("isa %P %P -> %d\n",arg1,arg2,ans);*/
00242 
00243   return ans;
00244 }
00245   
00246 
00247 #define isa_le_sel 0
00248 #define isa_lt_sel 1
00249 #define isa_ge_sel 2
00250 #define isa_gt_sel 3
00251 #define isa_eq_sel 4
00252 #define isa_nle_sel 5
00253 #define isa_nlt_sel 6
00254 #define isa_nge_sel 7
00255 #define isa_ngt_sel 8
00256 #define isa_neq_sel 9
00257 #define isa_cmp_sel 10
00258 #define isa_ncmp_sel 11
00259 
00260 /* Utility that selects one of several isa functions */
00261 static long isa_select(arg1,arg2,sel)
00262 ptr_psi_term arg1,arg2;
00263 long sel;
00264 {
00265   long ans;
00266 
00267   switch (sel) {
00268   case isa_le_sel: ans=isa(arg1,arg2);
00269     break;
00270   case isa_lt_sel: ans=isa(arg1,arg2) && !isa(arg2,arg1);
00271     break;
00272   case isa_ge_sel: ans=isa(arg2,arg1);
00273     break;
00274   case isa_gt_sel: ans=isa(arg2,arg1) && !isa(arg1,arg2);
00275     break;
00276   case isa_eq_sel: ans=isa(arg1,arg2) && isa(arg2,arg1);
00277     break;
00278 
00279   case isa_nle_sel: ans= !isa(arg1,arg2);
00280     break;
00281   case isa_nlt_sel: ans= !(isa(arg1,arg2) && !isa(arg2,arg1));
00282     break;
00283   case isa_nge_sel: ans= !isa(arg2,arg1);
00284     break;
00285   case isa_ngt_sel: ans= !(isa(arg2,arg1) && !isa(arg1,arg2));
00286     break;
00287   case isa_neq_sel: ans= !(isa(arg1,arg2) && isa(arg2,arg1));
00288     break;
00289 
00290   case isa_cmp_sel: ans=isa(arg1,arg2) || isa(arg2,arg1);
00291     break;
00292   case isa_ncmp_sel: ans= !(isa(arg1,arg2) || isa(arg2,arg1));
00293     break;
00294   }
00295   return ans;
00296 }
00297 
00298 /******** C_ISA_MAIN
00299   Main routine to handle all the isa built-in functions.
00300 */
00301 static long c_isa_main(sel)
00302 long sel;
00303 {
00304   long success=TRUE,ans;
00305   ptr_psi_term arg1,arg2,funct,result;
00306 
00307   funct=aim->a;
00308   deref_ptr(funct);
00309   result=aim->b;
00310   get_two_args(funct->attr_list,&arg1,&arg2);
00311   if (arg1 && arg2) {
00312     deref(arg1);
00313     deref(arg2);
00314     deref_args(funct,set_1_2);
00315     ans=isa_select(arg1,arg2,sel);
00316     unify_bool_result(result,ans);
00317   }
00318   else curry();
00319 
00320   return success;
00321 }
00322 
00323 /******** C_ISA_LE
00324   Type t1 isa t2 in the hierarchy, i.e. t1 is less than or equal to t2.
00325   This boolean function requires two arguments and never residuates.
00326   It will curry if insufficient arguments are given.
00327   It works correctly on the 'value' types, i.e. on integers, reals, strings,
00328   and lists.  For lists, it looks only at the top level, i.e. whether the
00329   object is nil or a cons cell.
00330 */
00331 static long c_isa_le()
00332 {
00333   return c_isa_main(isa_le_sel);
00334 }
00335 
00336 static long c_isa_lt()
00337 {
00338   return c_isa_main(isa_lt_sel);
00339 }
00340 
00341 static long c_isa_ge()
00342 {
00343   return c_isa_main(isa_ge_sel);
00344 }
00345 
00346 static long c_isa_gt()
00347 {
00348   return c_isa_main(isa_gt_sel);
00349 }
00350 
00351 static long c_isa_eq()
00352 {
00353   return c_isa_main(isa_eq_sel);
00354 }
00355 
00356 static long c_isa_nle()
00357 {
00358   return c_isa_main(isa_nle_sel);
00359 }
00360 
00361 static long c_isa_nlt()
00362 {
00363   return c_isa_main(isa_nlt_sel);
00364 }
00365 
00366 static long c_isa_nge()
00367 {
00368   return c_isa_main(isa_nge_sel);
00369 }
00370 
00371 static long c_isa_ngt()
00372 {
00373   return c_isa_main(isa_ngt_sel);
00374 }
00375 
00376 static long c_isa_neq()
00377 {
00378   return c_isa_main(isa_neq_sel);
00379 }
00380 
00381 static long c_isa_cmp()
00382 {
00383   return c_isa_main(isa_cmp_sel);
00384 }
00385 
00386 static long c_isa_ncmp()
00387 {
00388   return c_isa_main(isa_ncmp_sel);
00389 }
00390 
00391 
00392 
00393 /******** C_IS_FUNCTION
00394   Succeed iff argument is a function (built-in or user-defined).
00395 */
00396 static int c_is_function() /*  RM: Jan 29 1993  */
00397 {
00398   int success=TRUE,ans;
00399   ptr_psi_term arg1,funct,result;
00400 
00401   funct=aim->a;
00402   deref_ptr(funct);
00403   result=aim->b;
00404   get_one_arg(funct->attr_list,&arg1);
00405   if (arg1) {
00406     deref(arg1);
00407     deref_args(funct,set_1);
00408     ans=(arg1->type->type==function);
00409     unify_bool_result(result,ans);
00410   }
00411   else curry();
00412 
00413   return success;
00414 }
00415 
00416 
00417 
00418 /******** C_IS_PERSISTENT
00419   Succeed iff argument is a quoted persistent or on the heap.
00420 */
00421 static int c_is_persistent() /*  RM: Feb  9 1993  */
00422 {
00423   int success=TRUE,ans;
00424   ptr_psi_term arg1,glob,result;
00425 
00426   glob=aim->a;
00427   deref_ptr(glob);
00428   result=aim->b;
00429   get_one_arg(glob->attr_list,&arg1);
00430   if (arg1) {
00431     deref(arg1);
00432     deref_args(glob,set_1);
00433     ans=(
00434          arg1->type->type==global &&
00435          (GENERIC)arg1->type->global_value>=heap_pointer
00436          ) ||
00437            (GENERIC)arg1>=heap_pointer;
00438     unify_bool_result(result,ans);
00439   }
00440   else curry();
00441   
00442   return success;
00443 }
00444 
00445 
00446 
00447 /******** C_IS_PREDICATE
00448   Succeed iff argument is a predicate (built-in or user-defined).
00449 */
00450 static int c_is_predicate() /*  RM: Jan 29 1993  */
00451 {
00452   int success=TRUE,ans;
00453   ptr_psi_term arg1,funct,result;
00454 
00455   funct=aim->a;
00456   deref_ptr(funct);
00457   result=aim->b;
00458   get_one_arg(funct->attr_list,&arg1);
00459   if (arg1) {
00460     deref(arg1);
00461     deref_args(funct,set_1);
00462     ans=(arg1->type->type==predicate);
00463     unify_bool_result(result,ans);
00464   }
00465   else curry();
00466 
00467   return success;
00468 }
00469 
00470 
00471 
00472 /******** C_IS_SORT
00473   Succeed iff argument is a sort (built-in or user-defined).
00474 */
00475 static int c_is_sort() /*  RM: Jan 29 1993  */
00476 {
00477   int success=TRUE,ans;
00478   ptr_psi_term arg1,funct,result;
00479 
00480   funct=aim->a;
00481   deref_ptr(funct);
00482   result=aim->b;
00483   get_one_arg(funct->attr_list,&arg1);
00484   if (arg1) {
00485     deref(arg1);
00486     deref_args(funct,set_1);
00487     ans=(arg1->type->type==type);
00488     unify_bool_result(result,ans);
00489   }
00490   else curry();
00491 
00492   return success;
00493 }
00494 
00495 
00496 
00497 /******** C_IS_VALUE
00498   Return true iff argument has a value, i.e. if it is implemented in
00499   a quirky way in Wild_Life.  This is true for integers, reals,
00500   strings (which are potentially infinite sets of objects), and list objects.
00501 */
00502 static long c_is_value()
00503 {
00504   long success=TRUE,ans;
00505   ptr_psi_term arg1,arg2,funct,result;
00506 
00507   funct=aim->a;
00508   deref_ptr(funct);
00509   result=aim->b;
00510   get_two_args(funct->attr_list,&arg1,&arg2);
00511   if (arg1) {
00512     deref(arg1);
00513     deref_args(funct,set_1);
00514     ans=(arg1->value!=NULL);
00515     unify_bool_result(result,ans);
00516   }
00517   else curry();
00518 
00519   return success;
00520 }
00521 
00522 
00523 
00524 /******** C_IS_NUMBER
00525   Return true iff argument is an actual number.
00526 */
00527 static long c_is_number()
00528 {
00529   long success=TRUE,ans;
00530   ptr_psi_term arg1,arg2,funct,result;
00531 
00532   funct=aim->a;
00533   deref_ptr(funct);
00534   result=aim->b;
00535   get_two_args(funct->attr_list,&arg1,&arg2);
00536   if (arg1) {
00537     deref(arg1);
00538     deref_args(funct,set_1);
00539     ans=sub_type(arg1->type,real) && (arg1->value!=NULL);
00540     unify_bool_result(result,ans);
00541   }
00542   else curry();
00543 
00544   return success;
00545 }
00546 
00547 
00548 /******** C_ISA_SUBSORT(A,B)
00549   if A is a subsort of B => succeed and residuate on B
00550   else                   => fail
00551 */
00552 c_isa_subsort()
00553 {
00554   ptr_psi_term pred,arg1,arg2;
00555 
00556   pred=aim->a;
00557   deref_ptr(pred);
00558   get_two_args(pred->attr_list,&arg1,&arg2);
00559 
00560   if (!arg1) reportAndAbort(pred,"no first argument");
00561   deref(arg1);
00562   
00563   if (!arg2) reportAndAbort(pred,"no second argument");
00564   deref(arg2);
00565 
00566   deref_args(pred, set_1_2);
00567 
00568   if (isa(arg1, arg2))
00569   {
00570           residuate(arg2);
00571           return TRUE;
00572   }
00573   return FALSE;
00574 }
00575 
00576 
00577 
00578 isValue(p)
00579 ptr_psi_term p;
00580 {
00581         return (p->value != NULL);
00582 }
00583 
00584 
00585 
00586 /******** C_GLB(A,B)
00587   Return glb(A,B).  Continued calls will return each following type in
00588   the disjunction of the glb of A,B.
00589 */
00590 c_glb()
00591 {
00592   ptr_psi_term func,arg1,arg2, result, other;
00593   ptr_definition ans;
00594   ptr_int_list complexType;
00595   ptr_int_list decodedType = NULL;
00596   long ret;
00597   
00598   func=aim->a;
00599   deref_ptr(func);
00600   get_two_args(func->attr_list,&arg1,&arg2);
00601 
00602   if ((!arg1) || (!arg2)) {
00603     curry();
00604     return TRUE;
00605   }
00606   result = aim->b;
00607   deref(result);
00608   deref(arg1);
00609   deref(arg2);
00610   deref_args(func, set_1_2);
00611 
00612   if ((ret=glb(arg1->type, arg2->type, &ans, &complexType)) == 0)
00613     return FALSE;
00614 
00615   if ((ret != 4)&&(isValue(arg1)||isValue(arg2))) {
00616     /* glb is one of arg1->type or arg2->type AND at least one is a value */
00617     if (!isSubTypeValue(arg1, arg2) && !isSubTypeValue(arg2, arg1))
00618       return FALSE;
00619   }
00620   if (!ans) {
00621     decodedType = decode(complexType);
00622     ans = (ptr_definition)decodedType->value;
00623     decodedType = decodedType->next;
00624   }
00625   other=makePsiTerm(ans);
00626 
00627   if (isValue(arg1)) other->value=arg1->value;
00628   if (isValue(arg2)) other->value=arg2->value;
00629     
00630   if (isValue(arg1) || isValue(arg2)) {
00631     if (decodedType) {
00632       Errorline("glb of multiple-inheritance value sorts not yet implemented.\n");
00633       return FALSE;
00634     }
00635   }
00636     
00637   if (decodedType)
00638     push_choice_point(type_disj, result, decodedType, NULL);
00639 
00640   resid_aim = NULL;
00641   push_goal(unify,result,other,NULL);
00642   return TRUE;
00643 }
00644 
00645 
00646 
00647 /******** C_LUB(A,B)
00648   Return lub(A,B).  Continued calls will return each following type in
00649   the disjunction of the lub of A,B.
00650 */
00651 c_lub()
00652 {
00653   ptr_psi_term func,arg1,arg2, result, other;
00654   ptr_definition ans=NULL;
00655   ptr_int_list decodedType = NULL;
00656   
00657   func=aim->a;
00658   deref_ptr(func);
00659   get_two_args(func->attr_list,&arg1,&arg2);
00660 
00661   if ((!arg1) || (!arg2))
00662   {
00663     curry();
00664     return TRUE;
00665   }
00666   result = aim->b;
00667   deref(result);
00668   deref(arg1);
00669   deref(arg2);
00670   deref_args(func, set_1_2);
00671 
00672   /* now lets find the list of types that is the lub */
00673   
00674   decodedType = lub(arg1, arg2, &other);
00675 
00676   if (decodedType) {
00677     ans = (ptr_definition)decodedType->value;
00678     decodedType = decodedType->next;
00679     other = makePsiTerm(ans);
00680   }
00681 
00682   if (decodedType)
00683     push_choice_point(type_disj, result, decodedType, NULL);
00684     
00685   resid_aim = NULL;
00686   push_goal(unify,result,other,NULL);
00687   return TRUE;
00688 }
00689 
00690 
00691 
00692 void insert_type_builtins() /*  RM: Jan 29 1993  */
00693 {
00694   /* Sort comparisons */
00695   new_built_in(syntax_module,":=<",function,c_isa_le);
00696   new_built_in(syntax_module,":<",function,c_isa_lt);
00697   new_built_in(syntax_module,":>=",function,c_isa_ge);
00698   new_built_in(syntax_module,":>",function,c_isa_gt);
00699   new_built_in(syntax_module,":==",function,c_isa_eq);
00700   new_built_in(syntax_module,":><",function,c_isa_cmp);
00701   new_built_in(syntax_module,":\\=<",function,c_isa_nle);
00702   new_built_in(syntax_module,":\\<",function,c_isa_nlt);
00703   new_built_in(syntax_module,":\\>=",function,c_isa_nge);
00704   new_built_in(syntax_module,":\\>",function,c_isa_ngt);
00705   new_built_in(syntax_module,":\\==",function,c_isa_neq);
00706   new_built_in(syntax_module,":\\><",function,c_isa_ncmp);
00707 
00708 
00709   /* Type checks */
00710   new_built_in(bi_module,"is_value",function,c_is_value);
00711   new_built_in(bi_module,"is_number",function,c_is_number);
00712   new_built_in(bi_module,"is_function",function,c_is_function);
00713   new_built_in(bi_module,"is_predicate",function,c_is_predicate);
00714   new_built_in(bi_module,"is_sort",function,c_is_sort);
00715   new_built_in(bi_module,"is_persistent",function,c_is_persistent);
00716   
00717   /* Sort hierarchy maneuvering */
00718   new_built_in(bi_module,"children",function,c_children);
00719   new_built_in(bi_module,"parents",function,c_parents);
00720   new_built_in(bi_module,"least_sorts",function,c_smallest);
00721   new_built_in(bi_module,"subsort",predicate,c_isa_subsort);
00722   new_built_in(bi_module,"glb",function,c_glb);
00723   new_built_in(bi_module,"lub",function,c_lub);
00724 }

Generated on Sat Jan 26 08:48:06 2008 for WildLife by  doxygen 1.5.4