/*
This file is part of the dpll(t) engine sammy
Copyright (C) 2004  The University of Iowa
George Hagen
John Lee

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/////////////////////////////////////////////////////////////////////////////
//  CVCL/DPLLT - Theory Interface Module
//////////////////////////////////////////////////////////////////////////////
// File: theory.cpp                                                         //
// Author: John Lee                                                         //
// Course: 22C:295 - Spring 2003                                            //
// (C) University of Iowa - Department of Computer Science                  //
//                                                                          //
// theory_w.cpp is a module which interfaces OCAML to the CVCLite API       //
// Theory plugin for a satisfiability module theory module.                 //
//////////////////////////////////////////////////////////////////////////////
// Mostly re-written by George Hagen, 2003-2004
// last modified 09-06-05

#include <theory_w.h>

//#define CVC_API_DEBUG
#define CVC_API_TIMER
// #define CVC_API_TIMER_DEBUG
// #define CVC_OUTPUT

//note: do not define DEBUG if NEWCVCL is defined!
// #define DEBUG
#define NEWCVCL
//#define VALGRIND

//#define GCC4

#define VCSIMPLIFY(x) /*vc->simplify*/(x)
//#define REGISTER_PRED
//#define GETIMPLIED

#ifdef DEBUG
#define CVC_API_DEBUG
#endif

// C Library for timing.
#ifdef CVC_API_TIMER
  #include "sys/time.h"
#endif

// CVCLite Interface API
/*
#ifdef NEWCVCL
#include "cvcl/vc.h"
#include <fstream>
#include <iostream>
#include <deque>
#include "cvcl/compat_hash_map.h"
#include "cvcl/exception.h"
#include "cvcl/command_line_flags.h"
#include "cvcl/debug.h"
#else
*/
#include "vc.h"
#include <fstream>
#include <iostream>
#include <deque>
#include "compat_hash_map.h"
#include "exception.h"
#include "command_line_flags.h"
#include "debug.h"
//#endif

// Standard Template Library
#include <map>
#include <set>
#include <string>
#include <vector>

// IO
#include <fstream>
#include <iostream>

// OCAML Interfacing
#include <caml/mlvalues.h>

// int-to-string conversions
#include <sstream>

#define null 0
#define TRUE 1
#define FALSE 0

using namespace std;   // vector, map, string, hash
using namespace CVCL;  // CVCLite Interface

//////////////////////////////////////////////////////////////////////////////
// Global Variables
//////////////////////////////////////////////////////////////////////////////
ValidityChecker * vc = NULL;  // CVC Instance

// Static variables for cross-interface iterator.
vector<Expr> inconsistency;
vector<Expr>::const_iterator inconIterator;

// Single type for all uninterpreted variables.
Type UninterpretedType;

int definitions = DEFINITION_COUNTER_START; // other symbol counter

int intID = NEXT_DEFINITION_ID;
int realID = NEXT_DEFINITION_ID;
int boolID = NEXT_DEFINITION_ID;

int trueID = NEXT_DEFINITION_ID;
int falseID = NEXT_DEFINITION_ID;
int infinityID = NEXT_DEFINITION_ID;

int initial_layer = 1;

Type realType;
Type intType;
Type boolType;


//////////////////////////////////////////////////////////////////////////////
// Mappings
//////////////////////////////////////////////////////////////////////////////
// The mappings below are to translate from Expr instances and identification
// tags.
// The dpllt engine only communicates predicates by their associated id tags.

// type dec'l lookup: name -> ID
map<string,int> typeID;
typedef map<string,int>::iterator typeIDIterator;

// type object lookup: ID -> (object,basetype)
map<int,Type > typeObj;
typedef map<int,Type >::iterator typeObjIterator;

// a type id is present if it is boolean
set<int> boolSet;

// type size lookup: type ID -> number of parameters (function domains)
map<int,int > numParams;
//typedef map<int,int >::iterator numParamsIterator;

// type size lookup: type ID -> tuple size (or function range size, if tuple)
map<int,int > tupleSize;
//typedef map<int,int >::iterator tupleSizeIterator;

// type lookup: Op ID -> parameter types (function domains)
map<int,pair<int,int> > domRanType;
//typedef map<int,pair<int,int> >::iterator domRanTypeIterator;

// Expression identifier lookup
map<string,int> exprID;
typedef map<string,int>::iterator exprIDIterator;

// Expression field type lookup
map<pair<int,string>,int> fieldType;
typedef map<pair<int,string>,int>::iterator fieldTypeIterator;

// Expression name type lookup
map<string,int> exprNameType;
//typedef map<string,int>::iterator exprNameTypeIterator;

// Expression id type lookup
map<int,int> exprType;
//typedef map<int,int>::iterator exprTypeIterator;

// Expression Object lookup
map<int,Expr > exprObj;
//typedef map<int,Expr >::iterator exprObjIterator;

// Function opcode indexer
map<string,int > funcOpID;
//typedef map<string,int >::iterator funcOpIDIterator;

// Function Opcode Object Indexer (for building): ID -> (obj,#params)
map<int,pair<Op,int> > funcOpObj;
typedef map<int,pair<Op,int> >::iterator funcOpObjIterator;

// Function Application Lookup (with parameter listing)
map<pair<int,vector<int> >,int> funcAppID;
typedef map<pair<int,vector<int> >,int>::iterator funcAppIDIterator;


// Predicate Application Lookup
// Contains both Opcode created and Equalities
// Contains both Positive and Negative (Complement)
map<int,pair<Expr,Expr> > predicateList;
typedef map<int,pair<Expr,Expr> >::iterator predicateListIterator;

// Expr to ID lookup for returning inconsistent set
hash_map<unsigned int,int> predIndex;
typedef hash_map<unsigned int,int>::iterator predIndexIterator;

///////////////////////////////////////////////////////////////////////////
// Timing
///////////////////////////////////////////////////////////////////////////
//
// These functions are for timing how long the theory takes.
// This only accounts for this side of the API.
//   Theory.ml, Theory.mli and OCAML callings is not timed.
// This does include all calls to CVC.
//

// Microseconds taken.
long microseconds = 0;

// Seconds taken.
long seconds = 0;

#ifdef CVC_API_TIMER

#ifdef CVC_API_TIMER_DEBUG
// Checker for timer mismatches
bool timerrunning = FALSE;
#endif

struct timeval tv_b;

//************************************************************************
// The start of each function.
//
// Substract the current time from the timings.
inline void startClock( )
{

#ifdef CVC_API_TIMER_DEBUG
  if ( timerrunning )
  {
    cerr << "CVCI: Timer Mismatch Error! [startClock]\n";
    cerr.flush( );
  }
  timerrunning = TRUE;
#endif

  gettimeofday( &tv_b, NULL );
}

//************************************************************************
// The stop of each function.
//
// Add the current time from the timings.
inline void stopClock( )
{
  struct timeval tv;
  gettimeofday( &tv, NULL );

#ifdef CVC_API_TIMER_DEBUG
  if ( !timerrunning )
  {
    cerr << "CVCI: Timer Mismatch Error! [stopClock]\n";
    cerr.flush( );
  }
  timerrunning = FALSE;
  printf ("%i\n%i\n",seconds,microseconds);
#endif

  microseconds += tv.tv_usec - tv_b.tv_usec;
  seconds += tv.tv_sec - tv_b.tv_sec;

  if ( microseconds >= 1000000 )
  {
    seconds += microseconds / 1000000;
    microseconds = microseconds % 1000000;
  }
  while ( microseconds < 0 )
  {
    microseconds += 1000000;
    seconds -= 1;
  }
}
#endif


//************************************************************************
// int cvcSeconds(); int cvcMicroseconds();
// retrieve total time spent in theory
extern "C" value cvcSeconds()
{
  return (Val_int(seconds));
}
extern "C" value cvcMicroseconds()
{
  return (Val_int(microseconds));
}


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

///////////////////////////////////////////////////////////////////////////
// Local Functions
///////////////////////////////////////////////////////////////////////////

//************************************************************************
// safely removes all global objects
void cleanup()
{
/*
// Static variables for cross-interface iterator.
vector<Expr> inconsistency;
vector<Expr>::const_iterator inconIterator;

// Single type for all uninterpreted variables.
Type UninterpretedType;

Type realType;
Type intType;
Type boolType;


map<string,int> typeID;
typedef map<string,int>::iterator typeIDIterator;

// type object lookup: ID -> (object,basetype)
map<int,Type > typeObj;
typedef map<int,Type >::iterator typeObjIterator;

// a type id is present if it is boolean
set<int> boolSet;

// type size lookup: type ID -> number of parameters (function domains)
map<int,int > numParams;
//typedef map<int,int >::iterator numParamsIterator;

// type size lookup: type ID -> tuple size (or function range size, if tuple)
map<int,int > tupleSize;
//typedef map<int,int >::iterator tupleSizeIterator;

// type lookup: Op ID -> parameter types (function domains)
map<int,pair<int,int> > domRanType;
//typedef map<int,pair<int,int> >::iterator domRanTypeIterator;

// Expression identifier lookup
map<string,int> exprID;
typedef map<string,int>::iterator exprIDIterator;

// Expression field type lookup
map<pair<int,string>,int> fieldType;
typedef map<pair<int,string>,int>::iterator fieldTypeIterator;

// Expression name type lookup
map<string,int> exprNameType;
//typedef map<string,int>::iterator exprNameTypeIterator;

// Expression id type lookup
map<int,int> exprType;
//typedef map<int,int>::iterator exprTypeIterator;

// Expression Object lookup
map<int,Expr > exprObj;
//typedef map<int,Expr >::iterator exprObjIterator;

// Function opcode indexer
map<string,int > funcOpID;
//typedef map<string,int >::iterator funcOpIDIterator;

// Function Opcode Object Indexer (for building): ID -> (obj,#params)
map<int,pair<Op,int> > funcOpObj;
typedef map<int,pair<Op,int> >::iterator funcOpObjIterator;

// Function Application Lookup (with parameter listing)
map<pair<int,vector<int> >,int> funcAppID;
typedef map<pair<int,vector<int> >,int>::iterator funcAppIDIterator;


// Predicate Application Lookup
// Contains both Opcode created and Equalities
// Contains both Positive and Negative (Complement)
map<int,pair<Expr,Expr> > predicateList;
typedef map<int,pair<Expr,Expr> >::iterator predicateListIterator;

// Expr to ID lookup for returning inconsistent set
hash_map<unsigned int,int> predIndex;
typedef hash_map<unsigned int,int>::iterator predIndexIterator;


delete vc;
vc = NULL;  // CVC Instance
*/
}


