Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/otter2/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/otter2/is2.c

/* M. Beeson, 4.27.04
   retrieval from an is_tree of subsuming terms.
   This function, based on McCune's is_retrieve, has been written 
   for Otter-lambda so that it properly handles the complications
   resulting from the fact that the scope of lambda-bound  variables 
   is only the lambda term that contains them, rather than the whole 
   clause.   The changes are quite extensive and tricky.
3.27.06  made two dated changes that prevented segmentation faults on Unix   
   
*/     

#include <assert.h>
#include "header.h"
#include "is2.h"
#include "beta.h"   // for Beeson's BINDER macro
#include "bsym.h"   // LAMBDA
// #define DIAGNOSTICS  // for debug printout

struct term_ptr *is_retrieve2(struct term *t,
			     struct context *subst,
			     struct is_tree *is,
			     struct is_pos **is_pos)
{
  struct rel *rel_stack[MAX_FS_TERM_DEPTH];
  struct is_tree *i1 = NULL;
  struct is_pos *pos, *ip2;
  int found, backup, varnum, j, reset, sym;
  int top = 0;
  int lflag=0;
  int varstack2[MAX_FS_TERM_DEPTH];
  int varstack3[MAX_FS_TERM_DEPTH];
  int varstack_top=0;
#ifdef DIAGNOSTICS  
  if(t == NULL)
    fprintf(stdout,"Coming back to is_retrieve for more\n");
  else
    fprintf(stdout,"Entering is_retrieve with :");print_term_nl(stdout, t); // DEBUG
#endif  
  

  if (t != NULL) {  /* first call */
    pos = NULL;
    top = -1;
    i1 = is->u.kids;
    backup = 0;
  }
  else if (*is_pos != NULL) {  /* continuation with more to try */
    pos = *is_pos;  /* must remember to set is_pos on return */
    backup = 1;
  }
  else  /* continuation with nothing more to try */
    return(NULL);

