/*

QBF Solving Script. Copyright by Horst Samulowitz 2006

 A very simple script that given a QBF instance first applies the preprocessor Prequel,
 then applies Quantor (copyright by Armin Biere) with a time limit, and finally applies
 the QBF solver 2clsQ when the instance was not solved on an earlier stage.


The software available at this site is copyright (c) 2006 Horst Samulowitz. 
 All right are reserved. Use of this software is permitted for
non-commercial research purposes, and it may be copied only for that
use. All copies must include this copyright message. This software and
any documentation and/or information supplied with it is distributed
on an as is basis. Horst Samulwitz and the University of Toronto make
no warranties, express or implied, including but not limited to
implied warranties of merchantability and fitness for a particular
purpose, regarding the documentation, functions or performance of such
software, documentation and/or information.
*/

// **************************************************************************************************************
// **************************************************************************************************************
//
// IMPORTANT NOTE
//
// **************************************************************************************************************
//  You might have to change the output of PreQuel in such away that its output is called 'preprocessed.qdimacs'.
// **************************************************************************************************************


#include "stdio.h"
#include "string.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <string>

using namespace std;


int main(int argc, char * argv[])
{
  
  printf("The QBF solver 2clsQ with preprocessing (copyright by H. Samulowitz and F. Bacchus, University of Toronto, 2006)");

  // BEGIN: Read Filename from Input
  char fn[4096];
  fn[0] = '\0';
  int loc = 1;
  while(loc < argc) {
      if (fn[0] == '\0') {
          strcpy(fn, argv[loc]);
          printf("\nQBF source file: %s", fn);
          ++ loc;
          continue;
      }
  }


  if (fn[0] == '\0') {
      return -1;

  }
  // END: Read Filename from Input
  
   // Clean up intermediate files from a potential earlier run
   FILE * pFile;
   pFile = fopen ("out","wt");
   fclose(pFile);
   pFile = fopen ("result1","wt");
   fclose(pFile);
   pFile = fopen ("result2","wt");
   fclose(pFile);
   pFile = fopen ("result3","wt");
   fclose(pFile);
   pFile = fopen ("preprocessed.qdimacs","wt");
   fclose(pFile);
  //
   if(!(pFile = fopen(fn, "r"))){
    printf("\n FAIL: Could not open file: %s", fn);
    exit(0);
   }
  

  // 1st Stage: PreProcessor PreQuel

  int nReturnValue1,  nReturnValue2; 
  char strProgrammCall[5000]; 
  strcpy(strProgrammCall, "pQ "); 
  strcat(strProgrammCall, fn);
  strcat(strProgrammCall, " > out");
  printf("\n -> Stage 1: Apply preprocessor pQ (copyright by H. Samulowitz, J. Davies and F. Bacchus)... ");
  fflush(stdout);
  nReturnValue1 = system(strProgrammCall);
  
   
   char string [100];
   pFile = fopen ("result1" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (string , 10 , pFile);     
     fclose (pFile);
   }
  
  char szKeyTrue[]    = "SAT"; 
  char szKeyFalse[]   = "UNSAT"; 
  char szKeyUnknown[] = "UNKNOWN";
  if(strncmp(string,szKeyTrue,3) == 0)
  {
     printf("\n --> QSAT \n");
     exit(10);
  }
  if(strncmp(string,szKeyFalse,5) == 0)
  {
     printf("\n --> UNQSAT \n");
     exit(20);
  }

  // 2nd Stage: Time-Limited Quantor
  printf("\n -> Stage 2: Proceed with PreProcessing using Quantor (copyright by Armin Biere) with a timelimit... ");
  fflush(stdout);
  

  // Second Program Call
  char strProgrammCall2[5000];
  strcpy(strProgrammCall2, "quantor-2004.01.25 --time-limit=25 ");
  strcat(strProgrammCall2, "preprocessed.qdimacs > result2");
  nReturnValue2 = system(strProgrammCall2);

   char string2 [100];
   pFile = fopen ("result2" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (string2 , 14 , pFile);     
     fclose (pFile);
   }
  char szKeyTrue2[]    = "s TRUE"; 
  char szKeyTrue21[]   = "s SATISFIABLE";
  char szKeyFalse2[]   = "s FALSE"; 
  char szKeyUnknown2[] = "c TIMEOUT";
  if((strncmp(string2,szKeyTrue2,6) == 0) || (strncmp(string2,szKeyTrue21,13) == 0))
  {
     printf("\n -> QSAT \n");
     exit(10);
  }
  if(strncmp(string2,szKeyFalse2,7) == 0)
  {
     printf("\n -> UNQSAT \n");
     exit(20);
  } 

   // 3rd Stage: 2clsQ
   printf("\n -> Stage 3: Proceed with 2clsQ (copyright by H.Samulowitz and Fahiem Bacchus) ... ");
   fflush(stdout);
  

  // Second Program Call
  char strProgrammCall3[5000];
  strcpy(strProgrammCall3, "2clsQ ");
  strcat(strProgrammCall3, "preprocessed.qdimacs > out");
  nReturnValue2 = system(strProgrammCall3);

   char string3 [100];
   pFile = fopen ("result3" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (string3 , 10 , pFile);     
     fclose (pFile);
   }
  char szKeyTrue3[]    = "SAT"; 
  char szKeyFalse3[]   = "UNSAT"; 
  if(strncmp(string3,szKeyTrue3,3) == 0)
  {
     printf("\n --> QSAT \n");
     exit(10);
  }
  if(strncmp(string3,szKeyFalse3,5) == 0)
  {
     printf("\n --> UNQSAT \n");
     exit(20);
  } 
 
  printf("\n --> UNKNOWN \n"); 
  return 0;
}

// END
