/*                        logic_io_p.c               12-02-90 




*************************************************************
*************************************************************

 *****  The routines for reading in setups and for      *****
 *****  making the appropriate initialisations.  Also   *****
 *****  for printing out the matrices found. This       *****
 *****  version is for the parallel MaGIC only.         *****


************************************************************/



#define ADD while ( got_des() ) { add_prob(&max_index); \
 if ( gm->nprobs == PROBMAX || max_index >= 3*PROBMAX-SZ ) return(0); }

/*******************************************************************/

read_data()                 /*** Convert input into problem list ***/
{
   int max_index = 0, i, j;
   
   old_siz = siz;  old_negno = negno;
   FORALL(i) FORALL(j) old_ord[i][j] = ord[i][j];
   gm->nprobs = 0;
   if ( siz )
   {
      ADD
      while ( got_ord() ) ADD
      if ( theJob->f_n ) 
         while ( got_neg() ) 
         while ( got_ord() ) ADD
   }
   while ( got_siz() )
   if ( theJob->f_n ) 
      while ( got_neg() ) 
      while ( got_ord() ) ADD
   else while ( got_ord() ) ADD
   fclose(infil);  infil = 0;
}

/*******************************************************************/

add_prob(ptr)  int *ptr;
                             /*** Extend the problem list by one ***/
{
   int i,j,k=0;
   
   gm->p_siz[gm->nprobs] = siz;
   if ( theJob->f_n )
   {
      for ( i = 0; i < N[i]; i++ ) ;
      gm->p_N[gm->nprobs] = (((siz-2*i)+1)/2)+1;
   }
   gm->p_index[gm->nprobs] = *ptr;
   gm->p_ord[*ptr] = 0;
   FORALL(i) FORALL(j)
   {
      if ( ord[i][j] ) gm->p_ord[*ptr] |= (1 << k);
      if ( ++k == SUI ) 
      { 
         (*ptr)++; 
         gm->p_ord[*ptr] = 0; 
         k = 0; 
      }
   }
   if ( k ) (*ptr)++;
   gm->p_true[gm->nprobs] = 0;
   FORALL(i) 
   if ( true[i] ) gm->p_true[gm->nprobs] |= (1 << i);
   gm->ready[gm->nprobs++] = 0;
}

/******************************************************************/

got_siz()        /*** Return new size, or 0 if none ***/
{ 
  fscanf(infil, "%d", &siz);
  if ( DONE || siz==theJob->sizmax || siz<0 ) siz = 0;
  return( siz );
}



/******************************************************/

got_neg()       /*** Read neg. Return 0 if none ***/
{ int i;

  fscanf(infil, "%d", N);
  if ( *N < 0 ) return(0);
  for ( i = 1; i <=siz; i++ ) fscanf(infil, "%d", N+i);
  return(1);
}



/******************************************************/

got_ord()       /*** Read order.  Return 0 if none ***/
{ int i,j;

  fscanf(infil, "%d", *ord);
  if ( **ord < 0 ) return(0);
  FORALL(i)  FORALL(j)
  if ( i || j ) fscanf(infil, "%d", ord[i]+j);
  return(1);
}



/*******************************************************/

got_des()         /*** Get new des. Return 0 if none ***/
{ int i;

  FORALL(i) true[i] = 0;
  fscanf(infil, "%d", &des);
  if ( des < 0 ) return(0);
  if ( theJob->f_t ) FORALL(i) true[i] = ord[des][i];
  else while ( des >= 0 )
  {
     true[des] = 1;
     fscanf(infil, "%d", &des);
  }
  return(1);
}


/*******************************************************/
  

mat_print()     /*** This is the "accept" routine ***/
{
  int tim;
  
  good++;
  if ( theJob->tty_out ) C_print(stdout,theJob->tty_out);
  if ( theJob->fil_out ) C_print(outfil,theJob->fil_out);
  if ( !(matno++) )
  { 
     if ( !(desno++) )
     { 
        if ( !(ordno++) ) { if ( theJob->f_n ) negno++; }
     }
  }
  CLoCK(&tim);
  if ( theJob->maxtime && tim > theJob->maxtime ) DONE = 1;
  if ( theJob->maxmat && good == theJob->maxmat) DONE = 1;
}



/*******************************************************/

siz_print(f,x)  FILE *f;  int x;
{
  switch(x)
  { 
     case UGLY:    fprintf(f, " %d\n", siz);                 break;
     case PRETTY:  fprintf(f, "\n\n\n\n\n Size: %d", siz+1); break;
     case SUMMARY: fprintf(f, "\n\n\n Size: %d", siz+1);
  }
}