//************************************************************************
// Forward Lookup of an Expression for Assert / Query / etc...
//
// This function takes in a predicate identifier from DPLLT and matches it to
//   the prebuilt expression for passing to CVCLite.
// Positive identifiers will return the corresponding expression.
// Negative identifiers will return the pregenerated negation of the expression.
// If neither is found, the system will abort.
//
Expr& lookupExpr( int identifier )
{
#ifdef CVC_API_DEBUG
  cout << "CVCI: lookupExpr "<<identifier<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


  if ( ID_IS_POSITIVE(identifier) )
  {
      return (predicateList[identifier].first);
  }
  else if ( ID_IS_NEGATIVE(identifier) )
  {
      identifier = NEG_ID(identifier);
      return (predicateList[identifier].second);
  } 
  else //if (identifier <= 0) 
  {
    cerr << "CVCI: Cannot lookup identifier : " << identifier <<
	  ", index size is : " << predicateList.size( ) << endl;
    exit( 1 );
  }
}

//************************************************************************
// CVCLite matches each expression to a unique identifier however these
//   identifiers are generated by CVC.  Because we generate our own identifiers
//   for use with the DPLLT engine, we must perform a translation from CVC to
//   DPLLT.  This is only used during the translation of an inconsistency set.
//
//   Note: A hashtable is used for the mappings for the greatest efficiency.
//
//  The function will get the unique identifier, if it is found already in the
//     hashtable it will abort on a major error (non-unique identifiers).
//     Otherwise it will place the entry of the hashtable to the corresponding
//     DPLLT predicate identifier.
//
void addToIndex( Expr e, int id )
{
#ifdef CVC_API_DEBUG
  cout << "CVCI: addToIndex "<<id<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  int index = e.getIndex( );

  // mark this literal as "special"
#ifdef NEWCVCL
#ifdef REGISTER_PRED
  // we never want to report true...
  if (ID_IS_POSITIVE(id) && id!=trueID) 
  {
#ifdef CVC_OUTPUT
  cout << "vc->registerAtom(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->registerAtom(e);
  }
#endif
#endif

#ifdef CVC_API_DEBUG
  if ( predIndex.find( index ) != predIndex.end( ) )
  {
    cerr << "CVCI: Duplicate unique identifier ( "
         << index << " ) found for expr: " << endl;
    vc->printExpr( e );
    exit( 1 );
  }
#endif
  predIndex[index] = id;
}

//************************************************************************
// Find index does the lookups of the procedure described above.
//
// It takes a CVC Generated Object from the expression and locates it
//   in the table.  If it is not in the table then a abort occurs.
//
int findIndex( Expr e )
{
#ifdef CVC_API_DEBUG
  cout << "CVCI: findIndex entered\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  int index = e.getIndex( );
  predIndexIterator i = predIndex.find( index );
  if ( i == predIndex.end( ) )
  {
    cerr << "CVCI: Unique Identifier ( " << index <<
	    " ) not found for: " << endl;
    vc->printExpr( e );
    exit(1);
  }
  return i->second;
}

//************************************************************************
// do a lookup on the type object, get the id
int typeIDFromObj (Type t)
{
  for( typeObjIterator j = typeObj.begin( ); j != typeObj.end( ); j++ )
  {
    if ( j->second == t )
    {
      return j->first;
    }
  }
  cout << "Cannot find type object identifier" <<endl;
  exit(1);
}


//************************************************************************
// isBoolean checks to see if a type is boolean or not
// this should also consider X->BOOL functions as boolean
bool isBoolean (int tid)
{
	return (boolSet.find(tid) != boolSet.end());
}

/********************************************************************/
// cvcIsDeclaredExpr checks to see if an identifier has been declared
// to the theory or not.
extern "C" value cvcIsDeclaredExpr( value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  bool is_declared;
  string identifier = String_val(n_val);

#ifdef CVC_API_DEBUG
  cout << "CVCI:IsDeclaredExpr (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  // check that parameters exist
  if ( exprID.find( identifier ) == exprID.end( ))
  {
    is_declared = false;
  }
  else
  {
	is_declared = true;
  }

#ifdef CVC_API_DEBUG
  cout << is_declared << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif
  return Val_bool (is_declared);
}


//************************************************************************
// returns the type ID of an expression (ID)
extern "C" value cvcGetExprTypeID(value ival)
{

  int id = Int_val(ival);
#ifdef CVC_API_DEBUG
  cout << "cvcGetExprTypeID " <<id <<endl;
#endif

  Expr e = exprObj[id];

  Type t = vc->getType(e);

  int rid = typeIDFromObj(t);

#ifdef CVC_API_DEBUG
  cout << "cvcGetExprTypeID " <<id <<":"<<rid<<" done" <<endl;
#endif

  return(Val_int(rid));
}

//************************************************************************
extern "C" value cvcGetExprBaseTypeID(value ival)
{

  int id = Int_val(ival);
#ifdef CVC_API_DEBUG
  cout << "cvcGetExprBaseTypeID " <<id <<endl;
#endif

  Expr e = exprObj[id];

  Type t = vc->getBaseType(e);

  int rid = typeIDFromObj(t);

#ifdef CVC_API_DEBUG
  cout << "cvcGetExprBaseTypeID " <<id <<":"<<rid<<" done" <<endl;
#endif

  return(Val_int(rid));
}

//************************************************************************
extern "C" value cvcGetTypeBaseTypeID(value ival)
{

  int id = Int_val(ival);
#ifdef CVC_API_DEBUG
  cout << "cvcGetTypeBaseTypeID " <<id <<endl;
#endif 

  Type t1 = typeObj[id];

  Type t = vc->getBaseType(t1);

  int rid = typeIDFromObj(t);

#ifdef CVC_API_DEBUG
  cout << "cvcGetTypeBaseTypeID " <<id <<":"<<rid<<" done" <<endl;
#endif

  return(Val_int(rid));
}

//************************************************************************
// exprIsBoolean checks whether an expression is boolean or not
// this checks the expression ID number against its true type (unlike above)
extern "C" value cvcExprIsBoolean(value ival)
{
	return (Val_bool (exprType[Int_val(ival)] == boolID));
}
//************************************************************************
// exprIsReal checks whether an expression is real or not
// this checks the expression ID number against its true type (unlike above)
extern "C" value cvcExprIsReal(value ival)
{
	return (Val_bool (exprType[Int_val(ival)] == realID));
}
//************************************************************************
// exprIsInteger checks whether an expression is integer or not
// this checks the expression ID number against its true type (unlike above)
extern "C" value cvcExprIsInteger(value ival)
{
	return (Val_bool (exprType[Int_val(ival)] == intID));
}


//************************************************************************
int cvcGetImplicants(int litin, int *reasons)
{
#ifdef CVC_API_TIMER
    startClock( );
#endif
                              
  int lit = NEG_ID(litin);
                                                  
  int num = 0;

#ifdef CVC_OUTPUT
  cout << "vc->stackLevel();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  int layer = vc -> stackLevel();

#ifdef CVC_API_DEBUG
  cout << "CVCI:GetImplicants (" << lit <<" @ level "<< layer <<"): ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  predicateListIterator pli;
  pli = predicateList.find(lit);

  // if not found, just return 0
  if (pli != predicateList.end())
  {
#ifdef CVC_API_DEBUG
  cout << "! ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "vc->push();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->push();
#ifdef CVC_OUTPUT
  cout << "vc->query(id"<<lit<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    bool qval = vc->query(lookupExpr(lit));
    if (!qval) {
#ifdef CVC_API_DEBUG
      cout << "ERROR! "<<lookupExpr(lit)<<"("<< lit <<") is not valid!\n";
#endif
      vc->popto(layer);
      vc->push();
      qval = vc->query(lookupExpr(NEG_ID(lit)));
      if (!qval) {
        cout << "ERROR! "<<lookupExpr(NEG_ID(lit))<<"("<< NEG_ID(lit) <<") is not valid!\n";
      }
      #ifndef GCC4
  cout.flush();
  #endif;
    }
#ifdef CVC_API_DEBUG
  cout << qval <<" queried! ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "vc->getAssumptions(inconsistency);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->getAssumptions(inconsistency);
    inconIterator = inconsistency.begin( );
    num = (unsigned int)inconsistency.size();
#ifdef CVC_API_DEBUG
  cout << num <<" in assumptions! ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    for (int i = 0; i < num; i++) {
      reasons [i] = (unsigned int)findIndex(inconsistency[i]);
#ifdef CVC_API_DEBUG
  cout << "a"<<i<<"="<<reasons[i]<<" ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    }
#ifdef CVC_OUTPUT
  cout << "vc->popto("<<layer<<");"<<endl;
  cout << "inconsistency.clear();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->popto(layer);
  }
  inconsistency.clear();
                                                                                
#ifdef CVC_API_DEBUG
  cout << " GetImp done!" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
    stopClock( );
#endif
                     
  return num;                                                           
}

//************************************************************************
// baseDefintions - basic definitions that are assumed to be present
// these may need to be reinstated if cleanParsing is called
void baseDefinitions()
{

#ifdef CVC_API_DEBUG
  cout << "CVCI: baseDefinitions being added\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  typeID["INT"] = intID;
  typeObj[intID] = intType;
  typeID["REAL"] = realID;
  typeObj[realID] = realType;
  typeID["BOOLEAN"] = boolID;
  typeObj[boolID] = boolType;
  boolSet.insert(boolID);

  exprID["TRUE"] = trueID;
  exprNameType["TRUE"] = exprType[trueID] = boolID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<trueID<<"=vc->trueExpr();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  exprObj[trueID] =  vc->trueExpr();
  exprID["FALSE"] = trueID;
  exprNameType["FALSE"] = exprType[NEG_ID(trueID)] = boolID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(trueID)<<"=vc->notExpr(vc->trueExpr());"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  exprObj[NEG_ID(trueID)] = vc->notExpr(vc->trueExpr()); //vc->falseExpr();

  addToIndex(exprObj[trueID],trueID);
  addToIndex(exprObj[NEG_ID(trueID)],NEG_ID(trueID));
  predicateList[trueID] = make_pair( exprObj[trueID], exprObj[NEG_ID(trueID)] );

#ifdef CVC_API_DEBUG
  cout << "CVCI: TYPE INT="<<intID<<endl;
  cout << "CVCI: TYPE REAL="<<realID<<endl;
  cout << "CVCI: TYPE BOOLEAN="<<boolID<<endl;
  cout << "CVCI: Expr TRUE="<<trueID<<endl;
  cout << "CVCI: Expr FALSE="<<NEG_ID(trueID)<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


  exprID["()"] = infinityID;
  exprNameType["()"] = exprType[infinityID] = intID;

#ifdef CVC_API_DEBUG
  cout << "CVCI: baseDefinitions finished being added\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
}

