Sindbad~EG File Manager

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

/* M. Beeson, for the Otter-lambda to MathXpert link */
/* ExternalSimplify takes clauses in string form and passes them to MathXpert for simplification,  returning answers also in string form.  The input strings are readable
by MathXpert and the output strings are readable by Otter. 
*/
/* This same pattern can be followed to link any external program to Otter to 
process clauses, changing them into "reduced" equivalent versions of the same clauses. 
Since the results are used by Otter in the same way as demodulation, the answers should 
be equivalent to the input, rather than just consequences, although if they are merely 
consequences, deductions will still be sound, we just might lose some desired conclusions.
If you want to make deductions externally rather than reductions,  the architecture
that calls ExternalSimplify should be modified to retain the original clauses too.
*/   

/* Last modified 1.17.06 
 3.20.06 removed superfluous include heaps.h, function.h, printdialog.h, freeptr.h
         changed pem to ParserErrorMessage
 7.2.06 added init_optable call.         
*/



#include <string.h>
#include <stdlib.h>
#include <stdio.h>  // fprintf 
#include <assert.h>
#define EXTERNALSIMP_DLL
#include "externalsimplify.h"
#include "export.h"
#include "globals.h"
#include "graphstr.h"
#include "document.h"
#include "userfunc.h"
#include "parser.h"
#include "ssolve.h"
#include "activate.h"
#include "cflags.h"
#include "mpmem.h"
#include "prover.h"
#include "mpstring.h"
#include "optable.h"
#include "probtype.h"    // SIMPLIFY  
#include "mathpertlink.h"
#include "englpem.h"  /* ParserErrorMessage */
#include "automode.h"  /* init_optable */

static PDOCDATA pProofData;
PDOCDATA GetDocData(void)
{ return pProofData;
}

/*___________________________________________________________*/
static void select_eigenvariable(term t)
/* choose the first non-bound variable in varlist that 
occurs in t, and call set_eigenvariable to make it the 
eigenvariable.  If there's no such variable, just take 
the first variable in varlist; if there are no variables
at all, do nothing.
*/
{ term *varlist = get_varlist();
  varinf *varinfo = get_varinfo(); 
  int i;
  int n = get_nvariables();
  for(i=0;i<n;i++)
     { if(varinfo[i].scope != BOUND && contains(t,FUNCTOR(varlist[i])))
           { set_eigenvariable(i);
             return;
           }
     }
  /* t is a constant term, so just pick SOME non-bound variable */
  for(i=0;i<n;i++)
     { if(varinfo[i].scope != BOUND )
           { set_eigenvariable(i);
             return;
           }
     }
  /* the entire clause has no non-bound variables */
  if(n > 0)
      set_eigenvariable(0);   // even if it's bound 
  // and if there are no variables at all don't do anything.
}       
/*___________________________________________________________*/
static char *term_string(term t)
{ int m = mpsize(t);
  char *ans = calloc(m+20,sizeof(char));  /* m+1 should be fine, but just in case.. */
  mpstring(t,ans,m+1);
  return ans;
}
/*___________________________________________________________*/  
static int almost_equals(term a, term b)
/* return 1 if one has the form not(a=b)and the other has the form ne(u,v);
   return 0 otherwise.
*/
{ if(FUNCTOR(a) == NOT && FUNCTOR(b) == NE)
     { SETFUNCTOR(b,'=',2);
       return equals(ARG(0,a),b);
     }
  if(FUNCTOR(b) == NOT && FUNCTOR(a) == NE)
     { SETFUNCTOR(a,'=',2);
       return equals(a,ARG(0,b));
     }
  return 0;
}  
  

/*___________________________________________________________*/  
static term negation(term t)
{ if(FUNCTOR(t) == NOT)
    return ARG(0,t);
  if(FUNCTOR(t) == NE)
    return equation(ARG(0,t),ARG(1,t));
  if(FUNCTOR(t) == LE)
    return lessthan(ARG(1,t),ARG(0,t));
  if(FUNCTOR(t) == '<')
    return le(ARG(1,t),ARG(0,t));
  if(FUNCTOR(t) == '=')
    return ne(ARG(0,t),ARG(1,t));
  return not(t);
}


/*___________________________________________________________*/    
int MEXPORT_EXTERNALSIMP ExternalSimplify(int nlits, char **atoms, char *signs, 
                     int *nNewLits, char **NewAtoms, char *NewSigns)
/*  The first three parameters represent an Otter clause in string form,
namely,  the number of literals, an array of strings, one for each atom, 
holding a term in string form, terminated by a period,  and an array 
of the signs of the literals.  The entries in the sign array are those
used in Otter: 0 for negation, 1 for positive occurrence.      
   The last three parameters similarly represent the output, the result of 
simplifying the input clause.  The number of literals can change; it comes
back in *nNewLits.  NewAtoms is an array of strings, each entry of 
which contains an atom in string form (must be parseable by Otter),  ending
in a period.   Newsigns is an array of the signs of those literals.
The dimension of these two output arrays is given by the initial value 
of *newLits.
   Return 0 if some simplification took place.  If not, return 1.  
   Return -1 if memory for the MathXpert heap can't be found.
   Space for the output strings is created using calloc.  This function 
leaves the MathXpert heaps in the same condition it found them. 
*/

