Wild Life  2.30
 All Data Structures Files Functions Variables Typedefs Macros
lefun.c
Go to the documentation of this file.
1 
6 /* Copyright 1991 Digital Equipment Corporation.
7 ** All Rights Reserved.
8 *****************************************************************/
9 
10 #include "defs.h"
11 
12 static long attr_missing;
13 static long check_func_flag;
14 
22 {
23  ptr_psi_term result;
24 
25  result=STACK_ALLOC(psi_term);
26  result->type=top;
27  result->status=stat;
28  result->flags=stat?QUOTED_TRUE:FALSE; /* 14.9 */
29  result->attr_list=NULL;
30  result->coref=NULL;
31 #ifdef TS
32  result->time_stamp=global_time_stamp; /* 9.6 */
33 #endif
34  result->resid=NULL;
35  result->value_3=NULL;
36 
37  return result;
38 }
39 
49 {
50  ptr_psi_term result;
51 
52  result=STACK_ALLOC(psi_term);
53  result->type = (thereal==floor(thereal)) ? integer : real;
54  result->status=stat;
55  result->flags=stat?QUOTED_TRUE:FALSE; /* 14.9 */
56  result->attr_list=NULL;
57  result->coref=NULL;
58 #ifdef TS
59  result->time_stamp=global_time_stamp; /* 9.6 */
60 #endif
61  result->resid=NULL;
62  result->value_3=heap_alloc(sizeof(REAL));
63  (* (REAL *)(result->value_3)) = thereal;
64 
65  return result;
66 }
67 
76 {
77  ptr_psi_term result;
78 
79  result=HEAP_ALLOC(psi_term);
80  result->type=top;
81  result->status=stat;
82  result->flags=stat?QUOTED_TRUE:FALSE; /* 14.9 */
83  result->attr_list=NULL;
84  result->coref=NULL;
85 #ifdef TS
86  result->time_stamp=global_time_stamp; /* 9.6 */
87 #endif
88  result->resid=NULL;
89  result->value_3=NULL;
90 
91  return result;
92 }
93 
94 /* Create an empty list on the stack, wiped out by RM: Dec 14 1992 */
95 /* ptr_psi_term stack_empty_list() is now aliased to stack_nil() */
96 
108 {
109  ptr_resid_list curr;
110 
111  curr=STACK_ALLOC(resid_list);
112  curr->var=t;
113  curr->othervar=u;
114  curr->next=resid_vars;
115  resid_vars=curr;
116 }
117 
126 {
127  ptr_resid_list curr;
128 
129  curr=STACK_ALLOC(resid_list);
130  curr->var=t;
131  curr->othervar=NULL; /* 21.9 */
132  curr->next=resid_vars;
133  resid_vars=curr;
134 }
135 
145 {
146  residuate(u);
147  if (v && u!=v) residuate(v);
148 }
149 
160 {
161  residuate(u);
162  if (v && u!=v) residuate(v);
163  if (w && u!=w && v!=w) residuate(w);
164 }
165 
174 void curry()
175 {
176  if (can_curry)
177  curried=TRUE;
178 }
179 
193 {
194  long result;
195  long resflag,resflag2;
196  GENERIC rescode,rescode2;
197  GENERIC resvalue;
198  GENERIC resvalue2;
199  /* Set to FALSE if the goal is already residuated on the var: */
200  long not_found = TRUE;
201  /* Points to a pointer to a residuation structure. Used so we can */
202  /* add the goal to the end of the residuation list, so that it can */
203  /* can be undone later if backtracking happens. See the call to */
204  /* push_ptr_value. */
205  ptr_residuation *r;
206 
207  /* 5.8 PVR */
208  if ((GENERIC)var>=heap_pointer) {
209  Errorline("attempt to residuate on psi-term %P in the heap.\n",var);
210 
211  return FALSE;
212  }
213 
214  r= &(var->resid);
215 
216  while (not_found && *r) {
217  if ((*r)->goal == g) { /* This goal is already attached */
218  /* Keep track of best sort so far */
219  /* Glb_code(..) tries to keep 'sortflag' TRUE if possible. */
220  result=glb_code((*r)->sortflag,(*r)->bestsort,
221  TRUE,(GENERIC)var->type,
222  &resflag,&rescode);
223  result=glb_value(result,resflag,rescode,(GENERIC)(*r)->value_2,var->value_3,
224  &resvalue); /* 6.10 */
225  if (!result)
226  return FALSE; /* 21.9 */
227  else if (othervar) {
228  result=glb_code(resflag,rescode,TRUE,(GENERIC)othervar->type,
229  &resflag2,&rescode2);
230  result=glb_value(result,resflag2,rescode2,resvalue,othervar->value_3,
231  &resvalue2); /* 6.10 */
232  if (!result) {
233  return FALSE;
234  }
235  else {
236  /* The value field only has to be trailed once, since its value */
237  /* does not change, once given. */
238  if ((*r)->value_2==NULL && resvalue2!=NULL) { /* 6.10 */
239  push_ptr_value(int_ptr,(GENERIC *)&((*r)->value_2));
240  }
241  if ((*r)->bestsort!=rescode2) {
242  push_ptr_value(((*r)->sortflag?def_ptr:code_ptr),
243  &((*r)->bestsort));
244  (*r)->bestsort=rescode2; /* 21.9 */
245  }
246  if ((*r)->sortflag!=resflag2) {
247  push_ptr_value(int_ptr,(GENERIC *)&((*r)->sortflag));
248  (*r)->sortflag=resflag2; /* 21.9 */
249  }
250  }
251  }
252  else {
253  if ((*r)->value_2==NULL && resvalue!=NULL) { /* 6.10 */
254  push_ptr_value(int_ptr,(GENERIC *)&((*r)->value_2));
255  }
256  if ((*r)->bestsort!=rescode) {
257  push_ptr_value(((*r)->sortflag?def_ptr:code_ptr),
258  &((*r)->bestsort));
259  (*r)->bestsort=rescode; /* 21.9 */
260  }
261  if ((*r)->sortflag!=resflag) {
262  push_ptr_value(int_ptr,(GENERIC *)&((*r)->sortflag));
263  (*r)->sortflag=resflag; /* 21.9 */
264  }
265  }
266  not_found = FALSE;
267  }
268  else
269  r= &((*r)->next); /* look at the next one */
270  }
271 
272  if (not_found) {
273  /* We must attach this goal & the variable's sort onto this variable */
274 
277  if (othervar) {
278  result=glb_code(TRUE,(GENERIC)var->type,TRUE,(GENERIC)othervar->type,&resflag,&rescode);
279  result=glb_value(result,resflag,rescode,var->value_3,othervar->value_3,
280  &resvalue); /* 6.10 */
281  if (!result) {
282  return FALSE;
283  }
284  else {
285  (*r)->sortflag=resflag;
286  (*r)->bestsort=rescode; /* 21.9 */
287  (*r)->value_2=resvalue; /* 6.10 */
288  }
289  }
290  else {
291  (*r)->sortflag=TRUE;
292  (*r)->bestsort=(GENERIC)var->type; /* 21.9 */
293  (*r)->value_2=var->value_3; /* 6.10 */
294  }
295  (*r)->goal=g;
296  (*r)->next=NULL;
297  }
298 
299  if (!(g->pending)) {
300  /* this goal is not pending, so make sure it will be put on the goal
301  * stack later
302  */
305  }
306 
307  return TRUE; /* 21.9 */
308 }
309 
322 /* LIFE-defined routines reset the goal stack to what it was */
323 /* before the function call. */
325 {
326  goal_stack=resid_aim->next; /* reset goal stack */
327  return do_residuation();
328 }
329 
337 {
338  long success;
339  ptr_psi_term t,u;
340  // ptr_goal *gs;
341 
342  /* This undoes perfectly valid work! */
343  /* The old version of Wild_Life did not trail anything
344  during matching, so I think this was a nop for it. */
345  /* PVR 11.5 undo(resid_limit); */
346  /* PVR 11.5 choice_stack=cut_point; */
347 
348  /* PVR 9.2.94 */
349  /* goal_stack=resid_aim->next; */
350 
351  if (trace) {
352  tracing();
354  }
355 
356  while (resid_vars) {
357 
358  t=resid_vars->var; /* 21.9 */
359  u=resid_vars->othervar; /* 21.9 */
360  /* PVR */ deref_ptr(t);
362  traceline("residuating on %P (other = %P)\n",t,u);
363 
364  success=residuateGoalOnVar(resid_aim, t, u); /* 21.9 */
365  if (!success) { /* 21.9 */
366  traceline("failure because of disentailment\n");
367  return FALSE;
368  }
369  }
370 
371  traceline("no failure because of disentailment\n");
372  return TRUE; /* 21.9 */
373 }
374 
384 {
385  ptr_psi_term funct,result;
386 
387  /* PVR 5.11 undo(resid_limit); */
388  /* PVR 5.11 choice_stack=cut_point; */
390  funct=(ptr_psi_term )resid_aim->aaaa_1;
391  result=(ptr_psi_term )resid_aim->bbbb_1;
392 
393  traceline("currying %P\n",funct);
394 
395  push_goal(unify_noeval,funct,result,NULL);
396  resid_aim=NULL;
397 }
398 
411 void release_resid_main(ptr_psi_term t,long trailflag)
412 {
413  ptr_goal g;
414  ptr_residuation r;
415 
416  if ((r=t->resid)) {
417  if (trailflag) push_ptr_value(resid_ptr,(GENERIC *)&(t->resid));
418  t->resid=NULL;
419 
420  while (r) {
421  g=r->goal;
422  if (g->pending) {
423 
425  g->pending=FALSE;
426 
428 
429  g->next=goal_stack;
430  goal_stack=g;
431 
432  traceline("releasing %P\n",g->aaaa_1);
433  }
434  r=r->next;
435  }
436  }
437 }
438 
446 {
448 }
449 
457 ptr_psi_term t;
458 {
460 }
461 
475 {
476  ptr_residuation *g;
477 
478  g= &(u->resid);
479  while (*g)
480  g = &((*g)->next);
481 
483  *g=v->resid;
484 }
485 
497 long eval_aim()
498 {
499  long success=TRUE;
500  ptr_psi_term funct,result,head,body;
501  ptr_pair_list rule;
502  /* RESID */ ptr_resid_block rb;
503  ptr_choice_point cutpt;
504  ptr_psi_term match_date; /* 13.6 */
505 
506  funct=(ptr_psi_term )aim->aaaa_1;
507  deref_ptr(funct);
508 
509  /* RM: Jun 18 1993 */
510  push2_ptr_value(int_ptr,(GENERIC *)&(funct->status),(GENERIC)(funct->status & SMASK));
511  funct->status=4;
512 
513  /* if (!funct->type->evaluate_args) mark_quote(funct); 25.8 */ /* 18.2 PVR */
514  result=(ptr_psi_term )aim->bbbb_1;
515  rule=(ptr_pair_list )aim->cccc_1;
516 
517  match_date=(ptr_psi_term )stack_pointer;
518  cutpt=choice_stack; /* 13.6 */
519 
520  /* For currying and residuation */
521  curried=FALSE;
522  can_curry=TRUE;
523  /* resid_aim=aim; */
525  /* resid_limit=(ptr_goal )stack_pointer; 12.6 */
526 
527  if (rule) {
528  traceline("evaluate %P\n",funct);
529  if ((unsigned long)rule<=MAX_BUILT_INS) {
530 
531  resid_aim=aim;
532  success=c_rule[(unsigned long)rule]();
533 
534  if (curried)
535  do_currying();
536  else
537  if (resid_vars)
538  success=do_residuation(); /* 21.9 */
539  else {
540  /* resid_aim=NULL; */
541  }
542  }
543  else {
544  while (rule && (rule->aaaa_2==NULL || rule->bbbb_2==NULL)) {
545  rule=rule->next;
546  traceline("alternative rule has been retracted\n");
547  }
548  if (rule) {
549  /* push_choice_point(eval,funct,result,rule->next); */ /* 17.6 */
550 
551  resid_aim=aim;
552  /* RESID */ rb = STACK_ALLOC(resid_block);
553  /* RESID */ save_resid(rb,match_date);
554  /* RESID */ /* resid_aim = NULL; */
555 
556  clear_copy();
557 
558  /* RM: Jun 18 1993: no functions in head */
559  /* if (TRUE)
560  head=eval_copy(rule->aaaa_1,STACK);
561  else */
562 
563  head=quote_copy(rule->aaaa_2,STACK);
564  body=eval_copy(rule->bbbb_2,STACK);
565  head->status=4;
566 
567  if (rule->next) /* 17.6 */
568  push_choice_point(eval,funct,result,(GENERIC)rule->next);
569 
570  push_goal(unify,body,result,NULL);
571  /* RESID */ push_goal(eval_cut,body,(ptr_psi_term)cutpt,(GENERIC)rb); /* 13.6 */
572  /* RESID */ push_goal(match,funct,head,(GENERIC)rb);
573  /* eval_args(head->attr_list); */
574  }
575  else {
576  success=FALSE;
577  /* resid_aim=NULL; */
578  }
579  }
580  }
581  else {
582  success=FALSE;
583  /* resid_aim=NULL; */
584  }
585  resid_aim=NULL;
586  /* match_date=NULL; */ /* 13.6 */
587  return success;
588 }
589 
599 /* RESID */ void match_attr1(ptr_node *u,ptr_node v,ptr_resid_block rb)
600 {
601  long cmp;
602  ptr_node temp;
603 
604  if (v) {
605  if (*u==NULL)
607  else {
608  cmp=featcmp((*u)->key,v->key);
609  if(cmp==0) {
610  ptr_psi_term t;
611  /* RESID */ match_attr1(&((*u)->right),v->right,rb);
612  t = (ptr_psi_term) (*u)->data;
613  /* RESID */ push_goal(match,(ptr_psi_term)(*u)->data,(ptr_psi_term)v->data,(GENERIC)rb);
614  /* deref2_eval(t); */
615  /* RESID */ match_attr1(&((*u)->left),v->left,rb);
616  }
617  else if (cmp>0) {
618  temp=v->right;
619  v->right=NULL;
620  /* RESID */ match_attr1(u,temp,rb);
621  /* RESID */ match_attr1(&((*u)->left),v,rb);
622  v->right=temp;
623  }
624  else {
625  temp=v->left;
626  v->left=NULL;
627  /* RESID */ match_attr1(&((*u)->right),v,rb);
628  /* RESID */ match_attr1(u,temp,rb);
629  v->left=temp;
630  }
631  }
632  }
633 }
634 
644 /* RESID */ void match_attr2(ptr_node *u,ptr_node v,ptr_resid_block rb)
645 {
646  long cmp;
647  ptr_node temp;
648 
649  if (v) {
650  if (*u==NULL) { /* PVR 12.03 */
651  ptr_psi_term t;
652  match_attr1(u,v->right,rb);
653  t = (ptr_psi_term) v->data;
654  deref2_rec_eval(t);
655  match_attr1(u,v->left,rb);
656  }
657  else {
658  cmp=featcmp((*u)->key,v->key);
659  if(cmp==0) {
660  /* RESID */ match_attr2(&((*u)->right),v->right,rb);
661  /* RESID */ match_attr2(&((*u)->left),v->left,rb);
662  }
663  else if (cmp>0) {
664  temp=v->right;
665  v->right=NULL;
666  /* RESID */ match_attr2(u,temp,rb);
667  /* RESID */ match_attr2(&((*u)->left),v,rb);
668  v->right=temp;
669  }
670  else {
671  temp=v->left;
672  v->left=NULL;
673  /* RESID */ match_attr2(&((*u)->right),v,rb);
674  /* RESID */ match_attr2(u,temp,rb);
675  v->left=temp;
676  }
677  }
678  }
679  else if (*u!=NULL) {
680  ptr_psi_term t /* , empty */ ;
681  match_attr1(&((*u)->right),v,rb);
682  t = (ptr_psi_term) (*u)->data;
683  /* Create a new psi-term to put the (useless) result: */
684  /* This is needed so that *all* arguments of a function call */
685  /* are evaluated, which avoids incorrect 'Yes' answers. */
686  deref2_rec_eval(t); /* Assumes goal_stack is already restored. */
687  match_attr1(&((*u)->left),v,rb);
688  }
689 }
690 
700 /* RESID */ void match_attr3(ptr_node *u,ptr_node v,ptr_resid_block rb)
701 {
702  long cmp;
703  ptr_node temp;
704 
705  if (v) {
706  if (*u==NULL)
708  else {
709  cmp=featcmp((*u)->key,v->key);
710  if(cmp==0) {
711  ptr_psi_term t1,t2;
712  /* RESID */ match_attr3(&((*u)->right),v->right,rb);
713  t1 = (ptr_psi_term) (*u)->data;
714  t2 = (ptr_psi_term) v->data;
715  /* RESID */ /* push_goal(match,(*u)->data,v->data,rb); */
716  deref2_eval(t1); /* Assumes goal_stack is already restored. */
717  deref2_eval(t2); /* PVR 12.03 */
718  /* RESID */ match_attr3(&((*u)->left),v->left,rb);
719  }
720  else if (cmp>0) {
721  temp=v->right;
722  v->right=NULL;
723  /* RESID */ match_attr3(u,temp,rb);
724  /* RESID */ match_attr3(&((*u)->left),v,rb);
725  v->right=temp;
726  }
727  else {
728  temp=v->left;
729  v->left=NULL;
730  /* RESID */ match_attr3(&((*u)->right),v,rb);
731  /* RESID */ match_attr3(u,temp,rb);
732  v->left=temp;
733  }
734  }
735  }
736 }
737 
753 {
754  match_attr1(u,v,rb); /* Match corresponding arguments (third) */
755  match_attr2(u,v,rb); /* Evaluate lone arguments (second) */
756  match_attr3(u,v,rb); /* Evaluate corresponding arguments (first) */
757 }
758 
770 long match_aim()
771 {
772  long success=TRUE;
773  ptr_psi_term u,v; // ,tmp;
774  REAL r;
775  long /* less, */ lesseq;
776  ptr_resid_block rb;
777  ptr_psi_term match_date;
778 
779  u=(ptr_psi_term )aim->aaaa_1;
780  v=(ptr_psi_term )aim->bbbb_1;
781  deref_ptr(u);
782  deref_ptr(v);
784  restore_resid(rb,&match_date);
785 
786  if (u!=v) {
787  if ((success=matches(u->type,v->type,&lesseq))) {
788  if (lesseq) {
789  if (u->type!=cut || v->type!=cut) { /* Ignore value field for cut! */
790  if (v->value_3) {
791  if (u->value_3) {
792  if (overlap_type(v->type,real))
793  success=(*((REAL *)u->value_3)==(*((REAL *)v->value_3)));
794  else if (overlap_type(v->type,quoted_string))
795  success=(strcmp((char *)u->value_3,(char *)v->value_3)==0);
796  /* DENYS: BYTEDATA */
797  else if (overlap_type(v->type,sys_bytedata)) {
798  unsigned long ulen = *((unsigned long *) u->value_3);
799  unsigned long vlen = *((unsigned long *) v->value_3);
800  success=(ulen==vlen && bcmp((char *)u->value_3,(char *)v->value_3,ulen)==0);
801  }
802  }
803  else
804  residuate_double(u,v);
805  }
806  }
807  }
808  else if (u->value_3) {
809  /* Here we have U <| V but U and V have values which cannot match. */
810  success=TRUE;
811 
812  if (v->value_3) {
813  if (overlap_type(v->type,real))
814  success=(*((REAL *)u->value_3)==(*((REAL *)v->value_3)));
815  }
816  else if (overlap_type(u->type,integer)) {
817  r= *((REAL *)u->value_3);
818  success=(r==floor(r));
819  }
820 
821  if (success) residuate_double(u,v);
822  }
823  else
824  residuate_double(u,v);
825 
826  if (success) {
827  if (FUNC_ARG(u) && FUNC_ARG(v)) { /* RM: Feb 10 1993 */
828  /* residuate2(u,v); 21.9 */
829  residuate_double(u,v); /* 21.9 */
830  residuate_double(v,u); /* 21.9 */
831  }
832  else if (FUNC_ARG(v)) { /* RM: Feb 10 1993 */
833  residuate_double(v,u); /* 21.9 */
834  }
835  else {
836  v->coref=u;
837  } /* 21.9 */
839  match_attr(&(u->attr_list),v->attr_list,rb);
840  if (attr_missing) {
841  if (can_curry)
842  curried=TRUE;
843  else
844  residuate_double(u,v);
845  }
846  /* } 21.9 */
847  }
848  }
849  }
850 
852  save_resid(rb,match_date); /* updated resid_block */
853  /* This should be a useless statement: */
854  resid_aim = NULL;
855 
856  return success;
857 }
858 
859 /******************************************************************************
860  The following routines prepare terms for unification, proof or matching.
861  They deal with conjunctions, disjunctions, functions and arguments which
862  have to be examined before the general proof can continue.
863 */
864 
875 {
877  return eval_args(n);
878 }
879 
890 {
891  long flag=TRUE;
892 
893  if (n) {
894  flag = eval_args(n->right);
895  flag = check_out((ptr_psi_term)n->data) && flag;
896  flag = eval_args(n->left) && flag;
897  }
898 
899  return flag;
900 }
901 
911 {
912  traceline("push disjunction goal %P\n",t);
913  if (t->value_3)
914  push_goal(disj,t,t,(GENERIC)TRUE); /* 18.2 PVR */
915  else
917 }
918 
929 {
930  ptr_psi_term result,t1,copy;
931 
932  /* Check for embedded definitions
933  RM: Dec 16 1992 Re-instated this check then disabled it again
934  if (resid_aim) {
935  Errorline("embedded functions appeared in %P.\n",resid_aim->aaaa_1);
936  fail_all();
937  }
938  else */ {
939 
940  traceline("setting up function call %P\n",t);
941  /* Create a psi-term to put the result */
942  result = stack_psi_term(0);
943 
944  /* Make a partial copy of the calling term */
945  copy=stack_copy_psi_term(*t);
946  copy->status &= ~RMASK;
947 
948  /* Bind the calling term to the result */
949  /* push_ptr_value(psi_term_ptr,(GENERIC *)&(t->coref)); */
950  push_psi_ptr_value(t,(GENERIC *)&(t->coref));
951  t->coref=result;
952 
953  /* Evaluate the copy of the calling term */
954  push_goal(eval,copy,result,(GENERIC)t->type->rule);
955 
956  /* Avoid evaluation for built-in functions with unevaluated arguments */
957  /* (cond and such_that) */
959  if (t->type==iff) {
960  get_one_arg(t->attr_list,&t1);
961  if (t1) {
962  /* mark_eval(t1); 24.8 */
963  (void)check_out(t1);
964  }
965  }
966  else if(t->type==disjunction) {
967  }
968  else if (t->type!=such_that) {
969  if (t->type->evaluate_args)
970  (void)eval_args(t->attr_list);
971  /* else mark_quote_tree(t->attr_list); 24.8 25.8 */
972  }
973  }
974 }
975 
991 {
992  long flag=FALSE;
993 
995  /* push_ptr_value(int_ptr,(GENERIC *)&(t->status)); */
996 
997  if (t->type->properties) {
998  if (t->attr_list || t->type->always_check) {
999  /* Check all constraints here: */
1000  fetch_def(t, TRUE); /* PVR 18.2.94 */
1001  /* t->status=(2 & SMASK) | (t->status & RMASK); PVR 18.2.94 */
1002 
1003  (void)eval_args(t->attr_list);
1004  flag=FALSE;
1005  }
1006  else {
1007  /* definition pending on more information */
1008  t->status= (2 & SMASK) | (t->status & RMASK);
1009  flag=TRUE;
1010  }
1011  }
1012  else {
1013 
1014  /* RM: Dec 15 1992 I don't know what this is for
1015  if (!ovverlap_type(t->type,alist))
1016  t->status= (4 & SMASK) | (t->status & RMASK);
1017  */
1018 
1019  flag=eval_args(t->attr_list);
1020  }
1021 
1022  return flag;
1023 }
1024 
1034 {
1036  return check_out(t);
1037 }
1038 
1047 ptr_psi_term t;
1048 {
1050  return check_out(t);
1051 }
1052 /* \fn long check_out(ptr_psi_term t)
1053  \brief long check_out
1054  \param t - ptr_psi_term t
1055 
1056 
1057 ******* CHECK_OUT(t)
1058  This routine checks out psi_term T.
1059  It deals with the following cases:
1060  - T is a conjunction,
1061  - T is a type which has properties to check.
1062  - The same for T's arguments.
1063  If any of the above holds then proof has to be suspended until the
1064  case has been dealt with. This is done by pushing goals on the goal_stack
1065  to handle the case. If all is dealt with then CHECK_OUT returns TRUE.
1066  I.e., CHECK_OUT returns TRUE iff it has not pushed any goals on the stack.
1067 
1068  Evaluation is *not* done here, but as a part of dereferencing when a value
1069  is needed.
1070 
1071  Of all the routines related to check_out, only i_check_out, check_func,
1072  i_eval_args, and the dereference routines are called from outside of this
1073  file (lefun.c).
1074  - i_check_out(t) checks out everything except functions. When a function
1075  is encountered, check_out returns immediately without looking inside it.
1076  - f_check_out(t) checks out functions too.
1077  - i_eval_args(n) checks out all arguments, except functions.
1078  - check_func(t) checks out a function & all its arguments (including all
1079  nested functions. This is done as part of dereferencing, which is part
1080  of unification, matching, built-ins, and user-defined routines.
1081 */
1082 
1084 {
1085  long flag=FALSE;
1086  deref_ptr(t);
1087 
1088  /* traceline("PVR: entering check_out with status %d and term %P\n",
1089  t->status,t); for brunobug.lf PVR 14.2.94 */
1090  traceline("PVR: entering check_out with status %d and term %P\n",
1091  t->status,t); /* for brunobug.lf PVR 14.2.94 */
1092 
1093  if (t->status || (GENERIC)t>=heap_pointer) /* RM: Feb 8 1993 */
1094  flag=TRUE;
1095  else {
1096  t->status |= RMASK;
1097 
1098  switch((long)t->type->type_def) { /* RM: Feb 8 1993 */
1099 
1100  case (long)function_it:
1101  if (check_func_flag) {
1102  check_func(t);
1103  flag=TRUE;
1104  }
1105  else {
1106  /* Function evaluation handled during matching and unification */
1107  flag=TRUE;
1108  }
1109  break;
1110 
1111  case (long)type_it:
1112  flag=check_type(t);
1113  break;
1114 
1115  case (long)global_it: /* RM: Feb 8 1993 */
1116  eval_global_var(t);
1117  (void)check_out(t);
1118  flag=FALSE;
1119  break;
1120 
1121  default:
1122  flag=eval_args(t->attr_list);
1123  }
1124  t->status &= ~RMASK;
1125  }
1126 
1127  return flag;
1128 }
1129 
1130 /********************************************************************/
1131 /* */
1132 /* New dereference routines for Wild_Life */
1133 /* These routines handle evaluation-by-need. Check_out is changed */
1134 /* to no longer call check_func, which is done in the new routines. */
1135 /* Functions inside of psi-terms are only evaluated if needed. It */
1136 /* is assumed that 'needed' is true when they are derefed. */
1137 /* */
1138 /* There are three new dereference routines: */
1139 /* deref_eval(P) */
1140 /* If the psi-term P is a function, call check_func to */
1141 /* push eval goals so that the function will be evaluated. */
1142 /* Then return TRUE so that the caller can itself return. */
1143 /* This only looks at the top level. */
1144 /* deref_rec(P) */
1145 /* If the psi-term P recursively contains any functions, then */
1146 /* push eval goals to evaluate all of them. Set a global */
1147 /* variable deref_flag if this is the case. */
1148 /* deref_args(P,S) */
1149 /* Same as above, except does not look at the top level or at */
1150 /* the arguments named in the set S. */
1151 /* This is needed to guarantee evaluation of all arguments of */
1152 /* a built-in, even those not used by the built-in. */
1153 /* */
1154 /* The original dereference macro is renamed to: */
1155 /* deref_ptr(P) = while (P->coref) P=P->coref */
1156 /* There are three new macros: */
1157 /* deref(P) = deref_ptr(P); */
1158 /* if (deref_eval(P)) then return TRUE */
1159 /* deref_rec(P) = deref_ptr(P); */
1160 /* if (deref_rec_eval(P)) then return TRUE */
1161 /* deref_args(P,S) = deref_ptr(P); */
1162 /* if (deref_args_eval(P,S)) then return TRUE */
1163 /* */
1164 /********************************************************************/
1165 
1166 static long deref_flag;
1167 
1179 /* Ensure evaluation of top of psi-term */
1181 {
1182  ptr_goal save=goal_stack;
1183 
1184  deref_flag=FALSE;
1185  goal_stack=aim;
1186 
1187  if (t->status==0) {
1188  if(t->type->type_def==(def_type)function_it) {
1189  check_func(t); /* Push eval goals to evaluate the function. */
1190  deref_flag=TRUE; /* TRUE so that caller will return to main_prove. */
1191  }
1192  else
1193  if(t->type->type_def==(def_type)global_it) { /* RM: Feb 10 1993 */
1194  eval_global_var(t);
1195  deref_ptr(t);/* RM: Jun 25 1993 */
1197  }
1198  else {
1199  if (((long)t->status)!=2) {
1200  if((GENERIC)t<heap_pointer)
1201  push_ptr_value(int_ptr,(GENERIC *)&(t->status)); /* RM: Jul 15 1993 */
1202  t->status=4;
1203  deref_flag=FALSE;
1204  }
1205  }
1206  }
1207  else
1208  deref_flag=FALSE;
1209 
1210  if (!deref_flag) goal_stack=save;
1211  return (deref_flag);
1212 }
1213 
1224 /* Ensure evaluation of *all* of psi-term */
1225 
1227 {
1228  ptr_goal save=goal_stack;
1229 
1230  deref_flag=FALSE;
1231  goal_stack=aim;
1232  deref_rec_body(t);
1233  if (!deref_flag) goal_stack=save;
1234  return (deref_flag);
1235 }
1236 
1244 {
1245  if (t->status==0) {
1246  if (t->type->type_def==(def_type)function_it) {
1247  check_func(t);
1248  deref_flag=TRUE;
1249  }
1250  else
1251  if(t->type->type_def==(def_type)global_it) { /* RM: Feb 10 1993 */
1252  eval_global_var(t);
1253  deref_ptr(t);/* RM: Jun 25 1993 */
1254  deref_rec_body(t);
1255  }
1256  else {
1257  /* if (t->status!=2) Tried adding this -- PVR 9.2.94 */
1258  if((GENERIC)t<heap_pointer)
1259  push_ptr_value(int_ptr,(GENERIC *)&(t->status));/* RM: Jul 15 1993 */
1260  t->status=4;
1262  }
1263  }
1264 }
1265 
1273 {
1274  ptr_psi_term t1;
1275 
1276  if (n) {
1277  deref_rec_args(n->right);
1278  t1 = (ptr_psi_term) (n->data);
1279  deref_ptr(t1);
1280  deref_rec_body(t1);
1281  deref_rec_args(n->left);
1282  }
1283 }
1284 
1295 {
1296  ptr_goal save = goal_stack;
1297  ptr_goal top_loc = aim;
1298 
1299  deref_flag = FALSE;
1300  goal_stack = top_loc;
1301  deref_rec_args_exc(t->attr_list,set);
1302  if (!deref_flag) goal_stack = save;
1303  return (deref_flag);
1304 }
1305 
1316 long in_set(char *str,long set)
1317 {
1318  if (set&1 && !featcmp(str,"1")) return TRUE;
1319  if (set&2 && !featcmp(str,"2")) return TRUE;
1320  if (set&4 && !featcmp(str,"3")) return TRUE;
1321  if (set&8 && !featcmp(str,"4")) return TRUE;
1322  return FALSE;
1323 }
1324 
1333 {
1334  ptr_psi_term t;
1335 
1336  if (n) {
1337  deref_rec_args_exc(n->right,set);
1338  if (!in_set(n->key,set)) {
1339  t = (ptr_psi_term) (n->data);
1340  deref_ptr(t);
1341  deref_rec_body(t);
1342  }
1343  deref_rec_args_exc(n->left,set);
1344  }
1345 }
1346 
1353 /* These two needed only for match_aim and match_attr: */
1354 
1355 /* Same as deref_eval, but assumes goal_stack already restored. */
1357 {
1358  deref_ptr(t);
1359  if (t->status==0) {
1360  if (t->type->type_def==(def_type)function_it) {
1361  check_func(t);
1362  }
1363  else
1364  if(t->type->type_def==(def_type)global_it) { /* RM: Feb 10 1993 */
1365  eval_global_var(t);
1366  deref_ptr(t);/* RM: Jun 25 1993 */
1367  deref2_eval(t);
1368  }
1369  else {
1370  t->status=4;
1371  }
1372  }
1373 }
1374 
1383 {
1384  deref_ptr(t);
1385  deref_rec_body(t);
1386 }
1387 
1388 /********************************************************************/
1389 
1399 {
1400  if (rb) {
1401  rb->cc_cr = (can_curry<<1) + curried; /* 11.9 */
1402  rb->ra = resid_aim;
1403  rb->rv = resid_vars;
1404  /* rb->cr = curried; 11.9 */
1405  /* rb->cc = can_curry; 11.9 */
1406  rb->md = match_date;
1407  }
1408 }
1409 
1418 {
1419  if (rb) {
1420  can_curry = (rb->cc_cr&2)?TRUE:FALSE; /* 11.9 */
1421  curried = (rb->cc_cr&1)?TRUE:FALSE; /* 11.9 */
1422  resid_aim = rb->ra;
1423  resid_vars = rb->rv;
1424  /* curried = rb->cr; 11.9 */
1425  /* can_curry = rb->cc; 11.9 */
1426  *match_date = rb->md;
1427  }
1428 }
1429 
1430 
1431 
1440 void eval_global_var(ptr_psi_term t) /* RM: Feb 10 1993 */
1441 {
1442  deref_ptr(t);
1443 
1444  /* Global variable (not persistent) */
1445 
1446  traceline("dereferencing variable %P\n",t);
1447 
1448  /* Trails the heap RM: Nov 10 1993 */
1449  if(!t->type->global_value) {
1450 
1451  /* Trail the heap !! */
1452  {
1453  ptr_stack n;
1454  n=STACK_ALLOC(stack);
1455  n->type=psi_term_ptr;
1456  n->aaaa_3= (GENERIC *) &(t->type->global_value);
1457  n->bbbb_3= (GENERIC *) NULL;
1458  n->next=undo_stack;
1459  undo_stack=n;
1460  }
1461 
1462 
1463  clear_copy();
1465 
1466  }
1467 
1468  /* var_occurred=TRUE; RM: Feb 4 1994 */
1469 
1470  if(t->type->type_def==(def_type)global_it && t!=t->type->global_value) {
1471  /*traceline("dereferencing variable %P\n",t);*/
1472  push_psi_ptr_value(t,(GENERIC *)&(t->coref));
1473  t->coref=t->type->global_value;
1474  }
1475 }
1476 
1484 void init_global_vars() /* RM: Feb 15 1993 */
1485 
1486 {
1487  ptr_definition def;
1488 
1489  /* printf("initializing global vars...\n"); */
1490 
1491  /*
1492  for(def=first_definition;def;def=def->next) {
1493  if(def->type==global_it && ((GENERIC)def->global_value<heap_pointer)) {
1494  clear_copy();
1495  def->global_value=eval_copy(def->init_value,STACK);
1496  }
1497  }
1498  */
1499 
1500  for(def=first_definition;def;def=def->next)
1502  def->global_value=NULL;
1503 }
1504 
1505 /********************************************************************/
GENERIC stack_pointer
used to allocate from stack - size allocated added - adj for alignment
Definition: def_glob.h:69
ptr_definition disjunction
symbol in bi module
Definition: def_glob.h:249
ptr_psi_term aaaa_1
Definition: def_struct.h:239
ptr_psi_term aaaa_2
Definition: def_struct.h:205
ptr_residuation resid
Definition: def_struct.h:189
#define function_it
was enum (def_type) in extern.h now there is typedef ptr_definition
Definition: def_const.h:1408
long do_residuation()
do_residuation
Definition: lefun.c:336
void push_ptr_value(type_ptr t, GENERIC *p)
push_ptr_value
Definition: login.c:383
long glb_value(long result, long f, GENERIC c, GENERIC value1, GENERIC value2, GENERIC *value)
glb_value
Definition: types.c:1290
struct wl_resid_block * ptr_resid_block
Definition: def_struct.h:259
void deref2_eval(ptr_psi_term t)
deref2_eval
Definition: lefun.c:1356
long eval_args(ptr_node n)
eval_args
Definition: lefun.c:889
ptr_psi_term init_value
Definition: def_struct.h:160
long deref_eval(ptr_psi_term t)
deref_eval
Definition: lefun.c:1180
void eval_global_var(ptr_psi_term t)
eval_global_var
Definition: lefun.c:1440
void clear_copy()
clear_copy
Definition: copy.c:53
ptr_psi_term real_stack_psi_term(long stat, REAL thereal)
real_stack_psi_term
Definition: lefun.c:48
GENERIC heap_pointer
used to allocate from heap - size allocated subtracted - adj for alignment
Definition: def_glob.h:55
void push2_ptr_value(type_ptr t, GENERIC *p, GENERIC v)
push2_ptr_value
Definition: login.c:573
char evaluate_args
Definition: def_struct.h:156
void deref_rec_args(ptr_node n)
deref_rec_args
Definition: lefun.c:1272
ptr_definition integer
symbol in bi module
Definition: def_glob.h:312
long check_out(ptr_psi_term t)
Definition: lefun.c:1083
ptr_goal goal_stack
Definition: def_glob.h:1025
static long deref_flag
Definition: lefun.c:1166
void match_attr2(ptr_node *u, ptr_node v, ptr_resid_block rb)
match_attr2
Definition: lefun.c:644
static long attr_missing
Definition: lefun.c:12
void push_choice_point(goals t, ptr_psi_term a, ptr_psi_term b, GENERIC c)
push_choice_point
Definition: login.c:638
void push_goal(goals t, ptr_psi_term a, ptr_psi_term b, GENERIC c)
push_goal
Definition: login.c:600
#define def_ptr
values of type_ptr
Definition: def_const.h:404
ptr_goal goal
Definition: def_struct.h:172
ptr_definition first_definition
All definition are stores in a linked list starting at first_definition.
Definition: def_glob.h:13
ptr_residuation next
Definition: def_struct.h:173
ptr_definition cut
symbol in syntax module
Definition: def_glob.h:242
ptr_pair_list next
Definition: def_struct.h:207
ptr_definition iff
symbol in bi module
Definition: def_glob.h:305
GENERIC * bbbb_3
Definition: def_struct.h:233
GENERIC cccc_1
Definition: def_struct.h:241
long(* c_rule[MAX_BUILT_INS])()
Definition: def_glob.h:888
void push_psi_ptr_value(ptr_psi_term q, GENERIC *p)
push_psi_ptr_value
Definition: login.c:474
void do_currying()
do_currying
Definition: lefun.c:383
void residuate3(ptr_psi_term u, ptr_psi_term v, ptr_psi_term w)
residuate3
Definition: lefun.c:159
void tracing()
tracing
Definition: error.c:678
def_type type_def
Definition: def_struct.h:153
includes
long matches(ptr_definition t1, ptr_definition t2, long *smaller)
matches
Definition: types.c:1666
ptr_resid_list next
Definition: def_struct.h:97
ptr_goal ra
Definition: def_struct.h:263
void get_one_arg(ptr_node t, ptr_psi_term *a)
get_one_arg
Definition: login.c:99
long check_type(ptr_psi_term t)
check_type
Definition: lefun.c:990
struct wl_psi_term * ptr_psi_term
quotedStackCopy
Definition: def_struct.h:62
#define global_it
was enum (def_type) in extern.h now there is typedef ptr_definition
Definition: def_const.h:1422
GENERIC data
Definition: def_struct.h:201
#define NULL
Definition: def_const.h:533
void init_global_vars()
init_global_vars
Definition: lefun.c:1484
#define REAL
Which C type to use to represent reals and integers in Wild_Life.
Definition: def_const.h:132
ptr_goal resid_aim
Definition: def_glob.h:865
long overlap_type(ptr_definition t1, ptr_definition t2)
overlap_type
Definition: types.c:1579
ptr_resid_list resid_vars
Definition: def_glob.h:866
char always_check
Definition: def_struct.h:154
#define eval
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1086
ptr_definition sys_bytedata
symbol in sys module
Definition: def_glob.h:983
long trace
Definition: def_glob.h:913
void residuate_double(ptr_psi_term t, ptr_psi_term u)
residuate_double
Definition: lefun.c:107
ptr_node left
Definition: def_struct.h:199
void traceline(char *format,...)
traceline
Definition: error.c:186
ptr_definition real
symbol in bi module
Definition: def_glob.h:375
void fetch_def(ptr_psi_term u, long allflag)
fetch_def
Definition: login.c:1208
#define type_it
was enum (def_type) in extern.h now there is typedef ptr_definition
Definition: def_const.h:1415
ptr_definition next
Definition: def_struct.h:164
ptr_stack undo_stack
Definition: def_glob.h:1027
ptr_psi_term quote_copy(ptr_psi_term t, long heap_flag)
quote_copy
Definition: copy.c:186
void Errorline(char *format,...)
Errorline.
Definition: error.c:465
unsigned long * GENERIC
unsigned long *GENERIC
Definition: def_struct.h:35
#define deref_ptr(P)
Definition: def_macro.h:100
void print_resid_message(ptr_psi_term t, ptr_resid_list r)
print_resid_message
Definition: print.c:1690
type_ptr type
Definition: def_struct.h:231
char * key
Definition: def_struct.h:198
#define TRUE
Standard boolean.
Definition: def_const.h:268
ptr_psi_term copy(ptr_psi_term t, long copy_flag, long heap_flag)
copy
Definition: copy.c:248
#define RMASK
Bit mask for status field of psi-terms: RMASK is used as a flag to avoid infinite loops when tracing ...
Definition: def_const.h:359
ptr_psi_term md
Definition: def_struct.h:267
long deref_rec_eval(ptr_psi_term t)
deref_rec_eval
Definition: lefun.c:1226
#define match
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1121
ptr_pair_list rule
Definition: def_struct.h:148
ptr_psi_term global_value
Definition: def_struct.h:159
#define FALSE
Standard boolean.
Definition: def_const.h:275
long f_check_out(ptr_psi_term t)
f_check_out
Definition: lefun.c:1046
#define code_ptr
values of type_ptr
Definition: def_const.h:411
long match_aim()
match_aim
Definition: lefun.c:770
struct wl_definition * ptr_definition
Definition: def_struct.h:59
ptr_definition such_that
symbol in syntax module
Definition: def_glob.h:396
long deref_args_eval(ptr_psi_term t, long set)
deref_args_eval
Definition: lefun.c:1294
void check_func(ptr_psi_term t)
check_func
Definition: lefun.c:928
GENERIC value_3
Definition: def_struct.h:186
void release_resid(ptr_psi_term t)
release_resid
Definition: lefun.c:445
ptr_psi_term bbbb_2
Definition: def_struct.h:206
ptr_psi_term var
Definition: def_struct.h:95
#define fail
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1044
ptr_goal aim
Definition: def_glob.h:1024
ptr_psi_term coref
Definition: def_struct.h:188
void append_resid(ptr_psi_term u, ptr_psi_term v)
append_resid
Definition: lefun.c:474
#define STACK_ALLOC(A)
Definition: def_macro.h:21
#define unify
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1058
GENERIC * aaaa_3
Definition: def_struct.h:232
ptr_psi_term stack_copy_psi_term(psi_term t)
stack_copy_psi_term
Definition: parser.c:205
long featcmp(char *str1, char *str2)
featcmp
Definition: trees.c:106
ptr_psi_term heap_psi_term(long stat)
heap_psi_term
Definition: lefun.c:75
long can_curry
Definition: def_glob.h:869
#define FUNC_ARG(t)
Definition: def_macro.h:31
#define unify_noeval
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1065
ptr_definition top
symbol in syntax module
Definition: def_glob.h:403
ptr_psi_term stack_psi_term(long stat)
stack_psi_term
Definition: lefun.c:21
long curried
Definition: def_glob.h:868
ptr_psi_term othervar
Definition: def_struct.h:96
#define eval_cut
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1093
void match_attr1(ptr_node *u, ptr_node v, ptr_resid_block rb)
void match_attr1
Definition: lefun.c:599
void curry()
curry
Definition: lefun.c:174
long residuateGoalOnVar(ptr_goal g, ptr_psi_term var, ptr_psi_term othervar)
residuateGoalOnVar
Definition: lefun.c:192
long i_eval_args(ptr_node n)
i_eval_args
Definition: lefun.c:874
long eval_aim()
eval_aim
Definition: lefun.c:497
void save_resid(ptr_resid_block rb, ptr_psi_term match_date)
save_resid
Definition: lefun.c:1398
long i_check_out(ptr_psi_term t)
i_check_out
Definition: lefun.c:1033
void residuate2(ptr_psi_term u, ptr_psi_term v)
residuate2
Definition: lefun.c:144
static long check_func_flag
Definition: lefun.c:13
void match_attr(ptr_node *u, ptr_node v, ptr_resid_block rb)
match_attr
Definition: lefun.c:752
unsigned long global_time_stamp
Definition: login.c:28
void match_attr3(ptr_node *u, ptr_node v, ptr_resid_block rb)
match_attr3
Definition: lefun.c:700
void deref_rec_body(ptr_psi_term t)
deref_rec_body
Definition: lefun.c:1243
#define disj
was enum (goal) – but must be long for error.c - now typedef
Definition: def_const.h:1072
long glb_code(long f1, GENERIC c1, long f2, GENERIC c2, long *f3, GENERIC *c3)
glb_code
Definition: types.c:1351
#define MAX_BUILT_INS
Maximum number of built_ins.
Definition: def_const.h:154
ptr_resid_list rv
Definition: def_struct.h:266
ptr_psi_term eval_copy(ptr_psi_term t, long heap_flag)
eval_copy
Definition: copy.c:196
void deref_rec_args_exc(ptr_node n, long set)
deref_rec_args_exc
Definition: lefun.c:1332
void residuate(ptr_psi_term t)
residuate
Definition: lefun.c:125
ptr_definition type
Definition: def_struct.h:181
void deref2_rec_eval(ptr_psi_term t)
deref2_rec_eval
Definition: lefun.c:1382
ptr_psi_term bbbb_1
Definition: def_struct.h:240
long in_set(char *str, long set)
in_set
Definition: lefun.c:1316
#define resid_ptr
values of type_ptr
Definition: def_const.h:390
ptr_triple_list properties
Definition: def_struct.h:149
void release_resid_notrail(ptr_psi_term t)
release_resid_notrail
Definition: lefun.c:456
void release_resid_main(ptr_psi_term t, long trailflag)
release_resid_main
Definition: lefun.c:411
#define QUOTED_TRUE
True flags for the flags field of psi-terms.
Definition: def_const.h:254
#define goal_ptr
values of type_ptr
Definition: def_const.h:418
#define HEAP_ALLOC(A)
Definition: def_macro.h:20
#define SMASK
Bit mask for status field of psi-terms: SMASK masks off the status bits. These are used in the 'mark'...
Definition: def_const.h:367
ptr_stack next
Definition: def_struct.h:234
ptr_node attr_list
Definition: def_struct.h:187
long do_residuation_user()
do_residuation_user()
Definition: lefun.c:324
ptr_definition pending
Definition: def_struct.h:243
ptr_definition quoted_string
symbol in bi module
Definition: def_glob.h:368
void restore_resid(ptr_resid_block rb, ptr_psi_term *match_date)
restore_resid
Definition: lefun.c:1417
GENERIC heap_alloc(long s)
heap_alloc
Definition: memory.c:1616
ptr_choice_point choice_stack
Definition: def_glob.h:1026
void check_disj(ptr_psi_term t)
check_disj
Definition: lefun.c:910
#define STACK
Flag to indicate stack allocation.
Definition: def_const.h:331
ptr_node right
Definition: def_struct.h:200
ptr_goal next
Definition: def_struct.h:242
#define psi_term_ptr
values of type_ptr
Definition: def_const.h:383
#define int_ptr
values of type_ptr
Definition: def_const.h:397