/*****************************************************************************
 *
 * FILE : atmprv.c - propositional prover for disjunction free theories
 * 		     implementaion of tableaux algorithm
 *
 * programmer - Pawel Cholewinski
 *
 * date 01/30/96
 * modified 19 Apr 1999 by Neil Moore <neil@cs.uky.edu>
 * modified 20 Aug 1999 by Neil Moore <neil@cs.uky.edu>
 * modified  4 Sep 1999 by Neil Moore <neil@cs.uky.edu>
 *
 * Part of sderes.  See COPYRIGHT for copyright information.
 *
 *****************************************************************************/


#include "global.h"
#include "token.h"
#include "proto.h"

#define MAXATOMS 1024 * 128

int *maintheory, *auxtheory;
int *spelltab;
int *facts;
int tempfacts[MAXATOMS];
int mts, ats, atn;
long *counter;
char **atomslexic;
int mode;

int prove(psi,val)
   int psi, val;
{
   int p = psi, v, varid, token;

   /* printf("prove: T|- ");*/
   /* if (val==0) printf(" not "); */
   /* if (p<0) printf(" empty "); */
   /* else printformula(psi); */
   /* printf("; result "); */
   /* fflush(stdout); */
   if (p<0) { return val;}
   (*counter)++;

   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   if (val) {                                       /* T |= psi       ? */
      while (1) {
         varid = spelltab[p];
         if (facts[varid]<0) {return 0;}
         else {
	    v = (spelltab[p-2]==NEG) ? 0 : 1;
            if (facts[varid] != v) { return 0;}
         }
	 p++;
         while ((token=spelltab[p++]) != VAR) if (stopsearch(token)) 
		{ return 1;}
      }
   }
   else  {                                           /* T |= not(psi) ? */
      while (1) {
         varid = spelltab[p];
	 v = (spelltab[p-2]==NEG) ? 0 : 1;
         if (facts[varid]>=0 && facts[varid]!=v) { return 1;}
	 p++;
	 while ((token=spelltab[p++]) != VAR) if (stopsearch(token)) 
			{return 0;}
      }
   }
   
   return -1;
}

int build_atomtable(auxtabind)
    int *auxtabind;
{
    int ans, i, resp = 0;

    for (i=0 ; i<mts ; i++) {
	ans = store_facts(maintheory[i]);
	if (ans<0) {
		if(verbosity > 0)
			fprintf(stderr, "formula %d yields inconsistency\n",i);
		return -1;
	}
	else if (ans>0) {
		if(verbosity > 0)
			fprintf(stderr, "formula %d not disjunction-free\n",i);
	        resp += ans;
	}
	
    }
    if (auxtabind==NULL) { 
        return resp;
    }
    for (i=0 ; i<ats ; i++) 
       if (auxtabind[i]==1) {
          ans = store_facts(auxtheory[i]);
	  /* printf("effect %d\n", ans);*/
          if (ans<0) {
		  if(verbosity > 0)
			  fprintf(stderr, "conc(%d) yields inconsistency\n",i);
		return -1;
	  }
          else if (ans>0) {
		  if(verbosity > 0)
			  fprintf(stderr, "conc(%d) not disjunction-free\n",i);
		  resp += ans;
	  }
       }
    return resp;
}

void clean_atomtable(void)
{
    int i;

    for (i=0 ; i<atn ; i++) facts[i] = -1;
}

int store_facts(psi)
    int psi;
{
   int p=psi, varid, token;

   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   /* printf("Storing facts: p=%d, varid=%d\n",p, varid);*/
   while (varid>=0) {
      /* printf("  ITER: p=%d, varid=%d\n",p, varid);*/
      if (spelltab[p-2]!=NEG) { /* positive occurence */
	 if (facts[varid]==0) return -1;
	 else facts[varid] = 1;
      }
      else {                   /* negative occurence */
	if (facts[varid]==1) return -1;
         else facts[varid] = 0;
      }
      p++;
      while ((token=spelltab[p++]) != VAR) 
	if (token==ENT || token==COLON || token==COMMA || token==SEMI) 
			return 0;
	else if (notdisjunctionfree(token)) return 1;
      varid = spelltab[p];
   }
   return 0;
}