/*******************************************************/

neg_print(f,x)  FILE *f;  int x;
{ int i;

  if ( !negno ) siz_print(f,x);
  switch(x)
  { 
     case UGLY:    FORALL(i) fprintf(f, " %d", N[i]);
                   fprintf(f, "\n");  break;
     case PRETTY:  fprintf
                   (f, "\n\n\n Negation table #%d   ~ |", negno+1);
                   FORALL(i) fprintf(f, " %x", i);
                   fprintf(f, "\n                     --+");
                   FORALL(i) fprintf(f, "--");  
                   fprintf(f, "\n                       |");
                   FORALL(i) fprintf(f, " %x", N[i]);
                   fprintf(f, "\n");  break;
     case SUMMARY: fprintf(f, "\n\n    Negation #%d", negno+1);
  }
}



/*******************************************************/

ord_print(f,x)  FILE *f;  int x;
{ int i,j;

  if ( !ordno ) 
  {
     if ( theJob->f_n ) neg_print(f,x);
     else siz_print(f,x);
  }
  switch(x)
  { 
     case UGLY:    FORALL(i) FORALL(j) 
                   fprintf(f, " %d", ord[i][j]); 
                   fprintf(f, "\n");  break;
     case PRETTY:  fprintf(f, "\n\n\n Order #%-3d   < |", ordno+1);
                   FORALL(i) fprintf(f, " %x", i);
                   fprintf(f, "\n              --+");
                   FORALL(i) fprintf(f, "--");
                   FORALL(i)
                   { 
                      fprintf(f, "\n%15x |", i);
                      FORALL(j) 
                      fprintf(f, " %c", (ord[i][j]? '+': '-'));
                   }
                   fprintf(f, "\n\n");  break;
     case SUMMARY: fprintf(f, "\n\n       Order #%d", ordno+1);
  }
}



/*******************************************************/

des_print(f,x)  FILE *f; int x;
{ 
  if ( !desno ) ord_print(f,x);
  if ( theJob->f_t ) switch(x)
  { 
     case UGLY:    fprintf(f, " %d\n", des);                 break;
     case PRETTY:  fprintf(f, "\n Choice of t: %x\n", des);  break;
     case SUMMARY: fprintf(f, "\n\n          t = %x", des);
  }
  else switch(x)
  {
     case UGLY:    FORALL(des) if ( true[des] ) 
                   fprintf(f, " %d", des); 
                   fprintf(f, " 0\n" );                      break;
     case PRETTY:  fprintf(f, "\n Choice of truths: ");
                   FORALL(des) if ( true[des] )
                   fprintf(f, " %x", des);
                   fprintf(f, "\n");  break;
     case SUMMARY: fprintf(f, "\n\n          truth =");
                   FORALL(des) if ( true[des] )
                   fprintf(f, " %x", des);
  }
}



/******************************************************/

C_print(f,x)  FILE *f; int x;
{ int i,j;
  
  if ( !matno ) des_print(f,x);
  switch(x)
  {
     case UGLY:   FORALL(i) FORALL(j) fprintf(f, " %d", C[i][j]);
                  fprintf(f, "\n");  break;
     case PRETTY: fprintf(f, "\n Matrix # %-6d  -> |", matno+1);
                  FORALL(i) fprintf(f, " %x", i);
                  fprintf(f, "\n                  ---+");
                  FORALL(i) fprintf(f, "--");
                  FORALL(i)
                  { 
                     fprintf(f, "\n%20x |", i);
                     FORALL(j) fprintf(f, " %x", C[i][j]);
                  }
                  if ( theJob->failure )
                  {
                     fprintf(f, "  ");
                     for ( i = 0; i < 4; i++ ) if ( badvalue[i] < SZ )
                     fprintf(f, "  %c = %d", 'p'+i, badvalue[i]);
                  }
                  fprintf(f, "\n\n");
  }
}



/******************************************************
******************************************************/

stats_print()
{ int tim;

  CLoCK(&tim);
  printf("\n\n\n\n\n Matrices generated by MaGIC:  "); fflush(stdout);
  system("date");
  printf("\n\n Good ones found:   %d\n", good);
      printf(" Bad ones tested:   %d\n", tot-good);
      printf(" Isomorphs omitted: %d\n", isoms);
      printf(" Time (wall clock): %1.2f seconds\n\n\n", 
                            (tim - start_time)/(TICK*1.0));
}