//************************************************************************
// Create and initialize the environment.
//
// This function creates an instance of the CVCLite engine as
// several basic definitions.
//
extern "C" void cvcInitialize( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif
#ifdef CVC_OUTPUT
  cout << "/*************/"<<endl;
  cout << "vector<Expr> inconsistency;"<<endl;
  cout << "/*************/"<<endl;
  cout << "CLFlags flags = ValidityChecker::createFlags();"<<endl;
#endif
  CLFlags flags = ValidityChecker::createFlags();
//to make this compatable with the earlier version, comment out all flags!
/*
#ifdef NEWCVCL
#ifdef CVC_OUTPUT
  cout << "flags.setFlag(\"track-literals\",true);"<<endl;
#endif
  flags.setFlag("track-literals",true);
#endif
*/
#ifdef VALGRIND
  flags.setFlag("dump-trace","vctrace.txt");
  flags.setFlag("dump-log","vclog.txt");
  flags.setFlag("mm","malloc");
#endif
#ifdef CVC_OUTPUT
  cout << "ValidityChecker* vc = ValidityChecker::create(flags);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  vc = ValidityChecker::create(flags);

#ifdef CVC_API_DEBUG
  cout << "CVCI: cvcInitialize: ValidityChecker flags...\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

//  CLFlags flags = ValidityChecker::createFlags();
//  flags.setFlag("track-literals",true);
//  vc = ValidityChecker::create(flags);

//  vc = ValidityChecker::create( );

  inconsistency.clear( );

#ifdef CVC_API_DEBUG
  cout << "CVCI: ValidityChecker created!\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "Type id"<< realID<<" = vc->realType();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  realType = vc->realType();
#ifdef CVC_API_DEBUG
  cout << "CVCI: REAL type id defined\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "Type id"<< intID<<" = vc->intType();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  intType = vc->intType();
#ifdef CVC_API_DEBUG
  cout << "CVCI: INT type id defined\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "Type id"<< boolID<<" = vc->boolType();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  boolType = vc->boolType();
#ifdef CVC_API_DEBUG
  cout << "CVCI: BOOLEAN type id defined\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  cout << "CVCI: base interpreted type ids defined\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_OUTPUT
  cout << "vc->push();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  vc -> push();
#ifdef CVC_OUTPUT
  cout << "vc->stackLevel();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  initial_layer = vc -> stackLevel();
//  initial_layer = 1;

  baseDefinitions();


#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// Cleanup after the parser.
//
// After this function we can assume that no declarations, prototypes, etc..
//   will be used and the corresponding data for them can be destroyed.
//
// This is done in an effort to speed up the switching time of the program.
// Possibly not a valid assumption given the quantification instantiation.
//
extern "C" void cvcCleanParsing( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif
#ifdef CVC_API_DEBUG
  cout << "CVCI: cvcCleanParsing"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  typeID.clear( );
  typeObj.clear( );
  boolSet.clear( );
  exprID.clear( );
  fieldType.clear( );
  exprNameType.clear();
  exprType.clear();
  funcOpID.clear( );
  funcAppID.clear( );
  funcOpObj.clear( );
  exprObj.clear( );
  numParams.clear();
  domRanType.clear();
  tupleSize.clear();
  predicateList.clear( );
  predIndex.clear( );

  //redefine base type/constant definitions
  //baseDefinitions();

#ifdef CVC_API_DEBUG
  cout << "CVCI: Parsing cleanup occured!\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// Reset the environment to its initial state.
//
// Eventually will...
// Delete the CVCLite engine instance and nullify its pointer.
// Call a cleanup of parsing (in case it has not been done).
// Reset the inconsistency iterator.
// Delete the entire predicate App table.
// Reset the identifier counters.
extern "C" void cvcCleanup( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

#ifdef CVC_OUTPUT
  cout << "delete vc;"<<endl;
  cout << "vc = NULL;"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  delete vc; // COMMENT THIS LINE TO REGRESS
  vc = NULL; // COMMENT THIS LINE TO REGRESS

#ifdef CVC_API_DEBUG
  cout << "ValidityChecker destroyed!\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  cvcCleanParsing( );
  inconsistency.clear( );
  // UNCOMMENT THE FOLLOWING 4 LINES TO REGRESS
//  definitions = DEFINITION_COUNTER;
//  vc->popto(initial_layer);
//  vc->push();
//  baseDefinitions();
  cvcInitialize(); // COMMENT THIS LINE TO REGRESS

#ifdef CVC_API_DEBUG
  cout << "CVCI: Finished resetting system\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


#ifdef CVC_API_TIMER
  stopClock( );
/*
  // round to nearest 1/100 sec
  microseconds = microseconds / 100000;
 
  cout << "Total time spent in theory is " << seconds << ".";
  if (microseconds >= 100)
    cout << microseconds ;
  else if ( microseconds >= 10 )
    cout << "0" << microseconds ;
  else
    cout << "00" << microseconds ;
  cout << " seconds." << endl;
*/
#endif

}

//************************************************************************
// int nextFreeIdentifier ();
// returns an identifier that is not used elsewhere
extern "C" value cvcNextFreeIdentifier()
{

  unsigned int return_val = (unsigned int)NEXT_DEFINITION_ID;

#ifdef CVC_API_DEBUG
  cout << "CVCI: NextFreeIdentifier: "<< return_val <<"\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if (return_val > MAX_ID) {
    cout << "Exhausted potential IDs\nAborting.\n";
    exit(1);
  }
  return (Val_int (return_val));
}

//************************************************************************
// void cvcAssert( int );
// Assert the predicate in the current CVC context.
//
// Lookup the expression and assert it in the CVC engine.
//
extern "C" void cvcAssert( value pvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  int pid = Int_val (pvalue);

#ifdef CVC_API_DEBUG
  cout << "CVCI::Assert " << pid
<< " at layer " << vc->stackLevel() <<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  Expr tmp = lookupExpr(pid);

#ifdef CVC_API_DEBUG
  cout << " Expr found " << tmp << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_OUTPUT
  cout << "vc->assertFormula(id"<<pid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  vc->assertFormula( tmp );

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// bool cvcQuery( int );
// Query the predicate in the current CVC context.
//
// Lookup the expression and query it in the CVC engine.
//
extern "C" value cvcQuery( value pvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id = Int_val (pvalue);

#ifdef CVC_API_DEBUG
  cout << "CVCI:Query " << id<<endl;
  cout << "CVCI:Query lookupExpr( "<<id<<" ) "<<lookupExpr( id )<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_OUTPUT
  cout << "vc->query(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  bool rvalue = vc->query( lookupExpr( id ) );


#ifdef CVC_API_DEBUG
  if (rvalue) {
	  cout << " = true" << endl;
  } else {
	  cout << " = false" << endl;
  }
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_bool (rvalue);
}

//************************************************************************
// void cvcPush( )
// Push the context of the CVC context stack.
//
extern "C" void cvcPush( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

#ifdef CVC_API_DEBUG
  cout << "CVCI:Push" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_OUTPUT
  cout << "vc->push();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  vc->push( );

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// void cvcPop( int )
//
// Pop to a given context in the CVC context stack.
// NO NOT CALL IF WE ARE BACKTRACKING TO THE SAME LEVEL!
//
extern "C" void cvcPopTo( value lvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

#ifdef CVC_API_DEBUG
  cout << "CVCI:PopTo " << Int_val( lvalue ) <<"+"<< initial_layer;
  cout << " from layer " << vc -> stackLevel() << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  int layer = Int_val( lvalue );
#ifdef CVC_API_DEBUG
  if ( layer < 0 )
  {
    cerr << "CVCI:PopTo pops to invalid layer! (" << layer << ")\n";
    exit( 1 );
  }
#endif
#ifdef CVC_OUTPUT
  cout << "vc->stackLevel();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  if (layer +initial_layer < vc->stackLevel()) {
#ifdef CVC_OUTPUT
  cout << "vc->popto("<<layer+initial_layer<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->popto( layer + initial_layer); 
    //remember -- we have the "initial" layer as 1
  }

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// void cvcStartInconsistency( void )
//
// Initialize the iterator for returning an inconsistency set.
// An iterator is used rather than allocating a list, registering it with OCAML
//   garbage collection, and having to deal with the structure of C to OCAML
//   type translations.
//
extern "C" void cvcStartInconsistency( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

#ifdef CVC_API_DEBUG
  cout << "CVCI:StartInconsistency\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  inconsistency.clear( );
//  vc->inconsistent( inconsistency );
#ifdef CVC_OUTPUT
  cout << "inconsistency.clear( );"<<endl;
  cout << "vc->getAssumptions(inconsistency);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  vc->getAssumptions( inconsistency );
  inconIterator = inconsistency.begin( );

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

//************************************************************************
// void cvcCollectInconsistency( void )
//
// Get the next inconsistent predicate in the set.
// Note: When the iterator becomes empty, it will return a value of 0.
//
// See cvcStartInconsistency for details of iterator reasoning.
//
extern "C" value cvcCollectInconsistency( )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

#ifdef CVC_API_DEBUG
  cout << "CVCI:CollectInconsistency entered\n";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if ( inconIterator == inconsistency.end( ) )
  {

#ifdef CVC_API_TIMER
    stopClock( );
#endif

    return Val_int( 0 );
  }
  else
  {
#ifdef CVC_API_DEBUG
  if (inconsistency.empty())
  {
    cout << "Empty inconsistency!"<<endl;
    #ifndef GCC4
  cout.flush();
  #endif;
  }
#endif

    int index = findIndex (*inconIterator);

#ifdef CVC_API_DEBUG
  cout << "CVCI:CollectInconsistency about to retrieve..." << index << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

    value rvalue = Val_int( abs( index ) );
    inconIterator++;

#ifdef CVC_API_TIMER
    stopClock( );
#endif

    return rvalue;
  }
}

//************************************************************************
// int cvcDeclareVariable( string name , int typeID )
//
// Generate the ID for a variable.
//
// Find if the identifier has been previously declared.
//   If so, then return it's past id value.
// If not, check to make sure that it isn't another type.
// If not, then go ahead and create it and add it to the list.
//
extern "C" value cvcDeclareVariable( value ivalue, value tvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( ivalue );
  int tid = Int_val (tvalue);
  int id;

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclareVariable (" << identifier << " type:"<< tid <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // Check if defined as function
  if ( exprNameType.find( identifier ) != exprNameType.end( ) &&
       exprNameType[identifier] != tid )
  {
    cerr << "identifier already assigned as something else! " << endl;
    cerr << identifier << endl;
    exit( 1 );
  }
#endif
//**********************************
  // Check it exists.  If not then create new.
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->varExpr(\""<<identifier<<"\",id"<<tid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = VCSIMPLIFY(vc->varExpr( identifier, typeObj[tid] ));
    exprID[identifier] = id;
    exprType[id] = tid;
    exprNameType[identifier] = tid;
    exprObj[id] = variable;

	// note all boolean variables
    if (isBoolean(tid)) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->varExpr(\""<<identifier<<"\",id"<<tid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
		Expr notvariable = VCSIMPLIFY(vc->notExpr( variable ));
        exprType[NEG_ID(id)] = boolID;
		addToIndex(variable,id);
		addToIndex(notvariable,NEG_ID(id));
	    predicateList[id] = make_pair( variable, notvariable );
	}
  }
  // If exists, send previous id.
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( id );
}

//************************************************************************
// int cvcDeclareNumeralConstant( string )
//
// Generate the ID for a string-form rational numeral.
// Relies on cvcl's internal string-to-rational conversion
//
// Check to see if that constant has already been declared.
// Create the new constant and return.
//
extern "C" value cvcDeclareNumeralConstant( value ivalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( ivalue );
  string key = "("+identifier+")";
  int id;

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclareNumeralConstant (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


  // Check to see if string is already in database.
  if ( exprID.find( key ) == exprID.end( ) )
  {
    // Create New
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->ratExpr("<<identifier<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr constant = vc->ratExpr( identifier );
    exprID[key] = id;
    exprType[id] = realID;
    exprObj[id] = constant;
  }
  else
    id = exprID[key];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( id );
}

//************************************************************************
// Create Operator
//
// Local function to create function prototype.
//
// Identifier is a string representing the function name.
// ftype is the function's type
//
Op makeOp( string identifier, int ftype )
{
  { // Create the opcode.
    exprNameType[identifier] = ftype;
    Op myop = vc->createOp( identifier, typeObj[ftype] );
    return myop;
  }
}

//************************************************************************
// int cvcDeclareFunction( string, int ).
//
// Declare a function and pass back its UID.
//
// fvalue as string is function name.
// pvalue as int is type ID
//
// Check to make sure that the identifier isn't already declared elsewhere.
// If not already declared, then declare (create Op and register).
// If already declared, verify that there is no type mismatch.
//
// Note the range and domain types for later (crude) internal type-checking
//
extern "C" value cvcDeclareFunction( value fvalue, value tvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( fvalue );
  int type_id = Int_val(tvalue);
  int id;


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvcDeclareFunction : " << identifier << "( " << type_id
       << " ) = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

//  Check identifier use as some other type.
//  if ( exprID.find( identifier ) != exprID.end( ) )
//  {
//    cerr << "identifier already assigned as something else! "
//	 << endl << identifier << endl;
//    exit( 1 );
//  }


  // Check existence of identifier - If not, then create.
  if ( funcOpID.find( identifier ) == funcOpID.end( ) )
  {

    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Op id"<<id<<"=vc->createOp(\""<<identifier<<"\",id"<<type_id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Op op = makeOp( identifier, type_id );
    funcOpID[identifier] = id;
    exprID[identifier] = id;
    exprType[id] = type_id;
    funcOpObj.insert(make_pair(id,make_pair(op,numParams[type_id])));

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
    stopClock( );
#endif

    return Val_int( id );
  }

#ifdef CVC_API_DEBUG
    cout << endl;
      #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  // If parameters same, then pass back already registered version.
  return Val_int( funcOpID[identifier] );
}


//************************************************************************
// void VectorVal (vector<int> & vlist, val olist)
// Converts an OCAML array of strings to C++ vector<int>
void VectorVal (vector<int>& vlist, value olist)
{
  int length = Wosize_val (olist);
  for (int index = 0; index < length; index++)
  {
    vlist.push_back (Int_val (Field(olist,index)));
  }
}

//************************************************************************
// void VectorVal (vector<istring> & vlist, val olist)
// Converts an OCAML array of ints to C++ vector<string>
void VectorVal (vector<string>& vlist, value olist)
{
  int length = Wosize_val (olist);
  for (int index = 0; index < length; index++)
  {
    vlist.push_back (String_val (Field(olist,index)));
  }
}

//************************************************************************
// void ObjVectorVal (vector<Expr> & vlist, val olist)
// Converts an OCAML array of int ids to C++ vector<Expr>
void VectorVal (vector<Expr>& vlist, value olist)
{
  int length = Wosize_val (olist);
  for (int index = 0; index < length; index++)
  {
    vlist.push_back (exprObj[Int_val (Field(olist,index))]);
  }
}

//************************************************************************
// string format of a vector of ints
string VecToString (vector<int>& vlist)
{
  int length = vlist.size();
  stringstream s;
  s << "" <<  vlist[0];
  for (int i = 1; i < length; i++) {
    s << "," << vlist[i];
  }
  return s.str();
}

//************************************************************************
// string format of a vector of strings
string VecToString (vector<string>& vlist)
{
  int length = vlist.size();
  stringstream s;
  s << "" <<  vlist[0];
  for (int i = 1; i < length; i++) {
    s << "," << vlist[i];
  }
  return s.str();
}

//************************************************************************
// lookupTypeID - returns a (possibly new) type id, given a Type
//                if this is a new type, it also associates it with its id
int lookupTypeID(Type t)
{
  for( typeObjIterator j = typeObj.begin( ); j != typeObj.end( ); j++ )
  {
    if ( j->second == t )
    {
      return (j->first);
    }
  }
                                                                                
  int tid = (NEXT_DEFINITION_ID);
  typeObj[tid] = t;
                                                                                
  return tid;
}
                                                                                

/********************************************************************/
// create a tuple with values v_vals
// v_vals: <int>vector = list f field values (ordered)
extern "C" value cvcTupleLiteral( value v_vals )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  vector<Expr> vals;
  vector<int> vids;
  VectorVal(vals,v_vals);
  VectorVal(vids,v_vals);
  string identifier = "(,"+VecToString(vids)+",)";

#ifdef CVC_API_DEBUG
  cout << "CVCI:TupleLiteral (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "inconsistency.clear();"<<endl;
  int length = Wosize_val (v_vals);
  for (int index = 0; index < length; index++)
  {
    cout << "inconsistency.push_back(id" << Int_val (Field(v_vals,index))<<");\n";
  }
  cout << "Expr id"<<id<<"=vc->tupleExpr(inconsistency);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr tup = vc->tupleExpr(vals);
    exprID[identifier] = id;
#ifdef CVC_OUTPUT
  cout << "vc->getType(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type mytype = vc->getType(tup);
    exprType[id] = lookupTypeID(mytype);
    exprObj[id] = tup;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

//************************************************************************
// int cvcApplyFunction( int, int array )
//
// Apply a function prototype with a list of
//   parameters to create a function expression.
//
// fvalue as int is predeclared function prototype (Op)
//     fvalue is created via cvcDeclareFunction
// nvalue as OCAML int array is list of parameters.
//     nvalue is created via cvcApplyFunction or one of the variable
//     declaration functions
//
// Verifies correct Op
// Verifies list of parameters
// Verifies Op number of parameters with parameter list length.
// Does crude type-checking, outputting a warning if it detects a possible
// mismatch.  CVCL does not handle type mismatches gracefully and generates
// segmentation faults (eventually -- generally when the mismatch is used
// later)
//
// Checks to see if Op and Parameter list has already been used.
// Constructs new expression based on Op and Parameters and registers.
//
// We are currently only dealing with functions of type X->Y (where X,Y may
// be tuples).  (CVCL now explicitly supports functions fo type a,b,c->d.)
extern "C" value cvcApplyFunction( value fvalue, value nvalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  int id = Int_val( fvalue );
  vector<int> vlist;
  VectorVal( vlist, nvalue );

  vector<int> paramTypeList;

#ifdef CVC_API_DEBUG
  cout << "CVCI:cvcApplyFunction (" << id << ":list[" << vlist.size( ) << "]{ ";

  for( vector<int>::iterator j = vlist.begin( ); j != vlist.end( ); j++ )
  {
    cout << *j << " , " ;
  }
  cout << "} = ";
#endif


  funcOpObjIterator i = funcOpObj.find( id );

#ifdef CVC_API_DEBUG
  // Check operator existence
  if ( i == funcOpObj.end( ) )
  {
    cerr << "CVCI::ApplyFunction Identifier not declared: " << id << endl;
    exit( 1 );
  }

  // Check number of parameters
  if ( (i->second).second != vlist.size( ) )
  {
    cerr << "CVCI::ApplyFunction -  Wrong number of parameters for function #: " << id << endl;
    exit( 1 );
  }
#endif

  vector<Expr> params;

  // Check each individual parameter
  for( vector<int>::iterator j = vlist.begin( ); j != vlist.end( ); j++ )
  {
#ifdef CVC_API_DEBUG
    // Make sure each parameter is ok!
    if ( exprObj.find( *j ) == exprObj.end( ) )
    {
      cerr << "CVCI::ApplyFunction Parameter is not an expr: " << *j << endl;

//      cerr.flush( );

      exit( 1 );
    }
#endif
    int pte = exprType[*j];
    if (domRanType.find(pte) != domRanType.end())
    {
      pte = domRanType[pte].second;
    }
    paramTypeList.push_back(pte);

    params.push_back( exprObj[*j] );
  }

#ifdef CVC_SPI_DEBUG
  // check parameter types (may miss function variables)
  if (paramTypeList.size() > 1)
  {
    string paramTypeID = "[" + VecToString(paramTypeList) + "]";
    if (typeID[paramTypeID] != domRanType[exprType[id]].first) {
        cerr << "WARNING: CVCI::ApplyFunction Possible type mismatch in: "<<
          paramTypeID << " expected: " << domRanType[exprType[id]].first << endl;
  for( typeIDIterator j = typeID.begin( ); j != typeID.end( ); j++ )
  {
    if ( j->second == domRanType[exprType[id]].first )
    {
      cerr << "function is " << paramTypeID << ": param is " << (j->first) << endl;
    }
  }

//      cerr.flush( );
    }
  }
  else
  {
    if (paramTypeList[0] != domRanType[exprType[id]].first) {
        cerr << "WARNING: CVCI::ApplyFunction Possible type mismatch in: " <<
          " ["<< paramTypeList[0] << "]" << " expected: " << domRanType[exprType[id]].first << endl;
//      cerr.flush( );
    }
  }
#endif

  // Check to see if Op and Parameters have already been used.
  funcAppIDIterator it = funcAppID.find(make_pair(id,vlist));
  if ( it != funcAppID.end( ) )
  {

#ifdef CVC_API_TIMER
    stopClock( );
#endif
	// found!  return old version
    return Val_int( it->second );
  }

  // Create new
  Expr f;
  int fid = NEXT_DEFINITION_ID;

  if ( params.size( ) > 1 )
  {
    // this could be done more gracefully, 
    // such as by explicitly creating the tuple
    Expr param = exprObj[Int_val(cvcTupleLiteral(nvalue))];
#ifdef CVC_OUTPUT
//HERE
  cout << "Expr id"<<fid<< " = vc->funExpr(id"<<(i->first)<<",id"<<Int_val(cvcTupleLiteral(nvalue))<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    f = VCSIMPLIFY(vc->funExpr( (i->second).first, param ));
  }
  else {
#ifdef CVC_OUTPUT
//HERE
  cout << "Expr id"<<fid<< " = vc->funExpr(id"<<(i->first)<<",id"<<vlist[0]<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    f = vc->funExpr( (i->second).first, params[0] );
  }

  exprObj[fid] = f;
  funcAppID[make_pair(id,vlist)] = fid;
  exprType[fid] = exprType[id];


  // note all boolean functions
  if (isBoolean(exprType[fid])) {
	Expr notf = VCSIMPLIFY(vc->notExpr( f ));
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(fid)<<"=vc->notExpr(id"<<fid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
	addToIndex(f,fid);
	addToIndex(notf,NEG_ID(fid));
    exprType[NEG_ID(fid)] = boolID;
    predicateList[fid] = make_pair( f, notf );
  }

#ifdef CVC_API_DEBUG
  cout << fid << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( fid );
}


//************************************************************************
//************************************************************************
//
// modifications by George Hagen, 6/24/03 or later:
//

//************************************************************************
// bool cvcCheckInconsistency();
// Checks for inconsistency of the current context.
// Returns true if it is inconsistent
extern "C" value cvcCheckInconsistency ( )
{
#ifdef CVC_API_TIMER
    startClock( );
#endif

#ifdef CVC_API_DEBUG
    cout << "CVCI:CheckInconsistency ";
    #ifndef GCC4
  cout.flush();
  #endif;
#endif

    inconsistency.clear( );
#ifdef CVC_OUTPUT
  cout << "inconsistency.clear( );"<<endl;
  cout << "vc->push();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->push();
#ifdef CVC_OUTPUT
  cout << "vc->query(id"<<NEG_ID(trueID)<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    bool falseval = vc->query(exprObj[NEG_ID(trueID)]);
#ifdef CVC_API_DEBUG
    cout << exprObj[NEG_ID(trueID)] << " = " <<falseval << endl;
    #ifndef GCC4
  cout.flush();
  #endif;
#endif
    // inconsistent() is apparently less reliable than checking falseExpr
#ifdef CVC_OUTPUT
  cout << "vc->inconsistent(inconsistency);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    bool rvalue = (vc->inconsistent(inconsistency));
    inconIterator = inconsistency.begin( );
#ifdef CVC_OUTPUT
  cout << "vc->pop();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    vc->pop();

#ifdef CVC_API_DEBUG
    cout << rvalue << endl;
    cout << "CVCI:CheckInconsistency end"<<endl;
    #ifndef GCC4
  cout.flush();
  #endif;
#endif


#ifdef CVC_API_TIMER
    stopClock( );
#endif

    return (Val_bool (falseval));
}

//************************************************************************
//returns 0 if there are no more implied literals
extern "C" value cvcGetImpliedLiteral()
{
#ifdef CVC_API_TIMER
    startClock( );
#endif
  int ret = 0;
#ifdef GETIMPLIED
#ifdef CVC_API_DEBUG
    cout << "cvcGetImpliedLiteral()" << endl;
    #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef NEWCVCL
#ifdef CVC_OUTPUT
  cout << "vc->getImpliedLiteral();"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  Expr impl = vc->getImpliedLiteral();
#endif
#ifdef NEWCVCL
  if (!impl.isNull()) {
//this is currently broken!
//vc->printExpr(impl);
    ret = findIndex (impl);
#ifdef CVC_API_DEBUG
    cout << "cvcGetImpliedLiteral() = "<<ret << endl;
    #ifndef GCC4
  cout.flush();
  #endif;
#endif
  }
#endif
#endif
#ifdef CVC_API_TIMER
    stopClock( );
#endif
  return (Val_int(ret));
}



//************************************************************************
// int cvcDeclareRealVariable( string )
// DEPRECIATED - this function has been replaced by the generic
// cvcDeclareVariable (above)
//
// Declare a real variable.
//
// ivalue as string is name of real variable.
//
// Check if identifier is declared as something else.
// Check to see if identifier is already created.
// Create if not, else return previous.
// returns ID associated with variable.
//
extern "C" value cvcDeclareRealVariable( value ivalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( ivalue );
  int id;

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclareRealVariable (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->varExpr(\""<<identifier<<"\",realType);"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = vc->varExpr( identifier, realType);
    exprID[identifier] = id;
    exprType[id] = realID;
    exprObj[id] = variable;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( id );
}


//************************************************************************
// int cvcDeclareRationalConst( int n, int d)
//
// Declare a rational constant.
//
// n is numerator, d is denominator (may not be 0)
// both are integer values, not identifiers
//
// Check if identifier is declared as something else.
// Check to see if identifier is already created.
// Create if not, else return previous.
// returns ID associated with const.
//
extern "C" value cvcDeclareRationalConst(value nvalue, value dvalue) {
#ifdef CVC_API_TIMER
  startClock( );
#endif

  int n = Int_val( nvalue );
  int d = Int_val( dvalue );

  int id;

  stringstream s;
  s << n << "," << d;
  string identifier = s.str();

  // make sure d != 0
  if (d == 0) {
	  d = 1;
	  cerr << "CVCI: Attempted divide by 0 in cvcDeclareRationalConst" << endl;

//	  cerr.flush( );

  }

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclareRationalConst (" << n << "/" << d << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->ratExpr("<<n<<","<<d<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = vc->ratExpr(n, d);
    exprID[identifier] = id;
    exprType[id] = realID;
    exprObj[id] = variable;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( id );
}


//************************************************************************
// int cvcApplyUnaryMinus(int e)
//
// Applys unary minus to real expression ID e
//
// Returns expression ID for "-e"
//
extern "C" value cvcApplyUnaryMinus(value evalue) {
#ifdef CVC_API_TIMER
  startClock( );
#endif

  int e = Int_val( evalue );

  int id;

  stringstream s;
  s << "-" << e;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:ApplyUnaryMinus (" << e << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
#ifdef CVC_API_DEBUG
	// Verify e is valid real expression.
    if ( exprObj.find( e ) == exprObj.end( ) )
    {
      cerr << "CVCI:ApplyUnaryMinus ID is not expression! : " << e << endl;
      exit( 1 );
    }
#endif

    Expr child = exprObj[e];

    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->uminusExpr(id"<<e<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = vc->uminusExpr(child);
    exprID[identifier] = id;
    exprType[id] = realID;
    exprObj[id] = variable;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

	return Val_int (id);
}

//************************************************************************
// int cvcApplyFloor(int e)
//
// Applys floor to real expression ID e
//
// Returns expression ID for "-e"
//
extern "C" value cvcApplyFloor(value evalue) {
#ifdef CVC_API_TIMER
  startClock( );
#endif

  int e = Int_val( evalue );

  int id;

  stringstream s;
  s << "FLOOR" << e;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:ApplyFloor (" << e << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifndef NEWCVCL
  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
#ifdef CVC_API_DEBUG
	// Verify e is valid real expression.
    if ( exprObj.find( e ) == exprObj.end( ) )
    {
      cerr << "CVCI:ApplyFloor ID is not expression! : " << e << endl;
      exit( 1 );
    }
#endif
    Expr child = exprObj[e];

    id = NEXT_DEFINITION_ID;

#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->floorExpr("<<e<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = vc->floorExpr(child);
    exprID[identifier] = id;
    exprType[id] = realID;
    exprObj[id] = variable;
  }
  // Return previous if exists
  else
    id = exprID[identifier];
#endif

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

	return Val_int (id);
}


//************************************************************************
// int ApplyRealOp(int ileft, int iright, string op)
//
// Applys binary operator: ileft op iright; used in the extern calls below
//
// checks that ileft & iright are both real
// Returns expression ID for "ileft op iright"
//

int ApplyRealOp(int ileft, int iright, char op) {
#ifdef CVC_API_TIMER
  startClock( );
#endif

  int id;

  stringstream s;
  switch (op) {
	  case '+' : s << ileft << "+" << iright; break;
	  case '-' : s << ileft << "-" << iright; break;
	  case '*' : s << ileft << "*" << iright; break;
	  case '^' : s << ileft << "^" << iright; break;
	  case '/' : s << ileft << "/" << iright; break;
	  default: cerr << "CVCI: Invalid op in ApplyRealOp : " << op << endl; exit(1);break;
  }
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:ApplyRealOp (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif


  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {

#ifdef CVC_API_DEBUG
	// Verify ileft is valid real expression.
	if ( exprObj.find( ileft ) == exprObj.end( ) )
	{
		cerr << "CVCI:ApplyRealOp ID is not expression! : " << ileft << endl;
		exit( 1 );
	}
#endif
	Expr left = exprObj[ileft];

#ifdef CVC_API_DEBUG
	// Verify ileft is valid real expression.
	if ( exprObj.find( iright ) == exprObj.end( ) )
	{
		cerr << "CVCI:ApplyRealOp ID is not expression! : " << iright << endl;
		exit( 1 );
	}
#endif
	Expr right = exprObj[iright];

    id = NEXT_DEFINITION_ID;
    Expr variable;
	switch (op) {
	  case '+' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->plusExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     variable = vc->plusExpr(left,right); break;
	  case '-' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->minusExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     variable = vc->minusExpr(left,right); break;
	  case '*' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->multExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     variable = vc->multExpr(left,right); break;
	  case '^' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->powExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     variable = vc->powExpr(left,right); break;
	  case '/' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->divideExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     variable = vc->divideExpr(left,right); break;
	  default: cerr << "CVCI: Invalid op in ApplyRealOp : " << op << endl; exit(1);break;
    }
    exprID[identifier] = id;
    exprType[id] = realID;
    exprObj[id] = variable;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

	return (id);
}

//************************************************************************
// int cvcApplyPlus(int ileft, int iright)
//
// Applys ileft + iright
//
// Returns expression ID for "ileft+iright"
//
extern "C" value cvcApplyPlus(value lvalue, value rvalue) {
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int (ApplyRealOp(ileft,iright,'+'));
}

//************************************************************************
// int cvcApplyMinus(int ileft, int iright)
//
// Applys ileft - iright
//
// Returns expression ID for "ileft-iright"
//
extern "C" value cvcApplyMinus(value lvalue, value rvalue) {
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int (ApplyRealOp(ileft,iright,'-'));
}

//************************************************************************
// int cvcApplyMult(int ileft, int iright)
//
// Applys ileft * iright
//
// Returns expression ID for "ileft*iright"
//
extern "C" value cvcApplyMult(value lvalue, value rvalue) {
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int (ApplyRealOp(ileft,iright,'*'));
}

//************************************************************************
// int cvcApplyPow(int ileft, int iright)
//
// Applys ileft ^ iright
//
// Returns expression ID for "ileft^iright"
//
extern "C" value cvcApplyPow(value lvalue, value rvalue) {
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int (ApplyRealOp(ileft,iright,'^'));
}

//************************************************************************
// int cvcApplyDiv(int ileft, int iright)
//
// Applys ileft / iright
//
// Returns expression ID for "ileft/iright"
//
extern "C" value cvcApplyDiv(value lvalue, value rvalue) {
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int (ApplyRealOp(ileft,iright,'/'));
}


//************************************************************************
// int CreateRelation( int, int, char rel )
//
// Create a relation predicate given two real number expressions.
// ileft R iright
// used in extern functions, below
//
// lvalue as int is left hand side real expression.
// rvalue as int is right hand side real expression.
//     lvalue, rvalue are declared via cvcApply* and cvcDeclare*
//
// Check for already created relation (duplicate).
// Verify left is real expression.
// Verify right is real expression.
// Create relation and return handle.
//
int CreateRelation( int ileft, int iright, char rel)
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  stringstream s;
  switch (rel) {
	  case '=' : s << ileft << "=" << iright; break;   // eq
	  case '>' : s << ileft << ">" << iright; break;   // gt
	  case '<' : s << ileft << "<" << iright; break;   // lt
	  case 'g' : s << ileft << ">=" << iright; break;  // ge
	  case 'l' : s << ileft << "=<" << iright; break;  // le
	  default: cerr << "CVCI: Invalid op in CreateRelation : " << rel << endl; exit(1);break;
  }
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVC:CreateRelation (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // Verify left is valid real expression.
  if ( exprObj.find( ileft ) == exprObj.end( ) )
  {
    cerr << "CVCI:CreateRelation ID is not a declared expression! : " << ileft << endl;
    exit( 1 );
  }
#endif

  Expr left = exprObj[ileft];

#ifdef CVC_API_DEBUG
  // verify right is valid real expression.
  if ( exprObj.find( iright ) == exprObj.end( ) )
  {
    cerr << "CVCI:CreateRelation ID is not a declared expression! : " << iright << endl;
    exit( 1 );
  }
#endif
  Expr right = exprObj[iright];

  // Check function already called (duplicate expressions).
  exprIDIterator i = exprID.find(identifier);
  if ( i != exprID.end( ) )
  {

#ifdef CVC_API_DEBUG
   cout << i->second << endl;
   #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
    stopClock( );
#endif

    return ( i->second );
  }

  // Create new.
  Expr p;
  int pid = NEXT_DEFINITION_ID;

  switch (rel) {
	  case '=' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<pid<<"=vc->eqExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     p = VCSIMPLIFY(vc->eqExpr( left, right )); break;   // eq
	  case '>' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<pid<<"=vc->gtExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     p = VCSIMPLIFY(vc->gtExpr( left, right )); break;   // gt
	  case '<' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<pid<<"=vc->ltExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     p = VCSIMPLIFY(vc->ltExpr( left, right )); break;   // lt
	  case 'g' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<pid<<"=vc->geExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     p = VCSIMPLIFY(vc->geExpr( left, right )); break;   // ge
	  case 'l' : 
#ifdef CVC_OUTPUT
  cout << "Expr id"<<pid<<"=vc->leExpr(id"<<ileft<<",id"<<iright<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
                     p = VCSIMPLIFY(vc->leExpr( left, right )); break;   // le
	  default: cerr << "CVCI: Invalid op in CreateRelation : " << rel << endl; exit(1);break;
  }
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(pid)<<"=vc->notExpr(id"<<pid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  Expr pn = VCSIMPLIFY(vc->notExpr( p ));
  addToIndex( p, pid );
  addToIndex( pn, NEG_ID(pid) );
  predicateList[pid]=( make_pair( p, pn ) );
  exprID[identifier] = pid;
  exprType[pid] = boolID;
  exprType[NEG_ID(pid)] = boolID;



#ifdef CVC_API_DEBUG
    cout << "\""<<p<<"\"" ;
    #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  cout << " ("<<pid<<")" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return (pid);
}


//************************************************************************
// int cvcCreateEquals( int, int )
//
// Create an equals predicate given two real number expressions.
// ileft = iright
//
// Create predicate and return handle.
//
extern "C" value cvcCreateEquals( value lvalue, value rvalue )
{
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );
#ifdef CVC_API_DEBUG
cout<< ileft << "(type " << exprType[ileft] << ") = "<<iright << "(type "<< exprType[iright] << ")\n";
#ifndef GCC4
  cout.flush();
  #endif;
#endif
  return Val_int( CreateRelation(ileft, iright, '=') );
}


//************************************************************************
// int cvcCreateLessThan( int, int )
//
// Create an less than predicate given two real number expressions.
// ileft < iright
//
// Create predicate and return handle.
//
extern "C" value cvcCreateLessThan( value lvalue, value rvalue )
{
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int( CreateRelation(ileft, iright, '<') );
}


//************************************************************************
// int cvcCreateGreaterThan( int, int )
//
// Create an greater than predicate given two real number expressions.
// ileft > iright
//
// Create predicate and return handle.
//
extern "C" value cvcCreateGreaterThan( value lvalue, value rvalue )
{
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int( CreateRelation(ileft, iright, '>') );
}

//************************************************************************
// int cvcCreateLessThanOrEquals( int, int )
//
// Create an less or equal to than predicate given two real number expressions.
// ileft =< iright
//
// Create predicate and return handle.
//
extern "C" value cvcCreateLessThanOrEquals( value lvalue, value rvalue )
{
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int( CreateRelation(ileft, iright, 'l') );
}


//************************************************************************
// int cvcCreateGreaterThanOrEquals( int, int )
//
// Create an greater than or equals to predicate given two real number expressions.
// ileft >= iright
//
// Create predicate and return handle.
//
extern "C" value cvcCreateGreaterThanOrEquals( value lvalue, value rvalue )
{
  int ileft = Int_val( lvalue );
  int iright = Int_val( rvalue );

  return Val_int( CreateRelation(ileft, iright, 'g') );
}


/********************************************************************/
/* type functions                                                   */
/********************************************************************/
// value cvcDeclareType (value svalue)
// svalue is the new type's name (string)
// returns type id (int)
// create a new uninterpreted type
extern "C" value cvcDeclareType (value svalue)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( svalue );
  int id;

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclareType (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // Check if defined as function
  if ( funcOpID.find( identifier ) != funcOpID.end( ) ||
       exprID.find(identifier) != exprID.end())
  {
    cerr << "type identifier "<< identifier;
    cerr << " already assigned as something else! " << endl;
    cerr << identifier << endl;
    exit( 1 );
  }
#endif
  // Check it exists.  If not then create new.
  if ( typeID.find( identifier ) == typeID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Type id"<<id<<"=vc->createType(\""<<identifier<<"\");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type t = vc->createType( identifier );
    typeID[identifier] = id;
    typeObj[id] = t;
  }
  // If exists, send previous id.
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int( id );
}

/********************************************************************/
// base type values
// cvcIntType returns the id for interpreted integer type
extern "C" value cvcIntType ()
{
#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_IntType" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  return Val_int( typeID["INT"] );
}

/********************************************************************/
// cvcRealType returns the id for interpreted real type
extern "C" value cvcRealType ()
{
#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_RealType" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  return Val_int( typeID["REAL"] );
}

/********************************************************************/
// cvcBoolType returns the id for interpreted boolean type
extern "C" value cvcBoolType ()
{
#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_BoolType" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  return Val_int( typeID["BOOLEAN"] );
}

/********************************************************************/
// value cvcFunctionType (value domv, value ranv)
// domv is the domain's type id (int)
// iranv is the range's type id (int)
// returns type id (int)
// create a function type
extern "C" value cvcFunctionType ( value domv, value ranv )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int domain = Int_val (domv);
  int range = Int_val (ranv);
  stringstream s;
  s << domain << "->" << range;
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_FunctionType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if ( typeID.find( identifier ) == typeID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_API_DEBUG
    if (typeObj.find(domain) == typeObj.end()
        || typeObj.find(range) == typeObj.end())
    {
      cerr << "CVCI: Unrecognized parameter in decl of function type ";
      cerr << identifier << endl;
      exit(1);
    }
#endif

    // figure out range & domain sizes
    int domain_size = 1;
    int range_size = 1;
    if (tupleSize.find(domain) != tupleSize.end())
    {
      domain_size = tupleSize[domain];
    }
    if (tupleSize.find(range) != tupleSize.end())
    {
      range_size = tupleSize[domain];
    }
#ifdef CVC_OUTPUT
  cout << "Type id"<<id<<"=vc->funType(id"<<domain<<",id"<<range<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type t = vc->funType( typeObj[domain], typeObj[range] );
    typeID[identifier] = id;
    domRanType[id] = make_pair(domain,range);
    numParams[id] = domain_size;
    if (range_size > 1)
    {
      tupleSize[id] = range_size;
    }
    typeObj[id] = t;
    if (isBoolean(range)) {
      boolSet.insert(id);
    }
  }
  // If exists, send previous id.
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// value cvcRecordType (value name_vals, value type_vals)
// name_vals is the ordered list of field names (string list)
// type_vals is the ordered list of field type ids (int list)
// returns type id (int)
// create a record type
extern "C" value cvcRecordType ( value name_vals, value type_vals )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  vector<string> nameids;
  vector<int> typeids;
  int id;

  VectorVal(nameids,name_vals);
  VectorVal(typeids,type_vals);

  string identifier = "[#" + VecToString(nameids) + "#]";


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_RecordType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  vector<Type> types;
  for (vector<int>::iterator i = typeids.begin(); i != typeids.end(); i++)
  {
#ifdef CVC_API_DEBUG
    if ( typeObj.find( *i ) == typeObj.end( ) )
    {
      cerr << "CVCI: parameter in record type decl not found: "
           << *i << endl;
      exit( 1 );
    }
#endif
    types.push_back( typeObj[*i] );
  }

  if (typeID.find (identifier) == typeID.end())
  {
#ifdef CVC_API_DEBUG
  cout << " (NEW TYPE) ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

    id = NEXT_DEFINITION_ID;
	  for (int i = 0; i < nameids.size(); i++)
	  {
		fieldType[make_pair(id,nameids[i])] = typeids[i];
	  }
#ifdef CVC_OUTPUT
//HERE
  cout << "Type id"<<id<<"=vc->recordType("<<"BLAH"<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type t = vc->recordType(nameids,types);
    typeID[identifier] = id;
    typeObj[id] = t;
  }
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// value cvcTupleType (value type_vals)
// type_vals is the ordered list of field type ids (int list)
// returns type id (int)
// create a tuple type
extern "C" value cvcTupleType ( value type_vals )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  vector<int> typeids;
  int id;

  VectorVal(typeids,type_vals);

  string identifier = "[" + VecToString(typeids) + "]";


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_TupleType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  vector<Type> types;
  for (vector<int>::iterator i = typeids.begin(); i != typeids.end(); i++)
  {
#ifdef CVC_API_DEBUG
    if ( typeObj.find( *i ) == typeObj.end( ) )
    {
      cerr << "CVCI: parameter in tuple type decl not found: "
           << *i << endl;
      exit( 1 );
    }
#endif
    types.push_back( typeObj[*i]);
  }

  if (typeID.find (identifier) == typeID.end())
  {
    id = NEXT_DEFINITION_ID;
    int sz = typeids.size();
    tupleSize[id] = sz;
    for (int i = 0; i < sz; i++)
    {
      fieldType[make_pair(id,""+(i+1))] = typeids[i];
    }
#ifdef CVC_OUTPUT
  cout << "Type id"<<id<<"=vc->tupleType(id"<<typeids[0];
  for(int i=1; i< sz;i++) {
    cout << ",id"<<typeids[i];
  }
  cout <<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type t = vc->tupleType(types);
    typeID[identifier] = id;
    typeObj[id] = t;
  }
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// value cvcArrayType (value index_val, value type_val)
// index_val is the indexing type id (int)
// type_val is the element type id (int)
// returns type id (int)
// create an array type
extern "C" value cvcArrayType ( value index_val , value type_val)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif

  int id;
  int index = Int_val (index_val);
  int mytype = Int_val (type_val);
  stringstream s;
  s << "ARRAY" << index << ":" << mytype;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_ArrayType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if (typeID.find (identifier) == typeID.end())
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_API_DEBUG
    if (typeObj.find(index) == typeObj.end()
        || typeObj.find(mytype) == typeObj.end())
    {
      cerr << "CVCI: Unrecognized parameter in decl of array type ";
      cerr << identifier << endl;
      exit(1);
    }
#endif
#ifdef CVC_OUTPUT
  cout << "Type id"<<id<<"=vc->arrayType(id"<<index<<",id"<<mytype<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Type t = vc->arrayType( typeObj[index], typeObj[mytype] );
    typeID[identifier] = id;
    fieldType[make_pair(id,"")] = mytype;
    typeObj[id] = t;
  }
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// value cvcSubType (value lambda_val)
// lambda_val is a lambda expression id (int)
// will probably crash if lambda_val is not a lambda expression
// returns type id (int)
// create a lambda type
extern "C" value cvcSubType ( value lambda_val)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int lambda = Int_val (lambda_val);
  stringstream s;
  s << "SUBTYPE" << lambda;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_SubType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if (typeID.find (identifier) == typeID.end())
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_API_DEBUG
    if (exprObj.find(lambda) == exprObj.end())
    {
      cerr << "CVCI: Unrecognized expression in decl of subtype ";
      cerr << identifier << endl;
      exit(1);
    }
#endif
    Type t = vc->subtypeType( exprObj[lambda] );
    typeID[identifier] = id;
    typeObj[id] = t;
  }
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// cvcSubrangeType (s_val,e_val)
// s_val is the start expression id (int)
// e_val is the end expression id (int)
// returns a subrange type id (int)
extern "C" value cvcSubrangeType ( value s_val, value e_val)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int s = Int_val (s_val);
  int e = Int_val (e_val);
  stringstream st;
  st << s << ".." << e;
  string identifier = st.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:cvc_SubrangeType " << identifier;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  if (typeID.find (identifier) == typeID.end())
  {
    id = NEXT_DEFINITION_ID;
    Type t;
/*    if (s == infinityID) {
        if (exprObj.find(e) == exprObj.end())
        {
          cerr << "CVCI: Unrecognized expression in decl of subrange ";
          cerr << identifier << endl;
          exit(1);
        }
        t = vc->subrangeType( CVCL::NEGINF ,exprObj[e] );
      } else if (e == infinityID) {
        if (exprObj.find(s) == exprObj.end())
        {
          cerr << "CVCI: Unrecognized expression in decl of subrange ";
          cerr << identifier << endl;
          exit(1);
        }
        t = vc->subrangeType( exprObj[s], CVCL::POSINF );
      } else
*/    {
#ifdef CVC_API_DEBUG
      if (exprObj.find(s) == exprObj.end()
         || exprObj.find(e) == exprObj.end())
      {
        cerr << "CVCI: Unrecognized expression in decl of subrange ";
        cerr << identifier << endl;
        exit(1);
      }
#endif
      t = vc->subrangeType( exprObj[s],exprObj[e] );
    }
    typeID[identifier] = id;
    typeObj[id] = t;
  }
  else
    id = typeID[identifier];

#ifdef CVC_API_DEBUG
  cout << "=" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// returns a lambda expression of the given expression
// p_val: <int>vector = parameter variable ids
// e_val(int): base expression id
extern "C" value cvcAppLambda (value p_val, value e_val)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
	int id;
	vector<Expr> params;
    vector<int> pids;
	VectorVal (params,p_val);
    VectorVal (pids, p_val);
	int e = Int_val(e_val);

  stringstream s;
  s << "LAMBDA" << VecToString(pids) << ":" <<e;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:AppLambda (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( e ) == exprObj.end( )
     )
  {
    cerr << "undefined expression in lambda "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
    Expr lam = vc->lambdaExpr(params, exprObj[e]);
    exprID[identifier] = id;
    Type mytype = vc->getType(lam);
    exprType[id] = lookupTypeID(mytype);
    exprObj[id] = lam;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// create a record
// name_vals: <string>vector = list of field names (ordered)
// v_vals: <int>vector = list of field values (ordered)
extern "C" value cvcRecordLiteral( value name_vals, value v_vals )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  vector<string> fields;
  vector<Expr> vals;
  vector<int> vids;
  VectorVal(fields,name_vals);
  VectorVal(vals,v_vals);
  VectorVal(vids,v_vals);
  string identifier = "(#"+VecToString(fields)+";"+VecToString(vids)+"#)";

#ifdef CVC_API_DEBUG
  cout << "CVCI:RecordLiteral (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
#ifdef CVC_API_DEBUG
  // check that lists are of same length!
  if (vals.size() != vids.size()) {
    cerr << "Record field and value sizes don't match!" << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->recordExpr(id"<<"BLAH"<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr recl = vc->recordExpr(fields, vals);
    exprID[identifier] = id;
    Type mytype = vc->getType(recl);
    exprType[id] = lookupTypeID(mytype);
    exprObj[id] = recl;
  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}


/********************************************************************/
// returns the array element in question
// a_val(int) = array id
// s_val(int) = element id
extern "C" value cvcReadArray( value a_val, value s_val )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int arr = Int_val(a_val);
  int sub = Int_val(s_val);
  stringstream s;
  s << arr << "[" << sub << "]";
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:ReadArray (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( arr ) == exprObj.end( ) ||
       exprObj.find( sub ) == exprObj.end()
     )
  {
    cerr << "undefined parameter in array lookup "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->readExpr(id"<<arr<<",id"<<sub<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->readExpr(exprObj[arr],exprObj[sub]));
    exprID[identifier] = id;
    exprType[id] = fieldType[make_pair(exprType[arr],"")];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// returns the record field in question
// r_val(int) = record id
// s_val(string) = field name
extern "C" value cvcRecordSelect( value r_val, value s_val )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int rec = Int_val(r_val);
  string field = String_val(s_val);
  stringstream s;
  s << rec << "." << field;
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:RecordSelect (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( rec ) == exprObj.end( ))
  {
    cerr << "undefined parameter in record lookup "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->recSelectExpr(id"<<rec<<",\""<<field<<"\");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->recSelectExpr(exprObj[rec],field));
    exprID[identifier] = id;
    exprType[id] = fieldType[make_pair(exprType[rec],field)];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << " (type= " << exprType[id] << ")" << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// returns the tuple field in question
// t_val(int) = tuple id
// i_val(int) = field number (starts at 1)
extern "C" value cvcTupleSelect( value t_val, value i_val )
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int t = Int_val(t_val);
  int index = Int_val(i_val);
  stringstream s;
  s << t << "." << index;
  string identifier = s.str();


#ifdef CVC_API_DEBUG
  cout << "CVCI:TupleSelect (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( t ) == exprObj.end( ))
  {
    cerr << "undefined parameter in tuple lookup "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->tupleSelectExpr(id"<<t<<","<<index<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->tupleSelectExpr(exprObj[t],index));
    exprID[identifier] = id;
    exprType[id] = fieldType[make_pair(exprType[t],""+index)];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}


/********************************************************************/
// update an array element
// a_val(int) = array id
// s_val(int) = element id
// n_val(int) = new value for element
extern "C" value cvcWriteArray( value a_val, value s_val, value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int arr = Int_val(a_val);
  int sub = Int_val(s_val);
  int vid = Int_val(n_val);
  stringstream s;
  s << arr << "[" << sub << "]:=" << vid;
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:WriteArray (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( arr ) == exprObj.end( ) ||
       exprObj.find( sub ) == exprObj.end() ||
       exprObj.find(vid) == exprObj.end()
     )
  {
    cerr << "undefined parameter in array update "<< identifier << endl;
    exit( 1 );
  }
#endif

  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->writeExpr(id"<<arr<<",id"<<sub<<",id"<<vid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->writeExpr(exprObj[arr],exprObj[sub],exprObj[vid]));
    exprID[identifier] = id;
    exprType[id] = exprType[arr];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// update a record field.
// r_val(int) = record id
// s_val(string) = field name
// n_val(int) = new value for field
extern "C" value cvcRecordUpdate( value r_val, value s_val, value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int rec = Int_val(r_val);
  string field = String_val(s_val);
  int vid = Int_val(n_val);
  stringstream s;
  s << rec << "." << field << ":=" << vid;
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:RecordUpdate (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( rec ) == exprObj.end( ) ||
       exprObj.find(vid) == exprObj.end()
  )
  {
    cerr << "undefined parameter in record update "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->recUpdateExpr(id"<<rec<<",\""<<field<<"\",id"<<vid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->recUpdateExpr(exprObj[rec],field,exprObj[vid]));
    exprID[identifier] = id;
    exprType[id] = exprType[rec];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}

/********************************************************************/
// update a tuple field.  i_val must be an integer x: 1<=x<=(tuple size)
// t_val(int) = tuple id
// i_val(int) = field number (starts with 1)
// n_val(int) = new value for field
extern "C" value cvcTupleUpdate( value t_val, value i_val, value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int t = Int_val(t_val);
  int index = Int_val(i_val);
  int vid = Int_val(n_val);
  stringstream s;
  s << t << "." << index <<":=" << vid;
  string identifier = s.str();

#ifdef CVC_API_DEBUG
  cout << "CVCI:TupleUpdate (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprObj.find( t ) == exprObj.end( ) ||
       exprObj.find(vid) == exprObj.end()
  )
  {
    cerr << "undefined parameter in tuple update "<< identifier << endl;
    exit( 1 );
  }
#endif

  // Check if defined as function, variable or predicate
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
    id = NEXT_DEFINITION_ID;
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->tupleUpdateExpr(id"<<t<<","<<index<<",id"<<vid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr ex = VCSIMPLIFY(vc->tupleUpdateExpr(exprObj[t],index,exprObj[vid]));
    exprID[identifier] = id;
    exprType[id] = exprType[t];
    exprObj[id] = ex;

    if (isBoolean(exprType[id])) {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
 	  Expr notex = VCSIMPLIFY(vc->notExpr( ex ));
	  addToIndex(ex,id);
	  addToIndex(notex,NEG_ID(id));
	  exprType[NEG_ID(id)] = boolID;
	  predicateList[id] = make_pair( ex, notex );
	}

  }
  // Return previous if exists
  else
    id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

  return Val_int (id);
}


/********************************************************************/
// returns the true type id iof a given expression identifier
extern "C" value cvcGetExprType( value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  string identifier = String_val(n_val);

#ifdef CVC_API_DEBUG
  cout << "CVCI:GetExprType (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprNameType.find( identifier ) == exprNameType.end( ))
  {
    cerr << "undefined expr id "<< identifier << endl;
    exit( 1 );
  }
#endif

  id = exprNameType[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif
  return Val_int (id);
}

/********************************************************************/
// returns the true type id of a given expression identifier
extern "C" value cvcGetExprTypeFromId( value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  int identifier = Int_val(n_val);

#ifdef CVC_API_DEBUG
  cout << "CVCI:cvcGetExprTypeFromId (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprType.find( identifier ) == exprType.end( ))
  {
    cerr << "undefined expr id "<< identifier << endl;
    exit( 1 );
  }
#endif

  id = exprType[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif
  return Val_int (id);
}

/********************************************************************/
// returns the expression id for a string identifier
// will return a function Op in that case
extern "C" value cvcGetExprID( value n_val )
{
	//assume it return new value
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id;
  string identifier = String_val(n_val);

#ifdef CVC_API_DEBUG
  cout << "CVCI:GetExprID (" << identifier <<") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // check that parameters exist
  if ( exprID.find( identifier ) == exprID.end( ))
  {
    cerr << "undefined expr id "<< identifier << endl;
    exit( 1 );
  }
#endif

  id = exprID[identifier];

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif
  return Val_int (id);
}

/********************************************************************/
// declare a previously uninterpreted predicate to the theory
// include pred name (string) and unique ID (int)
extern "C" void cvcDeclarePredicateVariable (value nvalue, value ivalue )
{

#ifdef CVC_API_TIMER
  startClock( );
#endif

  string identifier = String_val( nvalue );
  int tid = boolID;
  int id = Int_val(ivalue);

#ifdef CVC_API_DEBUG
  cout << "CVCI:DeclarePredicateVariable (" << identifier << ") = ";
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_DEBUG
  // Check if defined as some other type
  if ( exprNameType.find( identifier ) != exprNameType.end( ) &&
       exprNameType[identifier] != tid )
  {
    cerr << "identifier already assigned as something else! " << endl;
    cerr << identifier << endl;
    exit( 1 );
  }
#endif
  // Check it exists.  If not then create new.
  if ( exprID.find( identifier ) == exprID.end( ) )
  {
#ifdef CVC_OUTPUT
  cout << "Expr id"<<id<<"=vc->varExpr(\""<<identifier<<"\",id"<<tid<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr variable = VCSIMPLIFY(vc->varExpr( identifier, typeObj[tid] ));
    exprID[identifier] = id;
    exprType[id] = tid;
    exprNameType[identifier] = tid;
    exprObj[id] = variable;

#ifdef CVC_OUTPUT
  cout << "Expr id"<<NEG_ID(id)<<"=vc->notExpr(id"<<id<<");"<<endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
    Expr notvariable = VCSIMPLIFY(vc->notExpr( variable ));
    exprType[NEG_ID(id)] = boolID;
    addToIndex(variable,id);
    addToIndex(notvariable,NEG_ID(id));
    predicateList[id] = make_pair( variable, notvariable );
  }

#ifdef CVC_API_DEBUG
  cout << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

#ifdef CVC_API_TIMER
  stopClock( );
#endif

}

/********************************************************************/
// deletes references to an expression or op (which should then be caught
// by cvcl's gc)
// it is safe to try to remove a nonexistant expr
extern "C" void cvcRemoveExpr (value ivalue)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id = Int_val(ivalue);

#ifdef CVC_API_DEBUG
  cout << "CVCI: removing expression" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif

  // note: might be faster if we do the for loops backwards?
  
  if (exprType.find(id) != exprType.end()) {
    exprType.erase(exprType.find(id));
  }

  if (exprObj.find(id) != exprObj.end()) {
    exprObj.erase(exprObj.find(id));
  }

  if (funcOpObj.find(id) != funcOpObj.end()) {
    funcOpObj.erase(funcOpObj.find(id));
  }

  if (domRanType.find(id) != domRanType.end()) {
    domRanType.erase(domRanType.find(id));
  }

  if (predicateList.find(id) != predicateList.end()) {
    predicateList.erase(predicateList.find(id));
  }

  for( predIndexIterator j = predIndex.begin( ); j != predIndex.end( ); j++ )
  {
    if (j->second == id || j->second == NEG_ID(id))
    {
      predIndex.erase(j);
      break;
    }
  }
  // needs to run through twice -- removing the element while still in
  // the loop can cause a seg fault
  for( predIndexIterator j = predIndex.begin( ); j != predIndex.end( ); j++ )
  {
    if (j->second == id || j->second == NEG_ID(id))
    {
      predIndex.erase(j);
      break;
    }
  }

  for( exprIDIterator j = exprID.begin( ); j != exprID.end( ); j++ )
  {
    if ( j->second == id ) // name string
    {
      if (exprNameType.find(j->first) != exprNameType.end() ) {
        exprNameType.erase(exprNameType.find(j->first));
      }
      if (funcOpID.find(j->first) != funcOpID.end() ) {
        funcOpID.erase(funcOpID.find(j->first));
      }
      exprID.erase(j);
      break;
    }
  }

  for( funcAppIDIterator j = funcAppID.begin( ); j != funcAppID.end( ); j++ )
  {
    if ((j->first).first == id)
    {
      funcAppID.erase(j);
      break;
    }
  }
                                                                                
  for( fieldTypeIterator j = fieldType.begin( ); j != fieldType.end( ); j++ )
  {
    if ((j->first).first == id)
    {
      fieldType.erase(j);
      break;
    }
  }

#ifdef CVC_API_TIMER
  stopClock( );
#endif
}


/********************************************************************/
// deletes references to a type (which should then be caught
// by cvcl's gc)
// it is safe to try to remove a nonexistant type
extern "C" void cvcRemoveType (value ivalue)
{
#ifdef CVC_API_TIMER
  startClock( );
#endif
  int id = Int_val(ivalue);

#ifdef CVC_API_DEBUG
  cout << "CVCI: removing type" << id << endl;
  #ifndef GCC4
  cout.flush();
  #endif;
#endif
  
  if (tupleSize.find(id) != tupleSize.end()) {
    tupleSize.erase(tupleSize.find(id));
  }
  
  if (typeObj.find(id) != typeObj.end()) {
    typeObj.erase(typeObj.find(id));
  }

  if (numParams.find(id) != numParams.end()) {
    numParams.erase(numParams.find(id));
  }

  if (boolSet.find(id) != boolSet.end()) {
    boolSet.erase(boolSet.find(id));
  }

  for( typeIDIterator j = typeID.begin( ); j != typeID.end( ); j++ )
  {
    if ( j->second == id )
    {
      typeID.erase(j);
      break;
    }
  }
                                                                                



#ifdef CVC_API_TIMER
  stopClock( );
#endif
}