int add_facts(int psi, int *revvar, int *revval)
{
   int p=psi, varid, token, fnr=0;

   revvar[0] = -1;
   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   while (varid>=0) {
      revvar[fnr] = varid;
      revval[fnr] = facts[varid];
      revvar[++fnr] = -1;
      if (spelltab[p-2]!=NEG) { /* positive occurence */
         if (facts[varid]==0) return -1;
         else facts[varid] = 1;
      }
      else {                   /* negative occurence */
        if (facts[varid]==1) return -1;
         else facts[varid] = 0;
      }
      p++;
      while ((token=spelltab[p++])!=VAR) {
        if (token==ENT || token==COLON || token==COMMA || token==SEMI)
			return 0;
	}
      varid = spelltab[p];
   }
   return 0;
}

int remove_facts(int *revvar, int *revval)
{
   int i= -1;
   while (revvar[++i]>=0) facts[revvar[i]] = revval[i];
   return i;
}
	
int save_facts()
{
 int i;
 for (i=0 ;  i<atn ; i++) {
	tempfacts[i] = facts[i];
	facts[i] = -1;
 }
 return atn;
}

int save_stratum(int from, int to)
{
   int k;
   for (k=from ; k<to ; k++ ) {
        save_vars(auxtheory[k]);
   }
   for (k=from ; k<to ; k++ ) {
        clean_vars(auxtheory[k]);
   }
   for (k=0 ; k<mts ; k++) {
        store_facts(maintheory[k]);
   }
   return 1;
}

int save_vars(psi)
   int psi;
{
   int p = psi, varid, token;

   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   while (varid>=0) {
      tempfacts[varid] = facts[varid];   
      p++;
      while ((token=spelltab[p++])!=VAR && varid>0) {
	if (stopsearch(token)) return 1;
	}
      varid = spelltab[p];
   }
   return 1;
}

int clean_vars(psi)
   int psi;
{
   int p = psi, varid, token;
   
   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   while (varid>=0) {
      facts[varid] = -1;
      p++;
      while ((token=spelltab[p++])!=VAR && varid>0) {
	if (stopsearch(token)) return 1;
	}
      varid = spelltab[p];
   }
   return 1;
}

int restore_facts(void)
{
 int i;
 for (i=0 ;  i<atn ; i++) facts[i] = tempfacts[i];
 return atn;
}

int restore_stratum(int from, int to)
{
   int k;
   for (k=from ; k< to ; k++)
	restore_vars(auxtheory[k]);
   return 0;
}

int restore_vars(psi)
   int psi;
{
   int p = psi, token, varid;

   while (spelltab[p++] != VAR) ; /* rewind to first VAR id */
   varid = spelltab[p];
   while (varid>=0) {
      facts[varid] = tempfacts[varid];
      p++;
      while ((token=spelltab[p++])!=VAR && varid>0) {
	if (stopsearch(token)) return 1;
	}
      varid = spelltab[p];
   }
   return 1;
}

int stopsearch(tt)
  int tt;
{
   
   if (tt==COLON || tt==COMMA || tt==ENT || tt==SEMI) return 1;
   else return 0;
}

int notdisjunctionfree(tt)
  int tt;
{
   if (tt!=AND && tt!=VAR && tt!=NEG) return 1;
   else return 0;
}

void SetProverStructures(mth,ath,spell,mth_size,ath_size, 
			ftb, atoms_no,cntr,alex)
  int *mth, *ath, *spell, mth_size, ath_size, *ftb, atoms_no;
  long *cntr;
  char **alex;
{
 maintheory = mth;
 auxtheory  = ath;
 spelltab   = spell;
 mts        = mth_size;
 ats        = ath_size;
 facts      = ftb;
 atn        = atoms_no; 
 counter    = cntr;
 atomslexic = alex;
}