  while (1) {  /* loop until a leaf is found or done with tree */
    if (backup) {
      if (pos == NULL)
	      return(NULL);
      else {  /* pop top of stack (most recent variable node)
		           and restore state */
		  // we may have been inside one more more lambda terms when backtracking occurred.
		  // In that case some of the values of 'top-1' stored on varstack3
		  // are between the present value of top-1 and the new value  pos->stack_pos-1.
		  // On the other hand we may be backtracking INTO a lambda term that we had 
		  // already passed through.  
		  while(varstack_top > 0 &&                  // Beeson 3.27.06 
		        varstack3[varstack_top-1] <= top-1 &&
		        varstack3[varstack_top-1] >= pos->stack_pos-1
		       )
	        { // just finished last arg of a lambda term
	          int vn = varstack2[varstack_top-1];   // Beeson 4.25.04
	          subst->terms[vn] = NULL;
	          varstack_top--;
#ifdef DIAGNOSTICS	
              printf("Leaving lambda term\n");                // DEBUG              
	           fprintf(stdout,"Resetting variable %d\n to NULL",vn);   // DEBUG
#endif
	        }
	      top = pos->stack_pos;
	      for (j = 0; j <= top; j++)
	         rel_stack[j] = pos->rel_stack[j];
	      memcpy(subst->terms,pos->varvals,MAX_VARS*sizeof(struct term *));
	      i1 = pos->is;
	      t = subst->terms[i1->lab];
	      if ( pos->reset)  /* undo variable binding */
	         { subst->terms[i1->lab] = NULL;
#ifdef DIAGNOSTICS
              fprintf(stdout, "Unbinding %d \n", i1->lab);	            
#endif                 
            }
	      i1 = i1->next;
	      ip2 = pos;
	      pos = pos->next;
	      free_is_pos(ip2);
      }
    }

    /* at this point, i1 is the next node to try */
    found = 0;
    /* first try to match input term t with a variable node */
    while (found == 0 && i1 != NULL && i1->type == VARIABLE) {
      varnum = i1->lab;
      if (subst->terms[varnum] == NULL || lflag) 
        { /* if not bound, bind it; also if it's a lambda-variable that was bound, bind it anew */
	      subst->terms[varnum] = t;
	      subst->contexts[varnum] = NULL;
#ifdef DIAGNOSTICS	      
	      fprintf(stdout,"Binding %d to ",varnum); print_term_nl(stdout,t);  // DEBUG
	      fprintf(stdout,"varstack_top = %d and top = %d\n", varstack_top, top);
#endif	      
	      found = 1;
	      reset = 1;
	      if(lflag)
	         { lflag = 0;
	         
	       #ifdef DIAGNOSTICS
	           fprintf(stdout,"Setting lflag to 0\n");
	           fprintf(stdout, "storing variable %d in varstack2[%d]\n", varnum, varstack_top-1);
	       #endif

	           varstack2[varstack_top-1] = varnum;  // the variable being bound to lambda term
	           if(t->type != VARIABLE)
	               assert(0);
	         }
      }
      else {  /* bound variable, succeed iff identical */
              /* that is, identical up to renaming lambda-bound variables!--Beeson */
         found = term_ident(subst->terms[varnum], t);
	      reset = 0;  
      }

      if (found) {  /* save state */
	      ip2 = get_is_pos();
	      ip2->next = pos;
	      pos = ip2;
	      pos->is = i1;
	      pos->reset = reset;
	      for (j = 0; j <= top; j++)
	          pos->rel_stack[j] = rel_stack[j];
	      memcpy(pos->varvals,subst,MAX_VARS*sizeof(struct term *));
	      pos->stack_pos = top;
      }
      else  /* try next variable */
	      i1 = i1->next;
    }

    backup = 0;
    if (found == 0) {  /* couldn't match t with (another) variable */
      if (t->type == VARIABLE)
	       backup = 1;  /* because we can't instantiate given term */
      else {  /* NAME or COMPLEX */
	         sym = t->sym_num;
	         while (i1 != NULL && (int) i1->lab < sym)
	             i1 = i1->next;
	         if (i1 == NULL || i1->lab != sym)
	            backup = 1;
	         else if (t->type == COMPLEX && t->sym_num != Ignore_sym_num) {
	            top++;
	            if (top >= MAX_FS_TERM_DEPTH)
	               abend("is_retrieve, increase MAX_FS_TERM_DEPTH.");
	            rel_stack[top] = t->farg;  /* save pointer to subterms */
#ifdef DIAGNOSTICS	            
	            fprintf(stdout,"Pushing "); print_term_nl(stdout,t->farg->argval); // DEBUG
	            fprintf(stdout,"Now t is "); print_term_nl(stdout,t); // DEBUG
#endif 	            
	            if(BINDER(t->sym_num))
	                { 
	                  int vn =  t->farg->argval->varnum; // the lambda variable
	                  varstack3[varstack_top] = top-1; // where the list of args of the lambda term is stored
   #ifdef DIAGNOSTICS	                  
	                  fprintf(stdout, "Setting varstack3[%d] = %d", varstack_top, top-1);
   #endif	                  
	                  ++varstack_top;
	                  lflag = 1;  // used when we go to bind the lambda-variable.
	                  
   #ifdef DIAGNOSTICS
                     fprintf(stdout,"Setting lflag to 1\n");
                     fprintf(stdout, "Entering lambda term\n");     // DEBUG	                   
   #endif  	                   
	                }
	         }
      }
    }

    if (backup == 0) {  /* get next term from rel_stack */
      while (top >= 0 && rel_stack[top] == NULL)
	      { if(varstack_top > 0 &&                     // Beeson 3.27.06
	           varstack3[varstack_top-1] == top - 1)   // Beeson 4.2.04
	            { // just finished last arg of a lambda term
	              int vn = varstack2[varstack_top-1];   // Beeson 4.2.04
#ifdef DIAGNOSTICS	
                 printf("Leaving lambda term\n");                // DEBUG              
	              fprintf(stdout,"Resetting variable %d to NULL ",vn);   // DEBUG
#endif	         
                
	              subst->terms[vn] = NULL;     
	              varstack_top--;                                 // Beeson 4.2.04
	            }                                                 // Beeson 4.2.04
	        top--;
	      }                                                        // Beeson 4.2.04
	        
      if (top == -1) {  /* found a term */
	      *is_pos = pos;
	      return(i1->u.terms);
      }
      else {  /* pop a term and continue */
	         t = rel_stack[top]->argval;
#ifdef DIAGNOSTICS	         
	         fprintf(stdout,"just popped "), print_term_nl(stdout,t);  // DEBUG
#endif	         
	         rel_stack[top] = rel_stack[top]->narg;
	         i1 = i1->u.kids;
      }
    }
  }  /* end of while(1) loop */

}  /* is_retrieve2 */

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists