//---------------------------------------------------------------------------
#include <string.h>
//---------------------------------------------------------------------------
#include "tboolfnct.h"
#include "boom.h"
#include "tpfnct.h"
#include "buffers.h"
#include "bufferstruct.h"
#include "implcheck.h"
//---------------------------------------------------------------------------
int CompareImplCheck( TBoolFnct * fn, TPfnct * ff, int ovr ) // 0=neproslo, 1=proslo
{
  int i, j, d;
  TPfnct * ff4;
  TPfnct * cf;
  int stt;
  TBoolFnct * rfn;
  int flg;
  char * s;
  int flg2;

  if ( fn->type == 1 )
  {
    cf = fn->offset[ovr];
    while ( cf != 0 )
    {
      if ( cf->cvd == 0 )
      {
        stt = 1;
        for ( i = 0; i < fn->inpvars; i++ )
          if ( cf->iv[i] != '-' && ff->iv[i] != '-' && cf->iv[i] != ff->iv[i] )
          {
            stt = 0;
            break;
          }
        if ( stt == 1 ) return 0;
      }
      cf = cf->next;
    }
    return 1;
  }
  else if ( fn->type == 0 )
  {
    rfn = fn->CreateChildFnct();
    rfn->AddTermToEnd( ff->iv, ff->ov, ff->dim );
    flg2 = 0;
    do
    {
      if ( flg2 == 0 )
      {
        cf = fn->onset[ovr];
        flg2++;
      }
      else
      {
        cf = fn->dcset[ovr];
        flg2++;
      }
      while ( cf != 0 && rfn->terms > 0 )
      {
        ff = rfn->fnct;
        while ( ff != 0 )
        {
          flg = 0;
          for ( i = 0; i < fn->inpvars; i++ )
          {
            if ( cf->iv[i] != '-' && ff->iv[i] != '-' && cf->iv[i] != ff->iv[i] )
            {
              flg = -1;
              break;
            }
            if ( ff->iv[i] == '-' && cf->iv[i] != '-' ) flg++;
          }
          if ( flg == 0 ) ff->valid = 0;
          if ( flg > 0 )
          {
            for ( i = 0; i < fn->inpvars; i++ )
            {
              if ( ff->iv[i] == '-' && cf->iv[i] != '-' )
              {
                if ( cf->iv[i] == '1' ) ff->iv[i] = '0';
                else
                  ff->iv[i] = '1';
                ff->dim--;
                s = new( char[fn->inpvars + 1] );
                memcpy( s, ff->iv, fn->inpvars );
                s[i] = cf->iv[i];
                d = ff->dim;
                break;
              }
            }
            j = i + 1;
            for ( i = j; i < fn->inpvars; i++ )
            {
              if ( ff->iv[i] == '-' && cf->iv[i] != '-' )
              {
                d--;
                ff4 = rfn->AddTermToBeginning( s, ff->ov, d );
                if ( cf->iv[i] == '1' ) ff4->iv[i] = '0';
                else
                  ff4->iv[i] = '1';
                s[i] = cf->iv[i];
              }
            }
          }
          ff = ff->next;
        }
        rfn->DeleteInvalidTerms();
        cf = cf->next;
      }
    }
    while ( flg2 < 2 );
    i = rfn->terms;
    delete rfn;
    return ( ( i == 0 ) ? 1 : 0 );
  }
  return 0; // ??
}
//---------------------------------------------------------------------------
void ConstructValidOutputs( TBoolFnct * fn, MinimizeOptions * mo, TBuffers * buffers )
{
  TPfnct * ff;
  int i;

  ff = fn->fnct;
  while ( ff != 0 )
  {
    for ( i = 0; i < fn->outvars; i++ )
      if ( ImplCheck( fn->parent, ff, i, mo, buffers ) == 1 ) ff->ov[i] = '1';
      else ff->ov[i] = '0';
    ff = ff->next;
  }
}
//---------------------------------------------------------------------------
int TreeImplCheck( TBoolFnct * fn, TPfnct * ff, int ovr, TBuffers * buffers ) // 0=neproslo, 1=proslo
{
  return 1 - ( buffers->offtree[ovr]->GetRoot()->SearchInterNode( ff->iv, 0, fn->inpvars ) );
}
//---------------------------------------------------------------------------
int ImplCheck( TBoolFnct * fn, TPfnct * ff, int ovr, MinimizeOptions * mo, TBuffers * buffers ) // 0=neproslo, 1=proslo
{
  int k;

  if ( mo->IC_memory == 1 )
  {
    k = buffers->imp_test[ovr]->IsInTreeHistory( ff );
    if ( k > 0 ) return k - 1;
  }

  switch ( mo->IC_type )
  {
    case 0:
      k = CompareImplCheck( fn, ff, ovr );
    break;
    case 1:
      k = TreeImplCheck( fn, ff, ovr, buffers );
    break;
  }

  if ( mo->IC_memory == 1 ) buffers->imp_test[ovr]->ValAddToTreeHistory( ff, k + 1 );
  return k;
}
//---------------------------------------------------------------------------
