00001
00002
00003
00004
00005
00006 #ifndef lint
00007 static char vcid[] = "$Id: lefun.c,v 1.4 1995/01/14 00:24:55 duchier Exp $";
00008 #endif
00009
00010 #include "extern.h"
00011 #include "login.h"
00012 #include "copy.h"
00013 #include "trees.h"
00014 #include "parser.h"
00015 #include "print.h"
00016 #include "lefun.h"
00017 #include "token.h"
00018
00019
00020 ptr_goal resid_aim;
00021 ptr_resid_list resid_vars;
00022
00023
00024 long curried;
00025 long can_curry;
00026
00027
00028
00029
00030 static long attr_missing;
00031 static long check_func_flag;
00032
00033 void eval_global_var();
00034
00035
00036
00037 ptr_psi_term stack_psi_term(stat)
00038 long stat;
00039 {
00040 ptr_psi_term result;
00041
00042 result=STACK_ALLOC(psi_term);
00043 result->type=top;
00044 result->status=stat;
00045 result->flags=stat?QUOTED_TRUE:FALSE;
00046 result->attr_list=NULL;
00047 result->coref=NULL;
00048 #ifdef TS
00049 result->time_stamp=global_time_stamp;
00050 #endif
00051 result->resid=NULL;
00052 result->value=NULL;
00053
00054 return result;
00055 }
00056
00057
00058
00059
00060 ptr_psi_term real_stack_psi_term(stat,thereal)
00061 long stat;
00062 REAL thereal;
00063 {
00064 ptr_psi_term result;
00065
00066 result=STACK_ALLOC(psi_term);
00067 result->type = (thereal==floor(thereal)) ? integer : real;
00068 result->status=stat;
00069 result->flags=stat?QUOTED_TRUE:FALSE;
00070 result->attr_list=NULL;
00071 result->coref=NULL;
00072 #ifdef TS
00073 result->time_stamp=global_time_stamp;
00074 #endif
00075 result->resid=NULL;
00076 result->value=(GENERIC)heap_alloc(sizeof(REAL));
00077 (* (REAL *)(result->value)) = thereal;
00078
00079 return result;
00080 }
00081
00082
00083
00084
00085 ptr_psi_term heap_psi_term(stat)
00086 long stat;
00087 {
00088 ptr_psi_term result;
00089
00090 result=HEAP_ALLOC(psi_term);
00091 result->type=top;
00092 result->status=stat;
00093 result->flags=stat?QUOTED_TRUE:FALSE;
00094 result->attr_list=NULL;
00095 result->coref=NULL;
00096 #ifdef TS
00097 result->time_stamp=global_time_stamp;
00098 #endif
00099 result->resid=NULL;
00100 result->value=NULL;
00101
00102 return result;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 void residuate_double(t,u)
00118 ptr_psi_term t,u;
00119 {
00120 ptr_resid_list curr;
00121
00122 curr=STACK_ALLOC(resid_list);
00123 curr->var=t;
00124 curr->othervar=u;
00125 curr->next=resid_vars;
00126 resid_vars=curr;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 void residuate(t)
00136 ptr_psi_term t;
00137 {
00138 ptr_resid_list curr;
00139
00140 curr=STACK_ALLOC(resid_list);
00141 curr->var=t;
00142 curr->othervar=NULL;
00143 curr->next=resid_vars;
00144 resid_vars=curr;
00145 }
00146
00147
00148
00149
00150
00151
00152 void residuate2(u,v)
00153 ptr_psi_term u,v;
00154 {
00155 residuate(u);
00156 if (v && u!=v) residuate(v);
00157 }
00158
00159
00160
00161
00162
00163
00164 void residuate3(u,v,w)
00165 ptr_psi_term u,v,w;
00166 {
00167 residuate(u);
00168 if (v && u!=v) residuate(v);
00169 if (w && u!=w && v!=w) residuate(w);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 void curry()
00180 {
00181 if (can_curry)
00182 curried=TRUE;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 long residuateGoalOnVar(g, var, othervar)
00195 ptr_goal g;
00196 ptr_psi_term var,othervar;
00197 {
00198 long result;
00199 long resflag,resflag2;
00200 GENERIC rescode,rescode2,resvalue,resvalue2;
00201
00202 long not_found = TRUE;
00203
00204
00205
00206
00207 ptr_residuation *r;
00208
00209
00210 if ((GENERIC)var>=heap_pointer) {
00211 Errorline("attempt to residuate on psi-term %P in the heap.\n",var);
00212
00213 return FALSE;
00214 }
00215
00216 r= &(var->resid);
00217
00218 while (not_found && *r) {
00219 if ((*r)->goal == g) {
00220
00221
00222 result=glb_code((*r)->sortflag,(*r)->bestsort,
00223 TRUE,var->type,&resflag,&rescode);
00224 result=glb_value(result,resflag,rescode,(*r)->value,var->value,
00225 &resvalue);
00226 if (!result)
00227 return FALSE;
00228 else if (othervar) {
00229 result=glb_code(resflag,rescode,TRUE,othervar->type,
00230 &resflag2,&rescode2);
00231 result=glb_value(result,resflag2,rescode2,resvalue,othervar->value,
00232 &resvalue2);
00233 if (!result) {
00234 return FALSE;
00235 }
00236 else {
00237
00238
00239 if ((*r)->value==NULL && resvalue2!=NULL) {
00240 push_ptr_value(int_ptr,&((*r)->value));
00241 }
00242 if ((*r)->bestsort!=rescode2) {
00243 push_ptr_value(((*r)->sortflag?def_ptr:code_ptr),
00244 &((*r)->bestsort));
00245 (*r)->bestsort=rescode2;
00246 }
00247 if ((*r)->sortflag!=resflag2) {
00248 push_ptr_value(int_ptr,&((*r)->sortflag));
00249 (*r)->sortflag=resflag2;
00250 }
00251 }
00252 }
00253 else {
00254 if ((*r)->value==NULL && resvalue!=NULL) {
00255 push_ptr_value(int_ptr,&((*r)->value));
00256 }
00257 if ((*r)->bestsort!=rescode) {
00258 push_ptr_value(((*r)->sortflag?def_ptr:code_ptr),
00259 &((*r)->bestsort));
00260 (*r)->bestsort=rescode;
00261 }
00262 if ((*r)->sortflag!=resflag) {
00263 push_ptr_value(int_ptr,&((*r)->sortflag));
00264 (*r)->sortflag=resflag;
00265 }
00266 }
00267 not_found = FALSE;
00268 }
00269 else
00270 r= &((*r)->next);
00271 }
00272
00273 if (not_found) {
00274
00275
00276 push_ptr_value(resid_ptr,r);
00277 *r=STACK_ALLOC(residuation);
00278 if (othervar) {
00279 result=glb_code(TRUE,var->type,TRUE,othervar->type,&resflag,&rescode);
00280 result=glb_value(result,resflag,rescode,var->value,othervar->value,
00281 &resvalue);
00282 if (!result) {
00283 return FALSE;
00284 }
00285 else {
00286 (*r)->sortflag=resflag;
00287 (*r)->bestsort=rescode;
00288 (*r)->value=resvalue;
00289 }
00290 }
00291 else {
00292 (*r)->sortflag=TRUE;
00293 (*r)->bestsort=(GENERIC)var->type;
00294 (*r)->value=(GENERIC)var->value;
00295 }
00296 (*r)->goal=g;
00297 (*r)->next=NULL;
00298 }
00299
00300 if (!(g->pending)) {
00301
00302
00303
00304 push_ptr_value(int_ptr,&(g->pending));
00305 g->pending=TRUE;
00306 }
00307
00308 return TRUE;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 long do_residuation();
00323
00324
00325
00326 long do_residuation_user()
00327 {
00328 goal_stack=resid_aim->next;
00329 return do_residuation();
00330 }
00331
00332
00333 long do_residuation()
00334 {
00335 long success;
00336 ptr_psi_term t,u;
00337 ptr_goal *gs;
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 if (trace) {
00349 tracing();
00350 print_resid_message(resid_aim->a,resid_vars);
00351 }
00352
00353 while (resid_vars) {
00354
00355 t=resid_vars->var;
00356 u=resid_vars->othervar;
00357 deref_ptr(t);
00358 resid_vars=resid_vars->next;
00359 Traceline("residuating on %P (other = %P)\n",t,u);
00360
00361 success=residuateGoalOnVar(resid_aim, t, u);
00362 if (!success) {
00363 Traceline("failure because of disentailment\n");
00364 return FALSE;
00365 }
00366 }
00367
00368 Traceline("no failure because of disentailment\n");
00369 return TRUE;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379 void do_currying()
00380 {
00381 ptr_psi_term funct,result;
00382
00383
00384
00385 goal_stack=resid_aim->next;
00386 funct=(ptr_psi_term )resid_aim->a;
00387 result=(ptr_psi_term )resid_aim->b;
00388
00389 Traceline("currying %P\n",funct);
00390
00391 push_goal(unify_noeval,funct,result,NULL);
00392 resid_aim=NULL;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 void release_resid_main(t,trailflag)
00405 ptr_psi_term t;
00406 long trailflag;
00407 {
00408 ptr_goal g;
00409 ptr_residuation r;
00410
00411 if (r=t->resid) {
00412 if (trailflag) push_ptr_value(resid_ptr,&(t->resid));
00413 t->resid=NULL;
00414
00415 while (r) {
00416 g=r->goal;
00417 if (g->pending) {
00418
00419 push_ptr_value(int_ptr,&(g->pending));
00420 g->pending=FALSE;
00421
00422 push_ptr_value(goal_ptr,&(g->next));
00423
00424 g->next=goal_stack;
00425 goal_stack=g;
00426
00427 Traceline("releasing %P\n",g->a);
00428 }
00429 r=r->next;
00430 }
00431 }
00432 }
00433
00434 void release_resid(t)
00435 ptr_psi_term t;
00436 {
00437 release_resid_main(t,TRUE);
00438 }
00439
00440 void release_resid_notrail(t)
00441 ptr_psi_term t;
00442 {
00443 release_resid_main(t,FALSE);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void append_resid(u,v)
00455 ptr_psi_term u,v;
00456 {
00457 ptr_residuation *g;
00458
00459 g= &(u->resid);
00460 while (*g)
00461 g = &((*g)->next);
00462
00463 push_ptr_value(resid_ptr,g);
00464 *g=v->resid;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 long eval_aim()
00477 {
00478 long success=TRUE;
00479 ptr_psi_term funct,result,head,body;
00480 ptr_pair_list rule;
00481 ptr_resid_block rb;
00482 ptr_choice_point cutpt;
00483 ptr_psi_term match_date;
00484
00485 funct=(ptr_psi_term )aim->a;
00486 deref_ptr(funct);
00487
00488
00489 push2_ptr_value(int_ptr,&(funct->status),(funct->status & SMASK));
00490 funct->status=4;
00491
00492
00493
00494 result=(ptr_psi_term )aim->b;
00495 rule=(ptr_pair_list )aim->c;
00496
00497 match_date=(ptr_psi_term )stack_pointer;
00498 cutpt=choice_stack;
00499
00500
00501 curried=FALSE;
00502 can_curry=TRUE;
00503
00504 resid_vars=NULL;
00505
00506
00507 if (rule) {
00508 Traceline("evaluate %P\n",funct);
00509 if ((unsigned long)rule<=MAX_BUILT_INS) {
00510
00511 resid_aim=aim;
00512 success=c_rule[(unsigned long)rule]();
00513
00514 if (curried)
00515 do_currying();
00516 else
00517 if (resid_vars)
00518 success=do_residuation();
00519 else {
00520
00521 }
00522 }
00523 else {
00524 while (rule && (rule->a==NULL || rule->b==NULL)) {
00525 rule=rule->next;
00526 Traceline("alternative rule has been retracted\n");
00527 }
00528 if (rule) {
00529
00530
00531 resid_aim=aim;
00532 rb = STACK_ALLOC(resid_block);
00533 save_resid(rb,match_date);
00534
00535
00536 clear_copy();
00537
00538
00539
00540
00541
00542
00543 head=quote_copy(rule->a,STACK);
00544 body=eval_copy(rule->b,STACK);
00545 head->status=4;
00546
00547 if (rule->next)
00548 push_choice_point(eval,funct,result,rule->next);
00549
00550 push_goal(unify,body,result,NULL);
00551 push_goal(eval_cut,body,cutpt,rb);
00552 push_goal(match,funct,head,rb);
00553
00554 }
00555 else {
00556 success=FALSE;
00557
00558 }
00559 }
00560 }
00561 else {
00562 success=FALSE;
00563
00564 }
00565 resid_aim=NULL;
00566
00567 return success;
00568 }
00569
00570
00571
00572
00573 match_attr1(u,v,rb)
00574 ptr_node *u,v;
00575 ptr_resid_block rb;
00576 {
00577 long cmp;
00578 ptr_node temp;
00579
00580 if (v) {
00581 if (*u==NULL)
00582 attr_missing=TRUE;
00583 else {
00584 cmp=featcmp((*u)->key,v->key);
00585 if(cmp==0) {
00586 ptr_psi_term t;
00587 match_attr1(&((*u)->right),v->right,rb);
00588 t = (ptr_psi_term) (*u)->data;
00589 push_goal(match,(*u)->data,v->data,rb);
00590
00591 match_attr1(&((*u)->left),v->left,rb);
00592 }
00593 else if (cmp>0) {
00594 temp=v->right;
00595 v->right=NULL;
00596 match_attr1(u,temp,rb);
00597 match_attr1(&((*u)->left),v,rb);
00598 v->right=temp;
00599 }
00600 else {
00601 temp=v->left;
00602 v->left=NULL;
00603 match_attr1(&((*u)->right),v,rb);
00604 match_attr1(u,temp,rb);
00605 v->left=temp;
00606 }
00607 }
00608 }
00609 }
00610
00611
00612
00613 match_attr2(u,v,rb)
00614 ptr_node *u,v;
00615 ptr_resid_block rb;
00616 {
00617 long cmp;
00618 ptr_node temp;
00619
00620 if (v) {
00621 if (*u==NULL) {
00622 ptr_psi_term t;
00623 match_attr1(u,v->right,rb);
00624 t = (ptr_psi_term) v->data;
00625 deref2_rec_eval(t);
00626 match_attr1(u,v->left,rb);
00627 }
00628 else {
00629 cmp=featcmp((*u)->key,v->key);
00630 if(cmp==0) {
00631 match_attr2(&((*u)->right),v->right,rb);
00632 match_attr2(&((*u)->left),v->left,rb);
00633 }
00634 else if (cmp>0) {
00635 temp=v->right;
00636 v->right=NULL;
00637 match_attr2(u,temp,rb);
00638 match_attr2(&((*u)->left),v,rb);
00639 v->right=temp;
00640 }
00641 else {
00642 temp=v->left;
00643 v->left=NULL;
00644 match_attr2(&((*u)->right),v,rb);
00645 match_attr2(u,temp,rb);
00646 v->left=temp;
00647 }
00648 }
00649 }
00650 else if (*u!=NULL) {
00651 ptr_psi_term t ;
00652 match_attr1(&((*u)->right),v,rb);
00653 t = (ptr_psi_term) (*u)->data;
00654
00655
00656
00657 deref2_rec_eval(t);
00658 match_attr1(&((*u)->left),v,rb);
00659 }
00660 }
00661
00662
00663
00664 match_attr3(u,v,rb)
00665 ptr_node *u,v;
00666 ptr_resid_block rb;
00667 {
00668 long cmp;
00669 ptr_node temp;
00670
00671 if (v) {
00672 if (*u==NULL)
00673 attr_missing=TRUE;
00674 else {
00675 cmp=featcmp((*u)->key,v->key);
00676 if(cmp==0) {
00677 ptr_psi_term t1,t2;
00678 match_attr3(&((*u)->right),v->right,rb);
00679 t1 = (ptr_psi_term) (*u)->data;
00680 t2 = (ptr_psi_term) v->data;
00681
00682 deref2_eval(t1);
00683 deref2_eval(t2);
00684 match_attr3(&((*u)->left),v->left,rb);
00685 }
00686 else if (cmp>0) {
00687 temp=v->right;
00688 v->right=NULL;
00689 match_attr3(u,temp,rb);
00690 match_attr3(&((*u)->left),v,rb);
00691 v->right=temp;
00692 }
00693 else {
00694 temp=v->left;
00695 v->left=NULL;
00696 match_attr3(&((*u)->right),v,rb);
00697 match_attr3(u,temp,rb);
00698 v->left=temp;
00699 }
00700 }
00701 }
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 void match_attr(u,v,rb)
00714 ptr_node *u,v;
00715 ptr_resid_block rb;
00716 {
00717 match_attr1(u,v,rb);
00718 match_attr2(u,v,rb);
00719 match_attr3(u,v,rb);
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 long match_aim()
00734 {
00735 long success=TRUE;
00736 ptr_psi_term u,v,tmp;
00737 REAL r;
00738 long less,lesseq;
00739 ptr_resid_block rb;
00740 ptr_psi_term match_date;
00741
00742 u=(ptr_psi_term )aim->a;
00743 v=(ptr_psi_term )aim->b;
00744 deref_ptr(u);
00745 deref_ptr(v);
00746 rb=(ptr_resid_block)aim->c;
00747 restore_resid(rb,&match_date);
00748
00749 if (u!=v) {
00750 if (success=matches(u->type,v->type,&lesseq)) {
00751 if (lesseq) {
00752 if (u->type!=cut || v->type!=cut) {
00753 if (v->value) {
00754 if (u->value) {
00755 if (overlap_type(v->type,real))
00756 success=(*((REAL *)u->value)==(*((REAL *)v->value)));
00757 else if (overlap_type(v->type,quoted_string))
00758 success=(strcmp((char *)u->value,(char *)v->value)==0);
00759
00760 else if (overlap_type(v->type,sys_bytedata)) {
00761 unsigned long ulen = *((unsigned long *) u->value);
00762 unsigned long vlen = *((unsigned long *) v->value);
00763 success=(ulen==vlen && bcmp((char *)u->value,(char *)v->value,ulen)==0);
00764 }
00765 }
00766 else
00767 residuate_double(u,v);
00768 }
00769 }
00770 }
00771 else if (u->value) {
00772
00773 success=TRUE;
00774
00775 if (v->value) {
00776 if (overlap_type(v->type,real))
00777 success=(*((REAL *)u->value)==(*((REAL *)v->value)));
00778 }
00779 else if (overlap_type(u->type,integer)) {
00780 r= *((REAL *)u->value);
00781 success=(r==floor(r));
00782 }
00783
00784 if (success) residuate_double(u,v);
00785 }
00786 else
00787 residuate_double(u,v);
00788
00789 if (success) {
00790 if (FUNC_ARG(u) && FUNC_ARG(v)) {
00791
00792 residuate_double(u,v);
00793 residuate_double(v,u);
00794 }
00795 else if (FUNC_ARG(v)) {
00796 residuate_double(v,u);
00797 }
00798 else {
00799 v->coref=u;
00800 }
00801 attr_missing=FALSE;
00802 match_attr(&(u->attr_list),v->attr_list,rb);
00803 if (attr_missing) {
00804 if (can_curry)
00805 curried=TRUE;
00806 else
00807 residuate_double(u,v);
00808 }
00809
00810 }
00811 }
00812 }
00813
00814 can_curry=FALSE;
00815 save_resid(rb,match_date);
00816
00817 resid_aim = NULL;
00818
00819 return success;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 long check_out();
00834 long eval_args();
00835
00836
00837
00838
00839
00840
00841
00842 long i_eval_args(n)
00843 ptr_node n;
00844 {
00845 check_func_flag=FALSE;
00846 return eval_args(n);
00847 }
00848
00849
00850
00851 long eval_args(n)
00852 ptr_node n;
00853 {
00854 long flag=TRUE;
00855
00856 if (n) {
00857 flag = eval_args(n->right);
00858 flag = check_out(n->data) && flag;
00859 flag = eval_args(n->left) && flag;
00860 }
00861
00862 return flag;
00863 }
00864
00865
00866
00867
00868
00869
00870 void check_disj(t)
00871 ptr_psi_term t;
00872 {
00873 Traceline("push disjunction goal %P\n",t);
00874 if (t->value)
00875 push_goal(disj,t,t,(GENERIC)TRUE);
00876 else
00877 push_goal(fail,NULL,NULL,NULL);
00878 }
00879
00880
00881
00882
00883
00884
00885
00886 void check_func(t)
00887 ptr_psi_term t;
00888 {
00889 ptr_psi_term result,t1,copy;
00890
00891
00892
00893
00894
00895
00896
00897 {
00898
00899 Traceline("setting up function call %P\n",t);
00900
00901 result = stack_psi_term(0);
00902
00903
00904 copy=stack_copy_psi_term(*t);
00905 copy->status &= ~RMASK;
00906
00907
00908
00909 push_psi_ptr_value(t,&(t->coref));
00910 t->coref=result;
00911
00912
00913 push_goal(eval,copy,result,t->type->rule);
00914
00915
00916
00917 check_func_flag=TRUE;
00918 if (t->type==iff) {
00919 get_one_arg(t->attr_list,&t1);
00920 if (t1) {
00921
00922 check_out(t1);
00923 }
00924 }
00925 else if(t->type==disjunction) {
00926 }
00927 else if (t->type!=such_that) {
00928 if (t->type->evaluate_args)
00929 eval_args(t->attr_list);
00930
00931 }
00932 }
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 long check_type(t)
00948 ptr_psi_term t;
00949 {
00950 long flag=FALSE;
00951
00952 push2_ptr_value(int_ptr,&(t->status),(t->status & SMASK));
00953
00954
00955 if (t->type->properties) {
00956 if (t->attr_list || t->type->always_check) {
00957
00958 fetch_def(t, TRUE);
00959
00960
00961 eval_args(t->attr_list);
00962 flag=FALSE;
00963 }
00964 else {
00965
00966 t->status= (2 & SMASK) | (t->status & RMASK);
00967 flag=TRUE;
00968 }
00969 }
00970 else {
00971
00972
00973
00974
00975
00976
00977 flag=eval_args(t->attr_list);
00978 }
00979
00980 return flag;
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 long i_check_out(t)
01011 ptr_psi_term t;
01012 {
01013 check_func_flag=FALSE;
01014 return check_out(t);
01015 }
01016
01017 long f_check_out(t)
01018 ptr_psi_term t;
01019 {
01020 check_func_flag=TRUE;
01021 return check_out(t);
01022 }
01023
01024 long check_out(t)
01025 ptr_psi_term t;
01026 {
01027 long flag=FALSE;
01028
01029 deref_ptr(t);
01030
01031
01032
01033
01034 if (t->status || (GENERIC)t>=heap_pointer)
01035 flag=TRUE;
01036 else {
01037 t->status |= RMASK;
01038
01039 switch(t->type->type) {
01040
01041 case function:
01042 if (check_func_flag) {
01043 check_func(t);
01044 flag=TRUE;
01045 }
01046 else {
01047
01048 flag=TRUE;
01049 }
01050 break;
01051
01052 case type:
01053 flag=check_type(t);
01054 break;
01055
01056 case global:
01057 eval_global_var(t);
01058 check_out(t);
01059 flag=FALSE;
01060 break;
01061
01062 default:
01063 flag=eval_args(t->attr_list);
01064 }
01065 t->status &= ~RMASK;
01066 }
01067 return flag;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108 static long deref_flag;
01109 void deref_rec_body();
01110 void deref_rec_args();
01111 void deref_rec_args_exc();
01112
01113
01114 long deref_eval(t)
01115 ptr_psi_term t;
01116 {
01117 ptr_goal save=goal_stack;
01118
01119 deref_flag=FALSE;
01120 goal_stack=aim;
01121
01122 if (t->status==0) {
01123 if(t->type->type==function) {
01124 check_func(t);
01125 deref_flag=TRUE;
01126 }
01127 else
01128 if(t->type->type==global) {
01129 eval_global_var(t);
01130 deref_ptr(t);
01131 deref_flag=deref_eval(t);
01132 }
01133 else {
01134 if (t->status!=2) {
01135 if((GENERIC)t<heap_pointer)
01136 push_ptr_value(int_ptr,&(t->status));
01137 t->status=4;
01138 deref_flag=FALSE;
01139 }
01140 }
01141 }
01142 else
01143 deref_flag=FALSE;
01144
01145 if (!deref_flag) goal_stack=save;
01146 return (deref_flag);
01147 }
01148
01149
01150 long deref_rec_eval(t)
01151 ptr_psi_term t;
01152 {
01153 ptr_goal save=goal_stack;
01154
01155 deref_flag=FALSE;
01156 goal_stack=aim;
01157 deref_rec_body(t);
01158 if (!deref_flag) goal_stack=save;
01159 return (deref_flag);
01160 }
01161
01162 void deref_rec_body(t)
01163 ptr_psi_term t;
01164 {
01165 if (t->status==0) {
01166 if (t->type->type==function) {
01167 check_func(t);
01168 deref_flag=TRUE;
01169 }
01170 else
01171 if(t->type->type==global) {
01172 eval_global_var(t);
01173 deref_ptr(t);
01174 deref_rec_body(t);
01175 }
01176 else {
01177
01178 if((GENERIC)t<heap_pointer)
01179 push_ptr_value(int_ptr,&(t->status));
01180 t->status=4;
01181 deref_rec_args(t->attr_list);
01182 }
01183 }
01184 }
01185
01186 void deref_rec_args(n)
01187 ptr_node n;
01188 {
01189 ptr_psi_term t1;
01190
01191 if (n) {
01192 deref_rec_args(n->right);
01193 t1 = (ptr_psi_term) (n->data);
01194 deref_ptr(t1);
01195 deref_rec_body(t1);
01196 deref_rec_args(n->left);
01197 }
01198 }
01199
01200
01201
01202 long deref_args_eval(t,set)
01203 ptr_psi_term t;
01204 long set;
01205 {
01206 ptr_goal save = goal_stack;
01207 ptr_goal top = aim;
01208
01209 deref_flag = FALSE;
01210 goal_stack = top;
01211 deref_rec_args_exc(t->attr_list,set);
01212 if (!deref_flag) goal_stack = save;
01213 return (deref_flag);
01214 }
01215
01216
01217
01218
01219 long in_set(str,set)
01220 char *str;
01221 long set;
01222 {
01223 if (set&1 && !featcmp(str,"1")) return TRUE;
01224 if (set&2 && !featcmp(str,"2")) return TRUE;
01225 if (set&4 && !featcmp(str,"3")) return TRUE;
01226 if (set&8 && !featcmp(str,"4")) return TRUE;
01227 return FALSE;
01228 }
01229
01230 void deref_rec_args_exc(n,set)
01231 ptr_node n;
01232 long set;
01233 {
01234 ptr_psi_term t;
01235
01236 if (n) {
01237 deref_rec_args_exc(n->right,set);
01238 if (!in_set(n->key,set)) {
01239 t = (ptr_psi_term) (n->data);
01240 deref_ptr(t);
01241 deref_rec_body(t);
01242 }
01243 deref_rec_args_exc(n->left,set);
01244 }
01245 }
01246
01247
01248
01249
01250
01251 void deref2_eval(t)
01252 ptr_psi_term t;
01253 {
01254 deref_ptr(t);
01255 if (t->status==0) {
01256 if (t->type->type==function) {
01257 check_func(t);
01258 }
01259 else
01260 if(t->type->type==global) {
01261 eval_global_var(t);
01262 deref_ptr(t);
01263 deref2_eval(t);
01264 }
01265 else {
01266 t->status=4;
01267 }
01268 }
01269 }
01270
01271
01272 void deref2_rec_eval(t)
01273 ptr_psi_term t;
01274 {
01275 deref_ptr(t);
01276 deref_rec_body(t);
01277 }
01278
01279
01280
01281
01282
01283 void save_resid(rb,match_date)
01284 ptr_resid_block rb;
01285 ptr_psi_term match_date;
01286 {
01287 if (rb) {
01288 rb->cc_cr = (can_curry<<1) + curried;
01289 rb->ra = resid_aim;
01290 rb->rv = resid_vars;
01291
01292
01293 rb->md = match_date;
01294 }
01295 }
01296
01297 void restore_resid(rb,match_date)
01298 ptr_resid_block rb;
01299 ptr_psi_term *match_date;
01300 {
01301 if (rb) {
01302 can_curry = (rb->cc_cr&2)?TRUE:FALSE;
01303 curried = (rb->cc_cr&1)?TRUE:FALSE;
01304 resid_aim = rb->ra;
01305 resid_vars = rb->rv;
01306
01307
01308 *match_date = rb->md;
01309 }
01310 }
01311
01312
01313
01314
01315
01316
01317
01318 void eval_global_var(t)
01319
01320 ptr_psi_term t;
01321 {
01322 deref_ptr(t);
01323
01324
01325
01326 Traceline("dereferencing variable %P\n",t);
01327
01328
01329 if(!t->type->global_value) {
01330
01331
01332 {
01333 ptr_stack n;
01334 n=STACK_ALLOC(stack);
01335 n->type=psi_term_ptr;
01336 n->a= (GENERIC) &(t->type->global_value);
01337 n->b= NULL;
01338 n->next=undo_stack;
01339 undo_stack=n;
01340 }
01341
01342
01343 clear_copy();
01344 t->type->global_value=eval_copy(t->type->init_value,STACK);
01345
01346 }
01347
01348
01349
01350 if(t->type->type==global && t!=t->type->global_value) {
01351
01352 push_psi_ptr_value(t,&(t->coref));
01353 t->coref=t->type->global_value;
01354 }
01355 }
01356
01357
01358
01359
01360
01361
01362
01363
01364 void init_global_vars()
01365
01366 {
01367 ptr_definition def;
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 for(def=first_definition;def;def=def->next)
01381 if((GENERIC)(def->global_value)<(GENERIC)heap_pointer)
01382 def->global_value=NULL;
01383 }
01384
01385