{ int i,j,err,k,flag,r;
  int next_assumption, save_domain_assumptions;
  term *input;
  term *output;
  char *rest; 
  term t,q;
  int outputsize;
  int max_outup = *nNewLits;
  int heapsize = 1 << 15; /* in units of 16 bytes, yielding 512 kb total*/
  pProofData = (PDOCDATA) malloc(sizeof(DOCDATA));
  memset(pProofData,0,sizeof(DOCDATA));
  pProofData->currenttopic = _epsilon_delta;
  pProofData->docnumber = 1;
  // init_optable();
  err = init_doc_data(SYMBOLDOC, pProofData);
  if(err == 1)
      { printf("init_doc_data failed");
        free(pProofData);
        return 1;
      }

  activate(pProofData);
  set_polyvalfactorflag(0);  // don't content-factor
  set_polyvalfactorflag2(0);
  set_problemtype(SIMPLIFY);
  gensym(1);
  input = (term *) calloc(nlits, sizeof(term));
  outputsize = 5*nlits + 20;
  if (outputsize > max_outup)
     outputsize = max_outup;
  output = (term *) calloc(outputsize, sizeof(term));
  if(!input || !output)
     { fprintf(stderr, "Out of memory in ExternalSimplify\n");
       release_doc_data(pProofData);
       free(pProofData);
       return 1;
     }
  for(i=0;i<nlits;i++)
     {  // parse atoms[i]; negate the result if signs[i] == 0; 
        //  then put this term in input[i];
       err = mparse(&t, atoms[i],&rest);
       if(err)
          { fprintf(stderr,"Parser error parsing %s\n", atoms[i]);
            fprintf(stderr,"Unparsed part is %s\n",rest);
            fprintf(stderr,ParserErrorMessage(err)); 
            release_doc_data(pProofData);
            free(pProofData);
            return 1;
          }
       if(signs[i] == 0)
          t = negation(t);
       permcopy(t,&input[i]);
       vaux(input[i]);
       set_valuepointers(&input[i]);
     }
  for(i=0;i<nlits;i++)
     { term q = input[i];
       if(FUNCTOR(q) == NOT)
           q = ARG(0,q);
       if(INEQUALITY(FUNCTOR(q)))  // includes the case '='   
          { check(domain(ARG(0,q)));
            check(domain(ARG(1,q)));
          }
       else
          err = check(domain(input[i]));
       if(err == 1)  // one literal can't be defined 
          { // so nothing you could say about it could be true, e.g. 
            // sqrt(-1) = sqrt(-1) is false
            permfree(&input[i]);
            permcopy(make_term(FALSEFUNCTOR,0),&input[i]);
          }
      if(err != 0)
          assert(0);   // check can only return 2 if problemtype is SOLVE but now it's SIMPLIFY
     }
  save_domain_assumptions = get_nextassumption(); 
  k=0;
  flag = 0;  // set when some literal actually simplifies
  for(i=0;i<nlits;i++)
     { // assume the negations of all the input[j] for j > i 
       // and the negations of the output[j] for 0 <= j < k
       // then simplify input[i] using lpt 
       if(k==outputsize)
          { flag = 0;  // fail,  but don't cause an abend.
            fprintf(stdout,"\nSimplification failed:  too many literals\n");
            goto out;
          }
       for(j=i+1;j<nlits;j++)
           assume(negation(input[j]));
       for(j=0;j<k;j++)
          { if(NewSigns[j] == 0)
               assume(output[j]);
            else 
               assume(negation(output[j]));
          }
       next_assumption = get_nextassumption();
       select_eigenvariable(input[i]);
       t = lpt(input[i]);
       if(!equals(t,input[i]) && !almost_equals(t,input[i]))
          flag = 1;
       if( FUNCTOR(t) == TRUEFUNCTOR)
          { // one literal is TRUE so whole clause is TRUE
            NewAtoms[0] = "0=0";  // not 'true', so it will be subsumed in Otter 
            NewSigns[0] = 1;      // 7.5.05
            *nNewLits= 1;
            release_doc_data(pProofData);  // this also destroys the MathXpert heap
            free(pProofData);
            return 0;
          }
       if(FUNCTOR(t) == FALSEFUNCTOR) 
          { // skip this clause
            for(j=save_domain_assumptions;j< get_nextassumption();j++)
            permfree(&get_assumptions()[j]);
            set_nextassumption(save_domain_assumptions);
            continue;
          }
       if(FUNCTOR(t) == NOT)
          { t = ARG(0,t);
            NewSigns[k] = 0;
          }
       else if(FUNCTOR(t) == NE)
          { t = equation(ARG(0,t),ARG(1,t));
            NewSigns[k] = 0;
          }
       else if(FUNCTOR(t) == OR)
          { for(r=0;r<ARITY(t);r++)
               { q = ARG(r,t);
                 if(FUNCTOR(q) == NOT)
                     { q = ARG(0,q);
                       NewSigns[k] = 0;
                     }
                 else
                    NewSigns[k] = 1;
                 NewAtoms[k] = term_string(q);
                 permcopy(q,&output[k]);
                 ++k;
               }
            continue;
          }
       else
          NewSigns[k] = 1;
       NewAtoms[k] = term_string(t);
       permcopy(t,&output[k]);
       ++k;       
       for(j=next_assumption; j < get_nextassumption(); j++)
          { // put in the negation of any new assumptions
            // but not the domain assumptions or the negations of the other literals
            NewSigns[k] = 1;
            NewAtoms[k] = term_string(get_assumption(j));
            permcopy(get_assumption(j),&output[k]);
            ++k;
          }      
       set_nextassumption(save_domain_assumptions); // back to where only domains were assumed.
       reset_heap(NULL);  // assumptions are in perm memory so not on heap
     }
  /* free the MathXpert document that was created for this call */
  release_doc_data(pProofData);
//  delete_document(pProofData);
  out:
  if(!flag)
     { free(input);
       free(output);
       free(pProofData);
       return 1;
     }
  *nNewLits = k;
  free(pProofData);  // it was malloc'ed above
  free(input);
  free(output);
  return 0;
} 



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