[llvm-commits] [klee] r72205 [3/3] - in /klee/trunk: ./ autoconf/ docs/ docs/SMT-COMP/ examples/ examples/regexp/ examples/sort/ include/ include/expr/ include/klee/ include/klee/Config/ include/klee/Internal/ include/klee/Internal/ADT/ include/klee/Internal/Module/ include/klee/Internal/Support/ include/klee/Internal/System/ include/klee/util/ lib/ lib/Basic/ lib/Core/ lib/Expr/ lib/Module/ lib/Solver/ lib/Support/ runtime/ runtime/Intrinsic/ runtime/POSIX/ runtime/POSIX/testing-dir/ runtime/POSIX/testing-dir/e/ runti...

Daniel Dunbar daniel at zuster.org
Wed May 20 21:36:47 PDT 2009


Added: klee/trunk/stp/parser/PL.y
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/parser/PL.y?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/parser/PL.y (added)
+++ klee/trunk/stp/parser/PL.y Wed May 20 23:36:41 2009
@@ -0,0 +1,1006 @@
+%{
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+using namespace std; 
+
+  // Suppress the bogus warning suppression in bison (it generates
+  // compile error)
+#undef __GNUC_MINOR__
+
+  extern int yylex(void);
+  extern char* yytext;
+  extern int yylineno;
+  int yyerror(const char *s) {
+    cout << "syntax error: line " << yylineno << "\n" << s << endl;    
+    BEEV::FatalError("");
+    return 1;			/* Dill: don't know what it should return */
+  };
+
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 10485760
+#define YYERROR_VERBOSE 1
+#define YY_EXIT_FAILURE -1
+%}
+
+%union {
+
+  unsigned int uintval;			/* for numerals in types. */
+  struct {
+    //stores the indexwidth and valuewidth
+    //indexwidth is 0 iff type is bitvector. positive iff type is
+    //array, and stores the width of the indexing bitvector
+    unsigned int indexwidth;
+    //width of the bitvector type
+    unsigned int valuewidth;
+  } indexvaluewidth;
+
+  //ASTNode,ASTVec
+  BEEV::ASTNode *node;
+  BEEV::ASTVec *vec;
+
+  //Hash_Map to hold Array Updates during parse A map from array index
+  //to array values. To support the WITH construct
+  BEEV::ASTNodeMap * Index_To_UpdateValue;
+};
+
+%start cmd
+
+%token	AND_TOK			"AND"
+%token	OR_TOK			"OR"
+%token	NOT_TOK			"NOT"
+%token	XOR_TOK			"XOR"
+%token	NAND_TOK		"NAND"
+%token	NOR_TOK			"NOR"
+%token	IMPLIES_TOK		"=>"
+%token	IFF_TOK			"<=>"
+
+%token	IF_TOK			"IF"
+%token	THEN_TOK		"THEN"
+%token	ELSE_TOK		"ELSE"
+%token	ELSIF_TOK		"ELSIF"
+%token	END_TOK			"END"
+%token	ENDIF_TOK		"ENDIF"
+%token	NEQ_TOK			"/="
+%token  ASSIGN_TOK              ":="
+
+%token  BV_TOK                  "BV"
+%token  BVLEFTSHIFT_TOK         "<<"
+%token  BVRIGHTSHIFT_TOK        ">>"
+%token  BVPLUS_TOK              "BVPLUS"
+%token  BVSUB_TOK               "BVSUB"
+%token  BVUMINUS_TOK            "BVUMINUS"
+%token  BVMULT_TOK              "BVMULT"
+
+%token  BVDIV_TOK               "BVDIV"
+%token  BVMOD_TOK               "BVMOD"
+%token  SBVDIV_TOK              "SBVDIV"
+%token  SBVMOD_TOK              "SBVMOD"
+
+
+%token  BVNEG_TOK               "~"
+%token  BVAND_TOK               "&"
+%token  BVOR_TOK                "|"
+%token  BVXOR_TOK               "BVXOR"
+%token  BVNAND_TOK              "BVNAND"
+%token  BVNOR_TOK               "BVNOR"
+%token  BVXNOR_TOK              "BVXNOR"
+%token  BVCONCAT_TOK            "@"
+
+%token  BVLT_TOK                "BVLT"
+%token  BVGT_TOK                "BVGT"
+%token  BVLE_TOK                "BVLE"
+%token  BVGE_TOK                "BVGE"
+
+%token  BVSLT_TOK               "BVSLT"
+%token  BVSGT_TOK               "BVSGT"
+%token  BVSLE_TOK               "BVSLE"
+%token  BVSGE_TOK               "BVSGE"
+%token  BOOL_TO_BV_TOK          "BOOLBV"
+%token  BVSX_TOK                "BVSX"
+%token  BOOLEXTRACT_TOK         "BOOLEXTRACT"
+%token  ASSERT_TOK              "ASSERT"
+%token  QUERY_TOK               "QUERY"
+
+%token  BOOLEAN_TOK             "BOOLEAN"
+%token  ARRAY_TOK               "ARRAY"
+%token  OF_TOK                  "OF"
+%token  WITH_TOK                "WITH"
+
+%token  TRUELIT_TOK             "TRUE"
+%token  FALSELIT_TOK            "FALSE"
+
+%token  IN_TOK                  "IN"
+%token  LET_TOK                 "LET"
+//%token  COUNTEREXAMPLE_TOK      "COUNTEREXAMPLE"
+%token  PUSH_TOK                "PUSH"
+%token  POP_TOK                 "POP"
+
+%left IN_TOK
+%left XOR_TOK
+%left IFF_TOK
+%right IMPLIES_TOK
+%left OR_TOK
+%left AND_TOK
+%left NAND_TOK
+%left NOR_TOK
+%left NOT_TOK
+%left BVCONCAT_TOK
+%left BVOR_TOK
+%left BVAND_TOK
+%left BVXOR_TOK
+%left BVNAND_TOK
+%left BVNOR_TOK
+%left BVXNOR_TOK
+%left BVNEG_TOK
+%left BVLEFTSHIFT_TOK BVRIGHTSHIFT_TOK
+%left WITH_TOK
+
+%nonassoc '=' NEQ_TOK ASSIGN_TOK
+%nonassoc BVLT_TOK BVLE_TOK BVGT_TOK BVGE_TOK
+%nonassoc BVUMINUS_TOK BVPLUS_TOK BVSUB_TOK BVSX_TOK
+%nonassoc '[' 
+%nonassoc '{' '.' '('
+%nonassoc BV_TOK
+
+%type <vec>  Exprs FORM_IDs reverseFORM_IDs
+%type <vec>  Asserts 
+%type <node> Expr Formula IfExpr ElseRestExpr IfForm ElseRestForm Assert Query ArrayUpdateExpr
+%type <Index_To_UpdateValue> Updates
+
+%type <indexvaluewidth>  BvType BoolType ArrayType Type 
+
+%token <node> BVCONST_TOK
+%token <node> TERMID_TOK FORMID_TOK COUNTEREXAMPLE_TOK
+%token <uintval> NUMERAL_TOK
+
+%%
+
+cmd             :      other_cmd
+                |      other_cmd counterexample
+                ; 
+
+counterexample  :      COUNTEREXAMPLE_TOK ';'
+                       {
+			 BEEV::print_counterexample = true;			 
+			 BEEV::globalBeevMgr_for_parser->PrintCounterExample(true);
+		       }                              
+                ;
+
+other_cmd       :      other_cmd1
+                |      Query 
+                       { 
+			 BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE),*$1); 
+			 delete $1;
+		       }
+                |      VarDecls Query 
+                       { 
+			 BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE),*$2); 
+			 delete $2;
+		       }
+                |      other_cmd1 Query
+                       {
+			 BEEV::ASTVec aaa = BEEV::globalBeevMgr_for_parser->GetAsserts();
+			 if(aaa.size() == 0)
+			   yyerror("Fatal Error: parsing:  GetAsserts() call: no assertions: ");
+			 if(aaa.size() == 1)
+			   BEEV::globalBeevMgr_for_parser->TopLevelSAT(aaa[0],*$2);
+			 else  		   
+			   BEEV::globalBeevMgr_for_parser->TopLevelSAT(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND,aaa),*$2);
+			 delete $2;
+		       }
+                ;
+
+other_cmd1      :     VarDecls Asserts
+                      {
+			delete $2;
+                      }                 
+                |     Asserts
+                      {
+			delete $1;
+		      }
+                |     other_cmd1 VarDecls Asserts
+                      {
+                        delete $3;
+                      }
+                ;
+
+/* push            :     PUSH_TOK */
+/*                       { */
+/* 			BEEV::globalBeevMgr_for_parser->Push(); */
+/*                       } */
+/*                 | */
+/*                 ; */
+
+/* pop             :     POP_TOK */
+/*                       { */
+/* 			BEEV::globalBeevMgr_for_parser->Pop(); */
+/*                       } */
+/*                 | */
+/*                 ; */
+
+Asserts         :      Assert 
+                       {
+			 $$ = new BEEV::ASTVec;
+			 $$->push_back(*$1);
+			 BEEV::globalBeevMgr_for_parser->AddAssert(*$1);
+			 delete $1;
+                       }
+                |      Asserts Assert
+                       {
+			 $1->push_back(*$2);
+			 BEEV::globalBeevMgr_for_parser->AddAssert(*$2);
+			 $$ = $1;
+			 delete $2;
+		       }
+                ;
+
+Assert          :      ASSERT_TOK Formula ';' { $$ = $2; }                
+                ;
+
+Query           :      QUERY_TOK Formula ';' { BEEV::globalBeevMgr_for_parser->AddQuery(*$2); $$ = $2;}
+                ; 
+
+
+/* Grammar for Variable Declaration */
+VarDecls	:      VarDecl ';'
+                       {
+                       }
+                |      VarDecls  VarDecl ';'
+                       {
+		       }
+		;
+
+VarDecl		:      FORM_IDs ':' Type 
+                       {
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {
+			   BEEV::_parser_symbol_table.insert(*i);
+			   i->SetIndexWidth($3.indexwidth);
+			   i->SetValueWidth($3.valuewidth);
+
+			   //FIXME: HACK_ATTACK. this vector was hacked into the code to
+			   //support a special request by Dawson' group. They want the
+			   //counterexample to be printed in the order of variables declared.
+			   BEEV::globalBeevMgr_for_parser->_special_print_set.push_back(*i);
+			 }
+			 delete $1;
+		       }
+                |      FORM_IDs ':' Type '=' Expr
+		       {
+			 //do type checking. if doesn't pass then abort
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 if($3.indexwidth != $5->GetIndexWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 if($3.valuewidth != $5->GetValueWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {			   
+			   //set the valuewidth of the identifier
+			   i->SetValueWidth($5->GetValueWidth());
+			   i->SetIndexWidth($5->GetIndexWidth());
+			   
+			   BEEV::globalBeevMgr_for_parser->LetExprMgr(*i,*$5);
+			   delete $5;
+			 }
+		       }
+                |      FORM_IDs ':' Type '=' Formula
+                       {
+			 //do type checking. if doesn't pass then abort
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 if($3.indexwidth != $5->GetIndexWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 if($3.valuewidth != $5->GetValueWidth())
+			   yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			 
+			 for(BEEV::ASTVec::iterator i=$1->begin(),iend=$1->end();i!=iend;i++) {			   
+			   //set the valuewidth of the identifier
+			   i->SetValueWidth($5->GetValueWidth());
+			   i->SetIndexWidth($5->GetIndexWidth());
+			   
+			   BEEV::globalBeevMgr_for_parser->LetExprMgr(*i,*$5);
+			   delete $5;
+			 }
+		       }                
+		;
+
+reverseFORM_IDs  :      FORMID_TOK
+                       {
+			 $$ = new BEEV::ASTVec;		        
+			 $$->push_back(*$1);
+			 delete $1;
+                       }
+                |      FORMID_TOK ',' reverseFORM_IDs
+                       {
+			 $3->push_back(*$1);
+			 $$ = $3;
+			 delete $1;
+                       }
+                ;
+
+FORM_IDs         :     reverseFORM_IDs
+                      {
+			$$ = new BEEV::ASTVec($1->rbegin(),$1->rend());
+			delete $1;
+                      }
+                ;
+
+/* Grammar for Types */
+Type		:      BvType { $$ = $1; }
+                |      BoolType { $$ = $1; }
+                |      ArrayType { $$ = $1; }
+		;		
+
+BvType          :      BV_TOK '(' NUMERAL_TOK ')' 
+                       {
+                         /*((indexwidth is 0) && (valuewidth>0)) iff type is BV*/
+			 $$.indexwidth = 0;
+			 unsigned int length = $3;
+			 if(length > 0) {
+			   $$.valuewidth = length;
+			 }
+			 else
+			  BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+		       }
+                ;
+BoolType        :      BOOLEAN_TOK
+                       {
+			 $$.indexwidth = 0;
+			 $$.valuewidth = 0;
+		       }
+                ;
+ArrayType       :      ARRAY_TOK BvType OF_TOK BvType
+                       {
+			 $$.indexwidth = $2.valuewidth;
+			 $$.valuewidth = $4.valuewidth;
+		       }
+                ;
+
+/*Grammar for ITEs which are a type of Term*/
+IfExpr	        :      IF_TOK Formula THEN_TOK Expr ElseRestExpr 
+                       {
+			 unsigned int width = $4->GetValueWidth();
+			 if (width != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");			 
+			 if($4->GetIndexWidth() != $5->GetIndexWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE, width, *$2, *$4, *$5));
+			 $$->SetIndexWidth($5->GetIndexWidth());
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		      }
+		;
+
+ElseRestExpr	:      ELSE_TOK Expr ENDIF_TOK  { $$ = $2; }
+                |      ELSIF_TOK Expr THEN_TOK Expr ElseRestExpr 
+                       {
+			 unsigned int width = $2->GetValueWidth();
+			 if (width != $4->GetValueWidth() || width != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+			 if ($2->GetIndexWidth() != $4->GetValueWidth() || $2->GetIndexWidth() != $5->GetValueWidth())
+			   yyerror("Width mismatch in IF-THEN-ELSE");
+
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);			
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE, width, *$2, *$4, *$5));
+			 $$->SetIndexWidth($5->GetIndexWidth());
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		       }
+		;
+
+/* Grammar for formulas */
+Formula		:     '(' Formula ')' { $$ = $2; }
+		|      FORMID_TOK {  $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); delete $1;}
+                |      BOOLEXTRACT_TOK '(' Expr ',' NUMERAL_TOK ')'
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if(0 > (unsigned)$5 || width <= (unsigned)$5)
+			   yyerror("Fatal Error: BOOLEXTRACT: trying to boolextract a bit which beyond range");
+			 
+			 BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,1,*$3,hi,low));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 BEEV::ASTNode zero = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,0);			 
+			 BEEV::ASTNode * out = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::EQ,*n,zero));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*out);
+
+			 $$ = out;
+			 delete $3;
+                       }
+                |      Expr '=' Expr 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::EQ, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Expr NEQ_TOK Expr 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NEQ, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+		|      NOT_TOK Formula 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT, *$2));
+			 delete $2;
+		       }
+		|      Formula OR_TOK Formula %prec OR_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::OR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula NOR_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula AND_TOK Formula %prec AND_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula NAND_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NAND, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula IMPLIES_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IMPLIES, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       }
+		|      Formula IFF_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IFF, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+		|      Formula XOR_TOK Formula
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::XOR, *$1, *$3));
+			 delete $1;
+			 delete $3;
+		       } 
+	        |      BVLT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVGT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVLE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVGE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSLT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSGT_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGT, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSLE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVSGE_TOK '(' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGE, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+		|      IfForm
+		|      TRUELIT_TOK 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE)); 
+			 $$->SetIndexWidth(0); 
+			 $$->SetValueWidth(0);
+                       }
+		|      FALSELIT_TOK 
+                       { 
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::FALSE)); 
+			 $$->SetIndexWidth(0); 
+			 $$->SetValueWidth(0);
+		       }
+
+                |      LET_TOK LetDecls IN_TOK Formula
+                       {
+			 $$ = $4;
+			 //Cleanup the LetIDToExprMap
+			 BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();
+		       }
+                ;
+
+/*Grammar for ITEs which are Formulas */
+IfForm	        :      IF_TOK Formula THEN_TOK Formula ElseRestForm 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$2, *$4, *$5));
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		      }
+		;
+
+ElseRestForm	:      ELSE_TOK Formula ENDIF_TOK  { $$ = $2; }
+                |      ELSIF_TOK Formula THEN_TOK Formula ElseRestForm 
+                       {
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$2, *$4, *$5));
+			 delete $2;
+			 delete $4;
+			 delete $5;
+		       }
+		;
+
+/*Grammar for a list of expressions*/
+Exprs		:      Expr 
+                       {
+			 $$ = new BEEV::ASTVec;
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$1);
+			 $$->push_back(*$1);
+			 delete $1;
+		       }
+                |      Exprs ',' Expr 
+                       {
+			 $1->push_back(*$3);
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 $$ = $1; 
+			 delete $3;
+		       }
+		;
+
+/* Grammar for Expr */
+Expr		:      TERMID_TOK { $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); delete $1;}
+                |      '(' Expr ')' { $$ = $2; }
+	        |      BVCONST_TOK { $$ = $1; }
+                |      BOOL_TO_BV_TOK '(' Formula ')'		
+                       {
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 BEEV::ASTNode one = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,1);
+			 BEEV::ASTNode zero = BEEV::globalBeevMgr_for_parser->CreateBVConst(1,0);
+
+			 //return ITE(*$3, length(1), 0bin1, 0bin0)
+			 $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE,1,*$3,one,zero));
+			 delete $3;
+                       }
+		|      Expr '[' Expr ']' 
+                       {			 
+			 // valuewidth is same as array, indexwidth is 0.
+			 unsigned int width = $1->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $1;
+			 delete $3;
+		       }
+                |      Expr '(' Expr ')' //array read but in the form of a uninterpreted function application
+                       {
+			 // valuewidth is same as array, indexwidth is 0.
+			 unsigned int width = $1->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $1;
+			 delete $3;
+		       }
+	        |      Expr '[' NUMERAL_TOK ':' NUMERAL_TOK ']' 
+                       {
+			 int width = $3 - $5 + 1;
+			 if (width < 0)
+			   yyerror("Negative width in extract");
+			 
+			 if((unsigned)$3 >= $1->GetValueWidth() || (unsigned)$5 < 0)
+			   yyerror("Parsing: Wrong width in BVEXTRACT\n");			 
+
+			 BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $3);
+			 BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT, width, *$1,hi,low));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+		       }
+	        |      BVNEG_TOK Expr 
+                       {
+			 unsigned int width = $2->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNEG, width, *$2));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $2;
+		       }
+	        |      Expr BVAND_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth();
+			 if (width != $3->GetValueWidth()) {
+			   yyerror("Width mismatch in AND");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVAND, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+	        |      Expr BVOR_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth();
+			 if (width != $3->GetValueWidth()) {
+			   yyerror("Width mismatch in OR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVOR, width, *$1, *$3)); 
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+			 delete $3;
+		       }
+	        |      BVXOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in XOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVNAND_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NAND");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNAND, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+                |      BVNOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+	        |      BVXNOR_TOK '(' Expr ',' Expr ')' 
+                       {
+			 unsigned int width = $3->GetValueWidth();
+			 if (width != $5->GetValueWidth()) {
+			   yyerror("Width mismatch in NOR");
+			 }
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXNOR, width, *$3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $3;
+			 delete $5;
+		       }
+                |      BVSX_TOK '(' Expr ',' NUMERAL_TOK ')' 
+                       {
+			 //width of the expr which is being sign
+			 //extended. $5 is the resulting length of the
+			 //signextended expr
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+			 if($3->GetValueWidth() == $5) {
+			   $$ = $3;
+			 }
+			 else {
+			   BEEV::ASTNode width = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$5);
+			   BEEV::ASTNode *n =  
+			     new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSX, $5,*$3,width));
+			   BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			   $$ = n;
+			   delete $3;
+			 }
+		       }
+	        |      Expr BVCONCAT_TOK Expr 
+                       {
+			 unsigned int width = $1->GetValueWidth() + $3->GetValueWidth();
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, width, *$1, *$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 
+			 delete $1;
+			 delete $3;
+		       }
+                |      Expr BVLEFTSHIFT_TOK NUMERAL_TOK 
+                       {
+			 BEEV::ASTNode zero_bits = BEEV::globalBeevMgr_for_parser->CreateZeroConst($3);
+			 BEEV::ASTNode * n = 
+			   new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,
+											$1->GetValueWidth() + $3, *$1, zero_bits));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $1;
+                       }
+                |      Expr BVRIGHTSHIFT_TOK NUMERAL_TOK 
+                       {
+			 BEEV::ASTNode len = BEEV::globalBeevMgr_for_parser->CreateZeroConst($3);
+			 unsigned int w = $1->GetValueWidth();
+
+			 //the amount by which you are rightshifting
+			 //is less-than/equal-to the length of input
+			 //bitvector
+			 if((unsigned)$3 < w) {
+			   BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+			   BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$3);
+			   BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$1,hi,low);
+			   BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,len, extract));
+			   BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			   $$ = n;
+			 } 
+			 else
+			   $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateZeroConst(w));			 
+
+			 delete $1;
+                       }
+                |      BVPLUS_TOK '(' NUMERAL_TOK ',' Exprs ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVPLUS, $3, *$5));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+                       }
+                |      BVSUB_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSUB, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+                       }
+                |      BVUMINUS_TOK '(' Expr ')' 
+                       {
+			 unsigned width = $3->GetValueWidth();
+			 BEEV::ASTNode * n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVUMINUS,width,*$3));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $3;
+                       }
+                |      BVMULT_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMULT, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      BVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVDIV, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      BVMOD_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMOD, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      SBVDIV_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::SBVDIV, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+
+			 delete $5;
+			 delete $7;
+		       }
+                |      SBVMOD_TOK '(' NUMERAL_TOK ',' Expr ',' Expr ')' 
+                       {
+			 BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::SBVMOD, $3, *$5, *$7));
+			 BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+			 $$ = n;
+			 delete $5;
+			 delete $7;
+		       }        
+		|      IfExpr { $$ = $1; }
+                |      ArrayUpdateExpr
+                |      LET_TOK LetDecls IN_TOK Expr
+                       {
+			 $$ = $4;
+			 //Cleanup the LetIDToExprMap
+			 //BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();
+		       }
+		;
+
+/*Grammar for Array Update Expr*/
+ArrayUpdateExpr : Expr WITH_TOK Updates
+                  {
+		    BEEV::ASTNode * result;
+		    unsigned int width = $1->GetValueWidth();
+
+		    BEEV::ASTNodeMap::iterator it = $3->begin();
+		    BEEV::ASTNodeMap::iterator itend = $3->end();
+		    result = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,
+							      width,
+							      *$1,
+							      (*it).first,
+							      (*it).second));
+		    result->SetIndexWidth($1->GetIndexWidth());
+		    BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    for(it++;it!=itend;it++) {
+		      result = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,
+								width,
+								*result,
+								(*it).first,
+								(*it).second));
+		      result->SetIndexWidth($1->GetIndexWidth());
+		      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    }
+		    BEEV::globalBeevMgr_for_parser->BVTypeCheck(*result);
+		    $$ = result;
+		    delete $3;
+                  }
+                ;
+
+Updates         : '[' Expr ']' ASSIGN_TOK Expr 
+                  {
+		    $$ = new BEEV::ASTNodeMap();
+		    (*$$)[*$2] = *$5;		    
+                  }
+                | Updates WITH_TOK '[' Expr ']' ASSIGN_TOK Expr 
+                  {		    
+		    (*$1)[*$4] = *$7;
+                  }
+                ;
+
+/*Grammar for LET Expr*/
+LetDecls	:	LetDecl 
+		|	LetDecls ',' LetDecl 
+		;
+
+LetDecl		:	FORMID_TOK '=' Expr 
+                        {
+			  //Expr must typecheck
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($3->GetValueWidth());
+			  $1->SetIndexWidth($3->GetIndexWidth());
+
+			  //populate the hashtable from LET-var -->
+			  //LET-exprs and then process them:
+			  //
+			  //1. ensure that LET variables do not clash
+			  //1. with declared variables.
+			  //
+			  //2. Ensure that LET variables are not
+			  //2. defined more than once
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$3);
+			  delete $1;
+			  delete $3;
+			}
+                |	FORMID_TOK ':' Type '=' Expr
+			{
+			  //do type checking. if doesn't pass then abort
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+			  
+			  if($3.indexwidth != $5->GetIndexWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			  if($3.valuewidth != $5->GetValueWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($5->GetValueWidth());
+			  $1->SetIndexWidth($5->GetIndexWidth());
+
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$5);
+			  delete $1;
+			  delete $5;
+			}
+                |       FORMID_TOK '=' Formula
+                        {
+			  //Expr must typecheck
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($3->GetValueWidth());
+			  $1->SetIndexWidth($3->GetIndexWidth());
+
+			  //Do LET-expr management
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$3);
+			  delete $1;
+			  delete $3;
+			}
+                |	FORMID_TOK ':' Type '=' Formula
+			{
+			  //do type checking. if doesn't pass then abort
+			  BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+
+			  if($3.indexwidth != $5->GetIndexWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+			  if($3.valuewidth != $5->GetValueWidth())
+			    yyerror("Fatal Error: parsing: LET Expr: Type check fail: ");
+
+			  //set the valuewidth of the identifier
+			  $1->SetValueWidth($5->GetValueWidth());
+			  $1->SetIndexWidth($5->GetIndexWidth());
+
+			  //Do LET-expr management
+			  BEEV::globalBeevMgr_for_parser->LetExprMgr(*$1,*$5);
+			  delete $1;
+			  delete $5;
+			}                
+		;
+
+%%

Added: klee/trunk/stp/parser/let-funcs.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/parser/let-funcs.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/parser/let-funcs.cpp (added)
+++ klee/trunk/stp/parser/let-funcs.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,85 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include <stdlib.h>
+
+namespace BEEV {
+  //external parser table for declared symbols. Only symbols which are
+  //declared are stored here.
+  ASTNodeSet _parser_symbol_table;
+
+  // FUNC: This function maintains a map between LET-var names and
+  // LET-expressions
+  //
+  //1. if the Let-var is already defined in the LET scope, then the
+  //1. function returns an error.
+  //
+  //2. if the Let-var is already declared variable in the input, then
+  //2. the function returns an error
+  //
+  //3. otherwise add the <var,letExpr> pair to the _letid_expr table.
+  void BeevMgr::LetExprMgr(const ASTNode& var, const ASTNode& letExpr) {
+    ASTNodeMap::iterator it;
+    if(((it = _letid_expr_map.find(var)) != _letid_expr_map.end()) && 
+       it->second != ASTUndefined) {      
+      FatalError("LetExprMgr:The LET-var v has already been defined in this LET scope: v =", var);
+    }
+
+    if(_parser_symbol_table.find(var) != _parser_symbol_table.end()) {
+      FatalError("LetExprMgr:This var is already declared. cannot redeclare as a letvar: v =", var);
+    }
+
+    _letid_expr_map[var] = letExpr;   
+  }
+
+  //this function looksup the "var to letexpr map" and returns the
+  //corresponding letexpr. if there is no letexpr, then it simply
+  //returns the var.
+  ASTNode BeevMgr::ResolveID(const ASTNode& v) {
+    if(v.GetKind() != SYMBOL) {
+      return v;
+    }
+
+    if(_parser_symbol_table.find(v) != _parser_symbol_table.end()) {
+      return v;
+    }
+
+    ASTNodeMap::iterator it;
+    if((it =_letid_expr_map.find(v)) != _letid_expr_map.end()) {
+      if(it->second == ASTUndefined) 
+	FatalError("Unresolved Identifier: ",v);
+      else
+	return it->second;
+    }
+
+    //this is to mark the let-var as undefined. the let var is defined
+    //only after the LetExprMgr has completed its work, and until then
+    //'v' is undefined. 
+    //
+    //declared variables also get stored in this map, but there value
+    //is ASTUndefined. This is really a hack. I don't know how to get
+    //rid of this hack.
+    _letid_expr_map[v] = ASTUndefined;
+    return v;    
+  }
+  
+  // This function simply cleans up the LetID -> LetExpr Map.   
+  void BeevMgr::CleanupLetIDMap(void) { 
+    ASTNodeMap::iterator it = _letid_expr_map.begin();
+    ASTNodeMap::iterator itend = _letid_expr_map.end();
+    for(;it!=itend;it++) {
+      if(it->second != ASTUndefined) {
+	it->first.SetValueWidth(0);
+	it->first.SetIndexWidth(0);
+      }
+    }
+    _letid_expr_map.clear();
+  }
+};

Added: klee/trunk/stp/parser/main.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/parser/main.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/parser/main.cpp (added)
+++ klee/trunk/stp/parser/main.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,181 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <algorithm>
+#include <ctime>
+#include <unistd.h>
+#include <signal.h>
+//#include <zlib.h>
+#include <stdio.h>
+#include "../AST/AST.h"
+#include "parsePL_defs.h"
+#include "../sat/Solver.h"
+#include "../sat/SolverTypes.h"
+#include "../sat/VarOrder.h"
+
+#include <unistd.h>
+
+#ifdef EXT_HASH_MAP
+  using namespace __gnu_cxx;
+#endif
+
+/* GLOBAL FUNCTION: parser
+ */
+extern int yyparse();
+//extern int smtlibparse();
+
+/* GLOBAL VARS: Some global vars for the Main function.
+ *
+ */
+const char * prog = "stp";
+int linenum  = 1;
+const char * usage = "Usage: %s [-option] [infile]\n";
+std::string helpstring = "\n\n";
+
+// Amount of memory to ask for at beginning of main.
+static const intptr_t INITIAL_MEMORY_PREALLOCATION_SIZE = 4000000;
+
+// Used only in smtlib lexer/parser
+BEEV::ASTNode SingleBitOne;
+BEEV::ASTNode SingleBitZero;
+
+/******************************************************************************
+ * MAIN FUNCTION: 
+ *
+ * step 0. Parse the input into an ASTVec.
+ * step 1. Do BV Rewrites
+ * step 2. Bitblasts the ASTNode.
+ * step 3. Convert to CNF
+ * step 4. Convert to SAT
+ * step 5. Call SAT to determine if input is SAT or UNSAT
+ ******************************************************************************/
+int main(int argc, char ** argv) {
+  char * infile;
+  extern FILE *yyin;
+
+  // Grab some memory from the OS upfront to reduce system time when individual
+  // hash tables are being allocated
+
+  if (sbrk(INITIAL_MEMORY_PREALLOCATION_SIZE) == ((void *) -1)) {
+    // FIXME: figure out how to get and print the real error message.
+    BEEV::FatalError("Initial allocation of memory failed.");
+  }
+  
+  //populate the help string
+  helpstring +=  "-r  : switch refinement off (optimizations are ON by default)\n";
+  helpstring +=  "-w  : switch wordlevel solver off (optimizations are ON by default)\n";
+  helpstring +=  "-a  : switch optimizations off (optimizations are ON by default)\n";
+  helpstring +=  "-s  : print function statistics\n";
+  helpstring +=  "-v  : print nodes \n";
+  helpstring +=  "-c  : construct counterexample\n";
+  helpstring +=  "-d  : check counterexample\n";
+  helpstring +=  "-p  : print counterexample\n";
+  helpstring +=  "-x  : flatten nested XORs\n";
+  helpstring +=  "-h  : help\n";
+
+  for(int i=1; i < argc;i++) {
+    if(argv[i][0] == '-')
+      switch(argv[i][1]) {
+      case 'a' :
+	BEEV::optimize = false;
+	BEEV::wordlevel_solve = false;
+	break;
+      case 'b':
+	BEEV::print_STPinput_back = true;
+	break;
+      case 'c':
+	BEEV::construct_counterexample = true;
+	break;
+      case 'd':
+	BEEV::construct_counterexample = true;
+	BEEV::check_counterexample = true;
+	break;
+      case 'e':
+	BEEV::variable_activity_optimize = true;
+	break;
+      case 'f':
+	BEEV::smtlib_parser_enable = true;
+	break;
+      case 'h':
+	fprintf(stderr,usage,prog);
+	cout << helpstring;
+	//BEEV::FatalError("");
+	return -1;
+	break;
+      case 'l' :
+	BEEV::linear_search = true;
+	break;
+      case 'n':
+	BEEV::print_output = true;
+	break;
+      case 'p':
+	BEEV::print_counterexample = true;
+	break;
+      case 'q':
+	BEEV::print_arrayval_declaredorder = true;
+	break;
+      case 'r':
+	BEEV::arrayread_refinement = false;
+	break;
+      case 's' :
+	BEEV::stats = true;
+	break;
+      case 'u':
+	BEEV::arraywrite_refinement = false;
+	break;
+      case 'v' :
+	BEEV::print_nodes = true;
+	break;
+      case 'w':
+	BEEV::wordlevel_solve = false;
+	break;
+      case 'x':
+	BEEV::xor_flatten = true;
+	break;
+      case 'z':
+	BEEV::print_sat_varorder = true;
+	break;
+      default:
+	fprintf(stderr,usage,prog);
+	cout << helpstring;
+	//BEEV::FatalError("");
+	return -1;
+	break;
+      }
+    else {
+      infile = argv[i];
+      yyin = fopen(infile,"r");
+      if(yyin == NULL) {
+	fprintf(stderr,"%s: Error: cannot open %s\n",prog,infile);
+	BEEV::FatalError("");
+      }
+    }
+  }
+
+#ifdef NATIVE_C_ARITH
+#else
+  CONSTANTBV::ErrCode c = CONSTANTBV::BitVector_Boot(); 
+  if(0 != c) {
+    cout << CONSTANTBV::BitVector_Error(c) << endl;
+    return 0;
+  }
+#endif           
+
+  //want to print the output always from the commandline. 
+  BEEV::print_output = true;
+  BEEV::globalBeevMgr_for_parser = new BEEV::BeevMgr();  
+
+  SingleBitOne = BEEV::globalBeevMgr_for_parser->CreateOneConst(1);
+  SingleBitZero = BEEV::globalBeevMgr_for_parser->CreateZeroConst(1);
+  //BEEV::smtlib_parser_enable = true;
+  yyparse();
+}//end of Main

Added: klee/trunk/stp/parser/smtlib.lex
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/parser/smtlib.lex?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/parser/smtlib.lex (added)
+++ klee/trunk/stp/parser/smtlib.lex Wed May 20 23:36:41 2009
@@ -0,0 +1,232 @@
+%{
+  /********************************************************************
+   * AUTHORS: Vijay Ganesh, David L. Dill
+   *
+   * BEGIN DATE: July, 2006
+   *
+   * This file is modified version of the CVCL's smtlib.lex file. Please
+   * see CVCL license below
+   ********************************************************************/
+  
+  /********************************************************************
+   * \file smtlib.lex
+   * 
+   * Author: Sergey Berezin, Clark Barrett
+   * 
+   * Created: Apr 30 2005
+   *
+   * <hr>
+   * Copyright (C) 2004 by the Board of Trustees of Leland Stanford
+   * Junior University and by New York University. 
+   *
+   * License to use, copy, modify, sell and/or distribute this software
+   * and its documentation for any purpose is hereby granted without
+   * royalty, subject to the terms and conditions defined in the \ref
+   * LICENSE file provided with this distribution.  In particular:
+   *
+   * - The above copyright notice and this permission notice must appear
+   * in all copies of the software and related documentation.
+   *
+   * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
+   * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
+   * 
+   * <hr>
+   ********************************************************************/
+  // -*- c++ -*-
+#include <iostream>
+#include "../AST/AST.h"
+#include "parsePL_defs.h"
+  
+  extern char *yytext;
+  extern int yyerror (char *msg);
+  
+  // File-static (local to this file) variables and functions
+  static std::string _string_lit;
+  
+  static char escapeChar(char c) {
+    switch(c) {
+    case 'n': return '\n';
+    case 't': return '\t';
+    default: return c;
+    }
+  }      
+
+  extern BEEV::ASTNode SingleBitOne;
+  extern BEEV::ASTNode SingleBitZero;
+
+/* Changed for smtlib speedup */
+/* bv{DIGIT}+      { yylval.node = new BEEV::ASTNode(BEEV::_bm->CreateBVConst(yytext+2, 10)); return BVCONST_TOK;} */
+
+%}
+
+%option noyywrap
+%option nounput
+%option noreject
+%option noyymore
+%option yylineno
+
+%x	COMMENT
+%x	STRING_LITERAL
+%x      USER_VALUE
+
+LETTER	([a-zA-Z])
+DIGIT	([0-9])
+OPCHAR	(['\.\_]) 
+ANYTHING  ({LETTER}|{DIGIT}|{OPCHAR})
+
+%%
+[ \n\t\r\f]	{ /* sk'ip whitespace */ }
+{DIGIT}+	{ yylval.uintval = strtoul(yytext, NULL, 10); return NUMERAL_TOK; }
+
+
+bv{DIGIT}+	{ yylval.ullval = strtoull(yytext+2, NULL, 10); return BVCONST_TOK; }
+
+bit{DIGIT}+     {
+  		   char c = yytext[3];
+		   if (c == '1') {
+		     yylval.node = new BEEV::ASTNode(SingleBitOne);
+		   }
+		   else {
+		     yylval.node = new BEEV::ASTNode(SingleBitZero);
+		   }
+		   return BITCONST_TOK;
+		};
+
+
+";"		{ BEGIN COMMENT; }
+<COMMENT>"\n"	{ BEGIN INITIAL; /* return to normal mode */}
+<COMMENT>.	{ /* stay in comment mode */ }
+
+<INITIAL>"\""		{ BEGIN STRING_LITERAL;
+                          _string_lit.erase(_string_lit.begin(),
+                                            _string_lit.end()); }
+<STRING_LITERAL>"\\".	{ /* escape characters (like \n or \") */
+                          _string_lit.insert(_string_lit.end(),
+                                             escapeChar(yytext[1])); }
+<STRING_LITERAL>"\""	{ BEGIN INITIAL; /* return to normal mode */
+			  yylval.str = new std::string(_string_lit);
+                          return STRING_TOK; }
+<STRING_LITERAL>.	{ _string_lit.insert(_string_lit.end(),*yytext); }
+
+
+<INITIAL>"{"		{ BEGIN USER_VALUE;
+                          _string_lit.erase(_string_lit.begin(),
+                                            _string_lit.end()); }
+<USER_VALUE>"\\"[{}] { /* escape characters */
+                          _string_lit.insert(_string_lit.end(),yytext[1]); }
+
+<USER_VALUE>"}"	        { BEGIN INITIAL; /* return to normal mode */
+			  yylval.str = new std::string(_string_lit);
+                          return USER_VAL_TOK; }
+<USER_VALUE>"\n"        { _string_lit.insert(_string_lit.end(),'\n');}
+<USER_VALUE>.	        { _string_lit.insert(_string_lit.end(),*yytext); }
+
+"BitVec"        { return BITVEC_TOK;}
+"Array"         { return ARRAY_TOK;}
+"true"          { return TRUE_TOK; }
+"false"         { return FALSE_TOK; }
+"not"           { return NOT_TOK; }
+"implies"       { return IMPLIES_TOK; }
+"ite"           { return ITE_TOK;}
+"if_then_else"  { return IF_THEN_ELSE_TOK; }
+"and"           { return AND_TOK; }
+"or"            { return OR_TOK; }
+"xor"           { return XOR_TOK; }
+"iff"           { return IFF_TOK; }
+"let"           { return LET_TOK; }
+"flet"          { return FLET_TOK; }
+"notes"         { return NOTES_TOK; }
+"cvc_command"   { return CVC_COMMAND_TOK; }
+"sorts"         { return SORTS_TOK; }
+"funs"          { return FUNS_TOK; }
+"preds"         { return PREDS_TOK; }
+"extensions"    { return EXTENSIONS_TOK; }
+"definition"    { return DEFINITION_TOK; }
+"axioms"        { return AXIOMS_TOK; }
+"logic"         { return LOGIC_TOK; }
+"sat"           { return SAT_TOK; }
+"unsat"         { return UNSAT_TOK; }
+"unknown"       { return UNKNOWN_TOK; }
+"assumption"    { return ASSUMPTION_TOK; }
+"formula"       { return FORMULA_TOK; }
+"status"        { return STATUS_TOK; }
+"difficulty"    { return DIFFICULTY_TOK; }
+"benchmark"     { return BENCHMARK_TOK; }
+"source"        { return SOURCE_TOK;}
+"category"      { return CATEGORY_TOK;} 
+"extrasorts"    { return EXTRASORTS_TOK; }
+"extrafuns"     { return EXTRAFUNS_TOK; }
+"extrapreds"    { return EXTRAPREDS_TOK; }
+"language"      { return LANGUAGE_TOK; }
+"distinct"      { return DISTINCT_TOK; }
+"select"        { return SELECT_TOK; }
+"store"         { return STORE_TOK; }
+":"             { return COLON_TOK; }
+"\["            { return LBRACKET_TOK; }
+"\]"            { return RBRACKET_TOK; }
+"("             { return LPAREN_TOK; }
+")"             { return RPAREN_TOK; }
+"$"             { return DOLLAR_TOK; }
+"?"             { return QUESTION_TOK; }
+"="             {return EQ_TOK;}
+
+"nand"		{ return NAND_TOK;}
+"nor"		{ return NOR_TOK;}
+"/="		{ return NEQ_TOK; }
+ ":="           { return ASSIGN_TOK;}
+"shift_left0"   { return BVLEFTSHIFT_TOK;}
+"bvshl"         { return BVLEFTSHIFT_1_TOK;}
+"shift_right0"  { return BVRIGHTSHIFT_TOK;}
+"bvlshr"        { return BVRIGHTSHIFT_1_TOK;}
+"bvadd"         { return BVPLUS_TOK;}
+"bvsub"         { return BVSUB_TOK;}
+"bvnot"         { return BVNOT_TOK;}
+"bvmul"         { return BVMULT_TOK;}
+"bvdiv"         { return BVDIV_TOK;}
+"bvmod"         { return BVMOD_TOK;}
+"bvneg"         { return BVNEG_TOK;}
+"bvand"         { return BVAND_TOK;}
+"bvor"          { return BVOR_TOK;}
+"bvxor"         { return BVXOR_TOK;}
+"bvnand"        { return BVNAND_TOK;}
+"bvnor"         { return BVNOR_TOK;}
+"bvxnor"        { return BVXNOR_TOK;}
+"concat"        { return BVCONCAT_TOK;}
+"extract"       { return BVEXTRACT_TOK;}
+"bvlt"          { return BVLT_TOK;}
+"bvgt"          { return BVGT_TOK;}
+"bvleq"         { return BVLE_TOK;}
+"bvgeq"         { return BVGE_TOK;}
+"bvult"         { return BVLT_TOK;}
+"bvugt"         { return BVGT_TOK;}
+"bvuleq"        { return BVLE_TOK;}
+"bvugeq"        { return BVGE_TOK;}
+"bvule"         { return BVLE_TOK;}
+"bvuge"         { return BVGE_TOK;}
+
+"bvslt"         { return BVSLT_TOK;}
+"bvsgt"         { return BVSGT_TOK;}
+"bvsleq"        { return BVSLE_TOK;}
+"bvsgeq"        { return BVSGE_TOK;}
+"bvsle"         { return BVSLE_TOK;}
+"bvsge"         { return BVSGE_TOK;}
+
+"sign_extend"   { return BVSX_TOK;} 
+"boolextract"   { return BOOLEXTRACT_TOK;}
+"boolbv"        { return BOOL_TO_BV_TOK;}
+
+(({LETTER})|(_)({ANYTHING}))({ANYTHING})*	{
+  BEEV::ASTNode nptr = BEEV::globalBeevMgr_for_parser->CreateSymbol(yytext); 
+
+  // Check valuesize to see if it's a prop var.  I don't like doing
+  // type determination in the lexer, but it's easier than rewriting
+  // the whole grammar to eliminate the term/formula distinction.  
+  yylval.node = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(nptr));
+  //yylval.node = new BEEV::ASTNode(nptr);
+  if ((yylval.node)->GetType() == BEEV::BOOLEAN_TYPE)
+    return FORMID_TOK;
+  else 
+    return TERMID_TOK;  
+}
+. { yyerror("Illegal input character."); }
+%%

Added: klee/trunk/stp/parser/smtlib.y
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/parser/smtlib.y?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/parser/smtlib.y (added)
+++ klee/trunk/stp/parser/smtlib.y Wed May 20 23:36:41 2009
@@ -0,0 +1,1036 @@
+%{
+  /********************************************************************
+   * AUTHORS: Vijay Ganesh, David L. Dill
+   *
+   * BEGIN DATE: July, 2006
+   *
+   * This file is modified version of the CVCL's smtlib.y file. Please
+   * see CVCL license below
+   ********************************************************************/
+  
+  /********************************************************************
+   *
+   * \file smtlib.y
+   * 
+   * Author: Sergey Berezin, Clark Barrett
+   * 
+   * Created: Apr 30 2005
+   *
+   * <hr>
+   * Copyright (C) 2004 by the Board of Trustees of Leland Stanford
+   * Junior University and by New York University. 
+   *
+   * License to use, copy, modify, sell and/or distribute this software
+   * and its documentation for any purpose is hereby granted without
+   * royalty, subject to the terms and conditions defined in the \ref
+   * LICENSE file provided with this distribution.  In particular:
+   *
+   * - The above copyright notice and this permission notice must appear
+   * in all copies of the software and related documentation.
+   *
+   * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
+   * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
+   * 
+   * <hr>
+   ********************************************************************/
+  // -*- c++ -*-
+
+#include "../AST/AST.h"
+  using namespace std; 
+  
+  // Suppress the bogus warning suppression in bison (it generates
+  // compile error)
+#undef __GNUC_MINOR__
+  
+  extern char* yytext;
+  extern int yylineno;
+  
+  //int yylineno;
+
+  extern int yylex(void);
+
+  int yyerror(char *s) {
+    //yylineno = 0;
+    cout << "syntax error: line " << yylineno << "\n" << s << endl;
+    cout << "  token: " << yytext << endl;
+    BEEV::FatalError("");
+    return 1;
+  }
+
+  BEEV::ASTNode query;
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYMAXDEPTH 104857600
+#define YYERROR_VERBOSE 1
+#define YY_EXIT_FAILURE -1
+%}
+
+%union {  
+  // FIXME: Why is this not an UNSIGNED int?
+  int uintval;			/* for numerals in types. */
+
+  // for BV32 BVCONST 
+  unsigned long long ullval;
+
+  struct {
+    //stores the indexwidth and valuewidth
+    //indexwidth is 0 iff type is bitvector. positive iff type is
+    //array, and stores the width of the indexing bitvector
+    unsigned int indexwidth;
+    //width of the bitvector type
+    unsigned int valuewidth;
+  } indexvaluewidth;
+
+  //ASTNode,ASTVec
+  BEEV::ASTNode *node;
+  BEEV::ASTVec *vec;
+  std::string *str;
+};
+
+%start cmd
+
+%type <indexvaluewidth> sort_symb sort_symbs
+%type <node> status
+%type <vec> bench_attributes an_formulas
+
+%type <node> benchmark bench_name bench_attribute
+%type <node> an_term an_nonbvconst_term an_formula 
+
+%type <node> var fvar logic_name
+%type <str> user_value
+
+%token <uintval> NUMERAL_TOK
+%token <ullval> BVCONST_TOK
+%token <node> BITCONST_TOK
+%token <node> FORMID_TOK TERMID_TOK 
+%token <str> STRING_TOK
+%token <str> USER_VAL_TOK
+%token SOURCE_TOK
+%token CATEGORY_TOK
+%token DIFFICULTY_TOK
+%token BITVEC_TOK
+%token ARRAY_TOK
+%token SELECT_TOK
+%token STORE_TOK
+%token TRUE_TOK
+%token FALSE_TOK
+%token NOT_TOK
+%token IMPLIES_TOK
+%token ITE_TOK
+%token IF_THEN_ELSE_TOK
+%token AND_TOK
+%token OR_TOK
+%token XOR_TOK
+%token IFF_TOK
+%token EXISTS_TOK
+%token FORALL_TOK
+%token LET_TOK
+%token FLET_TOK
+%token NOTES_TOK
+%token CVC_COMMAND_TOK
+%token SORTS_TOK
+%token FUNS_TOK
+%token PREDS_TOK
+%token EXTENSIONS_TOK
+%token DEFINITION_TOK
+%token AXIOMS_TOK
+%token LOGIC_TOK
+%token COLON_TOK
+%token LBRACKET_TOK
+%token RBRACKET_TOK
+%token LPAREN_TOK
+%token RPAREN_TOK
+%token SAT_TOK
+%token UNSAT_TOK
+%token UNKNOWN_TOK
+%token ASSUMPTION_TOK
+%token FORMULA_TOK
+%token STATUS_TOK
+%token BENCHMARK_TOK
+%token EXTRASORTS_TOK
+%token EXTRAFUNS_TOK
+%token EXTRAPREDS_TOK
+%token LANGUAGE_TOK
+%token DOLLAR_TOK
+%token QUESTION_TOK
+%token DISTINCT_TOK
+%token SEMICOLON_TOK
+%token EOF_TOK
+%token EQ_TOK
+/*BV SPECIFIC TOKENS*/
+%token NAND_TOK
+%token NOR_TOK
+%token NEQ_TOK
+%token ASSIGN_TOK
+%token BV_TOK
+%token BOOLEAN_TOK
+%token BVLEFTSHIFT_TOK
+%token BVLEFTSHIFT_1_TOK
+%token BVRIGHTSHIFT_TOK
+%token BVRIGHTSHIFT_1_TOK
+%token BVPLUS_TOK
+%token BVSUB_TOK
+%token BVNOT_TOK //bvneg in CVCL
+%token BVMULT_TOK
+%token BVDIV_TOK
+%token BVMOD_TOK
+%token BVNEG_TOK //bvuminus in CVCL
+%token BVAND_TOK
+%token BVOR_TOK
+%token BVXOR_TOK
+%token BVNAND_TOK
+%token BVNOR_TOK
+%token BVXNOR_TOK
+%token BVCONCAT_TOK
+%token BVLT_TOK
+%token BVGT_TOK
+%token BVLE_TOK
+%token BVGE_TOK
+%token BVSLT_TOK
+%token BVSGT_TOK
+%token BVSLE_TOK
+%token BVSGE_TOK
+%token BVSX_TOK 
+%token BOOLEXTRACT_TOK
+%token BOOL_TO_BV_TOK
+%token BVEXTRACT_TOK
+
+%left LBRACKET_TOK RBRACKET_TOK
+
+%%
+
+cmd:
+    benchmark
+    {
+      if($1 != NULL) {
+	BEEV::globalBeevMgr_for_parser->TopLevelSAT(*$1,query);
+	delete $1;
+      }
+      YYACCEPT;
+    }
+;
+
+benchmark:
+    LPAREN_TOK BENCHMARK_TOK bench_name bench_attributes RPAREN_TOK
+    {
+      if($4 != NULL){
+	if($4->size() > 1) 
+	  $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND,*$4));
+	else
+	  $$ = new BEEV::ASTNode((*$4)[0]);	  
+	delete $4;
+      }
+      else {
+	$$ = NULL;
+      }
+    }
+/*   | EOF_TOK */
+/*     { */
+/*     } */
+;
+
+bench_name:
+    FORMID_TOK
+    {
+    }
+;
+
+bench_attributes:
+    bench_attribute
+    {
+      $$ = new BEEV::ASTVec;
+      if ($1 != NULL) {
+	$$->push_back(*$1);
+	BEEV::globalBeevMgr_for_parser->AddAssert(*$1);
+	delete $1;
+      }
+    }
+  | bench_attributes bench_attribute
+    {
+      if ($1 != NULL && $2 != NULL) {
+	$1->push_back(*$2);
+	BEEV::globalBeevMgr_for_parser->AddAssert(*$2);
+	$$ = $1;
+	delete $2;
+      }
+    }
+;
+
+bench_attribute:
+    COLON_TOK ASSUMPTION_TOK an_formula
+    {
+      //assumptions are like asserts
+      $$ = $3;
+    }
+  | COLON_TOK FORMULA_TOK an_formula
+    {
+      //the query
+      query = BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT,*$3);
+      BEEV::globalBeevMgr_for_parser->AddQuery(query);
+      //dummy true
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE));
+      
+      
+    }
+  | COLON_TOK STATUS_TOK status
+    {
+      $$ = NULL;
+    }
+  | COLON_TOK LOGIC_TOK logic_name
+    {
+      if (!(0 == strcmp($3->GetName(),"QF_UFBV")  ||
+            0 == strcmp($3->GetName(),"QF_AUFBV"))) {
+	yyerror("Wrong input logic:");
+      }
+      $$ = NULL;
+    }
+  | COLON_TOK EXTRAFUNS_TOK LPAREN_TOK var_decls RPAREN_TOK
+    {
+      $$ = NULL;
+    }
+  | COLON_TOK EXTRAPREDS_TOK LPAREN_TOK var_decls RPAREN_TOK
+    {
+      $$ = NULL;
+    }
+  | annotation 
+    {
+      $$ = NULL;
+    }
+;
+
+logic_name:
+    FORMID_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      $$ = $1;
+    }
+  | FORMID_TOK
+    {
+      $$ = $1;
+    }
+;
+
+status:
+    SAT_TOK { $$ = NULL; }
+  | UNSAT_TOK { $$ = NULL; }
+  | UNKNOWN_TOK { $$ = NULL; }
+;
+
+
+/* annotations: */
+/*     annotation */
+/*     { */
+/*     } */
+/*   | annotations annotation */
+/*     { */
+/*     } */
+/*   ; */
+  
+annotation:
+    attribute 
+    {
+    }
+  | attribute user_value 
+    {
+    }
+;
+
+user_value:
+    USER_VAL_TOK
+    {
+      //cerr << "Printing user_value: " << *$1 << endl;
+    }
+;
+
+attribute:
+    COLON_TOK SOURCE_TOK
+    {
+    }
+   | COLON_TOK CATEGORY_TOK
+    {
+    }
+   | COLON_TOK DIFFICULTY_TOK 
+;
+
+sort_symbs:
+    sort_symb 
+    {
+      //a single sort symbol here means either a BitVec or a Boolean
+      $$.indexwidth = $1.indexwidth;
+      $$.valuewidth = $1.valuewidth;
+    }
+  | sort_symb sort_symb
+    {
+      //two sort symbols mean f: type --> type
+      $$.indexwidth = $1.valuewidth;
+      $$.valuewidth = $2.valuewidth;
+    }
+;
+
+var_decls:
+    var_decl
+    {
+    }
+//  | LPAREN_TOK var_decl RPAREN_TOK
+  |
+    var_decls var_decl
+    {
+    }
+;
+
+var_decl:
+    LPAREN_TOK FORMID_TOK sort_symbs RPAREN_TOK
+    {
+      BEEV::_parser_symbol_table.insert(*$2);
+      //Sort_symbs has the indexwidth/valuewidth. Set those fields in
+      //var
+      $2->SetIndexWidth($3.indexwidth);
+      $2->SetValueWidth($3.valuewidth);
+    }
+   | LPAREN_TOK FORMID_TOK RPAREN_TOK
+    {
+      BEEV::_parser_symbol_table.insert(*$2);
+      //Sort_symbs has the indexwidth/valuewidth. Set those fields in
+      //var
+      $2->SetIndexWidth(0);
+      $2->SetValueWidth(0);
+    }
+;
+
+an_formulas:
+    an_formula
+    {
+      $$ = new BEEV::ASTVec;
+      if ($1 != NULL) {
+	$$->push_back(*$1);
+	delete $1;
+      }
+    }
+  |
+    an_formulas an_formula
+    {
+      if ($1 != NULL && $2 != NULL) {
+	$1->push_back(*$2);
+	$$ = $1;
+	delete $2;
+      }
+    }
+;
+
+an_formula:   
+    TRUE_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::TRUE)); 
+      $$->SetIndexWidth(0); 
+      $$->SetValueWidth(0);
+    }
+  | FALSE_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::FALSE)); 
+      $$->SetIndexWidth(0); 
+      $$->SetValueWidth(0);
+    }
+  | fvar
+    {
+      $$ = $1;
+    }
+  | LPAREN_TOK EQ_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK EQ_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateSimplifiedEQ(*$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSLT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSLT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSLE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSLE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSLE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSGT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSGT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVSGE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVSGE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVSGE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVLT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVLT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVLE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVLE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVLE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVGT_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVGT_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGT, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK BVGE_TOK an_term an_term RPAREN_TOK
+  //| LPAREN_TOK BVGE_TOK an_term an_term annotations RPAREN_TOK
+    {
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::BVGE, *$3, *$4));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $3;
+      delete $4;      
+    }
+  | LPAREN_TOK an_formula RPAREN_TOK
+    {
+      $$ = $2;
+    }
+  | LPAREN_TOK NOT_TOK an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::NOT, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK IMPLIES_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IMPLIES, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | LPAREN_TOK IF_THEN_ELSE_TOK an_formula an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::ITE, *$3, *$4, *$5));
+      delete $3;
+      delete $4;
+      delete $5;
+    }
+  | LPAREN_TOK AND_TOK an_formulas RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::AND, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK OR_TOK an_formulas RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::OR, *$3));
+      delete $3;
+    }
+  | LPAREN_TOK XOR_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::XOR, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | LPAREN_TOK IFF_TOK an_formula an_formula RPAREN_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateNode(BEEV::IFF, *$3, *$4));
+      delete $3;
+      delete $4;
+    }
+  | letexpr_mgmt an_formula RPAREN_TOK
+  //| letexpr_mgmt an_formula annotations RPAREN_TOK
+    {
+      $$ = $2;
+      //Cleanup the LetIDToExprMap
+      BEEV::globalBeevMgr_for_parser->CleanupLetIDMap();			 
+    }
+;
+
+letexpr_mgmt: 
+    LPAREN_TOK LET_TOK LPAREN_TOK QUESTION_TOK FORMID_TOK an_term RPAREN_TOK
+    {
+     //Expr must typecheck
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$6);
+      
+      //set the valuewidth of the identifier
+      $5->SetValueWidth($6->GetValueWidth());
+      $5->SetIndexWidth($6->GetIndexWidth());
+      
+      //populate the hashtable from LET-var -->
+      //LET-exprs and then process them:
+      //
+      //1. ensure that LET variables do not clash
+      //1. with declared variables.
+      //
+      //2. Ensure that LET variables are not
+      //2. defined more than once
+      BEEV::globalBeevMgr_for_parser->LetExprMgr(*$5,*$6);
+      delete $5;
+      delete $6;      
+   }
+ | LPAREN_TOK FLET_TOK LPAREN_TOK DOLLAR_TOK FORMID_TOK an_formula RPAREN_TOK 
+   {
+     //Expr must typecheck
+     BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$6);
+     
+     //set the valuewidth of the identifier
+     $5->SetValueWidth($6->GetValueWidth());
+     $5->SetIndexWidth($6->GetIndexWidth());
+     
+     //Do LET-expr management
+     BEEV::globalBeevMgr_for_parser->LetExprMgr(*$5,*$6);
+     delete $5;
+     delete $6;     
+   }
+
+/* an_terms: */
+/*     an_term */
+/*     { */
+/*     } */
+/*   | an_terms an_term */
+/*     { */
+/*     } */
+/* ; */
+
+an_term:
+    BVCONST_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(64, $1));
+    }
+  | BVCONST_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst($3, $1));
+    }
+  | an_nonbvconst_term
+  ;
+
+an_nonbvconst_term: 
+    BITCONST_TOK { $$ = $1; }
+  | var
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1));
+      delete $1;
+    }
+  | LPAREN_TOK an_term RPAREN_TOK
+  //| LPAREN_TOK an_term annotations RPAREN_TOK
+    {
+      $$ = $2;
+      //$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->SimplifyTerm(*$2));
+      //delete $2;
+    }
+  | LPAREN_TOK TERMID_TOK an_term RPAREN_TOK
+    {
+      //ARRAY READ
+      // valuewidth is same as array, indexwidth is 0.
+      BEEV::ASTNode in = *$2;
+      BEEV::ASTNode m = *$3;
+      unsigned int width = in.GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, in, m));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  | SELECT_TOK an_term an_term
+    {
+      //ARRAY READ
+      // valuewidth is same as array, indexwidth is 0.
+      BEEV::ASTNode array = *$2;
+      BEEV::ASTNode index = *$3;
+      unsigned int width = array.GetValueWidth();
+      BEEV::ASTNode * n = 
+	new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::READ, width, array, index));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  | STORE_TOK an_term an_term an_term
+    {
+      //ARRAY WRITE
+      unsigned int width = $4->GetValueWidth();
+      BEEV::ASTNode array = *$2;
+      BEEV::ASTNode index = *$3;
+      BEEV::ASTNode writeval = *$4;
+      BEEV::ASTNode write_term = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::WRITE,width,array,index,writeval);
+      write_term.SetIndexWidth($2->GetIndexWidth());
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(write_term);
+      BEEV::ASTNode * n = new BEEV::ASTNode(write_term);
+      $$ = n;
+      delete $2;
+      delete $3;
+      delete $4;
+    }
+/*   | BVEXTRACT_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK BVCONST_TOK */
+/*     { */
+/*       // This special case is when we have an extract on top of a constant bv, which happens */
+/*       // almost all the time in the smt syntax. */
+
+/*       // $3 is high, $5 is low.  They are ints (why not unsigned? See uintval) */
+/*       int hi  =  $3; */
+/*       int low =  $5; */
+/*       int width = hi - low + 1; */
+
+/*       if (width < 0) */
+/* 	yyerror("Negative width in extract"); */
+
+/*       unsigned long long int val = $7; */
+
+/*       // cut and past from BV32 const evaluator */
+
+/*       unsigned long long int mask1 = 0xffffffffffffffffLL; */
+
+/*       mask1 >>= 64-(hi+1); */
+      
+/*       //extract val[hi:0] */
+/*       val &= mask1; */
+/*       //extract val[hi:low] */
+/*       val >>= low; */
+
+/*       // val is the desired BV32. */
+/*       BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(width, val)); */
+/*       $$ = n; */
+/*     } */
+  | BVEXTRACT_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK an_term
+    {
+      int width = $3 - $5 + 1;
+      if (width < 0)
+	yyerror("Negative width in extract");
+      
+      if((unsigned)$3 >= $7->GetValueWidth() || (unsigned)$5 < 0)
+	yyerror("Parsing: Wrong width in BVEXTRACT\n");			 
+      
+      BEEV::ASTNode hi  =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $3);
+      BEEV::ASTNode low =  BEEV::globalBeevMgr_for_parser->CreateBVConst(32, $5);
+      BEEV::ASTNode output = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT, width, *$7,hi,low);
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->SimplifyTerm(output));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $7;
+    }
+  |  ITE_TOK an_formula an_term an_term 
+    {
+      unsigned int width = $3->GetValueWidth();
+      if (width != $4->GetValueWidth()) {
+	cerr << *$3;
+	cerr << *$4;
+	yyerror("Width mismatch in IF-THEN-ELSE");
+      }			 
+      if($3->GetIndexWidth() != $4->GetIndexWidth())
+	yyerror("Width mismatch in IF-THEN-ELSE");
+      
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$2);
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$3);
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$4);
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateSimplifiedTermITE(*$2, *$3, *$4));
+      //$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::ITE,width,*$2, *$3, *$4));
+      $$->SetIndexWidth($4->GetIndexWidth());
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$$);
+      delete $2;
+      delete $3;
+      delete $4;
+    }
+  |  BVCONCAT_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth() + $3->GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      
+      delete $2;
+      delete $3;
+    }
+  |  BVNOT_TOK an_term
+    {
+      //this is the BVNEG (term) in the CVCL language
+      unsigned int width = $2->GetValueWidth();
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNEG, width, *$2));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+    }
+  |  BVNEG_TOK an_term
+    {
+      //this is the BVUMINUS term in CVCL langauge
+      unsigned width = $2->GetValueWidth();
+      BEEV::ASTNode * n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVUMINUS,width,*$2));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+    }
+  |  BVAND_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in AND");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVAND, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in OR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVOR, width, *$2, *$3)); 
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVXOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in XOR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVXOR, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVSUB_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVSUB");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSUB, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVPLUS_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVPLUS");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVPLUS, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+
+    }
+  |  BVMULT_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVMULT");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVMULT, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVNAND_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVNAND");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNAND, width, *$2, *$3));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVNOR_TOK an_term an_term 
+    {
+      unsigned int width = $2->GetValueWidth();
+      if (width != $3->GetValueWidth()) {
+	yyerror("Width mismatch in BVNOR");
+      }
+      BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVNOR, width, *$2, *$3)); 
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $2;
+      delete $3;
+    }
+  |  BVLEFTSHIFT_TOK an_term NUMERAL_TOK 
+    {
+      unsigned int w = $2->GetValueWidth();
+      if((unsigned)$3 < w) {
+	BEEV::ASTNode trailing_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst($3, 0);
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32, w-$3-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,0);
+	BEEV::ASTNode m = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,w,m,trailing_zeros));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      delete $2;
+    }
+   |  BVLEFTSHIFT_1_TOK an_term an_term 
+    {
+      unsigned int w = $2->GetValueWidth();
+      unsigned int shift_amt = GetUnsignedConst(*$3);
+      if((unsigned)shift_amt < w) {
+	BEEV::ASTNode trailing_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32, w-shift_amt-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,0);
+	BEEV::ASTNode m = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,w,m,trailing_zeros));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+      //delete $3;
+    }
+  |  BVRIGHTSHIFT_TOK an_term NUMERAL_TOK 
+    {
+      BEEV::ASTNode leading_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst($3, 0);
+      unsigned int w = $2->GetValueWidth();
+      
+      //the amount by which you are rightshifting
+      //is less-than/equal-to the length of input
+      //bitvector
+      if((unsigned)$3 < w) {
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,$3);
+	BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-$3,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,leading_zeros, extract));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+    }
+   |  BVRIGHTSHIFT_1_TOK an_term an_term 
+    {
+      unsigned int shift_amt = GetUnsignedConst(*$3);
+      BEEV::ASTNode leading_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
+      unsigned int w = $2->GetValueWidth();
+      
+      //the amount by which you are rightshifting
+      //is less-than/equal-to the length of input
+      //bitvector
+      if((unsigned)shift_amt < w) {
+	BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
+	BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,shift_amt);
+	BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
+	BEEV::ASTNode * n = 
+	  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,leading_zeros, extract));
+	BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+	$$ = n;
+      }
+      else {
+	$$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
+      }
+      delete $2;
+    }
+  |  BVSX_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK an_term 
+    {
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*$5);
+      unsigned w = $5->GetValueWidth() + $3;
+      BEEV::ASTNode width = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w);
+      BEEV::ASTNode *n =  new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVSX,w,*$5,width));
+      BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+      $$ = n;
+      delete $5;
+    }
+;
+  
+sort_symb:
+    BITVEC_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      // Just return BV width.  If sort is BOOL, width is 0.
+      // Otherwise, BITVEC[w] returns w. 
+      //
+      //((indexwidth is 0) && (valuewidth>0)) iff type is BV
+      $$.indexwidth = 0;
+      unsigned int length = $3;
+      if(length > 0) {
+	$$.valuewidth = length;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+    }
+   | ARRAY_TOK LBRACKET_TOK NUMERAL_TOK COLON_TOK NUMERAL_TOK RBRACKET_TOK
+    {
+      unsigned int index_len = $3;
+      unsigned int value_len = $5;
+      if(index_len > 0) {
+	$$.indexwidth = $3;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+
+      if(value_len > 0) {
+	$$.valuewidth = $5;
+      }
+      else {
+	BEEV::FatalError("Fatal Error: parsing: BITVECTORS must be of positive length: \n");
+      }
+    }
+;
+
+var:
+    FORMID_TOK 
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); 
+      delete $1;      
+    }
+   | TERMID_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1));
+      delete $1;
+    }
+   | QUESTION_TOK TERMID_TOK
+    {
+      $$ = $2;
+    }
+;
+
+fvar:
+    DOLLAR_TOK FORMID_TOK
+    {
+      $$ = $2; 
+    }
+  | FORMID_TOK
+    {
+      $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->ResolveID(*$1)); 
+      delete $1;      
+    }   
+;
+%%

Added: klee/trunk/stp/sat/Global.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Global.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Global.h (added)
+++ klee/trunk/stp/sat/Global.h Wed May 20 23:36:41 2009
@@ -0,0 +1,255 @@
+/****************************************************************************************[Global.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Global_h
+#define Global_h
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <new>
+
+// PKT: needs to be outside namespace MINISAT or mac os x compilation breaks
+#ifdef _MSC_VER
+#else
+#include <unistd.h>
+#endif
+
+namespace MINISAT {
+//=================================================================================================
+// Basic Types & Minor Things:
+
+// DWD: This is needed on darwin.
+typedef unsigned int uint;
+
+#ifdef _MSC_VER
+
+typedef INT64              int64;
+typedef UINT64             uint64;
+typedef INT_PTR            intp;
+typedef UINT_PTR           uintp;
+#define I64_fmt "I64d"
+#else
+
+typedef long long          int64;
+typedef unsigned long long uint64;
+typedef __PTRDIFF_TYPE__   intp;
+typedef unsigned __PTRDIFF_TYPE__ uintp;
+#define I64_fmt "lld"
+#endif
+
+template<class T> static inline T min(T x, T y) { return (x < y) ? x : y; }
+template<class T> static inline T max(T x, T y) { return (x > y) ? x : y; }
+
+template <bool> struct STATIC_ASSERTION_FAILURE;
+template <> struct STATIC_ASSERTION_FAILURE<true>{};
+#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE<false>()
+
+
+//=================================================================================================
+// 'malloc()'-style memory allocation -- never returns NULL; aborts instead:
+
+
+template<class T> static inline T* xmalloc(size_t size) {
+    T*   tmp = (T*)malloc(size * sizeof(T));
+    assert(size == 0 || tmp != NULL);
+    return tmp; }
+
+template<class T> static inline T* xrealloc(T* ptr, size_t size) {
+    T*   tmp = (T*)realloc((void*)ptr, size * sizeof(T));
+    assert(size == 0 || tmp != NULL);
+    return tmp; }
+
+template<class T> static inline void xfree(T *ptr) {
+    if (ptr != NULL) free((void*)ptr); }
+
+
+//=================================================================================================
+// Random numbers:
+
+
+// Returns a random float 0 <= x < 1. Seed must never be 0.
+static inline double drand(double& seed) {
+    seed *= 1389796;
+    int q = (int)(seed / 2147483647);
+    seed -= (double)q * 2147483647;
+    return seed / 2147483647; }
+
+// Returns a random integer 0 <= x < size. Seed must never be 0.
+static inline int irand(double& seed, int size) {
+    return (int)(drand(seed) * size); }
+
+
+//=================================================================================================
+// 'vec' -- automatically resizable arrays (via 'push()' method):
+
+
+// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
+
+template<class T>
+class vec {
+    T*  data;
+    int sz;
+    int cap;
+
+    void     init(int size, const T& pad);
+    void     grow(int min_cap);
+
+public:
+    // Types:
+    typedef int Key;
+    typedef T   Datum;
+
+    // Constructors:
+    vec(void)                   : data(NULL) , sz(0)   , cap(0)    { }
+    vec(int size)               : data(NULL) , sz(0)   , cap(0)    { growTo(size); }
+    vec(int size, const T& pad) : data(NULL) , sz(0)   , cap(0)    { growTo(size, pad); }
+    vec(T* array, int size)     : data(array), sz(size), cap(size) { }      // (takes ownership of array -- will be deallocated with 'xfree()')
+   ~vec(void)                                                      { clear(true); }
+
+    // Ownership of underlying array:
+    T*       release  (void)           { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; }
+    operator T*       (void)           { return data; }     // (unsafe but convenient)
+    operator const T* (void) const     { return data; }
+
+    // Size operations:
+    int      size   (void) const       { return sz; }
+    void     shrink (int nelems)       { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
+    void     pop    (void)             { sz--, data[sz].~T(); }
+    void     growTo (int size);
+    void     growTo (int size, const T& pad);
+    void     clear  (bool dealloc = false);
+    void     capacity (int size) { grow(size); }
+
+    // Stack interface:
+    void     push  (void)              { if (sz == cap) grow(sz+1); new (&data[sz]) T()    ; sz++; }
+    void     push  (const T& elem)     { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; }
+    const T& last  (void) const        { return data[sz-1]; }
+    T&       last  (void)              { return data[sz-1]; }
+
+    // Vector interface:
+    const T& operator [] (int index) const  { return data[index]; }
+    T&       operator [] (int index)        { return data[index]; }
+
+    // Don't allow copying (error prone):
+    vec<T>&  operator = (vec<T>& other) { TEMPLATE_FAIL; }
+             vec        (vec<T>& other) { TEMPLATE_FAIL; }
+
+    // Duplicatation (preferred instead):
+    void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (&copy[i]) T(data[i]); }
+    void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
+};
+
+template<class T>
+void vec<T>::grow(int min_cap) {
+    if (min_cap <= cap) return;
+    if (cap == 0) cap = (min_cap >= 2) ? min_cap : 2;
+    else          do cap = (cap*3+1) >> 1; while (cap < min_cap);
+    data = xrealloc(data, cap); }
+
+template<class T>
+void vec<T>::growTo(int size, const T& pad) {
+    if (sz >= size) return;
+    grow(size);
+    for (int i = sz; i < size; i++) new (&data[i]) T(pad);
+    sz = size; }
+
+template<class T>
+void vec<T>::growTo(int size) {
+    if (sz >= size) return;
+    grow(size);
+    for (int i = sz; i < size; i++) new (&data[i]) T();
+    sz = size; }
+
+template<class T>
+void vec<T>::clear(bool dealloc) {
+    if (data != NULL){
+        for (int i = 0; i < sz; i++) data[i].~T();
+        sz = 0;
+        if (dealloc) xfree(data), data = NULL, cap = 0; } }
+
+
+//=================================================================================================
+// Useful functions on vectors
+
+
+template<class V, class T>
+void remove(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    assert(j < ts.size());
+    for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
+    ts.pop();
+}
+
+
+template<class V, class T>
+bool find(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    return j < ts.size();
+}
+
+//=================================================================================================
+// Lifted booleans:
+
+
+class lbool {
+    int     value;
+    explicit lbool(int v) : value(v) { }
+
+public:
+    lbool()       : value(0) { }
+    lbool(bool x) : value((int)x*2-1) { }
+    int toInt(void) const { return value; }
+
+    bool  operator == (const lbool& other) const { return value == other.value; }
+    bool  operator != (const lbool& other) const { return value != other.value; }
+    lbool operator ~  (void)               const { return lbool(-value); }
+
+    friend int   toInt  (lbool l);
+    friend lbool toLbool(int   v);
+};
+inline int   toInt  (lbool l) { return l.toInt(); }
+inline lbool toLbool(int   v) { return lbool(v);  }
+
+const lbool l_True  = toLbool( 1);
+const lbool l_False = toLbool(-1);
+const lbool l_Undef = toLbool( 0);
+
+
+//=================================================================================================
+// Relation operators -- extend definitions from '==' and '<'
+
+
+#ifndef __SGI_STL_INTERNAL_RELOPS   // (be aware of SGI's STL implementation...)
+#define __SGI_STL_INTERNAL_RELOPS
+template <class T> static inline bool operator != (const T& x, const T& y) { return !(x == y); }
+template <class T> static inline bool operator >  (const T& x, const T& y) { return y < x;     }
+template <class T> static inline bool operator <= (const T& x, const T& y) { return !(y < x);  }
+template <class T> static inline bool operator >= (const T& x, const T& y) { return !(x < y);  }
+#endif
+
+
+//=================================================================================================
+};
+#endif

Added: klee/trunk/stp/sat/Heap.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Heap.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Heap.h (added)
+++ klee/trunk/stp/sat/Heap.h Wed May 20 23:36:41 2009
@@ -0,0 +1,151 @@
+/******************************************************************************************[Heap.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Heap_h
+#define Heap_h
+
+#include "../AST/ASTUtil.h"
+namespace MINISAT {
+
+//=================================================================================================
+
+
+static inline int left  (int i) { return i+i; }
+static inline int right (int i) { return i+i + 1; }
+static inline int parent(int i) { return i >> 1; }
+
+template<class C>
+class Heap {
+  public:
+    C        comp;
+    vec<int> heap;     // heap of ints
+    vec<int> indices;  // int -> index in heap
+
+    inline void percolateUp(int i)
+    {
+        int x = heap[i];
+        while (parent(i) != 0 && comp(x,heap[parent(i)])){
+            heap[i]          = heap[parent(i)];
+            indices[heap[i]] = i;
+            i                = parent(i);
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+    inline void percolateDown(int i)
+    {
+        int x = heap[i];
+        while (left(i) < heap.size()){
+            int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i);
+            if (!comp(heap[child],x)) break;
+            heap[i]          = heap[child];
+            indices[heap[i]] = i;
+            i                = child;
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+    bool ok(int n) const { 
+        return n >= 0 && n < (int)indices.size(); }
+
+  public:
+    Heap(C c) : comp(c) { heap.push(-1); }
+
+    void setBounds (int size)    { assert(size >= 0); indices.growTo(size,0); }
+    void increase  (int n)       { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); }
+    bool inHeap    (int n) const { assert(ok(n)); return indices[n] != 0; }
+    int  size      ()      const { return heap.size()-1; }
+    bool empty     ()      const { return size() == 0; }
+
+
+    void insert(int n) {
+        assert(!inHeap(n));
+        assert(ok(n));
+        indices[n] = heap.size();
+        heap.push(n);
+        percolateUp(indices[n]); 
+    }
+
+
+  int  getmin() {
+    //printing heap
+    if(BEEV::print_sat_varorder) {
+      // fprintf(stderr, "Vijay: heap before getmin: ");
+      //       for (uint i = 1; i < (uint)heap.size(); i++)
+      // 	fprintf(stderr, "%d ", heap[i]);
+      //       fprintf(stderr, "\n");
+    }
+    
+    int r            = heap[1];
+    heap[1]          = heap.last();
+    indices[heap[1]] = 1;
+    indices[r]       = 0;
+    heap.pop();
+    if (heap.size() > 1)
+      percolateDown(1);
+    return r; 
+  }
+
+    // fool proof variant of insert/increase
+    void update    (int n)    {
+        //fprintf(stderr, "update heap: ");
+        //for (uint i = 1; i < (uint)heap.size(); i++)
+        //    fprintf(stderr, "%d ", heap[i]);
+        //fprintf(stderr, "\n");
+        setBounds(n+1);
+        if (!inHeap(n))
+            insert(n);
+        else {
+            percolateUp(indices[n]);
+            percolateDown(indices[n]);
+        }
+    }
+
+
+    bool heapProperty() {
+        return heapProperty(1); }
+
+
+    bool heapProperty(int i) {
+        return i >= heap.size()
+            || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
+
+    template <class F> void filter(const F& filt) {
+        int i,j;
+        for (i = j = 1; i < heap.size(); i++)
+            if (filt(heap[i])){
+                heap[j]          = heap[i];
+                indices[heap[i]] = j++;
+            }else
+                indices[heap[i]] = 0;
+
+        heap.shrink(i - j);
+        for (int i = heap.size() / 2; i >= 1; i--)
+            percolateDown(i);
+
+        assert(heapProperty());
+    }
+
+};
+
+//=================================================================================================
+};
+#endif

Added: klee/trunk/stp/sat/LICENSE
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/LICENSE?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/LICENSE (added)
+++ klee/trunk/stp/sat/LICENSE Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Added: klee/trunk/stp/sat/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Makefile (added)
+++ klee/trunk/stp/sat/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+include ../Makefile.common
+
+SRCS = Solver.C Simplifier.C
+OBJS = $(SRCS:.C=.o)
+
+libsatsolver.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+Solver.o: Solver.C Solver.h Sort.h SolverTypes.h VarOrder.h Global.h Heap.h
+Simplifier.o: Simplifier.C Solver.h Sort.h SolverTypes.h VarOrder.h Global.h Heap.h
+
+clean:
+	rm -rf *.o *~  *.a  depend.mak .#*
+depend:
+	makedepend -- $(CFLAGS) -- $(SRCS)

Added: klee/trunk/stp/sat/Simplifier.C
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Simplifier.C?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Simplifier.C (added)
+++ klee/trunk/stp/sat/Simplifier.C Wed May 20 23:36:41 2009
@@ -0,0 +1,542 @@
+/************************************************************************************[Simplifier.C]
+MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "Solver.h"
+
+namespace MINISAT {
+
+static const int grow = 0;
+
+//#define WEAKEN
+//#define MATING
+//#define ASSYMM
+
+bool Solver::assymmetricBranching(Clause& c)
+{
+    assert(decisionLevel() == 0);
+
+    //fprintf(stderr, "assymmetric branching on clause: "); printClause(c); fprintf(stderr, "\n");
+    if (satisfied(c)){
+        //fprintf(stderr, "subsumed.\n");
+        return true; }
+
+    int      old;
+    vec<Lit> copy; for (int i = 0; i < c.size(); i++) copy.push(c[i]);
+
+    do {
+        assert(copy.size() == c.size());
+
+        old = copy.size();
+
+        //fprintf(stderr, "checking that clause is normalized\n");
+        //for (int i = 0; i < copy.size(); i++)
+        //    assert(value(copy[i]) == l_Undef);
+
+        for (int i = 0; i < copy.size(); i++){
+            trail_lim.push(trail.size());
+            //fprintf(stderr, " -- trying to delete literal "); printLit(copy[i]); 
+            for (int j = 0; j < copy.size(); j++)
+                if (j != i)
+                    check(enqueue(~copy[j]));
+
+            if (propagate() != NULL){
+                //fprintf(stderr, " succeeded\n");
+                cancelUntil(0);
+                Lit l = copy[i];
+                assert(find(copy, l));
+                remove(copy, l);
+                if (!strengthen(c, l))
+                    return false;
+                i--;
+
+                if (c.size() == 1)
+                    return propagate() == NULL;
+                else
+                    assert(qhead == trail.size());
+            }
+            else
+                //fprintf(stderr, " failed\n");
+
+            cancelUntil(0);
+        }
+
+        //} while (false);
+    } while (copy.size() < old);
+
+    return true;
+}
+
+// Returns FALSE if clause is always satisfied ('out_clause' should not be used). 
+//bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+bool Solver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+{  
+    stats.merges++;
+
+    bool  ps_smallest = _ps.size() < _qs.size();
+    const Clause& ps =  ps_smallest ? _qs : _ps;
+    const Clause& qs =  ps_smallest ? _ps : _qs;
+
+    for (int i = 0; i < qs.size(); i++){
+        if (var(qs[i]) != v){
+            for (int j = 0; j < ps.size(); j++)
+                if (var(ps[j]) == var(qs[i])) {
+                    if (ps[j] == ~qs[i])
+                        return false;
+                    else
+                        goto next;
+                }
+            out_clause.push(qs[i]);
+        }
+        next:;
+    }
+
+    for (int i = 0; i < ps.size(); i++)
+        if (var(ps[i]) != v)
+            out_clause.push(ps[i]);
+
+    return true;
+}
+
+
+void Solver::gather(vec<Clause*>& clauses)
+{
+    //fprintf(stderr, "Gathering clauses for backwards subsumption\n");
+    int ntouched = 0;
+    assert(touched.size() == occurs.size());
+    clauses.clear();
+    for (int i = 0; i < touched.size(); i++)
+        if (touched[i]){
+            const vec<Clause*>& cs = getOccurs(i);
+            ntouched++;
+            for (int j = 0; j < cs.size(); j++)
+                if (cs[j]->mark() == 0){
+                    clauses.push(cs[j]);
+                    cs[j]->mark(2);
+                }
+            touched[i] = 0;
+        }
+
+    //fprintf(stderr, "Touched variables %d of %d yields %d clauses to check\n", ntouched, touched.size(), clauses.size());
+    for (int i = 0; i < clauses.size(); i++)
+        clauses[i]->mark(0);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  subsumes : (_c : ClauseId) (c : Clause&) (_d : ClauseId) (d : Clause&)  ->  bool
+|
+|  Description:
+|     Checks if c subsumes d, and at the same time, if c can be used to simplify d by subsumption
+|     resolution.
+|    
+|  Input:
+|     Indices into the 'clauses' vector _c, _d, and references to the corresponding clauses c, d.
+|
+|  Result:
+|     lit_Error  - No subsumption or simplification
+|     lit_Undef  - Clause c subsumes d
+|     l          - The literal l can be deleted from d
+|________________________________________________________________________________________________@*/
+inline Lit Solver::subsumes(const Clause& c, const Clause& d)
+{
+    stats.subsumption_checks++;
+    if (d.size() < c.size() || (c.abstraction() & ~d.abstraction()) != 0)
+        return lit_Error;
+
+    Lit ret = lit_Undef;
+
+    for (int i = 0; i < c.size(); i++) {
+        // search for c[i] or ~c[i]
+        for (int j = 0; j < d.size(); j++)
+            if (c[i] == d[j])
+                goto ok;
+            else if (ret == lit_Undef && c[i] == ~d[j]){
+                ret = c[i];
+                goto ok;
+            }
+
+        // did not find it
+        stats.subsumption_misses++;
+        return lit_Error;
+    ok:;
+    }
+
+    return ret;
+}
+
+
+// Backward subsumption + backward subsumption resolution
+bool Solver::backwardSubsumptionCheck()
+{
+    while (subsumption_queue.size() > 0 || qhead < trail.size()){
+
+        // if propagation queue is non empty, take the first literal and
+        // create a dummy unit clause
+        if (qhead < trail.size()){
+            Lit l = trail[qhead++];
+            (*bwdsub_tmpunit)[0] = l;
+            assert(bwdsub_tmpunit->mark() == 0);
+            subsumption_queue.push(bwdsub_tmpunit);
+        }
+        Clause&  c = *subsumption_queue.last(); subsumption_queue.pop();
+
+        if (c.mark())
+            continue;
+
+        if (c.size() == 1 && !enqueue(c[0]))
+            return false; 
+
+        // (1) find best variable to scan
+        Var best = var(c[0]);
+        for (int i = 1; i < c.size(); i++)
+            if (occurs[var(c[i])].size() < occurs[best].size())
+                best = var(c[i]);
+
+        // (2) search all candidates
+        const vec<Clause*>& cs = getOccurs(best);
+
+        for (int j = 0; j < cs.size(); j++)
+            if (cs[j] != &c){
+                if (cs[j]->mark())
+                    continue;
+                if (c.mark())
+                    break;
+
+                //fprintf(stderr, "backward candidate "); printClause(*cs[j]); fprintf(stderr, "\n"); 
+                Lit l = subsumes(c, *cs[j]);
+                if (l == lit_Undef){
+                    //fprintf(stderr, "clause backwards subsumed\n");
+                    //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
+                    //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
+                    removeClause(*cs[j], false);
+                }else if (l != lit_Error){
+                    //fprintf(stderr, "backwards subsumption resolution\n");
+                    //fprintf(stderr, " >> clause %d: ", cs[j]->mark()); printClause(*cs[j]); fprintf(stderr, "\n");
+                    //fprintf(stderr, " >> clause %d: ", c.mark()); printClause(c); fprintf(stderr, "\n");
+
+                    assert(cs[j]->size() > 1);
+                    assert(find(*cs[j], ~l));
+
+                    subsumption_queue.push(cs[j]);
+                    if (!strengthen(*cs[j], ~l))
+                        return false;
+
+                    // did current candidate get deleted from cs? then check candidate at index j again
+                    if (var(l) == best)
+                        j--;
+                }
+            }
+    }
+
+    return true;
+}
+
+
+bool Solver::eliminateVar(Var v, bool fail)
+{
+    assert(hasVarProp(v, p_frozen));
+
+    vec<Clause*>  pos, neg;
+    const vec<Clause*>& cls = getOccurs(v);
+
+    if (value(v) != l_Undef || cls.size() == 0)
+        return true;
+
+    //fprintf(stderr, "trying to eliminate var %d\n", v+1);
+    for (int i = 0; i < cls.size(); i++){
+        //fprintf(stderr, "clause: "); printClause(*cls[i]); fprintf(stderr, "\n");
+        if (find(*cls[i], Lit(v)))
+            pos.push(cls[i]);
+        else{
+            assert(find(*cls[i], ~Lit(v)));
+            neg.push(cls[i]);
+        }
+    }
+
+#ifdef WEAKEN
+    vec<int> posc(pos.size(), 0);
+    vec<int> negc(neg.size(), 0);
+#endif
+    // check if number of clauses decreases
+    int      cnt = 0;
+    vec<Lit> resolvent;
+    for (int i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++){
+            resolvent.clear();
+            if (merge(*pos[i], *neg[j], v, resolvent)){
+                cnt++;
+#ifdef WEAKEN
+                posc[i]++;
+                negc[j]++;
+#endif
+            }
+#ifndef WEAKEN
+            if (cnt > cls.size() + grow)
+                return true;
+#else
+#ifdef MATING
+            if (cnt > cls.size() + grow)
+                if (posc[i] > 0)
+                    break;
+#endif
+#endif
+            assert(pos.size() <= n_occ[toInt(Lit(v))]);
+            assert(neg.size() <= n_occ[toInt(~Lit(v))]);
+        }
+
+#ifdef WEAKEN
+#ifdef MATING
+    for (int i = 0; i < neg.size(); i++)
+        if (negc[i] == 0)
+            for (int j = 0; j < pos.size(); j++){
+                resolvent.clear();
+                if (merge(*neg[i], *pos[j], v, resolvent)){
+                    negc[i]++;
+                    break;
+                }
+            }
+#endif
+    for (int i = 0; i < pos.size(); i++)
+        if (posc[i] == 0)
+            removeClause(*pos[i], false);
+
+    for (int i = 0; i < neg.size(); i++)
+        if (negc[i] == 0)
+            removeClause(*neg[i], false);
+
+    if (cnt > cls.size() + grow)
+        return true;
+#endif    
+    //if (pos.size() != n_occ[toInt(Lit(v))])
+    //    fprintf(stderr, "pos.size() = %d, n_occ[toInt(Lit(v))] = %d\n", pos.size(), n_occ[toInt(Lit(v))]);
+    assert(pos.size() == n_occ[toInt(Lit(v))]);
+    //if (neg.size() != n_occ[toInt(~Lit(v))])
+    //    fprintf(stderr, "neg.size() = %d, n_occ[toInt(Lit(v))] = %d\n", neg.size(), n_occ[toInt(Lit(v))]);
+    assert(neg.size() == n_occ[toInt(~Lit(v))]);
+    assert(cnt <= cls.size() + grow);
+    setVarProp(v, p_decisionvar, false);
+
+    // produce clauses in cross product
+    int top = clauses.size();
+    for (int i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++){
+            resolvent.clear();
+#ifdef WEAKEN
+            if (pos[i]->mark() == 1)
+                break;
+            if (neg[j]->mark() == 1)
+                continue;
+#endif
+
+            if (merge(*pos[i], *neg[j], v, resolvent)){
+                int i, j;
+                for (i = j = 0; i < resolvent.size(); i++)
+                    if (value(resolvent[i]) == l_True)
+                        goto next;
+                    else if (value(resolvent[i]) == l_Undef)
+                        resolvent[j++] = resolvent[i];
+                resolvent.shrink(i - j);
+
+                if (resolvent.size() == 1){
+                    if (!enqueue(resolvent[0]))
+                        return false;
+                }else{
+                    int apa = clauses.size();
+                    check(newClause(resolvent, false, true));
+                    assert(apa + 1 == clauses.size());
+                }
+            }
+            next:;
+        }
+
+    if (fail){
+        fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
+        fprintf(stderr, "previous clauses:\n");
+        for (int i = 0; i < cls.size(); i++){
+            printClause(*cls[i]);
+            fprintf(stderr, "\n");
+        }
+        
+        fprintf(stderr, "new clauses:\n");
+        for (int i = top; i < clauses.size(); i++){
+            printClause(*clauses[i]);
+            fprintf(stderr, "\n");
+        }
+
+        assert(0); }
+
+    //fprintf(stderr, "eliminated var %d, %d <= %d\n", v+1, cnt, cls.size());
+    //fprintf(stderr, "previous clauses:\n");
+    //for (int i = 0; i < cls.size(); i++){
+    //    printClause(*cls[i]);
+    //    fprintf(stderr, "\n");
+    //}
+    //
+    //fprintf(stderr, "new clauses:\n");
+    //for (int i = top; i < clauses.size(); i++){
+    //    printClause(*clauses[i]);
+    //    fprintf(stderr, "\n");
+    //}
+
+    // delete + store old clauses
+    eliminated_var.push(v);
+    eliminated_lim.push(eliminated.size());
+    for (int i = 0; i < cls.size(); i++){
+        eliminated.push(Clause_new(*cls[i]));
+
+#ifdef WEAKEN
+        if (cls[i]->mark() == 0)
+#endif
+            removeClause(*cls[i], false); 
+
+    }
+
+    assert(subsumption_queue.size() == 0);
+    for (int i = top; i < clauses.size(); i++)
+#ifdef ASSYMM
+        if (clauses[i]->mark() == 0)
+            if (!assymmetricBranching(*clauses[i]))
+                return false;
+            else
+                subsumption_queue.push(clauses[i]);
+#else
+        if (clauses[i]->mark() == 0)
+            subsumption_queue.push(clauses[i]);
+#endif
+
+    return backwardSubsumptionCheck();
+}
+
+
+void Solver::extendModel()
+{
+    assert(eliminated_var.size() == eliminated_lim.size());
+    for (int i = eliminated_var.size()-1; i >= 0; i--){
+        Var v = eliminated_var[i];
+        Lit l = lit_Undef;
+
+        //fprintf(stderr, "extending var %d\n", v+1);
+
+        for (int j = eliminated_lim[i]; j < (i+1 >= eliminated_lim.size() ? eliminated.size() : eliminated_lim[i+1]); j++){
+            assert(j < eliminated.size());
+            Clause& c = *eliminated[j];
+
+            //fprintf(stderr, "checking clause: "); printClause(c); fprintf(stderr, "\n");
+
+            for (int k = 0; k < c.size(); k++)
+                if (var(c[k]) == v)
+                    l = c[k];
+                else if (value(c[k]) != l_False)
+                    goto next;
+
+            assert(l != lit_Undef);
+            //fprintf(stderr, "Fixing var %d to %d\n", v+1, !sign(l));
+
+            assigns[v] = toInt(lbool(!sign(l)));
+            break;
+
+        next:;
+        }
+
+        if (value(v) == l_Undef)
+            assigns[v] = toInt(l_True);
+    }
+}
+
+
+bool Solver::eliminate()
+{
+    assert(subsumption);
+
+    int cnt = 0;
+    //fprintf(stderr, "eliminating variables\n");
+
+#ifdef INVARIANTS
+    // check that all clauses are simplified
+    fprintf(stderr, "Checking that all clauses are normalized prior to variable elimination\n");
+    for (int i = 0; i < clauses.size(); i++)
+        if (clauses[i]->mark() == 0){
+            Clause& c = *clauses[i];
+            for (int j = 0; j < c.size(); j++)
+                assert(value(c[j]) == l_Undef);
+        }
+    fprintf(stderr, "done.\n");
+#endif
+
+    for (;;){
+        gather(subsumption_queue);
+
+        if (subsumption_queue.size() == 0 && heap.size() == 0)
+            break;
+
+        //fprintf(stderr, "backwards subsumption: %10d\n", subsumption_queue.size());
+        if (!backwardSubsumptionCheck())
+            return false;
+
+        //fprintf(stderr, "variable elimination:  %10d\n", heap.size());
+        cnt = 0;
+        for (;;){
+            assert(!heap.empty() || heap.size() == 0);
+            if (heap.empty())
+                break;
+
+            Var elim = heap.getmin();
+
+            assert(hasVarProp(elim, p_frozen));
+
+            //for (int i = 1; i < heap.heap.size(); i++)
+            //    assert(heap.comp(elim, heap.heap[i]) || !heap.comp(elim, heap.heap[i]));
+
+            //if (cnt++ % 100 == 0)
+            //    fprintf(stderr, "left %10d\r", heap.size());
+            
+            if (!eliminateVar(elim))
+                return false;
+        }
+    }
+#ifdef INVARIANTS
+    // check that no more subsumption is possible
+    fprintf(stderr, "Checking that no more subsumption is possible\n");
+    cnt = 0;
+    for (int i = 0; i < clauses.size(); i++){
+        if (cnt++ % 1000 == 0)
+            fprintf(stderr, "left %10d\r", clauses.size() - i);
+        for (int j = 0; j < i; j++)
+            assert(clauses[i]->mark() ||
+                   clauses[j]->mark() ||
+                   subsumes(*clauses[i], *clauses[j]) == lit_Error);
+    }
+    fprintf(stderr, "done.\n");
+
+    // check that no more elimination is possible
+    fprintf(stderr, "Checking that no more elimination is possible\n");
+    for (int i = 0; i < nVars(); i++){
+        if (hasVarProp(i, p_frozen))
+            eliminateVar(i, true);
+    }
+    fprintf(stderr, "done.\n");
+
+#endif
+
+    assert(qhead == trail.size());
+
+    return true;
+}
+};

Added: klee/trunk/stp/sat/Solver.C
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Solver.C?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Solver.C (added)
+++ klee/trunk/stp/sat/Solver.C Wed May 20 23:36:41 2009
@@ -0,0 +1,811 @@
+/****************************************************************************************[Solver.C]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#include "Solver.h"
+#include "Sort.h"
+#include <cmath>
+
+namespace MINISAT {
+//=================================================================================================
+// Operations on clauses:
+
+
+/*_________________________________________________________________________________________________
+|
+|  newClause : (ps : const vec<Lit>&) (learnt : bool)  ->  [void]
+|  
+|  Description:
+|    Allocate and add a new clause to the SAT solvers clause database. 
+|  
+|  Input:
+|    ps     - The new clause as a vector of literals.
+|    learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the
+|             asserting literal. An appropriate 'enqueue()' operation will be performed on this
+|             literal. One of the watches will always be on this literal, the other will be set to
+|             the literal with the highest decision level.
+|  
+|  Effect:
+|    Activity heuristics are updated.
+|________________________________________________________________________________________________@*/
+bool Solver::newClause(const vec<Lit>& ps_, bool learnt, bool normalized)
+{
+    vec<Lit>    qs;
+    if (!learnt && !normalized){
+        assert(decisionLevel() == 0);
+        ps_.copyTo(qs);             // Make a copy of the input vector.
+
+        // Remove duplicates:
+        sortUnique(qs);
+
+        // Check if clause is satisfied:
+        for (int i = 0; i < qs.size()-1; i++){
+            if (qs[i] == ~qs[i+1])
+                return true; }
+        for (int i = 0; i < qs.size(); i++){
+            if (value(qs[i]) == l_True)
+                return true; }
+
+        // Remove false literals:
+        int     i, j;
+        for (i = j = 0; i < qs.size(); i++)
+            if (value(qs[i]) != l_False)
+                qs[j++] = qs[i];
+        qs.shrink(i - j);
+    }
+    const vec<Lit>& ps = learnt || normalized ? ps_ : qs;     // 'ps' is now the (possibly) reduced vector of literals.
+
+    if (ps.size() == 0)
+        return false;
+    else if (ps.size() == 1){
+        assert(decisionLevel() == 0);
+        return enqueue(ps[0]);
+    }else{
+        // Allocate clause:
+        Clause* c   = Clause_new(ps, learnt);
+
+        if (learnt){
+            // Put the second watch on the first literal with highest decision level:
+            // (requires that this method is called at the level where the clause is asserting!)
+            int i;
+            for (i = 1; i < ps.size() && position(trailpos[var(ps[i])]) < trail_lim.last(); i++)
+                ;
+            (*c)[1] = ps[i];
+            (*c)[i] = ps[1];
+
+            // Bump, enqueue, store clause:
+            claBumpActivity(*c);        // (newly learnt clauses should be considered active)
+            check(enqueue((*c)[0], c));
+            learnts.push(c);
+            stats.learnts_literals += c->size();
+        }else{
+            // Store clause:
+            clauses.push(c);
+            stats.clauses_literals += c->size();
+
+            if (subsumption){
+                c->calcAbstraction();
+                for (int i = 0; i < c->size(); i++){
+                    assert(!find(occurs[var((*c)[i])], c));
+                    occurs[var((*c)[i])].push(c);
+                    n_occ[toInt((*c)[i])]++;
+                    touched[var((*c)[i])] = 1;
+
+                    if (heap.inHeap(var((*c)[i])))
+		      updateHeap(var((*c)[i]));
+                }
+            }
+
+        }
+        // Watch clause:
+        watches[toInt(~(*c)[0])].push(c);
+        watches[toInt(~(*c)[1])].push(c);
+    }
+
+    return true;
+}
+
+
+// Disposes a clauses and removes it from watcher lists. NOTE!
+// Low-level; does NOT change the 'clauses' and 'learnts' vector.
+//
+void Solver::removeClause(Clause& c, bool dealloc)
+{
+    //fprintf(stderr, "delete %d: ", _c); printClause(c); fprintf(stderr, "\n");
+    assert(c.mark() == 0);
+
+    if (c.size() > 1){
+        assert(find(watches[toInt(~c[0])], &c));
+        assert(find(watches[toInt(~c[1])], &c));
+        remove(watches[toInt(~c[0])], &c);
+        remove(watches[toInt(~c[1])], &c); }
+
+    if (c.learnt()) stats.learnts_literals -= c.size();
+    else            stats.clauses_literals -= c.size();
+
+    if (subsumption && !c.learnt()){
+        for (int i = 0; i < c.size(); i++){
+            if (dealloc){
+                assert(find(occurs[var(c[i])], &c));
+                remove(occurs[var(c[i])], &c); 
+            }
+            n_occ[toInt(c[i])]--;
+            updateHeap(var(c[i]));
+        }
+    }
+
+    if (dealloc)
+        xfree(&c);
+    else
+        c.mark(1);
+}
+
+
+bool Solver::satisfied(Clause& c) const
+{
+    for (int i = 0; i < c.size(); i++)
+        if (value(c[i]) == l_True)
+            return true;
+    return false; }
+
+
+bool Solver::strengthen(Clause& c, Lit l)
+{
+    assert(decisionLevel() == 0);
+    assert(c.size() > 1);
+    assert(c.mark() == 0);
+
+    assert(toInt(~c[0]) < watches.size());
+    assert(toInt(~c[1]) < watches.size());
+    
+    assert(find(watches[toInt(~c[0])], &c));
+    assert(find(watches[toInt(~c[1])], &c));
+    assert(find(c,l));
+
+    if (c.learnt()) stats.learnts_literals -= 1;
+    else            stats.clauses_literals -= 1;
+
+    if (c[0] == l || c[1] == l){
+        assert(find(watches[toInt(~l)], &c));
+        remove(c,l);
+        remove(watches[toInt(~l)], &c);
+        if (c.size() > 1){
+            assert(!find(watches[toInt(~c[1])], &c));
+            watches[toInt(~c[1])].push(&c); }
+        else {
+            assert(find(watches[toInt(~c[0])], &c));
+            remove(watches[toInt(~c[0])], &c);
+            removeClause(c, false);
+        }
+    }
+    else
+        remove(c,l);
+        
+    assert(c.size() == 1 || find(watches[toInt(~c[0])], &c));
+    assert(c.size() == 1 || find(watches[toInt(~c[1])], &c));
+
+    if (subsumption){
+        assert(find(occurs[var(l)], &c));
+        remove(occurs[var(l)], &c);
+        assert(!find(occurs[var(l)], &c));
+
+        c.calcAbstraction();
+
+        n_occ[toInt(l)]--;
+        updateHeap(var(l));
+    }
+
+    return c.size() == 1 ? enqueue(c[0]) : true;
+}
+
+
+//=================================================================================================
+// Minor methods:
+
+
+// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be
+// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
+//
+Var Solver::newVar(bool polarity, bool dvar) {
+    int     index;
+    index = nVars();
+    watches     .push();          // (list for positive literal)
+    watches     .push();          // (list for negative literal)
+    reason      .push(NULL);
+    assigns     .push(toInt(l_Undef));
+    trailpos    .push(TrailPos(0,0));
+    activity    .push(0);
+    order       .newVar(polarity,dvar);
+    seen        .push(0);
+    touched     .push(0);
+    if (subsumption){
+        occurs  .push();
+        n_occ   .push(0);
+        n_occ   .push(0);
+        heap    .setBounds(index+1);
+    }
+    return index; }
+
+
+// Returns FALSE if immediate conflict.
+bool Solver::assume(Lit p) {
+    trail_lim.push(trail.size());
+    return enqueue(p); }
+
+
+// Revert to the state at given level.
+void Solver::cancelUntil(int level) {
+    if (decisionLevel() > level){
+        for (int c = trail.size()-1; c >= trail_lim[level]; c--){
+            Var     x  = var(trail[c]);
+            assigns[x] = toInt(l_Undef);
+            reason [x] = NULL; 
+            order.undo(x); }
+        qhead = trail_lim[level];
+        trail.shrink(trail.size() - trail_lim[level]);
+        trail_lim.shrink(trail_lim.size() - level);
+    }
+}
+
+
+//=================================================================================================
+// Major methods:
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
+|  
+|  Description:
+|    Analyze conflict and produce a reason clause.
+|  
+|    Pre-conditions:
+|      * 'out_learnt' is assumed to be cleared.
+|      * Current decision level must be greater than root level.
+|  
+|    Post-conditions:
+|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
+|  
+|  Effect:
+|    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
+|________________________________________________________________________________________________@*/
+void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel)
+{
+    int            pathC = 0;
+    int            btpos = -1;
+    Lit            p     = lit_Undef;
+
+    // Generate conflict clause:
+    //
+    out_learnt.push();      // (leave room for the asserting literal)
+    int index = trail.size()-1;
+    do{
+        assert(confl != NULL);          // (otherwise should be UIP)
+        Clause& c = *confl;
+
+        if (c.learnt())
+            claBumpActivity(c);
+
+        for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
+            Lit q = c[j];
+            if (!seen[var(q)] && position(trailpos[var(q)]) >= trail_lim[0]){
+	      varBumpActivity(q);
+                seen[var(q)] = 1;
+                if (position(trailpos[var(q)]) >= trail_lim.last())
+                    pathC++;
+                else{
+                    out_learnt.push(q);
+                    btpos = max(btpos, position(trailpos[var(q)]));
+                }
+            }
+        }
+
+        // Select next clause to look at:
+        while (!seen[var(trail[index--])]);
+        p     = trail[index+1];
+        confl = reason[var(p)];
+        seen[var(p)] = 0;
+        pathC--;
+
+    }while (pathC > 0);
+    out_learnt[0] = ~p;
+
+    // Find correct backtrack level
+    for (out_btlevel = trail_lim.size()-1; out_btlevel > 0 && trail_lim[out_btlevel-1] > btpos; out_btlevel--)
+        ;
+
+    int     i, j;
+    if (expensive_ccmin){
+        // Simplify conflict clause (a lot):
+        //
+        uint    min_level = 0;
+        for (i = 1; i < out_learnt.size(); i++)
+            min_level |= abstractLevel(trailpos[var(out_learnt[i])]);     // (maintain an abstraction of levels involved in conflict)
+
+        out_learnt.copyTo(analyze_toclear);
+        for (i = j = 1; i < out_learnt.size(); i++)
+            if (reason[var(out_learnt[i])] == NULL || !analyze_removable(out_learnt[i], min_level))
+                out_learnt[j++] = out_learnt[i];
+    }else{
+        // Simplify conflict clause (a little):
+        //
+        out_learnt.copyTo(analyze_toclear);
+        for (i = j = 1; i < out_learnt.size(); i++){
+            Clause& c = *reason[var(out_learnt[i])];
+            for (int k = 1; k < c.size(); k++)
+                if (!seen[var(c[k])] && position(trailpos[var(c[k])]) >= trail_lim[0]){
+                    out_learnt[j++] = out_learnt[i];
+                    break; }
+        }
+    }
+
+    stats.max_literals += out_learnt.size();
+    out_learnt.shrink(i - j);
+    stats.tot_literals += out_learnt.size();
+
+    for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
+}
+
+
+// Check if 'p' can be removed. 'min_level' is used to abort early if visiting literals at a level that cannot be removed.
+//
+bool Solver::analyze_removable(Lit p, uint min_level)
+{
+    analyze_stack.clear(); analyze_stack.push(p);
+    int top = analyze_toclear.size();
+    while (analyze_stack.size() > 0){
+        assert(reason[var(analyze_stack.last())] != NULL);
+        Clause& c = *reason[var(analyze_stack.last())]; analyze_stack.pop();
+
+        for (int i = 1; i < c.size(); i++){
+            Lit      p   = c[i];
+            TrailPos tp = trailpos[var(p)];
+            if (!seen[var(p)] && position(tp) >= trail_lim[0]){
+                if (reason[var(p)] != NULL && (abstractLevel(tp) & min_level) != 0){
+                    seen[var(p)] = 1;
+                    analyze_stack.push(p);
+                    analyze_toclear.push(p);
+                }else{
+                    for (int j = top; j < analyze_toclear.size(); j++)
+                        seen[var(analyze_toclear[j])] = 0;
+                    analyze_toclear.shrink(analyze_toclear.size() - top);
+                    return false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyzeFinal : (p : Lit) ->  [void]
+|  
+|  Description:
+|    Specialized analysis procedure to express the final conflict in terms of assumptions.
+|    Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
+|    stores the result in 'out_conflict'.
+|________________________________________________________________________________________________@*/
+void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
+{
+    out_conflict.clear();
+    out_conflict.push(p);
+
+    if (decisionLevel() == 0)
+        return;
+
+    seen[var(p)] = 1;
+
+    int start = position(trailpos[var(p)]);
+    for (int i = start; i >= trail_lim[0]; i--){
+        Var     x = var(trail[i]);
+        if (seen[x]){
+            if (reason[x] == NULL){
+                assert(position(trailpos[x]) >= trail_lim[0]);
+                out_conflict.push(~trail[i]);
+            }else{
+                Clause& c = *reason[x];
+                for (int j = 1; j < c.size(); j++)
+                    if (position(trailpos[var(c[j])]) >= trail_lim[0])
+                        seen[var(c[j])] = 1;
+            }
+            seen[x] = 0;
+        }
+    }
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  enqueue : (p : Lit) (from : Clause*)  ->  [bool]
+|  
+|  Description:
+|    Puts a new fact on the propagation queue as well as immediately updating the variable's value.
+|    Should a conflict arise, FALSE is returned.
+|  
+|  Input:
+|    p    - The fact to enqueue
+|    from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'.
+|           Default value is NULL (no reason).
+|  
+|  Output:
+|    TRUE if fact was enqueued without conflict, FALSE otherwise.
+|________________________________________________________________________________________________@*/
+bool Solver::enqueue(Lit p, Clause* from)
+{
+
+    if (value(p) != l_Undef)
+        return value(p) != l_False;
+    else{
+        assigns [var(p)] = toInt(lbool(!sign(p)));
+        trailpos[var(p)] = TrailPos(trail.size(),decisionLevel());
+        reason  [var(p)] = from;
+        trail.push(p);
+        return true;
+    }
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  propagate : [void]  ->  [Clause*]
+|  
+|  Description:
+|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
+|    otherwise NULL.
+|  
+|    Post-conditions:
+|      * the propagation queue is empty, even if there was a conflict.
+|________________________________________________________________________________________________@*/
+Clause* Solver::propagate()
+{
+    if (decisionLevel() == 0 && subsumption)
+        return backwardSubsumptionCheck() ? NULL : propagate_tmpempty;
+
+    Clause* confl = NULL;
+    //fprintf(stderr, "propagate, qhead = %d, qtail = %d\n", qhead, qtail);
+    while (qhead < trail.size()){
+        stats.propagations++;
+        simpDB_props--;
+
+        Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
+        vec<Clause*>&  ws  = watches[toInt(p)];
+        Clause         **i, **j, **end;
+
+        for (i = j = (Clause**)ws, end = i + ws.size();  i != end;){
+            Clause& c = **i++;
+            
+            // Make sure the false literal is data[1]:
+            Lit false_lit = ~p;
+            if (c[0] == false_lit)
+                c[0] = c[1], c[1] = false_lit;
+
+            assert(c[1] == false_lit);
+
+            // If 0th watch is true, then clause is already satisfied.
+            Lit first = c[0];
+            if (value(first) == l_True){
+                *j++ = &c;
+            }else{
+                // Look for new watch:
+                for (int k = 2; k < c.size(); k++)
+                    if (value(c[k]) != l_False){
+                        c[1] = c[k]; c[k] = false_lit;
+                        watches[toInt(~c[1])].push(&c);
+                        goto FoundWatch; }
+
+                // Did not find watch -- clause is unit under assignment:
+                *j++ = &c;
+                if (!enqueue(first, &c)){
+                    confl = &c;
+                    qhead = trail.size();
+                    // Copy the remaining watches:
+                    while (i < end)
+                        *j++ = *i++;
+                }
+            FoundWatch:;
+            }
+        }
+        ws.shrink(i - j);
+    }
+
+    return confl;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  reduceDB : ()  ->  [void]
+|  
+|  Description:
+|    Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
+|    clauses are clauses that are reason to some assignment. Binary clauses are never removed.
+|________________________________________________________________________________________________@*/
+struct reduceDB_lt { bool operator () (Clause* x, Clause* y) { return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity()); } };
+void Solver::reduceDB()
+{
+    int     i, j;
+    double  extra_lim = cla_inc / learnts.size();    // Remove any clause below this activity
+
+    sort(learnts, reduceDB_lt());
+    for (i = j = 0; i < learnts.size() / 2; i++){
+        if (learnts[i]->size() > 2 && !locked(*learnts[i]))
+            removeClause(*learnts[i]);
+        else
+            learnts[j++] = learnts[i];
+    }
+    for (; i < learnts.size(); i++){
+        if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity() < extra_lim)
+            removeClause(*learnts[i]);
+        else
+            learnts[j++] = learnts[i];
+    }
+    learnts.shrink(i - j);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  simplifyDB : [void]  ->  [bool]
+|  
+|  Description:
+|    Simplify the clause database according to the current top-level assigment. Currently, the only
+|    thing done here is the removal of satisfied clauses, but more things can be put here.
+|________________________________________________________________________________________________@*/
+bool Solver::simplifyDB(bool expensive)
+{
+    assert(decisionLevel() == 0);
+    if (!ok || propagate() != NULL)
+        return ok = false;
+
+    if (nAssigns() == simpDB_assigns || 
+        (!subsumption && simpDB_props > 0)) // (nothing has changed or preformed a simplification too recently)
+        return true;
+
+    if (subsumption){
+        if (expensive && !eliminate())
+            return ok = false;
+
+        // Move this cleanup code to its own method ?
+        int      i , j;
+        vec<Var> dirty;
+        for (i = 0; i < clauses.size(); i++)
+            if (clauses[i]->mark() == 1){
+                Clause& c = *clauses[i];
+                for (int k = 0; k < c.size(); k++)
+                    if (!seen[var(c[k])]){
+                        seen[var(c[k])] = 1;
+                        dirty.push(var(c[k]));
+                    }
+            }
+        
+        for (i = 0; i < dirty.size(); i++){
+            cleanOcc(dirty[i]);
+            seen[dirty[i]] = 0;
+        }
+
+        for (i = j = 0; i < clauses.size(); i++)
+            if (clauses[i]->mark() == 1)
+                xfree(clauses[i]);
+            else
+                clauses[j++] = clauses[i];
+        clauses.shrink(i - j);
+    }
+
+    // Remove satisfied clauses:
+    for (int type = 0; type < (subsumption ? 1 : 2); type++){  // (only scan learnt clauses if subsumption is on)
+        vec<Clause*>& cs = type ? learnts : clauses;
+        int     j  = 0;
+        for (int i = 0; i < cs.size(); i++){
+            assert(cs[i]->mark() == 0);
+            if (satisfied(*cs[i]))
+                removeClause(*cs[i]);
+            else
+                cs[j++] = cs[i];
+        }
+        cs.shrink(cs.size()-j);
+    }
+    order.cleanup();
+
+    simpDB_assigns = nAssigns();
+    simpDB_props   = stats.clauses_literals + stats.learnts_literals;   // (shouldn't depend on 'stats' really, but it will do for now)
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&)  ->  [lbool]
+|  
+|  Description:
+|    Search for a model the specified number of conflicts, keeping the number of learnt clauses
+|    below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to
+|    indicate infinity.
+|  
+|  Output:
+|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
+|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
+|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
+|________________________________________________________________________________________________@*/
+lbool Solver::search(int nof_conflicts, int nof_learnts)
+{
+    assert(ok);
+    int         backtrack_level;
+    int         conflictC = 0;
+    vec<Lit>    learnt_clause;
+
+    stats.starts++;
+    var_decay = 1 / params.var_decay;
+    cla_decay = 1 / params.clause_decay;
+
+    for (;;){
+        Clause* confl = propagate();
+        if (confl != NULL){
+            // CONFLICT
+            stats.conflicts++; conflictC++;
+            if (decisionLevel() == 0) return l_False;
+
+            learnt_clause.clear();
+            analyze(confl, learnt_clause, backtrack_level);
+            cancelUntil(backtrack_level);
+            newClause(learnt_clause, true);
+            varDecayActivity();
+            claDecayActivity();
+
+        }else{
+            // NO CONFLICT
+
+            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
+                // Reached bound on number of conflicts:
+                progress_estimate = progressEstimate();
+                cancelUntil(0);
+                return l_Undef; }
+
+            // Simplify the set of problem clauses:
+            if (decisionLevel() == 0 && !simplifyDB())
+                return l_False;
+
+            if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts)
+                // Reduce the set of learnt clauses:
+                reduceDB();
+
+            Lit next = lit_Undef;
+
+            if (decisionLevel() < assumptions.size()){
+                // Perform user provided assumption:
+                next = assumptions[decisionLevel()]; 
+                if (value(next) == l_False){
+                    analyzeFinal(~next, conflict);
+                    return l_False; }
+            }else{
+                // New variable decision:
+                stats.decisions++;
+                next = order.select(params.random_var_freq, decisionLevel());		
+	    }
+            if (next == lit_Undef)
+                // Model found:
+                return l_True;
+
+            check(assume(next));
+        }
+    }
+}
+
+
+// Return search-space coverage. Not extremely reliable.
+//
+double Solver::progressEstimate()
+{
+    double  progress = 0;
+    double  F = 1.0 / nVars();
+
+    for (int i = 0; i <= decisionLevel(); i++){
+        int beg = i == 0 ? 0 : trail_lim[i - 1];
+        int end = i == decisionLevel() ? trail.size() : trail_lim[i];
+        progress += pow(F, i) * (end - beg);
+    }
+
+    return progress / nVars();
+}
+
+
+// Divide all variable activities by 1e100.
+//
+void Solver::varRescaleActivity()
+{
+    for (int i = 0; i < nVars(); i++)
+        activity[i] *= 1e-100;
+    var_inc *= 1e-100;
+}
+
+
+// Divide all constraint activities by 1e100.
+//
+void Solver::claRescaleActivity()
+{
+    for (int i = 0; i < learnts.size(); i++)
+        learnts[i]->activity() *= 1e-20;
+    cla_inc *= 1e-20;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  solve : (assumps : const vec<Lit>&)  ->  [bool]
+|  
+|  Description:
+|    Top-level solve.
+|________________________________________________________________________________________________@*/
+bool Solver::solve(const vec<Lit>& assumps)
+{
+    model.clear();
+    conflict.clear();
+
+    if (!simplifyDB(true)) return false;
+
+
+    double  nof_conflicts = params.restart_first;
+    double  nof_learnts   = nClauses() * params.learntsize_factor;
+    lbool   status        = l_Undef;
+    assumps.copyTo(assumptions);
+
+    if (verbosity >= 1){
+        reportf("==================================[MINISAT]====================================\n");
+        reportf("| Conflicts |          ORIGINAL         |          LEARNT          | Progress |\n");
+        reportf("|           |    Vars  Clauses Literals |    Limit  Clauses Lit/Cl |          |\n");
+        reportf("===============================================================================\n");
+    }
+
+    // Search:
+    while (status == l_Undef){
+        if (verbosity >= 1)
+            //reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", (int)stats.conflicts, nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (int)stats.learnts_literals, (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
+            reportf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)stats.conflicts, order.size(), nClauses(), (int)stats.clauses_literals, (int)nof_learnts, nLearnts(), (double)stats.learnts_literals/nLearnts(), progress_estimate*100);
+        status = search((int)nof_conflicts, (int)nof_learnts);
+        nof_conflicts *= params.restart_inc;
+        nof_learnts   *= params.learntsize_inc;
+    }
+
+    if (verbosity >= 1)
+        reportf("==============================================================================\n");
+
+    if (status == l_True){
+        // Copy model:
+        extendModel();
+#if 1
+        //fprintf(stderr, "Verifying model.\n");
+        for (int i = 0; i < clauses.size(); i++)
+            assert(satisfied(*clauses[i]));
+        for (int i = 0; i < eliminated.size(); i++)
+            assert(satisfied(*eliminated[i]));
+#endif
+        model.growTo(nVars());
+        for (int i = 0; i < nVars(); i++) model[i] = value(i);
+    }else{
+        assert(status == l_False);
+        if (conflict.size() == 0)
+            ok = false;
+    }
+
+    cancelUntil(0);
+    return status == l_True;
+}
+};//end of MINISAT namespace

Added: klee/trunk/stp/sat/Solver.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Solver.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Solver.h (added)
+++ klee/trunk/stp/sat/Solver.h Wed May 20 23:36:41 2009
@@ -0,0 +1,359 @@
+/****************************************************************************************[Solver.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Solver_h
+#define Solver_h
+
+#include "SolverTypes.h"
+#include "VarOrder.h"
+
+namespace MINISAT {
+// Redfine if you want output to go somewhere else:
+#define reportf(format, args...) ( printf(format , ## args), fflush(stdout) )
+
+
+//=================================================================================================
+// Solver -- the main class:
+struct SolverStats {
+    int64   starts, decisions, propagations, conflicts;
+    int64   clauses_literals, learnts_literals, max_literals, tot_literals;
+    int64   subsumption_checks, subsumption_misses, merges;
+    SolverStats() : 
+        starts(0), decisions(0), propagations(0), conflicts(0)
+      , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) 
+      , subsumption_checks(0), subsumption_misses(0), merges(0)
+    { }
+};
+
+
+struct SearchParams {
+    double  var_decay, clause_decay, random_var_freq;
+    double  restart_inc, learntsize_inc, learntsize_factor;
+    int     restart_first;
+    
+    SearchParams(double v = 0.95, double c = 0.999, double r = 0.02,
+                 double ri = 1.5, double li = 1.1, double lf = (double)1/(double)3,
+                 int rf = 100) : 
+        var_decay(v), clause_decay(c), random_var_freq(r),
+        restart_inc(ri), learntsize_inc(li), learntsize_factor(lf),
+        restart_first(rf) { }
+};
+
+  struct ElimLt {
+    const vec<int>& n_occ;
+    
+    ElimLt(const vec<int>& no) : n_occ(no) {}
+    int  cost      (Var x)        const { return n_occ[toInt(Lit(x))] * n_occ[toInt(~Lit(x))]; }
+    bool operator()(Var x, Var y) const { return cost(x) < cost(y); } 
+  };
+
+class Solver {
+protected:
+    // Solver state:    
+    bool                ok;               // If FALSE,the constraints are already unsatisfiable. 
+                                          // No part of solver state may be used!
+    vec<Clause*>        clauses;          // List of problem clauses.
+    vec<Clause*>        learnts;          // List of learnt clauses.
+    int                 n_bin_clauses;    // Keep track of number of binary clauses "inlined" into the watcher lists (we do this primarily to get identical behavior to the version without the binary clauses trick).
+    double              cla_inc;          // Amount to bump next clause with.
+    double              cla_decay;        // INVERSE decay factor for clause activity: stores 1/decay.
+
+    vec<double>         activity;         // A heuristic measurement of the activity of a variable.
+    double              var_inc;          // Amount to bump next variable with.
+    double              var_decay;        // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
+    VarOrder            order;            // Keeps track of the decision variable order.
+    vec<char>           properties;       // TODO: describe!!!
+
+    vec<vec<Clause*> >  watches;          // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
+    vec<char>           assigns;          // The current assignments (lbool:s stored as char:s).
+    vec<Lit>            trail;            // Assignment stack; stores all assigments made in the order they were made.
+    vec<int>            trail_lim;        // Separator indices for different decision levels in 'trail'.
+    vec<Clause*>        reason;           // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
+    vec<TrailPos>       trailpos;         // 'trailpos[var]' contains the position in the trail at wich the assigment was made.
+    int                 qhead;            // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
+    int                 simpDB_assigns;   // Number of top-level assignments since last execution of 'simplifyDB()'.
+    int64               simpDB_props;     // Remaining number of propagations that must be made before next execution of 'simplifyDB()'.
+    vec<Lit>            assumptions;      // Current set of assumptions provided to solve by the user.
+
+    bool                subsumption;
+    vec<char>           touched;
+    vec<vec<Clause*> >  occurs;
+    vec<int>            n_occ;
+    Heap<ElimLt>        heap;
+    vec<Clause*>        subsumption_queue;
+
+    vec<Clause*>        eliminated;
+    vec<int>            eliminated_lim;
+    vec<Var>            eliminated_var;
+
+    // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
+    // used, exept 'seen' wich is used in several places.
+    //
+    vec<char>           seen;
+    vec<Lit>            analyze_stack;
+    vec<Lit>            analyze_toclear;
+    Clause*             propagate_tmpempty;
+    Clause*             propagate_tmpbin;
+    Clause*             analyze_tmpbin;
+    Clause*             bwdsub_tmpunit;
+
+    vec<Lit>            addBinary_tmp;
+    vec<Lit>            addTernary_tmp;
+
+    // Main internal methods:
+    //
+    bool        assume           (Lit p);
+    void        cancelUntil      (int level);
+    void        record           (const vec<Lit>& clause);
+
+    void        analyze          (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
+    bool        analyze_removable(Lit p, uint min_level);                                 // (helper method for 'analyze()')
+    void        analyzeFinal     (Lit p, vec<Lit>& out_conflict);
+    bool        enqueue          (Lit fact, Clause* from = NULL);
+    Clause*     propagate        ();
+    void        reduceDB         ();
+    Lit         pickBranchLit    ();
+    lbool       search           (int nof_conflicts, int nof_learnts);
+    double      progressEstimate ();
+
+    // Variable properties:
+    void        setVarProp (Var v, uint prop, bool b) { order.setVarProp(v, prop, b); }
+    bool        hasVarProp (Var v, uint prop) const   { return order.hasVarProp(v, prop); }
+    void        updateHeap (Var v) { 
+        if (hasVarProp(v, p_frozen))
+            heap.update(v); }
+
+    // Simplification methods:
+    //
+    void cleanOcc (Var v) {
+        assert(subsumption);
+        vec<Clause*>& occ = occurs[v];
+        int i, j;
+        for (i = j = 0; i < occ.size(); i++)
+            if (occ[i]->mark() != 1)
+                occ[j++] = occ[i];
+        occ.shrink(i - j); 
+    }
+
+    vec<Clause*>& getOccurs                (Var x) { cleanOcc(x); return occurs[x]; }
+    void          gather                   (vec<Clause*>& clauses);
+    Lit           subsumes                 (const Clause& c, const Clause& d);
+    bool          assymmetricBranching     (Clause& c);
+    bool          merge                    (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
+    
+    bool          backwardSubsumptionCheck ();
+    bool          eliminateVar             (Var v, bool fail = false);
+    bool          eliminate                ();
+    void          extendModel              ();
+
+    // Activity:
+    //
+    void     varBumpActivity(Lit p) {
+        if (var_decay < 0) return;     // (negative decay means static variable order -- don't bump)
+        if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
+        order.update(var(p)); }
+    void     varDecayActivity  () { if (var_decay >= 0) var_inc *= var_decay; }
+    void     varRescaleActivity();
+    void     claDecayActivity  () { cla_inc *= cla_decay; }
+    void     claRescaleActivity();
+
+    // Operations on clauses:
+    //
+    bool     newClause(const vec<Lit>& ps, bool learnt = false, bool normalized = false);
+    void     claBumpActivity (Clause& c) { if ( (c.activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
+    bool     locked          (const Clause& c) const { return reason[var(c[0])] == &c; }
+    bool     satisfied       (Clause& c) const;
+    bool     strengthen      (Clause& c, Lit l);
+    void     removeClause    (Clause& c, bool dealloc = true);
+
+    int      decisionLevel() const { return trail_lim.size(); }
+
+public:
+    Solver() : ok               (true)
+             , n_bin_clauses    (0)
+             , cla_inc          (1)
+             , cla_decay        (1)
+             , var_inc          (1)
+             , var_decay        (1)
+             , order            (assigns, activity)
+             , qhead            (0)
+             , simpDB_assigns   (-1)
+             , simpDB_props     (0)
+             , subsumption      (true)
+             , heap             (n_occ)
+             , params           ()
+             , expensive_ccmin  (true)
+             , verbosity        (0)
+             , progress_estimate(0)
+             {
+                vec<Lit> dummy(2,lit_Undef);
+                propagate_tmpbin   = Clause_new(dummy);
+                analyze_tmpbin     = Clause_new(dummy);
+                dummy.pop();
+                bwdsub_tmpunit     = Clause_new(dummy);
+                dummy.pop();
+                propagate_tmpempty = Clause_new(dummy);
+                addBinary_tmp .growTo(2);
+                addTernary_tmp.growTo(3);
+             }
+
+   ~Solver() {
+       xfree(propagate_tmpbin);
+       xfree(analyze_tmpbin);
+       xfree(bwdsub_tmpunit);
+       xfree(propagate_tmpempty);
+       for (int i = 0; i < eliminated.size(); i++) xfree(eliminated[i]);
+       for (int i = 0; i < learnts.size();    i++) xfree(learnts[i]);
+       for (int i = 0; i < clauses.size();    i++) xfree(clauses[i]); }
+
+    // Helpers: (semi-internal)
+    //
+    lbool   value(Var x) const { return toLbool(assigns[x]); }
+    lbool   value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
+
+    int     nAssigns()   { return trail.size(); }
+    int     nClauses()   { return clauses.size(); }
+    int     nLearnts()   { return learnts.size(); }
+    int     nConflicts() { return (int)stats.conflicts; }
+
+    // Statistics: (read-only member variable)
+    //
+    SolverStats     stats;
+
+    // Mode of operation:
+    //
+    SearchParams    params;             // Restart frequency etc.
+    bool            expensive_ccmin;    // Controls conflict clause minimization. TRUE by default.
+    int             verbosity;          // Verbosity level. 0=silent, 1=some progress report, 2=everything
+
+    // Problem specification:
+    //
+    Var     newVar    (bool polarity = true, bool dvar = true);
+    int     nVars     ()                    { return assigns.size(); }
+    bool    addUnit   (Lit p)               { return ok && (ok = enqueue(p)); }
+    bool    addBinary (Lit p, Lit q)        { addBinary_tmp [0] = p; addBinary_tmp [1] = q; return addClause(addBinary_tmp); }
+    bool    addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; return addClause(addTernary_tmp); }
+    bool    addClause (const vec<Lit>& ps)  { if (ok && !newClause(ps)) ok = false; return ok; }
+
+    // Variable mode:
+    // 
+    void    freezeVar    (Var v) { setVarProp(v, p_frozen, true); updateHeap(v); }
+
+    // Solving:
+    //
+    bool    okay         () { return ok; }       // FALSE means solver is in a conflicting state
+    bool    simplifyDB   (bool expensive = true);
+    bool    solve        (const vec<Lit>& assumps);
+    bool    solve        () { vec<Lit> tmp; return solve(tmp); }
+    void    turnOffSubsumption() {
+        subsumption = false;
+        occurs.clear(true);
+        n_occ.clear(true);
+    }
+
+    double      progress_estimate;  // Set by 'search()'.
+    vec<lbool>  model;              // If problem is satisfiable, this vector contains the model (if any).
+    vec<Lit>    conflict;           // If problem is unsatisfiable (possibly under assumptions), this vector represent the conflict clause expressed in the assumptions.
+
+  double  returnActivity(int i) { return activity[i];}
+  void    updateInitialActivity(int i, double act) {activity[i] = act; order.heap.update(i);}
+};
+
+
+//=================================================================================================
+// Debug:
+
+
+#define L_LIT    "%sx%d"
+#define L_lit(p) sign(p)?"~":"", var(p)
+
+// Just like 'assert()' but expression will be evaluated in the release version as well.
+inline void check(bool expr) { assert(expr); }
+
+static void printLit(Lit l)
+{
+    fprintf(stderr, "%s%d", sign(l) ? "-" : "", var(l)+1);
+}
+
+template<class C>
+static void printClause(const C& c)
+{
+    for (int i = 0; i < c.size(); i++){
+        printLit(c[i]);
+        fprintf(stderr, " ");
+    }
+}
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#ifdef _MSC_VER
+
+#include <ctime>
+
+static inline double cpuTime(void) {
+    return (double)clock() / CLOCKS_PER_SEC; }
+
+static inline int64 memUsed() {
+    return 0; }
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#else
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static inline double cpuTime(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
+
+#if defined(__linux__) || defined(__CYGWIN__)
+static inline int memReadStat(int field)
+{
+    char    name[256];
+    pid_t pid = getpid();
+    sprintf(name, "/proc/%d/statm", pid);
+    FILE*   in = fopen(name, "rb");
+    if (in == NULL) return 0;
+    int     value;
+    for (; field >= 0; field--) {
+      int res = fscanf(in, "%d", &value);
+      (void) res;
+    }
+    fclose(in);
+    return value;
+}
+
+static inline int64 memUsed() { return (int64)memReadStat(0) * (int64)getpagesize(); }
+#else
+// use this by default. Mac OS X (Darwin) does not define an os type
+//defined(__FreeBSD__)
+
+static inline int64 memUsed(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return ru.ru_maxrss*1024; }
+
+#endif
+
+//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#endif
+
+//=================================================================================================
+};
+#endif

Added: klee/trunk/stp/sat/SolverTypes.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/SolverTypes.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/SolverTypes.h (added)
+++ klee/trunk/stp/sat/SolverTypes.h Wed May 20 23:36:41 2009
@@ -0,0 +1,127 @@
+/***********************************************************************************[SolverTypes.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+
+#ifndef SolverTypes_h
+#define SolverTypes_h
+
+#include "Global.h"
+
+namespace MINISAT {
+
+//=================================================================================================
+// Variables, literals, clause IDs:
+
+
+// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
+// so that they can be used as array indices.
+
+typedef int Var;
+#define var_Undef (-1)
+
+
+struct Lit {
+    int     x;
+
+    Lit() : x(2*var_Undef)                                              { }   // (lit_Undef)
+    explicit Lit(Var var, bool sign = false) : x((var+var) + (int)sign) { }
+};
+
+// Don't use these for constructing/deconstructing literals. Use the normal constructors instead.
+inline  int  toInt       (Lit p)           { return p.x; }                   // A "toInt" method that guarantees small, positive integers suitable for array indexing.
+inline  Lit  toLit       (int i)           { Lit p; p.x = i; return p; }     // Inverse of 'toInt()'
+
+inline  Lit  operator   ~(Lit p)           { Lit q; q.x = p.x ^ 1; return q; }
+inline  bool sign        (Lit p)           { return p.x & 1; }
+inline  int  var         (Lit p)           { return p.x >> 1; }
+inline  Lit  unsign      (Lit p)           { Lit q; q.x = p.x & ~1; return q; }
+inline  Lit  id          (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
+
+inline  bool operator == (Lit p, Lit q)    { return toInt(p) == toInt(q); }
+inline  bool operator != (Lit p, Lit q)    { return toInt(p) != toInt(q); }
+inline  bool operator <  (Lit p, Lit q)    { return toInt(p)  < toInt(q); }  // '<' guarantees that p, ~p are adjacent in the ordering.
+
+
+const Lit lit_Undef(var_Undef, false);  // }- Useful special constants.
+const Lit lit_Error(var_Undef, true );  // }
+
+
+//=================================================================================================
+// Clause -- a simple class for representing a clause:
+
+class Clause {
+    uint    size_etc;
+    union { float act; uint abst; } apa;
+    Lit     data[0];
+public:
+    // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
+    template<class V>
+    Clause(const V& ps, bool learnt) {
+        size_etc = (ps.size() << 3) | (uint)learnt;
+        for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
+        if (learnt) apa.act = 0; else apa.abst = 0; }
+
+    // -- use this function instead:
+    template<class V>
+    friend Clause* Clause_new(const V& ps, bool learnt = false) {
+        assert(sizeof(Lit)      == sizeof(uint));
+        assert(sizeof(float)    == sizeof(uint));
+        void*   mem = xmalloc<char>(sizeof(Clause) + sizeof(uint)*(ps.size()));
+        return new (mem) Clause(ps, learnt); }
+
+    int       size        ()      const { return size_etc >> 3; }
+    void      shrink      (int i)       { assert(i <= size()); size_etc = (((size_etc >> 3) - i) << 3) | (size_etc & 7); }
+    void      pop         ()            { shrink(1); }
+    bool      learnt      ()      const { return size_etc & 1; }
+    uint      mark        ()      const { return (size_etc >> 1) & 3; }
+    void      mark        (uint m)      { size_etc = (size_etc & ~6) | ((m & 3) << 1); }
+    Lit       operator [] (int i) const { return data[i]; }
+    Lit&      operator [] (int i)       { return data[i]; }
+
+    float&    activity    ()       { return apa.act; }
+
+    uint      abstraction () const { return apa.abst; }
+
+    void calcAbstraction() {
+        uint abstraction = 0;
+        for (int i = 0; i < size(); i++)
+            abstraction |= 1 << (var(data[i]) & 31);
+        apa.abst = abstraction;  }
+};
+
+
+//=================================================================================================
+// TrailPos -- Stores an index into the trail as well as an approximation of a level. This data
+// is recorded for each assigment. (Replaces the old level information)
+
+
+class TrailPos {
+    int tp;
+ public:
+    explicit TrailPos(int index, int level) : tp( (index << 5) + (level & 31) ) { }
+
+    friend int abstractLevel(const TrailPos& p) { return 1 << (p.tp & 31); }
+    friend int position     (const TrailPos& p) { return p.tp >> 5; }
+
+    bool operator ==  (TrailPos other) const { return tp == other.tp; }
+    bool operator <   (TrailPos other) const { return tp <  other.tp; }
+};
+
+};
+#endif

Added: klee/trunk/stp/sat/Sort.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/Sort.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/Sort.h (added)
+++ klee/trunk/stp/sat/Sort.h Wed May 20 23:36:41 2009
@@ -0,0 +1,133 @@
+/******************************************************************************************[Sort.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Sort_h
+#define Sort_h
+
+
+namespace MINISAT {
+//=================================================================================================
+
+
+template<class T>
+struct LessThan_default {
+    bool operator () (T x, T y) { return x < y; }
+};
+
+
+//=================================================================================================
+
+
+template <class T, class LessThan>
+void selectionSort(T* array, int size, LessThan lt)
+{
+    int     i, j, best_i;
+    T       tmp;
+
+    for (i = 0; i < size-1; i++){
+        best_i = i;
+        for (j = i+1; j < size; j++){
+            if (lt(array[j], array[best_i]))
+                best_i = j;
+        }
+        tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
+    }
+}
+template <class T> static inline void selectionSort(T* array, int size) {
+    selectionSort(array, size, LessThan_default<T>()); }
+
+
+template <class T, class LessThan>
+void sort(T* array, int size, LessThan lt, double& seed)
+{
+    if (size <= 15)
+        selectionSort(array, size, lt);
+
+    else{
+        T           pivot = array[irand(seed, size)];
+        T           tmp;
+        int         i = -1;
+        int         j = size;
+
+        for(;;){
+            do i++; while(lt(array[i], pivot));
+            do j--; while(lt(pivot, array[j]));
+
+            if (i >= j) break;
+
+            tmp = array[i]; array[i] = array[j]; array[j] = tmp;
+        }
+
+        sort(array    , i     , lt, seed);
+        sort(&array[i], size-i, lt, seed);
+    }
+}
+template <class T, class LessThan> void sort(T* array, int size, LessThan lt) {
+    double  seed = 91648253; sort(array, size, lt, seed); }
+template <class T> static inline void sort(T* array, int size) {
+    sort(array, size, LessThan_default<T>()); }
+
+
+template <class T, class LessThan>
+void sortUnique(T* array, int& size, LessThan lt)
+{
+    int         i, j;
+    T           last;
+
+    if (size == 0) return;
+
+    sort(array, size, lt);
+
+    i    = 1;
+    last = array[0];
+    for (j = 1; j < size; j++){
+        if (lt(last, array[j])){
+            last = array[i] = array[j];
+            i++; }
+    }
+
+    size = i;
+}
+template <class T> static inline void sortUnique(T* array, int& size) {
+    sortUnique(array, size, LessThan_default<T>()); }
+
+
+//=================================================================================================
+// For 'vec's:
+
+
+template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
+    sort((T*)v, v.size(), lt); }
+template <class T> void sort(vec<T>& v) {
+    sort(v, LessThan_default<T>()); }
+
+
+template <class T, class LessThan> void sortUnique(vec<T>& v, LessThan lt) {
+    int     size = v.size();
+    T*      data = v.release();
+    sortUnique(data, size, lt);
+    v.~vec<T>();
+    new (&v) vec<T>(data, size); }
+template <class T> void sortUnique(vec<T>& v) {
+    sortUnique(v, LessThan_default<T>()); }
+
+
+//=================================================================================================
+};
+#endif

Added: klee/trunk/stp/sat/VarOrder.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/sat/VarOrder.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/sat/VarOrder.h (added)
+++ klee/trunk/stp/sat/VarOrder.h Wed May 20 23:36:41 2009
@@ -0,0 +1,146 @@
+/**************************************************************************************[VarOrder.h]
+MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef VarOrder_h
+#define VarOrder_h
+
+#include "SolverTypes.h"
+#include "Solver.h"
+#include "Heap.h"
+#include "../AST/ASTUtil.h"
+
+namespace MINISAT {
+  //=================================================================================================
+
+  struct VarOrder_lt {
+    const vec<double>&  activity;
+    bool operator () (Var x, Var y) { return activity[x] > activity[y]; }
+    VarOrder_lt(const vec<double>&  act) : activity(act) { }
+  };
+  
+
+  enum { p_decisionvar = 0, p_polarity = 1, p_frozen = 2, p_dontcare = 3 };
+  
+  
+  class VarOrder {
+    const vec<char>&    assigns;     // var->val. Pointer to external assignment table.
+    const vec<double>&  activity;    // var->act. Pointer to external activity table.
+    vec<char>           properties;
+    //Heap<VarOrder_lt>   heap;
+    //double              random_seed; // For the internal random number generator
+    
+    friend class VarFilter;
+  public:
+    //FIXME: Vijay: delete after experiments
+    Heap<VarOrder_lt>   heap;
+    double              random_seed; // For the internal random number generator
+    //FIXME ENDS HERE
+
+    VarOrder(const vec<char>& ass, const vec<double>& act) :
+      assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(2007)
+      //assigns(ass), activity(act), heap(VarOrder_lt(act))
+    { }
+    
+    int  size       ()                         { return heap.size(); }
+    void setVarProp (Var v, uint prop, bool b) { properties[v] = (properties[v] & ~(1 << prop)) | (b << prop); }
+    bool hasVarProp (Var v, uint prop) const   { return properties[v] & (1 << prop); }
+    inline void cleanup    ();
+    
+    inline void newVar(bool polarity, bool dvar);
+    inline void update(Var x);                  // Called when variable increased in activity.
+    inline void undo(Var x);                    // Called when variable is unassigned and may be selected again.
+    //Selects a new, unassigned variable (or 'var_Undef' if none exists).
+    inline Lit  select(double random_freq =.0, int decision_level = 0); 
+  };
+  
+  
+  struct VarFilter {
+    const VarOrder& o;
+    VarFilter(const VarOrder& _o) : o(_o) {}
+    bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef  && o.hasVarProp(v, p_decisionvar); }
+    //bool operator()(Var v) const { return toLbool(o.assigns[v]) == l_Undef; }
+  };
+  
+  void VarOrder::cleanup()
+  {
+    VarFilter f(*this);
+    heap.filter(f);
+  }
+  
+  void VarOrder::newVar(bool polarity, bool dvar)
+  {
+    Var v = assigns.size()-1;
+    heap.setBounds(v+1);
+    properties.push(0);
+    setVarProp(v, p_decisionvar, dvar);
+    setVarProp(v, p_polarity, polarity);
+    undo(v);
+  }
+  
+  
+  void VarOrder::update(Var x)
+  {
+    if (heap.inHeap(x))
+      heap.increase(x);
+  }
+  
+  
+  void VarOrder::undo(Var x)
+  {
+    if (!heap.inHeap(x) && hasVarProp(x, p_decisionvar))
+      heap.insert(x);
+  }
+  
+  
+  Lit VarOrder::select(double random_var_freq, int decision_level)
+  {
+    Var next = var_Undef;
+    
+    if (drand(random_seed) < random_var_freq && !heap.empty())
+      next = irand(random_seed,assigns.size());
+
+    // Activity based decision:
+    while (next == var_Undef || toLbool(assigns[next]) != l_Undef || !hasVarProp(next, p_decisionvar))
+      if (heap.empty()){
+	next = var_Undef;
+	break;
+      }else
+	next = heap.getmin();
+    
+    //printing
+    if(BEEV::print_sat_varorder) {
+      if (next != var_Undef) {
+	BEEV::Convert_MINISATVar_To_ASTNode_Print(next,
+						  decision_level,
+						  hasVarProp(next, p_polarity));
+	// fprintf(stderr,"var = %d, prop = %d, decision = %d, polarity = %d, frozen = %d\n", 
+	// 		next+1, properties[next], hasVarProp(next, p_decisionvar), 
+	// 		hasVarProp(next, p_polarity), hasVarProp(next, p_frozen));
+      }
+      else
+	fprintf(stderr, "var = undef\n");
+    }
+    
+    return next == var_Undef ? lit_Undef : Lit(next, hasVarProp(next, p_polarity));
+  }
+  
+  
+  //=================================================================================================
+};
+#endif

Added: klee/trunk/stp/simplifier/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/simplifier/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/simplifier/Makefile (added)
+++ klee/trunk/stp/simplifier/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+include ../Makefile.common
+
+SRCS = simplifier.cpp bvsolver.cpp
+OBJS = $(SRCS:.cpp=.o)
+
+libsimplifier.a: $(OBJS)
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:	
+	rm -rf *.o *~ *.a .#*

Added: klee/trunk/stp/simplifier/bvsolver.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/simplifier/bvsolver.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/simplifier/bvsolver.cpp (added)
+++ klee/trunk/stp/simplifier/bvsolver.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,714 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+#include "bvsolver.h"
+
+  //This file contains the implementation of member functions of
+  //bvsolver class, which represents the bitvector arithmetic linear
+  //solver. Please also refer the STP's CAV 2007 paper for the
+  //complete description of the linear solver algorithm
+  //
+  //The bitvector solver is a partial solver, i.e. it does not solve
+  //for all variables in the system of equations. it is
+  //best-effort. it relies on the SAT solver to be complete.
+  //
+  //The BVSolver assumes that the input equations are normalized, and
+  //have liketerms combined etc.
+  //
+  //0. Traverse top-down over the input DAG, looking for a conjunction
+  //0. of equations. if you find one, then for each equation in the
+  //0. conjunction, do the following steps.
+  //
+  //1. check for Linearity of the input equation
+  //
+  //2. Solve for a "chosen" variable. The variable should occur
+  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+  //2. paper for actual solving procedure
+  //
+  //4. Outside the solver, Substitute and Re-normalize the input DAG 
+namespace BEEV {  
+  //check the solver map for 'key'. If key is present, then return the
+  //value by reference in the argument 'output'
+  bool BVSolver::CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = FormulasAlreadySolvedMap.find(key)) != FormulasAlreadySolvedMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  } //CheckAlreadySolvedMap()
+
+  void BVSolver::UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value) {
+    FormulasAlreadySolvedMap[key] = value;
+  } //end of UpdateAlreadySolvedMap()
+
+  //FIXME This is doing way more arithmetic than it needs to.
+  //accepts an even number "in", and splits it into an odd number and
+  //a power of 2. i.e " in = b.(2^k) ". returns the odd number, and
+  //the power of two by reference
+  ASTNode BVSolver::SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, 
+						unsigned int& number_shifts) {
+    if(BVCONST != in.GetKind() || _bm->BVConstIsOdd(in)) {
+      FatalError("BVSolver:SplitNum_Odd_PowerOf2: input must be a BVCONST and even\n",in);
+    }
+    
+    unsigned int len = in.GetValueWidth();
+    ASTNode zero = _bm->CreateZeroConst(len);
+    ASTNode two = _bm->CreateTwoConst(len);
+    ASTNode div_by_2 = in;
+    ASTNode mod_by_2 = 
+      _bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two)); 
+    while(mod_by_2 == zero) {
+      div_by_2 = 
+	_bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,div_by_2,two));
+      number_shifts++;
+      mod_by_2 = 
+	_bm->BVConstEvaluator(_bm->CreateTerm(BVMOD,len,div_by_2,two));
+    }
+    return div_by_2;
+  } //end of SplitEven_into_Oddnum_PowerOf2()
+
+  //Checks if there are any ARRAYREADS in the term, after the
+  //alreadyseenmap is cleared, i.e. traversing a new term altogether
+  bool BVSolver::CheckForArrayReads_TopLevel(const ASTNode& term) {
+    TermsAlreadySeenMap.clear();
+    return CheckForArrayReads(term);
+  }
+  
+  //Checks if there are any ARRAYREADS in the term
+  bool BVSolver::CheckForArrayReads(const ASTNode& term) {
+    ASTNode a = term;
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      //if the term has been seen, then simply return true, else
+      //return false
+      if(ASTTrue == (it->second)) {
+	return true;
+      }
+      else {
+	return false;
+      }
+    }
+
+    switch(term.GetKind()) {
+    case READ:
+      //an array read has been seen. Make an entry in the map and
+      //return true
+      TermsAlreadySeenMap[term] = ASTTrue;
+      return true;
+    default: {
+      ASTVec c = term.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	if(CheckForArrayReads(*it)) {
+	  return true;
+	}
+      }
+      break;
+    }
+    }
+
+    //If control is here, then it means that no arrayread was seen for
+    //the input 'term'. Make an entry in the map with the term as key
+    //and FALSE as value.
+    TermsAlreadySeenMap[term] = ASTFalse;
+    return false;
+  } //end of CheckForArrayReads()
+  
+  //check the solver map for 'key'. If key is present, then return the
+  //value by reference in the argument 'output'
+  bool BeevMgr::CheckSolverMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = SolverMap.find(key)) != SolverMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  } //end of CheckSolverMap()
+
+  bool BeevMgr::CheckSolverMap(const ASTNode& key) {
+    if(SolverMap.find(key) != SolverMap.end())	
+      return true;
+    else
+      return false;
+  } //end of CheckSolverMap()
+  
+  //update solvermap with (key,value) pair
+  bool BeevMgr::UpdateSolverMap(const ASTNode& key, const ASTNode& value) {
+    ASTNode var = (BVEXTRACT == key.GetKind()) ? key[0] : key;
+    if(!CheckSolverMap(var) && key != value) {
+      SolverMap[key] = value;
+      return true;
+    }  
+    return false;
+  } //end of UpdateSolverMap()
+
+  //collects the vars in the term 'lhs' into the multiset Vars
+  void BVSolver::VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& Vars) {
+    TermsAlreadySeenMap.clear();
+    VarsInTheTerm(lhs,Vars);
+  }
+
+  //collects the vars in the term 'lhs' into the multiset Vars
+  void BVSolver::VarsInTheTerm(const ASTNode& term, ASTNodeMultiSet& Vars) {
+    ASTNode a = term;
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      //if the term has been seen, then simply return
+      return;
+    }
+
+    switch(term.GetKind()) {
+    case BVCONST:
+      return;
+    case SYMBOL:
+      //cerr << "debugging: symbol added: " << term << endl;
+      Vars.insert(term);
+      break;
+    case READ:
+      //skip the arrayname, provided the arrayname is a SYMBOL
+      if(SYMBOL == term[0].GetKind()) {
+	VarsInTheTerm(term[1],Vars);
+      }
+      else {
+	VarsInTheTerm(term[0],Vars);
+	VarsInTheTerm(term[1],Vars);
+      }
+      break;
+    default: {
+      ASTVec c = term.GetChildren();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  VarsInTheTerm(*it,Vars);	  
+      }
+      break;
+    }
+    }
+
+    //ensures that you don't double count. if you have seen the term
+    //once, then memoize
+    TermsAlreadySeenMap[term] = ASTTrue;
+    return;
+  } //end of VarsInTheTerm()  
+
+  bool BVSolver::DoNotSolveThis(const ASTNode& var) {
+    if(DoNotSolve_TheseVars.find(var) != DoNotSolve_TheseVars.end()) {
+      return true;
+    }
+    return false;
+  }
+
+  //chooses a variable in the lhs and returns the chosen variable
+  ASTNode BVSolver::ChooseMonom(const ASTNode& eq, ASTNode& modifiedlhs) {
+    if(!(EQ == eq.GetKind() && BVPLUS == eq[0].GetKind())) {
+      FatalError("ChooseMonom: input must be a EQ",eq);
+    }
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    ASTNode zero = _bm->CreateZeroConst(32);
+
+    //collect all the vars in the lhs and rhs
+    ASTNodeMultiSet Vars;
+    VarsInTheTerm_TopLevel(lhs,Vars);
+
+    //handle BVPLUS case
+    ASTVec c = lhs.GetChildren();
+    ASTVec o;    
+    ASTNode outmonom = _bm->CreateNode(UNDEFINED);
+    bool chosen_symbol = false;
+    bool chosen_odd = false;
+
+    //choose variables with no coeffs
+    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+      ASTNode monom = *it;
+      if(SYMBOL == monom.GetKind() &&
+	 Vars.count(monom) == 1    &&	 
+	 !_bm->VarSeenInTerm(monom,rhs) &&
+	 !DoNotSolveThis(monom)   &&
+	 !chosen_symbol) {
+	outmonom = monom;
+	chosen_symbol = true;
+      }
+      else if(BVUMINUS == monom.GetKind()  &&
+	      SYMBOL == monom[0].GetKind() &&
+	      Vars.count(monom[0]) == 1    &&
+	      !DoNotSolveThis(monom[0])   &&
+	      !_bm->VarSeenInTerm(monom[0],rhs) &&
+	      !chosen_symbol) {
+	//cerr << "Chosen Monom: " << monom << endl;
+	outmonom = monom;
+	chosen_symbol = true;
+      }
+      else {
+	o.push_back(monom);
+      }
+    }
+
+    //try to choose only odd coeffed variables first
+    if(!chosen_symbol) {
+      o.clear();
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode monom = *it;
+	ASTNode var = (BVMULT == monom.GetKind()) ? monom[1] : _bm->CreateNode(UNDEFINED);
+
+	if(BVMULT == monom.GetKind()     && 
+	   BVCONST == monom[0].GetKind() &&
+	   _bm->BVConstIsOdd(monom[0])   &&
+	   ((SYMBOL == var.GetKind()  && 
+	     Vars.count(var) == 1) 
+	    || 
+	    (BVEXTRACT == var.GetKind()  && 
+	     SYMBOL == var[0].GetKind()  && 
+	     BVCONST == var[1].GetKind() && 
+	     zero == var[2] && 
+	     !_bm->VarSeenInTerm(var[0],rhs) &&
+	     !DoNotSolveThis(var[0]))	    
+	    ) &&
+	   !DoNotSolveThis(var)     &&
+	   !_bm->VarSeenInTerm(var,rhs)  &&
+	   !chosen_odd) {
+	  //monom[0] is odd.
+	  outmonom = monom;
+	  chosen_odd = true;
+	}
+	else {
+	o.push_back(monom);
+	}
+      }
+    }
+
+    modifiedlhs = (o.size() > 1) ? _bm->CreateTerm(BVPLUS,lhs.GetValueWidth(),o) : o[0];
+    return outmonom;
+  } //end of choosemonom()
+
+  //solver function which solves for variables with odd coefficient
+  ASTNode BVSolver::BVSolve_Odd(const ASTNode& input) {
+    ASTNode eq = input;
+    //cerr << "Input to BVSolve_Odd()" << eq << endl;
+    if(!(wordlevel_solve && EQ == eq.GetKind())) {
+      return input;
+    }
+
+    ASTNode output = input;
+    if(CheckAlreadySolvedMap(input,output)) {
+      return output;
+    }
+
+    //get the lhs and the rhs, and case-split on the lhs kind
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    if(BVPLUS == lhs.GetKind()) {
+      ASTNode chosen_monom = _bm->CreateNode(UNDEFINED);
+      ASTNode leftover_lhs;
+
+      //choose monom makes sure that it gets only those vars that
+      //occur exactly once in lhs and rhs put together
+      chosen_monom = ChooseMonom(eq, leftover_lhs);
+      if(chosen_monom == _bm->CreateNode(UNDEFINED)) {
+	//no monomial was chosen
+	return eq;
+      }
+      
+      //if control is here then it means that a monom was chosen
+      //
+      //construct:  rhs - (lhs without the chosen monom)
+      unsigned int len = lhs.GetValueWidth();
+      leftover_lhs = _bm->SimplifyTerm_TopLevel(_bm->CreateTerm(BVUMINUS,len,leftover_lhs));      
+      ASTNode newrhs = _bm->SimplifyTerm(_bm->CreateTerm(BVPLUS,len,rhs,leftover_lhs));
+      lhs = chosen_monom;
+      rhs = newrhs;
+    } //end of if(BVPLUS ...)
+
+    if(BVUMINUS == lhs.GetKind()) {
+      //equation is of the form (-lhs0) = rhs
+      ASTNode lhs0 = lhs[0];
+      rhs = _bm->SimplifyTerm(_bm->CreateTerm(BVUMINUS,rhs.GetValueWidth(),rhs));
+      lhs = lhs0;      
+    }
+
+    switch(lhs.GetKind()) {
+    case SYMBOL: {     
+      //input is of the form x = rhs first make sure that the lhs
+      //symbol does not occur on the rhs or that it has not been
+      //solved for
+      if(_bm->VarSeenInTerm(lhs,rhs)) {
+	//found the lhs in the rhs. Abort!
+	DoNotSolve_TheseVars.insert(lhs);
+	return eq;
+      }
+      
+      //rhs should not have arrayreads in it. it complicates matters
+      //during transformation
+      // if(CheckForArrayReads_TopLevel(rhs)) {
+      //       	return eq;
+      //       }
+
+      DoNotSolve_TheseVars.insert(lhs);
+      if(!_bm->UpdateSolverMap(lhs,rhs)) {
+	return eq;
+      }
+
+      output = ASTTrue;
+      break;
+    }
+    case BVEXTRACT: {
+      ASTNode zero = _bm->CreateZeroConst(32);
+      
+      if(!(SYMBOL == lhs[0].GetKind()  && 
+      	   BVCONST == lhs[1].GetKind() && 
+      	   zero == lhs[2] && 
+      	   !_bm->VarSeenInTerm(lhs[0],rhs) &&
+      	   !DoNotSolveThis(lhs[0]))) {
+      	return eq;
+      }
+      
+      if(_bm->VarSeenInTerm(lhs[0],rhs)) {
+      	DoNotSolve_TheseVars.insert(lhs[0]);
+      	return eq;
+      }
+      
+      DoNotSolve_TheseVars.insert(lhs[0]);
+      if(!_bm->UpdateSolverMap(lhs,rhs)) {
+      	return eq;
+      }
+
+      //if the extract of x[i:0] = t is entered into the solvermap,
+      //then also add another entry for x = x1 at t
+      ASTNode var = lhs[0];
+      ASTNode newvar = NewVar(var.GetValueWidth() - lhs.GetValueWidth());
+      newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,rhs);
+      _bm->UpdateSolverMap(var,newvar);      
+      output = ASTTrue;
+      break;
+    }
+    case BVMULT: {
+      //the input is of the form a*x = t. If 'a' is odd, then compute
+      //its multiplicative inverse a^-1, multiply 't' with it, and
+      //update the solver map
+      if(BVCONST != lhs[0].GetKind()) {
+	return eq;
+      }
+      
+      if(!(SYMBOL == lhs[1].GetKind() ||
+	   (BVEXTRACT == lhs[1].GetKind() &&
+	   SYMBOL == lhs[1][0].GetKind()))) {
+	return eq;
+      }
+
+      bool ChosenVar_Is_Extract = (BVEXTRACT == lhs[1].GetKind()) ? true : false;
+
+      //if coeff is even, then we know that all the coeffs in the eqn
+      //are even. Simply return the eqn
+      if(!_bm->BVConstIsOdd(lhs[0])) {
+	return eq;
+      }
+
+      ASTNode a = _bm->MultiplicativeInverse(lhs[0]);
+      ASTNode chosenvar = (BVEXTRACT == lhs[1].GetKind()) ? lhs[1][0] : lhs[1];
+      ASTNode chosenvar_value = 
+	_bm->SimplifyTerm(_bm->CreateTerm(BVMULT,rhs.GetValueWidth(),a,rhs));
+      
+      //if chosenvar is seen in chosenvar_value then abort
+      if(_bm->VarSeenInTerm(chosenvar,chosenvar_value)) {
+	//abort solving
+	DoNotSolve_TheseVars.insert(lhs);
+	return eq;
+      }
+
+      //rhs should not have arrayreads in it. it complicates matters
+      //during transformation
+      // if(CheckForArrayReads_TopLevel(chosenvar_value)) {
+      //       	return eq;
+      //       }
+            
+      //found a variable to solve
+      DoNotSolve_TheseVars.insert(chosenvar);
+      chosenvar = lhs[1];
+      if(!_bm->UpdateSolverMap(chosenvar,chosenvar_value)) {
+	return eq;
+      }
+
+      if(ChosenVar_Is_Extract) {
+	ASTNode var = lhs[1][0];
+	ASTNode newvar = NewVar(var.GetValueWidth() - lhs[1].GetValueWidth());
+	newvar = _bm->CreateTerm(BVCONCAT,var.GetValueWidth(),newvar,chosenvar_value);
+	_bm->UpdateSolverMap(var,newvar);
+      }
+      output = ASTTrue;
+      break;
+    }    
+    default:
+      output = eq;
+      break;
+    }
+    
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of BVSolve_Odd()
+
+  //Create a new variable of ValueWidth 'n'
+  ASTNode BVSolver::NewVar(unsigned int n) {
+    std:: string c("v");
+    char d[32];
+    sprintf(d,"%d",_symbol_count++);
+    std::string ccc(d);
+    c += "_solver_" + ccc;
+    
+    ASTNode CurrentSymbol = _bm->CreateSymbol(c.c_str());
+    CurrentSymbol.SetValueWidth(n);
+    CurrentSymbol.SetIndexWidth(0);
+    return CurrentSymbol;
+  } //end of NewVar()
+
+  //The toplevel bvsolver(). Checks if the formula has already been
+  //solved. If not, the solver() is invoked. If yes, then simply drop
+  //the formula
+  ASTNode BVSolver::TopLevelBVSolve(const ASTNode& input) {
+    if(!wordlevel_solve) {
+      return input;
+    }
+    
+    Kind k = input.GetKind();
+    if(!(EQ == k || AND == k)) {
+      return input;
+    }
+
+    ASTNode output = input;
+    if(CheckAlreadySolvedMap(input,output)) {
+      //output is TRUE. The formula is thus dropped
+      return output;
+    }
+    ASTVec o;
+    ASTVec c;
+    if(EQ == k) 
+      c.push_back(input);
+    else 
+      c = input.GetChildren();
+    ASTVec eveneqns;
+    ASTNode solved = ASTFalse;
+    for(ASTVec::iterator it = c.begin(), itend = c.end();it != itend;it++) { 
+      //_bm->ASTNodeStats("Printing before calling simplifyformula inside the solver:", *it);
+      ASTNode aaa = (ASTTrue == solved && EQ == it->GetKind()) ? _bm->SimplifyFormula(*it,false) : *it;
+      //ASTNode aaa = *it;
+      //_bm->ASTNodeStats("Printing after calling simplifyformula inside the solver:", aaa);
+      aaa = BVSolve_Odd(aaa);
+      //_bm->ASTNodeStats("Printing after oddsolver:", aaa);
+      bool even = false;
+      aaa = CheckEvenEqn(aaa, even);
+      if(even) {
+	eveneqns.push_back(aaa);
+      }
+      else {
+	if(ASTTrue != aaa) {
+	  o.push_back(aaa);
+	}
+      }
+      solved = aaa;
+    }
+
+    ASTNode evens;
+    if(eveneqns.size() > 0) {
+      //if there is a system of even equations then solve them
+      evens = (eveneqns.size() > 1) ? _bm->CreateNode(AND,eveneqns) : eveneqns[0];
+      //evens = _bm->SimplifyFormula(evens,false);
+      evens = BVSolve_Even(evens);
+      _bm->ASTNodeStats("Printing after evensolver:", evens);
+    }
+    else {
+      evens = ASTTrue;
+    }
+    output = (o.size() > 0) ? ((o.size() > 1) ? _bm->CreateNode(AND,o) : o[0]) : ASTTrue;
+    output = _bm->CreateNode(AND,output,evens);
+
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of TopLevelBVSolve()
+
+  ASTNode BVSolver::CheckEvenEqn(const ASTNode& input, bool& evenflag) {
+    ASTNode eq = input;
+    //cerr << "Input to BVSolve_Odd()" << eq << endl;
+    if(!(wordlevel_solve && EQ == eq.GetKind())) {
+      evenflag = false;
+      return eq;
+    }
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+    //lhs must be a BVPLUS, and rhs must be a BVCONST
+    if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+      evenflag = false;
+      return eq;
+    }
+    
+    ASTVec lhs_c = lhs.GetChildren();
+    ASTNode savetheconst = rhs;
+    for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+      ASTNode aaa = *it;
+      Kind itk = aaa.GetKind();
+
+      if(BVCONST == itk){
+	//check later if the constant is even or not
+	savetheconst = aaa;
+	continue;
+      }
+      
+      if(!(BVMULT == itk &&
+	   BVCONST == aaa[0].GetKind() &&
+	   SYMBOL == aaa[1].GetKind() &&
+	   !_bm->BVConstIsOdd(aaa[0]))) {
+	//If the monomials of the lhs are NOT of the form 'a*x' where
+	//'a' is even, then return the false
+	evenflag = false;
+	return eq;
+      }  
+    }//end of for loop
+
+    //if control is here then it means that all coeffs are even. the
+    //only remaining thing is to check if the constant is even or not
+    if(_bm->BVConstIsOdd(savetheconst)) {
+      //the constant turned out to be odd. we have UNSAT eqn
+      evenflag = false;
+      return ASTFalse;
+    }
+    
+    //all is clear. the eqn in even, through and through
+    evenflag = true;
+    return eq;
+  } //end of CheckEvenEqn
+
+  //solve an eqn whose monomials have only even coefficients
+  ASTNode BVSolver::BVSolve_Even(const ASTNode& input) {
+    if(!wordlevel_solve) {
+      return input;
+    }
+
+    if(!(EQ == input.GetKind() || AND == input.GetKind())) {
+      return input;
+    }
+
+    ASTNode output;
+    if(CheckAlreadySolvedMap(input,output)) {
+      return output;
+    }
+
+    ASTVec input_c;
+    if(EQ == input.GetKind()) {
+      input_c.push_back(input);
+    }
+    else {
+      input_c = input.GetChildren();
+    }
+
+    //power_of_2 holds the exponent of 2 in the coeff
+    unsigned int power_of_2 = 0;
+    //we need this additional variable to find the lowest power of 2
+    unsigned int power_of_2_lowest = 0xffffffff;
+    //the monom which has the least power of 2 in the coeff
+    ASTNode monom_with_best_coeff;
+    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
+      ASTNode eq = *jt;
+      ASTNode lhs = eq[0];
+      ASTNode rhs = eq[1];
+      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+      //lhs must be a BVPLUS, and rhs must be a BVCONST
+      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+	return input;
+      }
+    
+      ASTVec lhs_c = lhs.GetChildren();
+      ASTNode odd;
+      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+	ASTNode aaa = *it;
+	Kind itk = aaa.GetKind();
+	if(!(BVCONST == itk &&
+	     !_bm->BVConstIsOdd(aaa)) &&
+	   !(BVMULT == itk &&
+	     BVCONST == aaa[0].GetKind() &&
+	     SYMBOL == aaa[1].GetKind() &&
+	     !_bm->BVConstIsOdd(aaa[0]))) {
+	  //If the monomials of the lhs are NOT of the form 'a*x' or 'a'
+	  //where 'a' is even, then return the eqn
+	  return input;
+	}
+	
+	//we are gauranteed that if control is here then the monomial is
+	//of the form 'a*x' or 'a', where 'a' is even
+	ASTNode coeff = (BVCONST == itk) ? aaa : aaa[0];
+	odd = SplitEven_into_Oddnum_PowerOf2(coeff,power_of_2);
+	if(power_of_2  < power_of_2_lowest) {
+	  power_of_2_lowest = power_of_2;
+	  monom_with_best_coeff = aaa;
+	}
+	power_of_2 = 0;
+      }//end of inner for loop
+    } //end of outer for loop    
+
+    //get the exponent
+    power_of_2 = power_of_2_lowest;
+    
+    //if control is here, we are gauranteed that we have chosen a
+    //monomial with fewest powers of 2
+    ASTVec formula_out;
+    for(ASTVec::iterator jt=input_c.begin(),jtend=input_c.end();jt!=jtend;jt++) {
+      ASTNode eq = *jt;      
+      ASTNode lhs = eq[0];
+      ASTNode rhs = eq[1];
+      ASTNode zero = _bm->CreateZeroConst(rhs.GetValueWidth());
+      //lhs must be a BVPLUS, and rhs must be a BVCONST
+      if(!(BVPLUS == lhs.GetKind() && zero == rhs)) {
+	return input;
+      }
+      
+      unsigned len = lhs.GetValueWidth();
+      ASTNode hi = _bm->CreateBVConst(32,len-1);
+      ASTNode low = _bm->CreateBVConst(32,len - power_of_2);
+      ASTNode low_minus_one = _bm->CreateBVConst(32,len - power_of_2 - 1);
+      ASTNode low_zero = _bm->CreateZeroConst(32);
+      unsigned newlen = len - power_of_2;
+      ASTNode two_const = _bm->CreateTwoConst(len);
+
+      unsigned count = power_of_2;
+      ASTNode two = two_const;
+      while(--count) {
+	two = _bm->BVConstEvaluator(_bm->CreateTerm(BVMULT,len,two_const,two));
+      }
+      ASTVec lhs_c = lhs.GetChildren();
+      ASTVec lhs_out;
+      for(ASTVec::iterator it=lhs_c.begin(),itend=lhs_c.end();it!=itend;it++) {
+	ASTNode aaa = *it;
+	Kind itk = aaa.GetKind();
+	if(BVCONST == itk) {
+	  aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa,two));
+	  aaa = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,aaa,low_minus_one,low_zero));
+	}
+	else {
+	  //it must be of the form a*x
+	  ASTNode coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVDIV,len,aaa[0],two));
+	  coeff = _bm->BVConstEvaluator(_bm->CreateTerm(BVEXTRACT,newlen,coeff,low_minus_one,low_zero));
+	  ASTNode upper_x, lower_x;
+	  //upper_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, power_of_2, aaa[1], hi, low));
+	  lower_x = _bm->SimplifyTerm(_bm->CreateTerm(BVEXTRACT, newlen,aaa[1],low_minus_one,low_zero));
+	  aaa = _bm->CreateTerm(BVMULT,newlen,coeff,lower_x);
+	}
+	lhs_out.push_back(aaa);
+      }//end of inner forloop()
+      rhs = _bm->CreateZeroConst(newlen);
+      lhs = _bm->CreateTerm(BVPLUS,newlen,lhs_out);     
+      formula_out.push_back(_bm->CreateSimplifiedEQ(lhs,rhs));
+    } //end of outer forloop()
+
+    output = 
+      (formula_out.size() > 0) ? (formula_out.size() > 1) ? _bm->CreateNode(AND,formula_out) : formula_out[0] : ASTTrue;
+
+    UpdateAlreadySolvedMap(input,output);
+    return output;
+  } //end of BVSolve_Even()
+};//end of namespace BEEV

Added: klee/trunk/stp/simplifier/bvsolver.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/simplifier/bvsolver.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/simplifier/bvsolver.h (added)
+++ klee/trunk/stp/simplifier/bvsolver.h Wed May 20 23:36:41 2009
@@ -0,0 +1,134 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+namespace BEEV {
+
+  //This class represents the bitvector arithmetic linear solver.
+  //
+  //The bitvector solver is a partial solver, i.e. it does not solve
+  //for all variables in the system of equations. it is
+  //best-effort. it relies on the SAT solver to be complete.
+  //
+  //The BVSolver assumes that the input equations are normalized, and
+  //have liketerms combined etc.
+  //
+  //0. Traverse top-down over the input DAG, looking for a conjunction
+  //0. of equations. if you find one, then for each equation in the
+  //0. conjunction, do the following steps.
+  //
+  //1. check for Linearity of the input equation
+  //
+  //2. Solve for a "chosen" variable. The variable should occur
+  //2. exactly once and must have an odd coeff. Refer STP's CAV 2007
+  //2. paper for actual solving procedure
+  //
+  //4. Outside the solver, Substitute and Re-normalize the input DAG 
+  class BVSolver {
+    //Ptr to toplevel manager that manages bit-vector expressions
+    //(i.e. construct various kinds of expressions), and also has
+    //member functions that simplify bit-vector expressions
+    BeevMgr * _bm;
+    ASTNode ASTTrue, ASTFalse;
+
+    //Those formulas which have already been solved. If the same
+    //formula occurs twice then do not solve the second occurence, and
+    //instead drop it
+    ASTNodeMap FormulasAlreadySolvedMap;
+
+    //this map is useful while traversing terms and uniquely
+    //identifying variables in the those terms. Prevents double
+    //counting.
+    ASTNodeMap TermsAlreadySeenMap;
+    ASTNodeMap TermsAlreadySeenMap_ForArrays;
+
+    //count is used in the creation of new variables
+    unsigned int _symbol_count;
+
+    //solved variables list: If a variable has been solved for then do
+    //not solve for it again
+    ASTNodeSet DoNotSolve_TheseVars;
+
+    //checks if var has been solved for or not. if yes, then return
+    //true else return false
+    bool DoNotSolveThis(const ASTNode& var);
+
+    //traverses a term, and creates a multiset of all variables in the
+    //term. Does memoization to avoid double counting.
+    void VarsInTheTerm(const ASTNode& lhs, ASTNodeMultiSet& v);
+    void VarsInTheTerm_TopLevel(const ASTNode& lhs, ASTNodeMultiSet& v);
+
+    //choose a suitable var from the term
+    ASTNode ChooseMonom(const ASTNode& eq, ASTNode& modifiedterm);
+    //accepts an equation and solves for a variable or a monom in it
+    ASTNode BVSolve_Odd(const ASTNode& eq);
+
+    //solves equations of the form a*x=t where 'a' is even. Has a
+    //return value, unlike the normal BVSolve()
+    ASTNode BVSolve_Even(const ASTNode& eq);
+    ASTNode CheckEvenEqn(const ASTNode& input, bool& evenflag);
+
+    //Checks for arrayreads in a term. if yes then returns true, else
+    //return false
+    bool CheckForArrayReads(const ASTNode& term);
+    bool CheckForArrayReads_TopLevel(const ASTNode& term);
+
+    //Creates new variables used in solving
+    ASTNode NewVar(unsigned int n);
+
+    //this function return true if the var occurs in term, else the
+    //function returns false
+    bool VarSeenInTerm(const ASTNode& var, const ASTNode& term);
+    
+    //takes an even number "in" as input, and returns an odd number
+    //(return value) and a power of 2 (as number_shifts by reference),
+    //such that in = (odd_number * power_of_2).
+    //
+    //Refer STP's CAV 2007 (or Clark Barrett's 1998 paper on
+    //bit-vector arithmetic published in DAC 1998) paper for precise
+    //understanding of the algorithm
+    ASTNode SplitEven_into_Oddnum_PowerOf2(const ASTNode& in, unsigned int& number_shifts);
+
+    //Once a formula has been solved, then update the alreadysolvedmap
+    //with the formula, and the solved value. The solved value can be
+    //described using the following example: Suppose input to the
+    //solver is
+    //
+    // input key: x = 2 AND y = x + t
+    //
+    // output value: y = 2 + t
+    void UpdateAlreadySolvedMap(const ASTNode& key, const ASTNode& value);
+
+    //This function checks if the key (formula) has already been
+    //solved for.
+    //
+    //If yes it returns TRUE and fills the "output" with the
+    //solved-value (call by reference argument),
+    //
+    //else returns FALSE
+    bool CheckAlreadySolvedMap(const ASTNode& key, ASTNode& output);
+  public:
+    //constructor
+    BVSolver(BeevMgr * bm) : _bm(bm), _symbol_count(0) {
+      ASTTrue = _bm->CreateNode(TRUE);
+      ASTFalse = _bm->CreateNode(FALSE);
+    };
+
+    //Destructor
+    ~BVSolver() {
+      TermsAlreadySeenMap.clear();
+      DoNotSolve_TheseVars.clear();
+    }
+
+    //Top Level Solver: Goes over the input DAG, identifies the
+    //equation to be solved, solves them,
+    ASTNode TopLevelBVSolve(const ASTNode& a);
+  }; //end of class bvsolver
+};//end of namespace BEEV

Added: klee/trunk/stp/simplifier/simplifier.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/stp/simplifier/simplifier.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/stp/simplifier/simplifier.cpp (added)
+++ klee/trunk/stp/simplifier/simplifier.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,2495 @@
+/********************************************************************
+ * AUTHORS: Vijay Ganesh, David L. Dill
+ *
+ * BEGIN DATE: November, 2005
+ *
+ * LICENSE: Please view LICENSE file in the home dir of this Program
+ ********************************************************************/
+// -*- c++ -*-
+
+#include "../AST/AST.h"
+#include "../AST/ASTUtil.h"
+namespace BEEV {
+  
+  bool BeevMgr::CheckSimplifyMap(const ASTNode& key, 
+				 ASTNode& output, bool pushNeg) {
+    ASTNodeMap::iterator it, itend;
+    it = pushNeg ? SimplifyNegMap.find(key) : SimplifyMap.find(key);
+    itend = pushNeg ? SimplifyNegMap.end() : SimplifyMap.end();
+    
+    if(it != itend) {
+      output = it->second;
+      CountersAndStats("Successful_CheckSimplifyMap");
+      return true;
+    }
+
+    if(pushNeg && (it = SimplifyMap.find(key)) != SimplifyMap.end()) {
+      output = 
+	(ASTFalse == it->second) ? 
+	ASTTrue : 
+	(ASTTrue == it->second) ? ASTFalse : CreateNode(NOT, it->second);
+      CountersAndStats("2nd_Successful_CheckSimplifyMap");
+      return true;
+    }
+
+    return false;
+  }
+  
+  void BeevMgr::UpdateSimplifyMap(const ASTNode& key, const ASTNode& value, bool pushNeg) {
+    if(pushNeg) 
+      SimplifyNegMap[key] = value;
+    else
+      SimplifyMap[key] = value;
+  }
+
+  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = SolverMap.find(key)) != SolverMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  }
+  
+  bool BeevMgr::CheckSubstitutionMap(const ASTNode& key) {
+    if(SolverMap.find(key) != SolverMap.end())	
+      return true;
+    else
+      return false;
+  }
+  
+  bool BeevMgr::UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1) {
+    int i = TermOrder(e0,e1);
+    if(0 == i)
+      return false;
+
+    //e0 is of the form READ(Arr,const), and e1 is const, or
+    //e0 is of the form var, and e1 is const    
+    if(1 == i && !CheckSubstitutionMap(e0)) {
+      SolverMap[e0] = e1;
+      return true;
+    }
+    
+    //e1 is of the form READ(Arr,const), and e0 is const, or
+    //e1 is of the form var, and e0 is const
+    if (-1 == i && !CheckSubstitutionMap(e1)) { 
+      SolverMap[e1] = e0;
+      return true;
+    }
+
+    return false;
+  }
+
+  bool BeevMgr::CheckMultInverseMap(const ASTNode& key, ASTNode& output) {
+    ASTNodeMap::iterator it;
+    if((it = MultInverseMap.find(key)) != MultInverseMap.end()) {
+      output = it->second;
+      return true;
+    }
+    return false;
+  }
+
+  void BeevMgr::UpdateMultInverseMap(const ASTNode& key, const ASTNode& value) {
+      MultInverseMap[key] = value;
+  }
+
+
+  bool BeevMgr::CheckAlwaysTrueFormMap(const ASTNode& key) {
+    ASTNodeSet::iterator it = AlwaysTrueFormMap.find(key);
+    ASTNodeSet::iterator itend = AlwaysTrueFormMap.end();
+    
+    if(it != itend) {
+      //cerr << "found:" << *it << endl;
+      CountersAndStats("Successful_CheckAlwaysTrueFormMap");
+      return true;
+    }
+    
+    return false;
+  }
+  
+  void BeevMgr::UpdateAlwaysTrueFormMap(const ASTNode& key) {
+    AlwaysTrueFormMap.insert(key);
+  }
+
+  //if a is READ(Arr,const) or SYMBOL, and b is BVCONST then return 1
+  //if b is READ(Arr,const) or SYMBOL, and a is BVCONST then return -1
+  //
+  //else return 0 by default
+   int BeevMgr::TermOrder(const ASTNode& a, const ASTNode& b) {
+    Kind k1 = a.GetKind();
+    Kind k2 = b.GetKind();
+
+    //a is of the form READ(Arr,const), and b is const, or
+    //a is of the form var, and b is const
+    if((k1 == READ 
+	&& 
+	a[0].GetKind() == SYMBOL && 
+	a[1].GetKind() == BVCONST
+	)
+       && 
+       (k2 == BVCONST)
+       )
+      return 1;
+
+    if(k1 == SYMBOL) 
+      return 1;
+
+    //b is of the form READ(Arr,const), and a is const, or
+    //b is of the form var, and a is const
+    if((k1  == BVCONST)
+       &&
+       ((k2 == READ
+	 && 
+	 b[0].GetKind() == SYMBOL &&
+	 b[1].GetKind() == BVCONST
+	 ) 
+	 ||
+	k2 == SYMBOL
+	))
+      return -1;
+    return 0;
+  }
+
+  //This function records all the const-indices seen so far for each
+  //array. It populates the map '_arrayname_readindices' whose key is
+  //the arrayname, and vlaue is a vector of read-indices.
+  //
+  //fill the arrayname_readindices vector if e0 is a READ(Arr,index)
+  //and index is a BVCONST.  
+  //
+  //Since these arrayreads are being nuked and recorded in the
+  //substitutionmap, we have to also record the fact that each
+  //arrayread (e0 is of the form READ(Arr,const) here is represented
+  //by a BVCONST (e1). This is necessary for later Leibnitz Axiom
+  //generation
+  void BeevMgr::FillUp_ArrReadIndex_Vec(const ASTNode& e0, const ASTNode& e1) {
+    int i = TermOrder(e0,e1);
+    if(0 == i) return;
+
+    if(1 == i && e0.GetKind() != SYMBOL && !CheckSubstitutionMap(e0)) {
+      _arrayname_readindices[e0[0]].push_back(e0[1]);
+      //e0 is the array read : READ(A,i) and e1 is a bvconst
+      _arrayread_symbol[e0] = e1;
+      return;
+    }
+    if(-1 == i && e1.GetKind() != SYMBOL &&  !CheckSubstitutionMap(e1)) {
+      _arrayname_readindices[e1[0]].push_back(e1[1]);
+      //e0 is the array read : READ(A,i) and e1 is a bvconst
+      _arrayread_symbol[e1] = e0;
+      return;
+    }
+  }
+
+  ASTNode BeevMgr::SimplifyFormula_NoRemoveWrites(const ASTNode& b, bool pushNeg) {
+    Begin_RemoveWrites = false;
+    ASTNode out = SimplifyFormula(b,pushNeg);
+    return out;
+  }
+
+  ASTNode BeevMgr::SimplifyFormula_TopLevel(const ASTNode& b, bool pushNeg) {
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    ASTNode out = SimplifyFormula(b,pushNeg);
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    return out;
+  }
+
+  ASTNode BeevMgr::SimplifyFormula(const ASTNode& b, bool pushNeg){
+    if(!optimize)
+      return b;
+
+    Kind kind = b.GetKind();
+    if(BOOLEAN_TYPE != b.GetType()) {
+      FatalError(" SimplifyFormula: You have input a nonformula kind: ",ASTUndefined,kind);
+    }
+    
+    ASTNode a = b;
+    ASTVec ca = a.GetChildren();
+    if(!(IMPLIES == kind || 
+	 ITE == kind ||
+	 isAtomic(kind))) {
+      SortByExprNum(ca);
+      a = CreateNode(kind,ca);
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    switch(kind){
+    case AND:
+    case OR:
+      output = SimplifyAndOrFormula(a,pushNeg);
+      break;
+    case NOT:
+      output = SimplifyNotFormula(a,pushNeg);
+      break;
+    case XOR:
+      output = SimplifyXorFormula(a,pushNeg);
+      break;
+    case NAND:
+      output = SimplifyNandFormula(a,pushNeg);
+      break;
+    case NOR:
+      output = SimplifyNorFormula(a,pushNeg);
+      break;
+    case IFF:
+      output = SimplifyIffFormula(a,pushNeg);
+      break;
+    case IMPLIES:
+      output = SimplifyImpliesFormula(a,pushNeg);
+      break;
+    case ITE:
+      output = SimplifyIteFormula(a,pushNeg);
+      break;
+    default:
+      //kind can be EQ,NEQ,BVLT,BVLE,... or a propositional variable
+      output = SimplifyAtomicFormula(a,pushNeg);
+      //output = pushNeg ? CreateNode(NOT,a) : a;
+      break;
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output, pushNeg);
+    return output;
+  }
+    
+  ASTNode BeevMgr::SimplifyAtomicFormula(const ASTNode& a, bool pushNeg) {    
+    if(!optimize) {
+      return a;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg)) {
+      return output;
+    }
+
+    ASTNode left,right;
+    if(a.Degree() == 2) {
+      //cerr << "Input to simplifyterm: left: " << a[0] << endl;
+      left = SimplifyTerm(a[0]);
+      //cerr << "Output of simplifyterm:left: " << left << endl;
+      //cerr << "Input to simplifyterm: right: " << a[1] << endl;
+      right = SimplifyTerm(a[1]);
+      //cerr << "Output of simplifyterm:left: " << right << endl;
+    }
+
+    Kind kind = a.GetKind();
+    switch(kind) {
+    case TRUE:
+      output = pushNeg ? ASTFalse : ASTTrue;
+      break;
+    case FALSE:
+      output = pushNeg ? ASTTrue : ASTFalse;
+      break;
+    case SYMBOL:
+      if(!CheckSolverMap(a,output)) {
+	output = a;
+      }
+      output = pushNeg ? CreateNode(NOT,output) : output;           
+      break;
+    case BVGETBIT: {
+      ASTNode term = SimplifyTerm(a[0]);
+      ASTNode thebit = a[1];
+      ASTNode zero = CreateZeroConst(1);
+      ASTNode one = CreateOneConst(1);
+      ASTNode getthebit = SimplifyTerm(CreateTerm(BVEXTRACT,1,term,thebit,thebit));
+      if(getthebit == zero)
+	output = pushNeg ? ASTTrue : ASTFalse;
+      else if(getthebit == one)
+	output = pushNeg ? ASTFalse : ASTTrue;
+      else {
+	output = CreateNode(BVGETBIT,term,thebit);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      break;
+    }
+    case EQ:{
+      output = CreateSimplifiedEQ(left,right);
+      output = LhsMinusRhs(output);
+      output = ITEOpt_InEqs(output);
+      if(output == ASTTrue)
+	output = pushNeg ? ASTFalse : ASTTrue;
+      else if (output == ASTFalse)
+	output = pushNeg ? ASTTrue : ASTFalse;
+      else
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      break;  
+    } 
+    case NEQ: {
+      output = CreateSimplifiedEQ(left,right);
+      output = LhsMinusRhs(output);
+      if(output == ASTTrue)
+      	output = pushNeg ? ASTTrue : ASTFalse;
+      else if (output == ASTFalse)
+      	output = pushNeg ? ASTFalse : ASTTrue;
+      else
+	output = pushNeg ? output : CreateNode(NOT,output);
+      break;
+    }
+    case BVLT:
+    case BVLE:
+    case BVGT:
+    case BVGE:
+    case BVSLT:
+    case BVSLE:
+    case BVSGT:
+    case BVSGE: {
+      //output = CreateNode(kind,left,right);
+      //output = pushNeg ? CreateNode(NOT,output) : output;      
+      output = CreateSimplifiedINEQ(kind,left,right,pushNeg);
+      break;
+    }
+    default:
+      FatalError("SimplifyAtomicFormula: NO atomic formula of the kind: ",ASTUndefined,kind);
+      break;      
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  } //end of SimplifyAtomicFormula()
+
+  ASTNode BeevMgr::CreateSimplifiedINEQ(Kind k, 
+					const ASTNode& left, 
+					const ASTNode& right, 
+					bool pushNeg) {
+    ASTNode output;
+    if(BVCONST == left.GetKind() && BVCONST == right.GetKind()) {
+      output = BVConstEvaluator(CreateNode(k,left,right));
+      output = pushNeg ? (ASTFalse == output) ? ASTTrue : ASTFalse : output;
+      return output;
+    }
+
+    unsigned len = left.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode one = CreateOneConst(len);
+    ASTNode max = CreateMaxConst(len);
+    switch(k){
+    case BVLT:
+      if(right == zero) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(one == right) {
+	output = CreateSimplifiedEQ(left,zero);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      else {
+	output = pushNeg ? CreateNode(BVLE,right,left) : CreateNode(BVLT,left,right);
+      }
+      break;
+    case BVLE:
+      if(left == zero) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(max == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(zero == right) {
+	output = CreateSimplifiedEQ(left,zero);
+	output = pushNeg ? CreateNode(NOT,output) : output;
+      }
+      else {
+	output = pushNeg ? CreateNode(BVLT,right,left) : CreateNode(BVLE,left,right);
+      }
+      break;
+    case BVGT:
+      if(left == zero) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTTrue : ASTFalse;
+      }
+      else {
+      output = pushNeg ? CreateNode(BVLE,left,right) : CreateNode(BVLT,right,left);
+      }
+      break;
+    case BVGE:
+      if(right == zero) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else if(left == right) {
+	output = pushNeg ? ASTFalse : ASTTrue;
+      }
+      else {
+      output = pushNeg ? CreateNode(BVLT,left,right) : CreateNode(BVLE,right,left);
+      }
+      break;
+    case BVSLT:
+    case BVSLE:
+    case BVSGE:
+    case BVSGT: {
+      output = CreateNode(k,left,right);
+      output = pushNeg ? CreateNode(NOT,output) : output;
+    }
+      break;
+    default:
+      FatalError("Wrong Kind");
+      break;
+    }
+
+    return output;
+  }
+
+  //takes care of some simple ITE Optimizations in the context of equations
+  ASTNode BeevMgr::ITEOpt_InEqs(const ASTNode& in) {
+    CountersAndStats("ITEOpts_InEqs");
+
+    if(!(EQ == in.GetKind() && optimize)) {
+      return in;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(in,output,false)) {
+      return output;
+    }
+
+    ASTNode in1 = in[0];
+    ASTNode in2 = in[1];
+    Kind k1 = in1.GetKind();
+    Kind k2 = in2.GetKind();
+    if(in1 == in2) {
+      //terms are syntactically the same
+      output = ASTTrue;    
+    }
+    else if(BVCONST == k1 && BVCONST == k2) {
+      //here the terms are definitely not syntactically equal but may
+      //be semantically equal.
+      output = ASTFalse;
+    }
+    else if(ITE == k1 && 
+	    BVCONST == in1[1].GetKind() && 
+	    BVCONST == in1[2].GetKind() && BVCONST == k2) {
+      //if one side is a BVCONST and the other side is an ITE over
+      //BVCONST then we can do the following optimization:
+      //
+      // c = ITE(cond,c,d) <=> cond
+      //
+      // similarly ITE(cond,c,d) = c <=> cond
+      //
+      // c = ITE(cond,d,c) <=> NOT(cond) 
+      //
+      //similarly ITE(cond,d,c) = d <=> NOT(cond)
+      ASTNode cond = in1[0];
+      if(in1[1] == in2) {
+	//ITE(cond, c, d) = c <=> cond
+	output = cond;
+      }
+      else if(in1[2] == in2) {
+	cond = SimplifyFormula(cond,true);
+	output = cond;
+      }
+      else {
+	//last resort is to CreateNode
+	output = CreateNode(EQ,in1,in2);   
+      }    
+    }    
+    else if(ITE == k2 && 
+	    BVCONST == in2[1].GetKind() && 
+	    BVCONST == in2[2].GetKind() && BVCONST == k1) {
+      ASTNode cond = in2[0];
+      if(in2[1] == in1) {
+	//ITE(cond, c, d) = c <=> cond
+	output = cond;
+      }
+      else if(in2[2] == in1) {
+	cond = SimplifyFormula(cond,true);
+	output = cond;
+      }
+      else {
+	//last resort is to CreateNode
+	output = CreateNode(EQ,in1,in2);   
+      }    
+    }
+    else {
+      //last resort is to CreateNode
+      output = CreateNode(EQ,in1,in2);   
+    }
+    
+    UpdateSimplifyMap(in,output,false);
+    return output;
+ } //End of ITEOpts_InEqs()
+
+  //Tries to simplify the input to TRUE/FALSE. if it fails, then
+  //return the constructed equality
+  ASTNode BeevMgr::CreateSimplifiedEQ(const ASTNode& in1, const ASTNode& in2) {
+    CountersAndStats("CreateSimplifiedEQ");        
+    Kind k1 = in1.GetKind();
+    Kind k2 = in2.GetKind();
+
+    if(!optimize) {
+      return CreateNode(EQ,in1,in2);
+    }
+    
+    if(in1 == in2)
+      //terms are syntactically the same
+      return ASTTrue;    
+    
+    //here the terms are definitely not syntactically equal but may be
+    //semantically equal.    
+    if(BVCONST == k1 && BVCONST == k2)
+      return ASTFalse;
+    
+    //last resort is to CreateNode
+    return CreateNode(EQ,in1,in2);
+  }
+  
+  //accepts cond == t1, then part is t2, and else part is t3
+  ASTNode BeevMgr::CreateSimplifiedTermITE(const ASTNode& in0, 
+					   const ASTNode& in1, const ASTNode& in2) {
+    ASTNode t0 = in0;
+    ASTNode t1 = in1;
+    ASTNode t2 = in2;
+    CountersAndStats("CreateSimplifiedITE");
+    if(!optimize) {
+      if(t1.GetValueWidth() != t2.GetValueWidth()) {
+	cerr << "t2 is : = " << t2;
+	FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
+      }
+      if(t1.GetIndexWidth() != t2.GetIndexWidth()) {
+	cerr << "t2 is : = " << t2;
+	FatalError("CreateSimplifiedTermITE: the lengths of then and else branches don't match",t1);
+      }
+      return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
+    }
+
+    if(t0 == ASTTrue)
+      return t1;
+    if (t0 == ASTFalse)
+      return t2;    
+    if(t1 == t2)
+      return t1;    
+    if(CheckAlwaysTrueFormMap(t0)) {
+	return t1;
+    }     
+    if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) || 
+       (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
+      return t2;
+    }
+    
+    return CreateTerm(ITE,t1.GetValueWidth(),t0,t1,t2);
+  }
+
+  ASTNode BeevMgr::SimplifyAndOrFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    //cerr << "input:\n" << a << endl;
+
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    ASTVec c, outvec;
+    c = a.GetChildren();
+    ASTNode flat = FlattenOneLevel(a);
+    c = flat.GetChildren();
+    SortByExprNum(c);
+
+    Kind k = a.GetKind();
+    bool isAnd = (k == AND) ? true : false;
+
+    ASTNode annihilator = isAnd ? 
+      (pushNeg ? ASTTrue : ASTFalse): 
+      (pushNeg ? ASTFalse : ASTTrue);
+
+    ASTNode identity = isAnd ? 
+      (pushNeg ? ASTFalse : ASTTrue): 
+      (pushNeg ? ASTTrue : ASTFalse);
+
+    //do the work
+    ASTVec::const_iterator next_it;
+    for(ASTVec::const_iterator i=c.begin(),iend=c.end();i!=iend;i++) {
+      ASTNode aaa = *i;
+      next_it = i+1;
+      bool nextexists = (next_it < iend);
+      
+      aaa = SimplifyFormula(aaa,pushNeg);
+      if(annihilator == aaa) {
+	//memoize
+	UpdateSimplifyMap(*i,annihilator,pushNeg);
+	UpdateSimplifyMap(a, annihilator,pushNeg);
+	//cerr << "annihilator1: output:\n" << annihilator << endl;
+	return annihilator;
+      }
+      ASTNode bbb = ASTFalse;
+      if(nextexists) {
+      	bbb = SimplifyFormula(*next_it,pushNeg);
+      }      
+      if(nextexists &&  bbb == aaa) {
+      	//skip the duplicate aaa. *next_it will be included
+      }
+      else if(nextexists && 
+      	      ((bbb.GetKind() == NOT && bbb[0] == aaa))) {
+      	//memoize
+      	UpdateSimplifyMap(a, annihilator,pushNeg);
+      	//cerr << "annihilator2: output:\n" << annihilator << endl;
+      	return annihilator;
+      }
+      else if(identity == aaa) {
+	// //drop identites
+      }
+      else if((!isAnd && !pushNeg) ||
+	      (isAnd && pushNeg)) { 
+	outvec.push_back(aaa);	
+      }
+      else if((isAnd && !pushNeg) ||
+	      (!isAnd && pushNeg)) {
+	outvec.push_back(aaa);	
+      }
+      else {
+	outvec.push_back(aaa);
+      }
+    }
+
+    switch(outvec.size()) {
+    case 0: {
+      //only identities were dropped 
+      output = identity;
+      break;
+    }
+    case 1: {
+      output = SimplifyFormula(outvec[0],false);
+      break;
+    }
+    default: {
+      output = (isAnd) ? 
+	(pushNeg ? CreateNode(OR,outvec) : CreateNode(AND,outvec)): 
+	(pushNeg ? CreateNode(AND,outvec) : CreateNode(OR,outvec));
+      //output = FlattenOneLevel(output);
+      break;
+    }
+    }
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    //cerr << "output:\n" << output << endl;
+    return output;
+  } //end of SimplifyAndOrFormula
+
+
+  ASTNode BeevMgr::SimplifyNotFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree() == 1 && NOT == a.GetKind())) 
+      FatalError("SimplifyNotFormula: input vector with more than 1 node",ASTUndefined);
+
+    //if pushNeg is set then there is NOT on top
+    unsigned int NotCount = pushNeg ? 1 : 0;
+    ASTNode o = a;
+    //count the number of NOTs in 'a'
+    while(NOT == o.GetKind()) {
+      o = o[0];
+      NotCount++;
+    }
+
+    //pushnegation if there are odd number of NOTs
+    bool pn = (NotCount % 2 == 0) ? false : true;
+
+    if(CheckAlwaysTrueFormMap(o)) {
+      output = pn ? ASTFalse : ASTTrue;
+      return output;
+    }
+
+    if(CheckSimplifyMap(o,output,pn)) {
+      return output;
+    }
+
+    if (ASTTrue == o) {
+      output = pn ? ASTFalse : ASTTrue;
+    }
+    else if (ASTFalse == o) {
+      output = pn ? ASTTrue : ASTFalse;
+    }
+    else {
+      output = SimplifyFormula(o,pn);
+    }
+    //memoize
+    UpdateSimplifyMap(o,output,pn);
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyXorFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if (a.GetChildren().size() > 2) {
+      FatalError("Simplify got an XOR with more than two children.");
+    }
+
+    ASTNode a0 = SimplifyFormula(a[0],false);
+    ASTNode a1 = SimplifyFormula(a[1],false);        
+    output = pushNeg ? CreateNode(IFF,a0,a1) : CreateNode(XOR,a0,a1);
+    
+    if(XOR == output.GetKind()) {
+      a0 = output[0];
+      a1 = output[1];
+      if(a0 == a1)
+	output = ASTFalse;
+      else if((a0 == ASTTrue  && a1 == ASTFalse) ||
+	      (a0 == ASTFalse && a1 == ASTTrue))
+	output = ASTTrue;
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyNandFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output,a0,a1;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    //the two NOTs cancel out
+    if(pushNeg) {
+      a0 = SimplifyFormula(a[0],false);
+      a1 = SimplifyFormula(a[1],false);
+      output = CreateNode(AND,a0,a1);
+    }
+    else {
+      //push the NOT implicit in the NAND
+      a0 = SimplifyFormula(a[0],true);
+      a1 = SimplifyFormula(a[1],true);
+      output = CreateNode(OR,a0,a1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyNorFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output,a0,a1;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    //the two NOTs cancel out
+    if(pushNeg) {
+      a0 = SimplifyFormula(a[0],false);
+      a1 = SimplifyFormula(a[1],false);
+      output = CreateNode(OR,a0,a1);
+    }
+    else {
+      //push the NOT implicit in the NAND
+      a0 = SimplifyFormula(a[0],true);
+      a1 = SimplifyFormula(a[1],true);
+      output = CreateNode(AND,a0,a1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyImpliesFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree()==2 && IMPLIES==a.GetKind()))
+      FatalError("SimplifyImpliesFormula: vector with wrong num of nodes",ASTUndefined);
+    
+    ASTNode c0,c1;
+    if(pushNeg) {
+      c0 = SimplifyFormula(a[0],false);
+      c1 = SimplifyFormula(a[1],true);
+      output = CreateNode(AND,c0,c1);
+    }
+    else {
+      c0 = SimplifyFormula(a[0],false);
+      c1 = SimplifyFormula(a[1],false);
+      if(ASTFalse == c0) {
+	output = ASTTrue;
+      }
+      else if (ASTTrue == c0) {
+	output = c1;
+      }
+      else if (c0 == c1) {
+	output = ASTTrue;
+      }
+      else if(CheckAlwaysTrueFormMap(c0)) {
+	// c0 AND (~c0 OR c1) <==> c1
+	//
+	//applying modus ponens
+	output = c1;
+      }
+      else if(CheckAlwaysTrueFormMap(c1)	||
+	      CheckAlwaysTrueFormMap(CreateNode(NOT,c0)) ||
+	      (NOT == c0.GetKind() && CheckAlwaysTrueFormMap(c0[0]))) {
+	//(~c0 AND (~c0 OR c1)) <==> TRUE
+	//
+	//(c0 AND ~c0->c1) <==> TRUE
+	output = ASTTrue;
+      }
+      else if (CheckAlwaysTrueFormMap(CreateNode(NOT,c1)) ||
+	       (NOT == c1.GetKind() && CheckAlwaysTrueFormMap(c1[0]))) {
+	//(~c1 AND c0->c1) <==> (~c1 AND ~c1->~c0) <==> ~c0
+	//(c1 AND c0->~c1) <==> (c1 AND c1->~c0) <==> ~c0
+	output = CreateNode(NOT,c0);
+      }
+      else {
+	if(NOT == c0.GetKind()) {
+	  output = CreateNode(OR,c0[0],c1);
+	}
+	else {
+	  output = CreateNode(OR,CreateNode(NOT,c0),c1);
+	}
+      }
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyIffFormula(const ASTNode& a, bool pushNeg) {
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,pushNeg))
+      return output;
+
+    if(!(a.Degree()==2 && IFF==a.GetKind()))
+      FatalError("SimplifyIffFormula: vector with wrong num of nodes",ASTUndefined);
+    
+    ASTNode c0 = a[0];
+    ASTNode c1 = SimplifyFormula(a[1],false);
+
+    if(pushNeg)
+      c0 = SimplifyFormula(c0,true);
+    else 
+      c0 = SimplifyFormula(c0,false);
+
+    if(ASTTrue == c0) {
+      output = c1;
+    }
+    else if (ASTFalse == c0) {
+      output = SimplifyFormula(c1,true);
+    }
+    else if (ASTTrue == c1) {
+      output = c0;
+    }
+    else if (ASTFalse == c1) {
+      output = SimplifyFormula(c0,true);
+    }
+    else if (c0 == c1) {
+      output = ASTTrue;
+    }
+    else if((NOT == c0.GetKind() && c0[0] == c1) ||
+	    (NOT == c1.GetKind() && c0 == c1[0])) {
+      output = ASTFalse;
+    }
+    else if(CheckAlwaysTrueFormMap(c0)) {
+      output = c1;
+    }
+    else if(CheckAlwaysTrueFormMap(c1)) {
+      output = c0;
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c0))) {
+      output = CreateNode(NOT,c1);
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,c1))) {
+      output = CreateNode(NOT,c0);
+    }
+    else {
+      output = CreateNode(IFF,c0,c1);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;
+  }
+
+  ASTNode BeevMgr::SimplifyIteFormula(const ASTNode& b, bool pushNeg) {
+    if(!optimize)
+      return b;
+
+    ASTNode output;
+    if(CheckSimplifyMap(b,output,pushNeg))
+      return output;
+
+    if(!(b.Degree() == 3 && ITE == b.GetKind()))
+      FatalError("SimplifyIteFormula: vector with wrong num of nodes",ASTUndefined);    
+    
+    ASTNode a = b;
+    ASTNode t0 = SimplifyFormula(a[0],false);
+    ASTNode t1,t2;
+    if(pushNeg) {
+      t1 = SimplifyFormula(a[1],true);
+      t2 = SimplifyFormula(a[2],true);
+    }
+    else {
+      t1 = SimplifyFormula(a[1],false);
+      t2 = SimplifyFormula(a[2],false);
+    }
+    
+    if(ASTTrue == t0) {
+      output = t1;
+    }
+    else if (ASTFalse == t0) {
+      output = t2;
+    }
+    else if (t1 == t2) {
+      output = t1;
+    }
+    else if(ASTTrue == t1 && ASTFalse == t2) {
+      output = t0;
+    }
+    else if(ASTFalse == t1 && ASTTrue == t2) {
+      output = SimplifyFormula(t0,true);
+    }
+    else if(ASTTrue == t1) {
+      output = CreateNode(OR,t0,t2);
+    }
+    else if(ASTFalse == t1) {
+      output = CreateNode(AND,CreateNode(NOT,t0),t2);
+    }
+    else if(ASTTrue == t2) {
+      output = CreateNode(OR,CreateNode(NOT,t0),t1);
+    }
+    else if(ASTFalse == t2) {
+      output = CreateNode(AND,t0,t1);
+    }
+    else if(CheckAlwaysTrueFormMap(t0)) {
+      output = t1;
+    }
+    else if(CheckAlwaysTrueFormMap(CreateNode(NOT,t0)) ||
+    	    (NOT == t0.GetKind() && CheckAlwaysTrueFormMap(t0[0]))) {
+      output = t2;
+    }
+    else {
+      output = CreateNode(ITE,t0,t1,t2);
+    }
+
+    //memoize
+    UpdateSimplifyMap(a,output,pushNeg);
+    return output;    
+  }
+
+  //one level deep flattening
+  ASTNode BeevMgr::FlattenOneLevel(const ASTNode& a) {
+    Kind k = a.GetKind();
+    if(!(BVPLUS == k || 
+	 AND == k || OR == k
+	 //|| BVAND == k 
+	 //|| BVOR == k
+	 )
+       ) {
+      return a;
+    }
+    
+    ASTNode output;
+    // if(CheckSimplifyMap(a,output,false)) {
+    //       //check memo table
+    //       //cerr << "output of SimplifyTerm Cache: " << output << endl;
+    //       return output;
+    //     }
+
+    ASTVec c = a.GetChildren();
+    ASTVec o;
+    for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+      ASTNode aaa = *it;
+      if(k == aaa.GetKind()) {
+	ASTVec ac = aaa.GetChildren();
+	o.insert(o.end(),ac.begin(),ac.end());
+      }
+      else
+	o.push_back(aaa);      
+    } 
+    
+    if(is_Form_kind(k))
+      output = CreateNode(k,o);
+    else
+      output = CreateTerm(k,a.GetValueWidth(),o);
+
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+    //memoize
+  } //end of flattenonelevel()
+
+  ASTNode BeevMgr::SimplifyTerm_TopLevel(const ASTNode& b) {
+    SimplifyMap.clear();
+    SimplifyNegMap.clear();
+    ASTNode out = SimplifyTerm(b);
+    SimplifyNegMap.clear();
+    SimplifyMap.clear();
+    return out;
+  }
+
+  //This function simplifies terms based on their kind
+  ASTNode BeevMgr::SimplifyTerm(const ASTNode& inputterm) {
+    //cout << "SimplifyTerm: input: " << a << endl;
+    if(!optimize) {
+      return inputterm;
+    }
+
+    BVTypeCheck(inputterm);
+    ASTNode output;
+    if(wordlevel_solve && CheckSolverMap(inputterm,output)) {
+      //cout << "SimplifyTerm: output: " << output << endl;
+      return SimplifyTerm(output);     
+    }
+
+    if(CheckSimplifyMap(inputterm,output,false)) {
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+
+    Kind k = inputterm.GetKind();    
+    if(!is_Term_kind(k)) {
+      FatalError("SimplifyTerm: You have input a Non-term",ASTUndefined);
+    }
+
+    unsigned int inputValueWidth = inputterm.GetValueWidth();
+    switch(k) {
+    case BVCONST:
+      output = inputterm;
+      break;
+    case SYMBOL:
+      if(CheckSolverMap(inputterm,output)) {
+	return SimplifyTerm(output);
+      }
+      output = inputterm;
+      break;
+    case BVMULT:
+    case BVPLUS:{
+      if(BVMULT == k && 2 != inputterm.Degree()) {
+	FatalError("SimplifyTerm: We assume that BVMULT is binary",inputterm);
+      }
+      
+      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+      SortByExprNum(c);
+      ASTVec constkids, nonconstkids;
+
+      //go through the childnodes, and separate constant and
+      //nonconstant nodes. combine the constant nodes using the
+      //constevaluator. if the resultant constant is zero and k ==
+      //BVPLUS, then ignore it (similarily for 1 and BVMULT).  else,
+      //add the computed constant to the nonconst vector, flatten,
+      //sort, and create BVPLUS/BVMULT and return
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST == aaa.GetKind()) {
+	  constkids.push_back(aaa);
+	}
+	else {
+	  nonconstkids.push_back(aaa);
+	}
+      }
+      
+      ASTNode one = CreateOneConst(inputValueWidth);
+      ASTNode max = CreateMaxConst(inputValueWidth);
+      ASTNode zero = CreateZeroConst(inputValueWidth);
+
+      //initialize constoutput to zero, in case there are no elements
+      //in constkids
+      ASTNode constoutput = (k == BVPLUS) ? zero : one;
+
+      if(1 == constkids.size()) {
+	//only one element in constkids
+	constoutput = constkids[0];
+      } 
+      else if (1 < constkids.size()) {
+	//many elements in constkids. simplify it
+	constoutput = CreateTerm(k,inputterm.GetValueWidth(),constkids);
+	constoutput = BVConstEvaluator(constoutput);
+      }
+
+      if(BVMULT == k && zero == constoutput) {
+	output = zero;
+      }
+      else if(BVMULT == k && 
+	      1 == nonconstkids.size() && 
+	      constoutput == max) {
+	//useful special case opt: when input is BVMULT(max_const,t),
+	//then output = BVUMINUS(t). this is easier on the bitblaster
+	output = CreateTerm(BVUMINUS,inputValueWidth,nonconstkids);
+      }
+      else {
+	if(0 < nonconstkids.size()) {
+	  //nonconstkids is not empty. First, combine const and
+	  //nonconstkids
+	  if(BVPLUS == k && constoutput != zero) {
+	    nonconstkids.push_back(constoutput);
+	  }
+	  else if(BVMULT == k && constoutput != one) {
+	    nonconstkids.push_back(constoutput);
+	  }
+
+	  if(1 == nonconstkids.size()) {
+	    //exactly one element in nonconstkids. output is exactly
+	    //nonconstkids[0]
+	    output = nonconstkids[0];
+	  }
+	  else {
+	    //more than 1 element in nonconstkids. create BVPLUS term
+	    SortByExprNum(nonconstkids);
+	    output = CreateTerm(k,inputValueWidth,nonconstkids);
+	    output = FlattenOneLevel(output);
+	    output = DistributeMultOverPlus(output,true);
+	    output = CombineLikeTerms(output);
+ 	  }
+	}
+	else {
+	  //nonconstkids was empty, all childnodes were constant, hence
+	  //constoutput is the output.
+	  output = constoutput;
+	}
+      }
+      if(BVMULT == output.GetKind() 
+	 || BVPLUS == output.GetKind()
+	 ) {
+	ASTVec d = output.GetChildren();
+	SortByExprNum(d);
+      	output = CreateTerm(output.GetKind(),output.GetValueWidth(),d);
+      }
+      break;
+    }
+    case BVSUB: {
+      ASTVec c = inputterm.GetChildren();
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      ASTNode a1 = SimplifyTerm(inputterm[1]);
+      unsigned int l = inputValueWidth;
+      if(a0 == a1)
+	output = CreateZeroConst(l);
+      else {
+	//covert x-y into x+(-y) and simplify. this transformation
+	//triggers more simplifications
+	a1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a1));
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,a0,a1));
+      }
+      break;
+    }
+    case BVUMINUS: {
+      //important to treat BVUMINUS as a special case, because it
+      //helps in arithmetic transformations. e.g.  x + BVUMINUS(x) is
+      //actually 0. One way to reveal this fact is to strip bvuminus
+      //out, and replace with something else so that combineliketerms
+      //can catch this fact.
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      Kind k1 = a0.GetKind();
+      unsigned int l = a0.GetValueWidth();
+      ASTNode one = CreateOneConst(l);
+      switch(k1) {
+      case BVUMINUS:
+	output = a0[0];
+	break;
+      case BVCONST: {
+	output = BVConstEvaluator(CreateTerm(BVUMINUS,l,a0));
+	break;
+      }
+      case BVNEG: {
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,a0[0],one));
+	break;
+      }
+      case BVMULT: {
+	if(BVUMINUS == a0[0].GetKind()) {
+	  output = CreateTerm(BVMULT,l,a0[0][0],a0[1]);
+	}
+	else if(BVUMINUS == a0[1].GetKind()) {
+	  output = CreateTerm(BVMULT,l,a0[0],a0[1][0]);
+	}
+	else {
+	  ASTNode a00 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[0]));	
+	  output = CreateTerm(BVMULT,l,a00,a0[1]);
+	}
+	break;
+      }
+      case BVPLUS: {
+	//push BVUMINUS over all the monomials of BVPLUS. Simplify
+	//along the way
+	//
+	//BVUMINUS(a1x1 + a2x2 + ...) <=> BVPLUS(BVUMINUS(a1x1) +
+	//BVUMINUS(a2x2) + ...
+	ASTVec c = a0.GetChildren();
+	ASTVec o;
+	for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  //Simplify(BVUMINUS(a1x1))
+	  ASTNode aaa = SimplifyTerm(CreateTerm(BVUMINUS,l,*it));
+	  o.push_back(aaa);
+	}
+	//simplify the bvplus
+	output = SimplifyTerm(CreateTerm(BVPLUS,l,o));	
+	break;
+      }
+      case BVSUB: {
+	//BVUMINUS(BVSUB(x,y)) <=> BVSUB(y,x)
+	output = SimplifyTerm(CreateTerm(BVSUB,l,a0[1],a0[0]));
+	break;
+      }
+      case ITE: {
+	//BVUMINUS(ITE(c,t1,t2)) <==> ITE(c,BVUMINUS(t1),BVUMINUS(t2))
+	ASTNode c = a0[0];
+	ASTNode t1 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[1]));
+	ASTNode t2 = SimplifyTerm(CreateTerm(BVUMINUS,l,a0[2]));
+	output = CreateSimplifiedTermITE(c,t1,t2);
+	break;
+      }
+      default: {
+	output = CreateTerm(BVUMINUS,l,a0);
+	break;
+      }
+      }
+      break;
+    }
+    case BVEXTRACT:{
+      //it is important to take care of wordlevel transformation in
+      //BVEXTRACT. it exposes oppurtunities for later simplification
+      //and solving (variable elimination)
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      Kind k1 = a0.GetKind();
+      unsigned int a_len = inputValueWidth;
+      
+      //indices for BVEXTRACT
+      ASTNode i = inputterm[1];
+      ASTNode j = inputterm[2];
+      ASTNode zero = CreateBVConst(32,0);
+      //recall that the indices of BVEXTRACT are always 32 bits
+      //long. therefore doing a GetBVUnsigned is ok.
+      unsigned int i_val = GetUnsignedConst(i);
+      unsigned int j_val = GetUnsignedConst(j);
+
+      // a0[i:0] and len(a0)=i+1, then return a0
+      if(0 == j_val && a_len == a0.GetValueWidth())
+	return a0;
+
+      switch(k1) {
+      case BVCONST: {
+	//extract the constant
+	output = BVConstEvaluator(CreateTerm(BVEXTRACT,a_len,a0,i,j));
+	break;
+      }
+      case BVCONCAT:{
+	//assumes concatenation is binary
+	//
+	//input is of the form a0[i:j]
+	//
+	//a0 is the conatentation t at u, and a0[0] is t, and a0[1] is u
+	ASTNode t = a0[0];
+	ASTNode u = a0[1];
+	unsigned int len_a0 = a0.GetValueWidth();
+	unsigned int len_u = u.GetValueWidth();
+
+	if(len_u > i_val) {
+	  //Apply the following rule:
+	  // (t at u)[i:j] <==> u[i:j], if len(u) > i
+	  //
+	  output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
+	}
+	else if(len_a0 > i_val && j_val >= len_u) {
+	  //Apply the rule:
+	  // (t at u)[i:j] <==> t[i-len_u:j-len_u], if len(t at u) > i >= j >= len(u)
+	  i = CreateBVConst(32, i_val - len_u);
+	  j = CreateBVConst(32, j_val - len_u);
+	  output = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	}
+	else {
+	  //Apply the rule:
+	  // (t at u)[i:j] <==> t[i-len_u:0] @ u[len_u-1:j]
+	  i = CreateBVConst(32,i_val-len_u);
+	  ASTNode m = CreateBVConst(32, len_u-1);
+	  t = SimplifyTerm(CreateTerm(BVEXTRACT,i_val-len_u+1,t,i,zero));
+	  u = SimplifyTerm(CreateTerm(BVEXTRACT,len_u-j_val,u,m,j));
+	  output = CreateTerm(BVCONCAT,a_len,t,u);
+	}
+	break;
+      }
+      case BVPLUS:
+      case BVMULT: {	
+	// (BVMULT(n,t,u))[i:j] <==> BVMULT(i+1,t[i:0],u[i:0])[i:j]
+	//similar rule for BVPLUS
+	ASTVec c = a0.GetChildren();
+	ASTVec o;
+	for(ASTVec::iterator jt=c.begin(),jtend=c.end();jt!=jtend;jt++) {
+	  ASTNode aaa = *jt;
+	  aaa = SimplifyTerm(CreateTerm(BVEXTRACT,i_val+1,aaa,i,zero));
+	  o.push_back(aaa);
+	}
+	output = CreateTerm(a0.GetKind(),i_val+1,o);	
+	if(j_val != 0) {
+	  //add extraction only if j is not zero
+	  output = CreateTerm(BVEXTRACT,a_len,output,i,j);
+	}
+	break;
+      }
+      case BVAND:
+      case BVOR:
+      case BVXOR: {
+	//assumes these operators are binary
+	//
+	// (t op u)[i:j] <==> t[i:j] op u[i:j]
+	ASTNode t = a0[0];
+	ASTNode u = a0[1];
+	t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	u = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,u,i,j));
+	BVTypeCheck(t);
+	BVTypeCheck(u);
+	output = CreateTerm(k1,a_len,t,u);
+	break;
+      }
+      case BVNEG:{
+	// (~t)[i:j] <==> ~(t[i:j])
+	ASTNode t = a0[0];
+	t = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,t,i,j));
+	output = CreateTerm(BVNEG,a_len,t);
+	break;
+      }
+      // case BVSX:{
+// 	//(BVSX(t,n)[i:j] <==> BVSX(t,i+1), if n >= i+1 and j=0 
+// 	ASTNode t = a0[0];
+// 	unsigned int bvsx_len = a0.GetValueWidth();
+// 	if(bvsx_len < a_len) {
+// 	  FatalError("SimplifyTerm: BVEXTRACT over BVSX:" 
+// 		     "the length of BVSX term must be greater than extract-len",inputterm);
+// 	}
+// 	if(j != zero) {
+// 	  output = CreateTerm(BVEXTRACT,a_len,a0,i,j);	  
+// 	}
+// 	else {
+// 	  output = CreateTerm(BVSX,a_len,t,CreateBVConst(32,a_len));
+// 	}
+// 	break;
+//       }
+      case ITE: {
+	ASTNode t0 = a0[0];
+	ASTNode t1 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[1],i,j));
+	ASTNode t2 = SimplifyTerm(CreateTerm(BVEXTRACT,a_len,a0[2],i,j));
+	output = CreateSimplifiedTermITE(t0,t1,t2);
+	break;
+      }
+      default: {
+	output = CreateTerm(BVEXTRACT,a_len,a0,i,j);
+	break;
+      }
+      }
+      break;
+    }
+    case BVNEG: {
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      unsigned len = inputValueWidth;
+      switch(a0.GetKind()) {
+      case BVCONST:
+	output = BVConstEvaluator(CreateTerm(BVNEG,len,a0));
+	break;
+      case BVNEG:
+	output = a0[0];
+	break;
+      // case ITE: {
+// 	ASTNode cond = a0[0];
+// 	ASTNode thenpart = SimplifyTerm(CreateTerm(BVNEG,len,a0[1]));
+// 	ASTNode elsepart = SimplifyTerm(CreateTerm(BVNEG,len,a0[2]));
+// 	output = CreateSimplifiedTermITE(cond,thenpart,elsepart);	
+// 	break;
+//       }
+      default:
+	output = CreateTerm(BVNEG,len,a0);
+	break;
+      }
+      break;
+    }
+    case BVSX:{
+      //a0 is the expr which is being sign extended
+      ASTNode a0 = SimplifyTerm(inputterm[0]);
+      //a1 represents the length of the term BVSX(a0)
+      ASTNode a1 = inputterm[1];
+      //output length of the BVSX term
+      unsigned len = inputValueWidth;
+      
+      if(a0.GetValueWidth() == len) {
+	//nothing to signextend
+	return a0;
+      }
+
+      switch(a0.GetKind()) {
+      case BVCONST:
+	output = BVConstEvaluator(CreateTerm(BVSX,len,a0,a1));
+	break;
+      case BVNEG:
+	output = CreateTerm(a0.GetKind(),len,CreateTerm(BVSX,len,a0[0],a1));
+	break;
+      case BVAND:
+      case BVOR:
+	//assuming BVAND and BVOR are binary
+	output = CreateTerm(a0.GetKind(),len,
+			    CreateTerm(BVSX,len,a0[0],a1),
+			    CreateTerm(BVSX,len,a0[1],a1));
+	break;
+      case BVPLUS: {	
+	//BVSX(m,BVPLUS(n,BVSX(t1),BVSX(t2))) <==> BVPLUS(m,BVSX(m,t1),BVSX(m,t2))
+	ASTVec c = a0.GetChildren();
+	bool returnflag = false;
+	for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	  if(BVSX != it->GetKind()) {
+	    returnflag = true;
+	    break;
+	  }
+	}
+	if(returnflag) {
+	  output = CreateTerm(BVSX,len,a0,a1);
+	}
+	else {
+	  ASTVec o;
+	  for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	    ASTNode aaa = SimplifyTerm(CreateTerm(BVSX,len,*it,a1));
+	    o.push_back(aaa);
+	  }
+	  output = CreateTerm(a0.GetKind(),len,o);
+	}
+	break;
+      }
+      case BVSX: {
+	//if you have BVSX(m,BVSX(n,a)) then you can drop the inner
+	//BVSX provided m is greater than n.
+	a0 = SimplifyTerm(a0[0]);
+	output = CreateTerm(BVSX,len,a0,a1);
+	break;
+      }
+      case ITE: {
+	ASTNode cond = a0[0];
+	ASTNode thenpart = SimplifyTerm(CreateTerm(BVSX,len,a0[1],a1));
+	ASTNode elsepart = SimplifyTerm(CreateTerm(BVSX,len,a0[2],a1));
+	output = CreateSimplifiedTermITE(cond,thenpart,elsepart);
+	break;
+      }
+      default:
+	output = CreateTerm(BVSX,len,a0,a1);
+	break;
+      }    
+      break;
+    }
+    case BVAND:
+    case BVOR:{
+      ASTNode max = CreateMaxConst(inputValueWidth);
+      ASTNode zero = CreateZeroConst(inputValueWidth);
+
+      ASTNode identity = (BVAND == k) ? max : zero;
+      ASTNode annihilator = (BVAND == k) ? zero : max;
+      ASTVec c = FlattenOneLevel(inputterm).GetChildren();
+      SortByExprNum(c);
+      ASTVec o;
+      bool constant = true;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST != aaa.GetKind()) {
+	  constant = false;
+	}
+
+	if(aaa == annihilator) {
+	  output = annihilator;
+	  //memoize
+	  UpdateSimplifyMap(inputterm,output,false);
+	  //cerr << "output of SimplifyTerm: " << output << endl;
+	  return output;
+	}
+	
+	if(aaa != identity) {
+	  o.push_back(aaa);
+	}
+      }
+      
+      switch(o.size()) {
+      case 0:
+	output = identity;
+	break;
+      case 1:
+	output = o[0];
+	break;
+      default:
+	SortByExprNum(o);
+	output = CreateTerm(k,inputValueWidth,o);
+	if(constant) {
+	  output = BVConstEvaluator(output);
+	}     
+	break;
+      }
+      break;
+    }
+    case BVCONCAT:{
+      ASTNode t = SimplifyTerm(inputterm[0]);
+      ASTNode u = SimplifyTerm(inputterm[1]);
+      Kind tkind = t.GetKind();
+      Kind ukind = u.GetKind();
+      
+      
+      if(BVCONST == tkind && BVCONST == ukind) {
+	output = BVConstEvaluator(CreateTerm(BVCONCAT,inputValueWidth,t,u));
+      }
+      else if(BVEXTRACT == tkind && 
+	      BVEXTRACT == ukind && 
+	      t[0] == u[0]) {
+	//to handle the case x[m:n]@x[n-1:k] <==> x[m:k]
+	ASTNode t_hi = t[1];
+	ASTNode t_low = t[2];
+	ASTNode u_hi = u[1];
+	ASTNode u_low = u[2];
+	ASTNode c = BVConstEvaluator(CreateTerm(BVPLUS,32,u_hi,CreateOneConst(32)));
+	if(t_low == c) {
+	  output = CreateTerm(BVEXTRACT,inputValueWidth,t[0],t_hi,u_low);
+	}
+	else {
+	  output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
+	}
+      }
+      else {
+	output = CreateTerm(BVCONCAT,inputValueWidth,t,u);
+      }
+      break;
+    }
+    case BVXOR:
+    case BVXNOR:
+    case BVNAND:
+    case BVNOR:
+    case BVLEFTSHIFT:
+    case BVRIGHTSHIFT:
+    case BVVARSHIFT:
+    case BVSRSHIFT:
+    case BVDIV:
+    case BVMOD: {
+      ASTVec c = inputterm.GetChildren();
+      ASTVec o;
+      bool constant = true;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	if(BVCONST != aaa.GetKind()) {
+	  constant = false;
+	}
+	o.push_back(aaa);
+      }
+      output = CreateTerm(k,inputValueWidth,o);
+      if(constant)
+	output = BVConstEvaluator(output);
+      break;
+    }
+    case READ: {
+      ASTNode out1;
+      //process only if not  in the substitution map. simplifymap
+      //has been checked already
+      if(!CheckSubstitutionMap(inputterm,out1)) {
+	if(WRITE == inputterm[0].GetKind()) {
+	  //get rid of all writes
+	  ASTNode nowrites = RemoveWrites_TopLevel(inputterm);
+	  out1 = nowrites;
+	}
+	else if (ITE == inputterm[0].GetKind()){
+	  ASTNode cond = SimplifyFormula(inputterm[0][0],false);
+	  ASTNode arr1 = SimplifyTerm(inputterm[0][1]);
+	  ASTNode arr2 = SimplifyTerm(inputterm[0][2]);
+
+	  ASTNode index = SimplifyTerm(inputterm[1]);
+	  
+	  ASTNode read1 = CreateTerm(READ,inputValueWidth,arr1,index);
+	  ASTNode read2 = CreateTerm(READ,inputValueWidth,arr2,index);
+	  out1 = CreateSimplifiedTermITE(cond,read1,read2);
+	}
+	else {
+	  //arr is a SYMBOL for sure
+	  ASTNode arr = inputterm[0];
+	  ASTNode index = SimplifyTerm(inputterm[1]);
+	  out1 = CreateTerm(READ,inputValueWidth,arr,index);     
+	}
+      }
+      //it is possible that after all the procesing the READ term
+      //reduces to READ(Symbol,const) and hence we should check the
+      //substitutionmap once again.      
+      if(!CheckSubstitutionMap(out1,output))
+	output = out1;      
+      break;
+    }
+    case ITE: {
+      ASTNode t0 = SimplifyFormula(inputterm[0],false);
+      ASTNode t1 = SimplifyTerm(inputterm[1]);
+      ASTNode t2 = SimplifyTerm(inputterm[2]);
+      output = CreateSimplifiedTermITE(t0,t1,t2);      
+      break;
+    }
+    case SBVMOD:
+    case SBVDIV: {
+      ASTVec c = inputterm.GetChildren();
+      ASTVec o;
+      for(ASTVec::iterator it=c.begin(),itend=c.end();it!=itend;it++) {
+	ASTNode aaa = SimplifyTerm(*it);
+	o.push_back(aaa);
+      }
+      output = CreateTerm(k,inputValueWidth,o);
+      break;
+    }
+    case WRITE:     
+    default:
+      FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
+      return inputterm;
+      break;
+    }
+
+    //memoize
+    UpdateSimplifyMap(inputterm,output,false);
+    //cerr << "SimplifyTerm: output" << output << endl;
+    return output;
+  } //end of SimplifyTerm()
+
+
+  //At the end of each simplification call, we want the output to be
+  //always smaller or equal to the input in size.
+  void BeevMgr::CheckSimplifyInvariant(const ASTNode& a, const ASTNode& output) {
+    //Don't do the check in optimized mode
+    if(optimize)
+      return;
+
+    if(NodeSize(a,true) < NodeSize(output,true)) {
+      cerr << "lhs := " << a << endl;
+      cerr << "NodeSize of lhs is: " << NodeSize(a, true) << endl;
+      cerr << endl;
+      cerr << "rhs := " << output << endl;
+      cerr << "NodeSize of rhs is: " << NodeSize(output, true) << endl;
+      FatalError("SimplifyFormula: The nodesize shoudl decrease from lhs to rhs: ",ASTUndefined);
+    }
+  }
+
+  //this function assumes that the input is a vector of childnodes of
+  //a BVPLUS term. it combines like terms and returns a bvplus
+  //term. e.g. 1.x + 2.x is converted to 3.x
+  ASTNode BeevMgr::CombineLikeTerms(const ASTNode& a) {
+    if(BVPLUS != a.GetKind())
+      return a;
+    
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+    
+    ASTVec c = a.GetChildren();
+    //map from variables to vector of constants
+    ASTNodeToVecMap vars_to_consts;
+    //vector to hold constants
+    ASTVec constkids;
+    ASTVec outputvec;
+
+    //useful constants
+    unsigned int len = c[0].GetValueWidth();
+    ASTNode one = CreateOneConst(len);
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode max = CreateMaxConst(len);
+
+    //go over the childnodes of the input bvplus, and collect like
+    //terms in a map. the key of the map are the variables, and the
+    //values are stored in a ASTVec
+    for(ASTVec::const_iterator it=c.begin(),itend=c.end();it!=itend;it++){
+      ASTNode aaa = *it;
+      if(SYMBOL == aaa.GetKind()) {
+	vars_to_consts[aaa].push_back(one);
+      }
+      else if(BVMULT == aaa.GetKind() && 
+	      BVUMINUS == aaa[0].GetKind() &&
+	      BVCONST == aaa[0][0].GetKind()) {
+	//(BVUMINUS(c))*(y) <==> compute(BVUMINUS(c))*y
+	ASTNode compute_const = BVConstEvaluator(aaa[0]);
+	vars_to_consts[aaa[1]].push_back(compute_const);
+      }
+      else if(BVMULT == aaa.GetKind() && 
+	      BVUMINUS == aaa[1].GetKind() &&
+	      BVCONST == aaa[0].GetKind()) {
+	//c*(BVUMINUS(y)) <==> compute(BVUMINUS(c))*y
+	ASTNode cccc = BVConstEvaluator(CreateTerm(BVUMINUS,len,aaa[0]));
+	vars_to_consts[aaa[1][0]].push_back(cccc);      
+      }      
+      else if(BVMULT == aaa.GetKind() && BVCONST == aaa[0].GetKind()) {
+	//assumes that BVMULT is binary
+	vars_to_consts[aaa[1]].push_back(aaa[0]);
+      } 
+      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[0].GetKind()) {
+	//(-1*x)*(y) <==> -1*(xy)
+	ASTNode cccc = CreateTerm(BVMULT,len,aaa[0][0],aaa[1]);
+	ASTVec cNodes = cccc.GetChildren();
+	SortByExprNum(cNodes);
+	vars_to_consts[cccc].push_back(max);
+      }
+      else if(BVMULT == aaa.GetKind() && BVUMINUS == aaa[1].GetKind()) {
+	//x*(-1*y) <==> -1*(xy)
+	ASTNode cccc = CreateTerm(BVMULT,len,aaa[0],aaa[1][0]);
+	ASTVec cNodes = cccc.GetChildren();
+	SortByExprNum(cNodes);
+	vars_to_consts[cccc].push_back(max);      
+      }
+      else if(BVCONST == aaa.GetKind()) {
+	constkids.push_back(aaa);
+      }
+      else if(BVUMINUS == aaa.GetKind()) {
+	//helps to convert BVUMINUS into a BVMULT. here the max
+	//constant represents -1. this transformation allows us to
+	//conclude that x + BVUMINUS(x) is 0.
+	vars_to_consts[aaa[0]].push_back(max);
+      }
+      else 
+	vars_to_consts[aaa].push_back(one);
+    } //end of for loop
+
+    //go over the map from variables to vector of values. combine the
+    //vector of values, multiply to the variable, and put the
+    //resultant monomial in the output BVPLUS.
+    for(ASTNodeToVecMap::iterator it=vars_to_consts.begin(),itend=vars_to_consts.end();
+	it!=itend;it++){
+      ASTVec ccc = it->second;
+      
+      ASTNode constant;
+      if(1 < ccc.size()) {
+	constant = CreateTerm(BVPLUS,ccc[0].GetValueWidth(),ccc);
+	constant = BVConstEvaluator(constant);
+      }
+      else
+	constant = ccc[0];
+      
+      //constant * var
+      ASTNode monom;
+      if(zero == constant) 
+	monom = zero;
+      else if (one == constant)
+	monom = it->first;
+      else
+	monom = 
+	  SimplifyTerm(CreateTerm(BVMULT,constant.GetValueWidth(),constant,it->first));
+      if(zero != monom) {
+	outputvec.push_back(monom);
+      }
+    } //end of for loop
+
+    if(constkids.size() > 1) {
+      ASTNode output = CreateTerm(BVPLUS,constkids[0].GetValueWidth(),constkids);
+      output = BVConstEvaluator(output);
+      if(output != zero)
+	outputvec.push_back(output);
+    }
+    else if (constkids.size() == 1) {
+      if(constkids[0] != zero)
+	outputvec.push_back(constkids[0]);
+    }
+
+    if (outputvec.size() > 1) {
+      output = CreateTerm(BVPLUS,len,outputvec);
+    }
+    else if(outputvec.size() == 1) {
+      output = outputvec[0];
+    }
+    else {
+      output = zero;
+    }
+
+    //memoize
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of CombineLikeTerms()
+
+  //accepts lhs and rhs, and returns lhs - rhs = 0. The function
+  //assumes that lhs and rhs have already been simplified. although
+  //this assumption is not needed for correctness, it is essential for
+  //performance. The function also assumes that lhs is a BVPLUS
+  ASTNode BeevMgr::LhsMinusRhs(const ASTNode& eq) {
+    //if input is not an equality, simply return it
+    if(EQ != eq.GetKind())
+      return eq;
+
+    ASTNode lhs = eq[0];
+    ASTNode rhs = eq[1];
+    Kind k_lhs = lhs.GetKind();
+    Kind k_rhs = rhs.GetKind();
+    //either the lhs has to be a BVPLUS or the rhs has to be a
+    //BVPLUS
+    if(!(BVPLUS == k_lhs || 
+	 BVPLUS == k_rhs ||
+	 (BVMULT == k_lhs && 
+	  BVMULT == k_rhs)
+	 )) {
+      return eq;
+    }
+
+    ASTNode output;
+    if(CheckSimplifyMap(eq,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+    
+    //if the lhs is not a BVPLUS, but the rhs is a BVPLUS, then swap
+    //the lhs and rhs
+    bool swap_flag = false;
+    if(BVPLUS != k_lhs && BVPLUS == k_rhs) {
+      ASTNode swap = lhs;
+      lhs = rhs;
+      rhs = swap;
+      swap_flag = true;
+    }
+
+    unsigned int len = lhs.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    //right is -1*(rhs): Simplify(-1*rhs)
+    rhs = SimplifyTerm(CreateTerm(BVUMINUS,len,rhs));
+
+    ASTVec lvec = lhs.GetChildren();
+    ASTVec rvec = rhs.GetChildren();
+    ASTNode lhsplusrhs;
+    if(BVPLUS != lhs.GetKind() && BVPLUS != rhs.GetKind()) {
+      lhsplusrhs = CreateTerm(BVPLUS,len,lhs,rhs); 
+    }
+    else if(BVPLUS == lhs.GetKind() && BVPLUS == rhs.GetKind()) {
+      //combine the childnodes of the left and the right
+      lvec.insert(lvec.end(),rvec.begin(),rvec.end());
+      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
+    }
+    else if(BVPLUS == lhs.GetKind() && BVPLUS != rhs.GetKind()){
+      lvec.push_back(rhs);
+      lhsplusrhs = CreateTerm(BVPLUS,len,lvec);
+    }
+    else {
+      //Control should never reach here
+      FatalError("LhsMinusRhs: Control should never reach here\n");
+    }
+
+    //combine like terms
+    output = CombineLikeTerms(lhsplusrhs);
+    output = SimplifyTerm(output);
+    //
+    //Now make output into: lhs-rhs = 0
+    output = CreateSimplifiedEQ(output,zero);
+    //sort if BVPLUS
+    if(BVPLUS == output.GetKind()) {
+      ASTVec outv = output.GetChildren();
+      SortByExprNum(outv);
+      output = CreateTerm(BVPLUS,len,outv);
+    }
+    
+    //memoize
+    //UpdateSimplifyMap(eq,output,false);
+    return output;  
+  } //end of LhsMinusRHS()
+
+  //THis function accepts a BVMULT(t1,t2) and distributes the mult
+  //over plus if either or both t1 and t2 are BVPLUSes.
+  //
+  // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+  //
+  // (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
+  //
+  // The function assumes that the BVPLUSes have been flattened
+  ASTNode BeevMgr::DistributeMultOverPlus(const ASTNode& a, bool startdistribution) {
+    if(!startdistribution)
+      return a;
+    Kind k = a.GetKind();
+    if(BVMULT != k)
+      return a;
+
+    ASTNode left = a[0];
+    ASTNode right = a[1];
+    Kind left_kind = left.GetKind();
+    Kind right_kind = right.GetKind();
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of SimplifyTerm Cache: " << output << endl;
+      return output;
+    }
+
+    //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1
+    if(BVCONST == left_kind && 
+       BVMULT == right_kind && 
+       BVCONST == right[0].GetKind()) {
+      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[0]));
+      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[1]);
+      return c;
+      left = c[0];
+      right = c[1];
+      left_kind = left.GetKind();
+      right_kind = right.GetKind();    
+    }
+
+    //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1
+    if(BVCONST == left_kind && 
+       BVMULT == right_kind && 
+       BVCONST == right[1].GetKind()) {
+      ASTNode c = BVConstEvaluator(CreateTerm(BVMULT,a.GetValueWidth(),left,right[1]));
+      c = CreateTerm(BVMULT,a.GetValueWidth(),c,right[0]);
+      return c;
+      left = c[0];
+      right = c[1];
+      left_kind = left.GetKind();
+      right_kind = right.GetKind();    
+    }
+
+    //atleast one of left or right have to be BVPLUS
+    if(!(BVPLUS == left_kind || BVPLUS == right_kind)) {
+      return a;
+    }
+    
+    //if left is BVPLUS and right is not, then swap left and right. we
+    //can do this since BVMULT is communtative
+    ASTNode swap;
+    if(BVPLUS == left_kind && BVPLUS != right_kind) {
+      swap = left;
+      left = right;
+      right = swap;
+    }
+    left_kind = left.GetKind();
+    right_kind = right.GetKind();
+
+    //by this point we are gauranteed that right is a BVPLUS, but left
+    //may not be
+    ASTVec rightnodes = right.GetChildren();
+    ASTVec outputvec;
+    unsigned len = a.GetValueWidth();
+    ASTNode zero = CreateZeroConst(len);
+    ASTNode one = CreateOneConst(len);
+    if(BVPLUS != left_kind) {
+      //if the multiplier is not a BVPLUS then we have a special case
+      // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
+      if(zero == left) {
+	outputvec.push_back(zero);
+      }
+      else if(one == left) {
+	outputvec.push_back(left);
+      }
+      else {
+	for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
+	    j!=jend;j++) {
+	  ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,left,*j));
+	  outputvec.push_back(out);
+	}
+      }
+    }
+    else {
+      ASTVec leftnodes = left.GetChildren();
+      // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 +
+      // ... + x2*y1 + ... + xm*yn
+      for(ASTVec::iterator i=leftnodes.begin(),iend=leftnodes.end();
+	  i!=iend;i++) {
+	ASTNode multiplier = *i;
+	for(ASTVec::iterator j=rightnodes.begin(),jend=rightnodes.end();
+	    j!=jend;j++) {
+	  ASTNode out = SimplifyTerm(CreateTerm(BVMULT,len,multiplier,*j));
+	  outputvec.push_back(out);
+	}
+      }
+    }
+    
+    //compute output here
+    if(outputvec.size() > 1) {
+      output = CombineLikeTerms(CreateTerm(BVPLUS,len,outputvec));
+      output = SimplifyTerm(output);
+    }
+    else
+      output = SimplifyTerm(outputvec[0]);
+
+    //memoize
+    //UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of distributemultoverplus()
+
+  //converts the BVSX(len, a0) operator into ITE( check top bit,
+  //extend a0 by 1, extend a0 by 0)
+  ASTNode BeevMgr::ConvertBVSXToITE(const ASTNode& a) {
+    if(BVSX != a.GetKind())
+      return a;
+
+    ASTNode output;
+    if(CheckSimplifyMap(a,output,false)) {
+      //check memo table
+      //cerr << "output of ConvertBVSXToITE Cache: " << output << endl;
+      return output;
+    }
+    
+    ASTNode a0 = a[0];
+    unsigned a_len = a.GetValueWidth();
+    unsigned a0_len = a0.GetValueWidth();
+    
+    if(a0_len > a_len){
+      FatalError("Trying to sign_extend a larger BV into a smaller BV");
+      return ASTUndefined; //to stop the compiler from producing bogus warnings
+    }
+    
+    //sign extend
+    unsigned extensionlen = a_len-a0_len;
+    if(0 == extensionlen) {
+      UpdateSimplifyMap(a,output,false);
+      return a;
+    }
+
+    std::string ones;
+    for(unsigned c=0; c < extensionlen;c++)
+      ones += '1';			   
+    std::string zeros;
+    for(unsigned c=0; c < extensionlen;c++)
+      zeros += '0';
+			   
+    //string of oness of length extensionlen
+    BEEV::ASTNode BVOnes = CreateBVConst(ones.c_str(),2);
+    //string of zeros of length extensionlen
+    BEEV::ASTNode BVZeros = CreateBVConst(zeros.c_str(),2);
+			   
+    //string of ones BVCONCAT a0
+    BEEV::ASTNode concatOnes = CreateTerm(BEEV::BVCONCAT,a_len,BVOnes,a0);
+    //string of zeros BVCONCAT a0
+    BEEV::ASTNode concatZeros = CreateTerm(BEEV::BVCONCAT,a_len,BVZeros,a0);
+
+    //extract top bit of a0
+    BEEV::ASTNode hi = CreateBVConst(32,a0_len-1);
+    BEEV::ASTNode low = CreateBVConst(32,a0_len-1);
+    BEEV::ASTNode topBit = CreateTerm(BEEV::BVEXTRACT,1,a0,hi,low);
+
+    //compare topBit of a0 with 0bin1
+    BEEV::ASTNode condition = CreateSimplifiedEQ(CreateBVConst(1,1),topBit);
+
+    //ITE(topbit = 0bin1, 0bin1111...a0, 0bin000...a0)
+    output = CreateSimplifiedTermITE(condition,concatOnes,concatZeros);
+    UpdateSimplifyMap(a,output,false);
+    return output;
+  } //end of ConvertBVSXToITE()
+
+
+  ASTNode BeevMgr::RemoveWrites_TopLevel(const ASTNode& term) {
+    if(READ != term.GetKind() && WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+    
+    if(!Begin_RemoveWrites && 
+       !SimplifyWrites_InPlace_Flag && 
+       !start_abstracting) {
+      return term;
+    }
+    else if(!Begin_RemoveWrites && 
+	    SimplifyWrites_InPlace_Flag && 
+	    !start_abstracting) {
+      //return term;
+      return SimplifyWrites_InPlace(term);
+    }
+    else {
+      return RemoveWrites(term);
+    }
+  } //end of RemoveWrites_TopLevel()
+
+  ASTNode BeevMgr::SimplifyWrites_InPlace(const ASTNode& term) {
+    ASTNodeMultiSet WriteIndicesSeenSoFar;
+    bool SeenNonConstWriteIndex = false;
+
+    if(READ != term.GetKind() && 
+	WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+    
+    ASTNode output;
+    if(CheckSimplifyMap(term,output,false)) {
+      return output;
+    }
+
+    ASTVec writeIndices, writeValues;
+    unsigned int width = term.GetValueWidth();
+    ASTNode write = term[0];
+    unsigned indexwidth = write.GetIndexWidth();
+    ASTNode readIndex = SimplifyTerm(term[1]);
+        
+    do {
+      ASTNode writeIndex = SimplifyTerm(write[1]);
+      ASTNode writeVal = SimplifyTerm(write[2]);
+          
+      //compare the readIndex and the current writeIndex and see if they
+      //simplify to TRUE or FALSE or UNDETERMINABLE at this stage
+      ASTNode compare_readwrite_indices = 
+	SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
+    
+      //if readIndex and writeIndex are equal
+      if(ASTTrue == compare_readwrite_indices && !SeenNonConstWriteIndex) {
+	UpdateSimplifyMap(term,writeVal,false);
+	return writeVal;
+      }
+
+      if(!(ASTTrue == compare_readwrite_indices || 
+	   ASTFalse == compare_readwrite_indices)) {
+	SeenNonConstWriteIndex = true;
+      }
+
+      //if (readIndex=writeIndex <=> FALSE)
+      if(ASTFalse == compare_readwrite_indices 
+	 ||
+	 (WriteIndicesSeenSoFar.find(writeIndex) != WriteIndicesSeenSoFar.end())
+	 ) {
+	//drop the current level write
+	//do nothing
+      }
+      else {
+	writeIndices.push_back(writeIndex);
+	writeValues.push_back(writeVal);
+      }
+      
+      //record the write indices seen so far
+      //if(BVCONST == writeIndex.GetKind()) {
+	WriteIndicesSeenSoFar.insert(writeIndex);
+	//}
+
+      //Setup the write for the new iteration, one level inner write
+      write = write[0];
+    }while (SYMBOL != write.GetKind());
+
+    ASTVec::reverse_iterator it_index = writeIndices.rbegin();
+    ASTVec::reverse_iterator itend_index = writeIndices.rend();
+    ASTVec::reverse_iterator it_values = writeValues.rbegin();
+    ASTVec::reverse_iterator itend_values = writeValues.rend();
+
+    //"write" must be a symbol at the control point before the
+    //begining of the "for loop"
+
+    for(;it_index!=itend_index;it_index++,it_values++) {
+      write = CreateTerm(WRITE,width,write,*it_index,*it_values);
+      write.SetIndexWidth(indexwidth);
+    }
+
+    output = CreateTerm(READ,width,write,readIndex);
+    UpdateSimplifyMap(term,output,false);
+    return output;
+  } //end of SimplifyWrites_In_Place() 
+
+  //accepts a read over a write and returns a term without the write
+  //READ(WRITE(A i val) j) <==> ITE(i=j,val,READ(A,j)). We use a memo
+  //table for this function called RemoveWritesMemoMap
+  ASTNode BeevMgr::RemoveWrites(const ASTNode& input) {   
+    //unsigned int width = input.GetValueWidth();
+    if(READ != input.GetKind() || WRITE != input[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",input);
+    }
+
+    ASTNodeMap::iterator it;
+    ASTNode output = input;
+    if(CheckSimplifyMap(input,output,false)) {
+      return output;
+    }
+        
+    if(!start_abstracting && Begin_RemoveWrites) {
+      output= ReadOverWrite_To_ITE(input);
+    }
+
+    if(start_abstracting) {
+      ASTNode newVar;
+      if(!CheckSimplifyMap(input,newVar,false)) {
+	newVar = NewVar(input.GetValueWidth());
+	ReadOverWrite_NewName_Map[input] = newVar;
+	NewName_ReadOverWrite_Map[newVar] = input;
+
+	UpdateSimplifyMap(input,newVar,false);
+	ASTNodeStats("New Var Name which replace Read_Over_Write: ", newVar);
+      }
+      output = newVar;
+    } //end of start_abstracting if condition
+
+    //memoize
+    UpdateSimplifyMap(input,output,false);
+    return output;
+  } //end of RemoveWrites()
+
+  ASTNode BeevMgr::ReadOverWrite_To_ITE(const ASTNode& term) {
+    unsigned int width = term.GetValueWidth();
+    ASTNode input = term;
+    if(READ != term.GetKind() || WRITE != term[0].GetKind()) {
+      FatalError("RemovesWrites: Input must be a READ over a WRITE",term);
+    }
+
+    ASTNodeMap::iterator it;
+    ASTNode output;
+    // if(CheckSimplifyMap(term,output,false)) {
+    //       return output;
+    //     }
+    
+    ASTNode partialITE = term;
+    ASTNode writeA = ASTTrue;
+    ASTNode oldRead = term;
+    //iteratively expand read-over-write
+    do {
+      ASTNode write = input[0];
+      ASTNode readIndex = SimplifyTerm(input[1]);
+      //DO NOT CALL SimplifyTerm() on write[0]. You will go into an
+      //infinite loop
+      writeA = write[0];
+      ASTNode writeIndex = SimplifyTerm(write[1]);
+      ASTNode writeVal = SimplifyTerm(write[2]);
+      
+      ASTNode cond = SimplifyFormula(CreateSimplifiedEQ(writeIndex,readIndex),false);
+      ASTNode newRead = CreateTerm(READ,width,writeA,readIndex);
+      ASTNode newRead_memoized = newRead;
+      if(CheckSimplifyMap(newRead, newRead_memoized,false)) {
+	newRead = newRead_memoized;
+      }
+      
+      if(ASTTrue == cond && (term == partialITE)) {
+	//found the write-value in the first iteration itself. return
+	//it
+	output = writeVal;
+	UpdateSimplifyMap(term,output,false);
+	return output;
+      }
+      
+      if(READ == partialITE.GetKind() && WRITE == partialITE[0].GetKind()) {
+	//first iteration or (previous cond==ASTFALSE and partialITE is a "READ over WRITE")
+	partialITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+      }
+      else if (ITE == partialITE.GetKind()){
+	//ITE(i1 = j, v1, R(A,j))
+	ASTNode ElseITE = CreateSimplifiedTermITE(cond, writeVal, newRead);
+	//R(W(A,i1,v1),j) <==> ITE(i1 = j, v1, R(A,j))
+	UpdateSimplifyMap(oldRead,ElseITE,false);
+	//ITE(i2 = j, v2, R(W(A,i1,v1),j)) <==> ITE(i2 = j, v2, ITE(i1 = j, v1, R(A,j)))
+	partialITE = SimplifyTerm(partialITE);
+      }
+      else {
+	FatalError("RemoveWrites: Control should not reach here\n");
+      }
+      
+      if(ASTTrue == cond) {
+	//no more iterations required
+	output = partialITE;
+	UpdateSimplifyMap(term,output,false);
+	return output;
+      }
+      
+      input = newRead;
+      oldRead = newRead;
+    } while(READ == input.GetKind() && WRITE == input[0].GetKind());
+    
+    output = partialITE;
+    
+    //memoize
+    //UpdateSimplifyMap(term,output,false);
+    return output;
+  } //ReadOverWrite_To_ITE()
+
+  //compute the multiplicative inverse of the input
+  ASTNode BeevMgr::MultiplicativeInverse(const ASTNode& d) {
+    ASTNode c = d;
+    if(BVCONST != c.GetKind()) {
+      FatalError("Input must be a constant", c);
+    }
+
+    if(!BVConstIsOdd(c)) {
+      FatalError("MultiplicativeInverse: Input must be odd: ",c);
+    }
+    
+    //cerr << "input to multinverse function is: " << d << endl;
+    ASTNode inverse;
+    if(CheckMultInverseMap(d,inverse)) {
+      //cerr << "found the inverse of: " << d << "and it is: " << inverse << endl;
+      return inverse;
+    }
+
+    inverse = c;
+    unsigned inputwidth = c.GetValueWidth();
+
+#ifdef NATIVE_C_ARITH
+    ASTNode one = CreateOneConst(inputwidth);
+    while(c != one) {
+      //c = c*c
+      c = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,c,c));
+      //inverse = invsere*c
+      inverse = BVConstEvaluator(CreateTerm(BVMULT,inputwidth,inverse,c));
+    }
+#else
+    //Compute the multiplicative inverse of c using the extended
+    //euclidian algorithm
+    //
+    //create a '0' which is 1 bit long
+    ASTNode onebit_zero = CreateZeroConst(1);
+    //zero pad t0, i.e. 0 @ t0
+    c = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,c));
+
+    //construct 2^(inputwidth), i.e. a bitvector of length
+    //'inputwidth+1', which is max(inputwidth)+1
+    //
+    //all 1's 
+    ASTNode max = CreateMaxConst(inputwidth);
+    //zero pad max
+    max = BVConstEvaluator(CreateTerm(BVCONCAT,inputwidth+1,onebit_zero,max));
+    //Create a '1' which has leading zeros of length 'inputwidth'
+    ASTNode inputwidthplusone_one = CreateOneConst(inputwidth+1);    
+    //add 1 to max
+    max = CreateTerm(BVPLUS,inputwidth+1,max,inputwidthplusone_one);
+    max = BVConstEvaluator(max);
+    
+    ASTNode zero = CreateZeroConst(inputwidth+1);
+    ASTNode max_bvgt_0 = CreateNode(BVGT,max,zero);
+    ASTNode quotient, remainder;
+    ASTNode x, x1, x2;
+
+    //x1 initialized to zero
+    x1 = zero;
+    //x2 initialized to one
+    x2 = CreateOneConst(inputwidth+1);
+    while (ASTTrue == BVConstEvaluator(max_bvgt_0)) {
+      //quotient = (c divided by max)
+      quotient = BVConstEvaluator(CreateTerm(BVDIV,inputwidth+1, c, max));
+
+      //remainder of (c divided by max)
+      remainder = BVConstEvaluator(CreateTerm(BVMOD,inputwidth+1, c, max));
+
+      //x = x2 - q*x1
+      x = CreateTerm(BVSUB,inputwidth+1,x2,CreateTerm(BVMULT,inputwidth+1,quotient,x1));
+      x = BVConstEvaluator(x);
+
+      //fix the inputs to the extended euclidian algo
+      c = max;
+      max = remainder;
+      max_bvgt_0 = CreateNode(BVGT,max,zero);
+      
+      x2 = x1;
+      x1 = x;
+    }
+    
+    ASTNode hi = CreateBVConst(32,inputwidth-1);
+    ASTNode low = CreateZeroConst(32);
+    inverse = CreateTerm(BVEXTRACT,inputwidth,x2,hi,low);
+    inverse = BVConstEvaluator(inverse);
+#endif
+
+    UpdateMultInverseMap(d,inverse);
+    //cerr << "output of multinverse function is: " << inverse << endl;
+    return inverse;
+  } //end of MultiplicativeInverse()
+
+  //returns true if the input is odd
+  bool BeevMgr::BVConstIsOdd(const ASTNode& c) {
+    if(BVCONST != c.GetKind()) {
+      FatalError("Input must be a constant", c);
+    }
+   
+    ASTNode zero = CreateZeroConst(1);
+    ASTNode hi = CreateZeroConst(32);
+    ASTNode low = hi;
+    ASTNode lowestbit = CreateTerm(BVEXTRACT,1,c,hi,low);
+    lowestbit =  BVConstEvaluator(lowestbit);
+
+    if(lowestbit == zero) {
+      return false;
+    }
+    else {
+      return true;
+    }
+  } //end of BVConstIsOdd()
+
+  //The big substitution function
+  ASTNode BeevMgr::CreateSubstitutionMap(const ASTNode& a){
+    if(!optimize)
+      return a;
+
+    ASTNode output = a;
+    //if the variable has been solved for, then simply return it
+    if(CheckSolverMap(a,output))
+      return output;
+
+    //traverse a and populate the SubstitutionMap 
+    Kind k = a.GetKind();
+    if(SYMBOL == k && BOOLEAN_TYPE == a.GetType()) {
+      bool updated = UpdateSubstitutionMap(a,ASTTrue);
+      output = updated ? ASTTrue : a;      
+      return output;          
+    }
+    if(NOT == k
+       && SYMBOL == a[0].GetKind()) {
+      bool updated = UpdateSubstitutionMap(a[0],ASTFalse);
+      output = updated ? ASTTrue : a;      
+      return output;          
+    }
+    
+    if(IFF == k) {
+      ASTVec c = a.GetChildren();
+      SortByExprNum(c);
+      if(SYMBOL != c[0].GetKind() || 
+    	 VarSeenInTerm(c[0],SimplifyFormula_NoRemoveWrites(c[1],false))) {
+	return a;
+      }
+      bool updated = UpdateSubstitutionMap(c[0],c[1]);
+      output = updated ? ASTTrue : a;      
+      return output;      
+    }
+    
+    if(EQ == k) {
+      //fill the arrayname readindices vector if e0 is a
+      //READ(Arr,index) and index is a BVCONST
+      ASTVec c = a.GetChildren();
+      SortByExprNum(c);
+      FillUp_ArrReadIndex_Vec(c[0],c[1]);
+
+      if(SYMBOL == c[0].GetKind() && 
+	 VarSeenInTerm(c[0],SimplifyTerm(c[1]))) {
+	return a;
+      }
+
+      if(1 == TermOrder(c[0],c[1]) &&
+	 READ == c[0].GetKind() &&
+	 VarSeenInTerm(c[0][0],SimplifyTerm(c[1]))) {
+	return a;
+      }
+      bool updated = UpdateSubstitutionMap(c[0],c[1]);      
+      output = updated ? ASTTrue : a;      
+      return output;      
+    }
+
+    if(AND == k){
+      ASTVec o;
+      ASTVec c = a.GetChildren();
+      for(ASTVec::iterator it = c.begin(),itend=c.end();it!=itend;it++) {
+	UpdateAlwaysTrueFormMap(*it);
+	ASTNode aaa = CreateSubstitutionMap(*it);
+	
+	if(ASTTrue != aaa) {
+	  if(ASTFalse == aaa)
+	    return ASTFalse;
+	  else
+	    o.push_back(aaa);
+	}
+      }
+      if(o.size() == 0)
+	return ASTTrue;
+
+      if(o.size() == 1)
+	return o[0];
+      
+      return CreateNode(AND,o);
+    }
+    return output;
+  } //end of CreateSubstitutionMap()
+
+
+  bool BeevMgr::VarSeenInTerm(const ASTNode& var, const ASTNode& term) {
+    if(READ == term.GetKind() && 
+       WRITE == term[0].GetKind() && !Begin_RemoveWrites) {
+      return false;
+    }
+
+    if(READ == term.GetKind() && 
+       WRITE == term[0].GetKind() && Begin_RemoveWrites) {
+      return true;
+    }
+
+    ASTNodeMap::iterator it;    
+    if((it = TermsAlreadySeenMap.find(term)) != TermsAlreadySeenMap.end()) {
+      if(it->second == var) {
+	return false;
+      }
+    }
+
+    if(var == term) {
+      return true;
+    }
+
+    for(ASTVec::const_iterator it=term.begin(),itend=term.end();it!=itend;it++){
+      if(VarSeenInTerm(var,*it)) {
+	return true;
+      }
+      else {
+	TermsAlreadySeenMap[*it] = var;
+      }
+    }
+
+    TermsAlreadySeenMap[term] = var;
+    return false;
+  }
+};//end of namespace

Added: klee/trunk/test/CXX/ArrayNew.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/ArrayNew.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/ArrayNew.cpp (added)
+++ klee/trunk/test/CXX/ArrayNew.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,38 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+static int decon = 0;
+
+class Test {
+  int x;
+
+public:
+  Test() {}
+  Test(int _x) : x(_x) { }
+  ~Test() { decon += x; }
+
+  int getX() { return x; }
+  void setX(int _x) { x = _x; }
+};
+
+int main(int argc) {
+  Test *rt = new Test[4];
+  int i;
+
+  for (i=0; i<4; i++)
+    rt[i].setX(i+1);
+
+  int sum = 0;
+  for (i=0; i<4; i++)
+    sum += rt[i].getX();
+  
+  assert(sum==10);
+
+  delete[] rt;
+
+  assert(decon==10);
+
+  return 0;
+}

Added: klee/trunk/test/CXX/New.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/New.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/New.cpp (added)
+++ klee/trunk/test/CXX/New.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,29 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+class Test {
+  int x;
+
+public:
+  Test(int _x) : x(_x) {
+  }
+  ~Test() {
+  }
+
+  int getX() { return x; }
+};
+
+// This doesn't do what I want because
+// it is being changed to alloca, but
+// it is also failing.
+int main(int argc) {
+  Test *rt = new Test(2);
+  
+  assert(rt->getX()==2);
+
+  delete rt;
+
+  return 0;
+}

Added: klee/trunk/test/CXX/SimpleVirtual.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/SimpleVirtual.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/SimpleVirtual.cpp (added)
+++ klee/trunk/test/CXX/SimpleVirtual.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,38 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error --no-externals %t1.bc
+
+#include <cassert>
+
+static int decon = 0;
+
+class Thing {
+public:
+  Thing() {}
+  virtual ~Thing() { decon += getX(); }
+
+  virtual int getX() { return 1; };
+};
+
+class Thing2 : public Thing {
+public:
+  virtual int getX() { return 2; };
+};
+
+Thing *getThing(bool which) { 
+  return which ? new Thing() : new Thing2();
+}
+
+int main(int argc) {
+  Thing *one = getThing(false);
+  Thing *two = getThing(true);
+
+  int x = one->getX() + two->getX();
+  assert(x==3);
+
+  delete two;
+  delete one;
+  
+  assert(decon==2);
+
+  return 0;
+}

Added: klee/trunk/test/CXX/StaticConstructor.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/StaticConstructor.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/StaticConstructor.cpp (added)
+++ klee/trunk/test/CXX/StaticConstructor.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,25 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --no-output --exit-on-error %t1.bc
+
+#include <cassert>
+
+// to make sure globals are initialized
+int aGlobal = 21;
+
+class Test {
+  int x;
+
+public:
+  Test() : x(aGlobal + 1) {}
+  ~Test() {}
+
+  int getX() { return x; }
+};
+
+Test t;
+
+int main() {
+  assert(t.getX()==22);
+
+  return 0;
+}

Added: klee/trunk/test/CXX/StaticDestructor.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/StaticDestructor.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/StaticDestructor.cpp (added)
+++ klee/trunk/test/CXX/StaticDestructor.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,24 @@
+// don't optimize this, llvm likes to turn the *p into unreachable
+
+// RUN: %llvmgxx %s --emit-llvm -g -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --no-output %t1.bc 2> %t1.log
+// RUN: grep ":16: memory error" %t1.log
+
+#include <cassert>
+
+class Test {
+  int *p;
+
+public:
+  Test() : p(0) {}
+  ~Test() { 
+    assert(!p); 
+    assert(*p == 10); // crash here
+  }
+};
+
+Test t;
+
+int main() {
+  return 0;
+}

Added: klee/trunk/test/CXX/Trivial.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/Trivial.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/Trivial.cpp (added)
+++ klee/trunk/test/CXX/Trivial.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgxx %s --emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error %t1.bc
+
+#include <cassert>
+
+class Test {
+  int x;
+
+public:
+  Test(int _x) : x(_x) {}
+  ~Test() {}
+
+  int getX() { return x; }
+};
+
+int main() {
+  Test rt(2);
+  
+  assert(rt.getX()==2);
+
+  return 0;
+}

Added: klee/trunk/test/CXX/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/CXX/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/CXX/dg.exp (added)
+++ klee/trunk/test/CXX/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/test/Concrete/BitwiseOps.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/BitwiseOps.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/BitwiseOps.ll (added)
+++ klee/trunk/test/Concrete/BitwiseOps.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = or i32 12345678, 87654321
+	%b = and i32 %a, 87654321
+	%check = xor i32 %b, 87654321
+	%test = icmp eq i32 %check, 0
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/BoolReadWrite.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/BoolReadWrite.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/BoolReadWrite.ll (added)
+++ klee/trunk/test/Concrete/BoolReadWrite.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,13 @@
+declare void @print_i1(i1)
+
+define i32 @main() {
+        %mem = alloca i1
+        store i1 1, i1* %mem
+        %v = load i1* %mem
+        br i1 %v, label %ok, label %exit
+ok:
+	call void @print_i1(i1 %v)
+        br label %exit
+exit:
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/Casts.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/Casts.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/Casts.ll (added)
+++ klee/trunk/test/Concrete/Casts.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,28 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 315904, 128
+	%b = trunc i32 %a to i8
+	%c0 = icmp eq i8 %b, 128
+	%d = zext i8 %b to i32
+	%c1 = icmp eq i32 %d, 128
+	%e = sext i8 %b to i32
+	%c2 = icmp eq i32 %e, -128
+	%c0i = zext i1 %c0 to i32
+	%c1i = zext i1 %c1 to i32
+	%c2i = zext i1 %c2 to i32
+	%c0is = shl i32 %c0i, 0
+	%c1is = shl i32 %c1i, 1
+	%c2is = shl i32 %c2i, 2
+	%tmp = add i32 %c0is, %c1is
+	%res = add i32 %tmp, %c2is
+	%p = icmp eq i32 %res, 7
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Propchange: klee/trunk/test/Concrete/Casts.ll

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/test/Concrete/CmpEq.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/CmpEq.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/CmpEq.ll (added)
+++ klee/trunk/test/Concrete/CmpEq.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = add i8 0, 1
+	%b = add i8 %a, -1
+	%c = icmp eq i8 %b, 0
+	br i1 %c, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/ConcreteTest.py
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/ConcreteTest.py?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/ConcreteTest.py (added)
+++ klee/trunk/test/Concrete/ConcreteTest.py Wed May 20 23:36:41 2009
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+
+import os
+import sys
+import popen2
+
+class TestError(Exception):
+    pass
+
+kLLIPath = '../../llvm/Debug/bin/lli'
+kKleePath = '../../Debug/bin/klee'
+
+def getFiles():
+    for name in os.listdir('.'):
+        if (name[0]!='.' and name[0]!='_' and
+            (name.endswith('.ll') or name.endswith('.c'))):
+            yield name
+
+def readFile(f):
+    s = ""
+    while 1:
+        data = f.read()
+        if not data:
+            break
+        s += data
+    return s
+
+def testFile(name, printOutput=False):
+    baseName,ext = os.path.splitext(name)
+    exeFile = 'Output/linked_%s.bc'%baseName
+    if printOutput:
+        redirectStderr = ''
+    else:
+        redirectStderr = '2> /dev/null'
+
+    if os.system('make %s > /dev/null %s'%(exeFile,redirectStderr)):
+        raise TestError('make failed')
+
+    if printOutput:
+        print '-- running lli --'
+    lli = popen2.Popen3('%s -force-interpreter=true %s %s'%(kLLIPath,exeFile,redirectStderr))
+    lliOut = readFile(lli.fromchild)
+    if lli.wait():
+        raise TestError('lli execution failed')
+
+    if printOutput:
+        print lliOut
+
+    if printOutput:
+        print '-- running klee --'
+    klee = popen2.Popen3('%s --no-output %s %s'%(kKleePath,exeFile,redirectStderr))
+    kleeOut = readFile(klee.fromchild)
+    if klee.wait():
+        raise TestError('klee execution failed')
+    if printOutput:
+        print kleeOut
+        
+    if lliOut!=kleeOut:
+        raise TestError('outputs differ')
+        
+def testOneFile(f, printOutput=False, log=None):
+    try:
+        testFile(f, printOutput)
+        code = ['pass','xpass'][f.startswith('broken')]
+        extra = ''
+    except TestError,e:
+        code = ['fail','xfail'][f.startswith('broken')]
+        extra = str(e)
+
+    print '%s: %s -- %s'%(code,f,extra)
+    if log:
+        print >>log,'%s: %s -- %s'%(code,f,extra)
+
+def test():
+    if not os.path.exists('Output'):
+        os.mkdir('Output')
+    log = open("Output/test.log","w")
+    files = list(getFiles())
+    files.sort(key = lambda n: n.lower())
+    for f in files:
+        testOneFile(f, log=log)
+    log.close()
+
+if __name__=='__main__':
+    args = sys.argv
+    args.pop(0)
+    
+    runAll = not args
+
+    while args:
+        arg = args.pop(0)
+        if arg=='--run':
+            testFile(args.pop(0), printOutput=True)
+        else:
+            raise ValueError,'invalid argument: %s'%arg
+
+    if runAll:
+        test()
+        

Propchange: klee/trunk/test/Concrete/ConcreteTest.py

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/test/Concrete/ConstantExpr.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/ConstantExpr.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/ConstantExpr.ll (added)
+++ klee/trunk/test/Concrete/ConstantExpr.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,166 @@
+ at gInt = global i32 10
+ at gIntWithConstant = global i32 sub(i32 ptrtoint(i32* @gInt to i32), 
+                                 i32 ptrtoint(i32* @gInt to i32))
+
+define void @"test_int_to_ptr"()
+begin
+  %t1 = add i8 ptrtoint(i8* inttoptr(i32 100 to i8*) to i8), 0
+  %t2 = add i32 ptrtoint(i32* inttoptr(i8 100 to i32*) to i32), 0
+  %t3 = add i32 ptrtoint(i32* inttoptr(i64 100 to i32*) to i32), 0
+  %t4 = add i64 ptrtoint(i8* inttoptr(i32 100 to i8*) to i64), 0
+
+  call void @print_i8(i8 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  call void @print_i64(i64 %t4)
+    
+  ret void
+end
+
+define void @"test_constant_ops"()
+begin
+  %t1 = add i8 trunc(i64 add(i64 ptrtoint(i32* @gInt to i64), i64 -10) to i8), 10
+  %t2 = sub i64 sext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+  %t3 = sub i64 zext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+
+  %t4 = icmp eq i8 trunc(i64 ptrtoint(i32* @gInt to i64) to i8), %t1
+  %t5 = zext i1 %t4 to i8
+    
+  call void @print_i8(i8 %t5)
+  call void @print_i64(i64 %t2)
+  call void @print_i64(i64 %t3)
+  
+  ret void
+end
+
+define void @"test_logical_ops"()
+begin
+  %t1 = add i32 -10, and(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t2 = add i32 -10, or(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t3 = add i32 -10, xor(i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 1024),  i32 ptrtoint(i32* @gInt to i32))
+
+  call void @print_i32(i32 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  
+  %t4 = shl i32 lshr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t5 = shl i32 ashr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t6 = lshr i32 shl(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  
+  %t7 = icmp eq i32 %t4, %t5     
+  %t8 = icmp ne i32 %t4, %t6     
+  
+  %t9 = zext i1 %t7 to i8
+  %t10 = zext i1 %t8 to i8
+  
+  call void @print_i8(i8 %t9)
+  call void @print_i8(i8 %t10)
+  
+  ret void   
+end
+
+%test.struct.type = type { i32, i32 }
+ at test_struct = global %test.struct.type { i32 0, i32 10 }
+
+define void @"test_misc"()
+begin
+  ; probability that @gInt == 100 is very very low 
+  %t1 = add i32 select(i1 icmp eq (i32* @gInt, i32* inttoptr(i32 100 to i32*)), i32 10, i32 0), 0
+  call void @print_i32(i32 %t1)
+
+  %t2 = load i32* getelementptr(%test.struct.type* @test_struct, i32 0, i32 1)
+  call void @print_i32(i32 %t2)                             
+        
+  ret void
+end
+
+define void @"test_simple_arith"()
+begin
+  %t1 = add i32 add(i32 ptrtoint(i32* @gInt to i32), i32 0), 0
+  %t2 = add i32 sub(i32 0, i32 ptrtoint(i32* @gInt to i32)), %t1
+  %t3 = mul i32 mul(i32 ptrtoint(i32* @gInt to i32), i32 10), %t2
+
+  call void @print_i32(i32 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"()
+begin
+  %t1 = add i32 udiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t2 = add i32 urem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t3 = add i32 sdiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t4 = add i32 srem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+
+  %p = ptrtoint i32* @gInt to i32
+
+  %i1 = udiv i32 %p, 13
+  %i2 = urem i32 %p, 13
+  %i3 = sdiv i32 %p, 13
+  %i4 = srem i32 %p, 13
+
+  %x1 = sub i32 %t1, %i1
+  %x2 = sub i32 %t2, %i2
+  %x3 = sub i32 %t3, %i3
+  %x4 = sub i32 %t4, %i4
+
+  call void @print_i32(i32 %x1)
+  call void @print_i32(i32 %x2)
+  call void @print_i32(i32 %x3)
+  call void @print_i32(i32 %x4)
+
+  ret void     
+end
+        
+define void @test_cmp()
+begin
+  %t1 = add i8 zext(i1 icmp ult (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t2 = add i8 zext(i1 icmp ule (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t3 = add i8 zext(i1 icmp uge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t4 = add i8 zext(i1 icmp ugt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t5 = add i8 zext(i1 icmp slt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t6 = add i8 zext(i1 icmp sle (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t7 = add i8 zext(i1 icmp sge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t8 = add i8 zext(i1 icmp sgt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t9 = add i8 zext(i1 icmp eq (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+  %t10 = add i8 zext(i1 icmp ne (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+
+  call void @print_i1(i8 %t1)
+  call void @print_i1(i8 %t2)
+  call void @print_i1(i8 %t3)
+  call void @print_i1(i8 %t4)
+  call void @print_i1(i8 %t5)
+  call void @print_i1(i8 %t6)
+  call void @print_i1(i8 %t7)
+  call void @print_i1(i8 %t8)
+  call void @print_i1(i8 %t9)
+  call void @print_i1(i8 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith()
+
+    call void @test_div_and_mod()
+
+    call void @test_cmp()
+ 
+    call void @test_int_to_ptr()
+
+    call void @test_constant_ops()
+
+    call void @test_logical_ops()
+
+    call void @test_misc()
+    
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i8)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)

Added: klee/trunk/test/Concrete/FloatingPointOps.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/FloatingPointOps.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/FloatingPointOps.ll (added)
+++ klee/trunk/test/Concrete/FloatingPointOps.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,685 @@
+%struct.stdout = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.stdout*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i32, i32, [40 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct.stdout*, i32 }
+ at stdout = external global %struct.stdout*
+
+; casting error messages
+ at .strTrunc     = internal constant [15 x i8] c"FPTrunc broken\00"
+ at .strExt       = internal constant [13 x i8] c"FPExt broken\00"
+ at .strFPToUIFlt = internal constant [20 x i8] c"FPToUI float broken\00"
+ at .strFPToUIDbl = internal constant [21 x i8] c"FPToUI double broken\00"
+ at .strFPToSIFlt = internal constant [20 x i8] c"FPToSI float broken\00"
+ at .strFPToSIDbl = internal constant [21 x i8] c"FPToSI double broken\00"
+ at .strUIToFPFlt = internal constant [20 x i8] c"UIToFP float broken\00"
+ at .strUIToFPDbl = internal constant [21 x i8] c"UIToFP double broken\00"
+ at .strSIToFPFlt = internal constant [20 x i8] c"SIToFP float broken\00"
+ at .strSIToFPDbl = internal constant [21 x i8] c"SIToFP double broken\00"
+
+; mathematical operator error messages
+ at .strDivFlt    = internal constant [18 x i8] c"FDiv float broken\00"
+ at .strDivDbl    = internal constant [19 x i8] c"FDiv double broken\00"
+ at .strRemFlt    = internal constant [18 x i8] c"FRem float broken\00"
+ at .strRemDbl    = internal constant [19 x i8] c"FRem double broken\00"
+ at .strAddInt    = internal constant [16 x i8] c"Add ints broken\00"
+ at .strAddFlt    = internal constant [18 x i8] c"Add floats broken\00"
+ at .strAddDbl    = internal constant [19 x i8] c"Add doubles broken\00"
+ at .strSubInt    = internal constant [16 x i8] c"Sub ints broken\00"
+ at .strSubFlt    = internal constant [18 x i8] c"Sub floats broken\00"
+ at .strSubDbl    = internal constant [19 x i8] c"Sub doubles broken\00"
+ at .strMulInt    = internal constant [16 x i8] c"Mul ints broken\00"
+ at .strMulFlt    = internal constant [18 x i8] c"Mul floats broken\00"
+ at .strMulDbl    = internal constant [19 x i8] c"Mul doubles broken\00"
+
+; fcmp error messages
+ at .strCmpTrFlt  = internal constant [19 x i8] c"floats TRUE broken\00" ; fcmp::generic broken msgs
+ at .strCmpFaFlt  = internal constant [20 x i8] c"floats FALSE broken\00"
+ at .strCmpTrDbl  = internal constant [19 x i8] c"double TRUE broken\00"
+ at .strCmpFaDbl  = internal constant [20 x i8] c"double FALSE broken\00"
+ at .strCmpEqFlt  = internal constant [17 x i8] c"floats == broken\00" ; fcmp::ordered broken msgs
+ at .strCmpGeFlt  = internal constant [17 x i8] c"floats >= broken\00"
+ at .strCmpGtFlt  = internal constant [17 x i8] c"floats >  broken\00"
+ at .strCmpLeFlt  = internal constant [17 x i8] c"floats <= broken\00"
+ at .strCmpLtFlt  = internal constant [17 x i8] c"floats <  broken\00"
+ at .strCmpNeFlt  = internal constant [17 x i8] c"floats != broken\00"
+ at .strCmpOrdFlt = internal constant [18 x i8] c"floats ORD broken\00"
+ at .strCmpEqDbl  = internal constant [18 x i8] c"doubles == broken\00"
+ at .strCmpGeDbl  = internal constant [18 x i8] c"doubles >= broken\00"
+ at .strCmpGtDbl  = internal constant [18 x i8] c"doubles >  broken\00"
+ at .strCmpLeDbl  = internal constant [18 x i8] c"doubles <= broken\00"
+ at .strCmpLtDbl  = internal constant [18 x i8] c"doubles <  broken\00"
+ at .strCmpNeDbl  = internal constant [18 x i8] c"doubles != broken\00"
+ at .strCmpOrdDbl = internal constant [19 x i8] c"doubles ORD broken\00"
+ at .strCmpEqFltU = internal constant [17 x i8] c"U:floats==broken\00" ; fcmp::unordered broken msgs
+ at .strCmpGeFltU = internal constant [17 x i8] c"U:floats>=broken\00"
+ at .strCmpGtFltU = internal constant [17 x i8] c"U:floats> broken\00"
+ at .strCmpLeFltU = internal constant [17 x i8] c"U:floats<=broken\00"
+ at .strCmpLtFltU = internal constant [17 x i8] c"U:floats< broken\00"
+ at .strCmpNeFltU = internal constant [17 x i8] c"U:floats!=broken\00"
+ at .strCmpUnoFlt = internal constant [20 x i8] c"U:floats UNO broken\00"
+ at .strCmpEqDblU = internal constant [18 x i8] c"U:doubles==broken\00"
+ at .strCmpGeDblU = internal constant [18 x i8] c"U:doubles>=broken\00"
+ at .strCmpGtDblU = internal constant [18 x i8] c"U:doubles> broken\00"
+ at .strCmpLeDblU = internal constant [18 x i8] c"U:doubles<=broken\00"
+ at .strCmpLtDblU = internal constant [18 x i8] c"U:doubles< broken\00"
+ at .strCmpNeDblU = internal constant [18 x i8] c"U:doubles!=broken\00"
+ at .strCmpUnoDbl = internal constant [21 x i8] c"U:doubles UNO broken\00"
+
+ at .strWorks     = internal constant [20 x i8] c"Everything works!\0D\0A\00"
+ at .strNL        = internal constant [3 x i8]  c"\0D\0A\00"
+
+declare i32 @fprintf(%struct.stdout*, i8*, ...)
+declare void @exit(i32)
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
+
+; if isOk is false, then print errMsg to stdout and exit(1)
+define void @failCheck(i1 %isOk, i8* %errMsg) {
+entry:
+  %fail = icmp eq i1 %isOk, 0
+  br i1 %fail, label %failed, label %return
+
+failed:
+  ; print the error msg
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %errMsg )
+
+  ; add a newline to the ostream
+  %nl = getelementptr [3 x i8]* @.strNL, i32 0, i32 0
+  %ret2 = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %nl )
+
+  ; exit with return value 1 to denote that an error occurred
+  call void @exit( i32 1 )
+  unreachable
+
+return:
+  ret void
+}
+
+; test FPTrunc which casts doubles to floats
+define void @testFPTrunc() {
+entry:
+  %d_addr = alloca double, align 8
+  store double 8.000000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %f = fptrunc double %d to float
+  %matches = fcmp oeq float %f, 8.000000e+00
+  %err_msg = getelementptr [15 x i8]* @.strTrunc, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test FPExt which casts floats to doubles
+define void @testFPExt() {
+entry:
+  %f_addr = alloca float, align 4
+  store float 8.000000e+00, float* %f_addr
+  %f = load float* %f_addr
+  %d = fpext float %f to double
+  %matches = fcmp oeq double %d, 8.000000e+00
+  %err_msg = getelementptr [13 x i8]* @.strExt, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test casting fp to an unsigned int
+define void @testFPToUI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float to UI
+  store float 0x4020333340000000, float* %f_addr; %f = 8.1
+  %f = load float* %f_addr
+  %uf = fptoui float %f to i32
+  %matchesf = icmp eq i32 %uf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToUIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double to UI
+  store double 8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %ud = fptoui double %d to i32
+  %matchesd = icmp eq i32 %ud, 8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToUIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting fp to a signed int
+define void @testFPToSI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float 8.1 to signed int
+  store float 0x4020333340000000, float* %f_addr
+  %f = load float* %f_addr
+  %sf = fptosi float %f to i32
+  %matchesf = icmp eq i32 %sf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToSIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double -8.1 to signed int
+  store double -8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %sd = fptosi double %d to i32
+  %matchesd = icmp eq i32 %sd, -8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToSIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting unsigned int to fp
+define void @testUIToFP() {
+entry:
+  ; unsigned int to float
+  %f = uitofp i32 7 to float
+  %matchesf = fcmp oeq float %f, 7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strUIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; unsigned int to double
+  %d = uitofp i32 7 to double
+  %matchesd = fcmp oeq double %d, 7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strUIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting signed int to fp
+define void @testSIToFP() {
+entry:
+  ; signed int to float
+  %f = sitofp i32 -7 to float
+  %matchesf = fcmp oeq float %f, -7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strSIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; signed int to double
+  %d = sitofp i32 -7 to double
+  %matchesd = fcmp oeq double %d, -7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strSIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp division
+define void @testFDiv() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float division
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = fdiv float %fN, %fD
+  %matchesf = fcmp oeq float %f, 5.500000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strDivFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double division
+  store double 2.200000e+01, double* %dN_addr
+  store double -4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = fdiv double %dN, %dD
+  %matchesd = fcmp oeq double %d, -5.500000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strDivDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp modulo
+define void @testFRem() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float modoulo
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = frem float %fN, %fD
+  %matchesf = fcmp oeq float %f, 2.000000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strRemFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double modulo
+  store double -2.200000e+01, double* %dN_addr
+  store double 4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = frem double %dN, %dD
+  %matchesd = fcmp oeq double %d, -2.000000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strRemDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test addition (fp and int since add is polymorphic)
+define void @testAdd() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer addition (3 + 4)
+  %sumi = add i32 3, 4
+  %matchesi = icmp eq i32 %sumi, 7
+  %err_msgi = getelementptr [16 x i8]* @.strAddInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float addition (3.5 + 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %sumf = add float %f1, %f2
+  %matchesf = fcmp oeq float %sumf, 0x401ECCCCC0000000
+  %err_msgf = getelementptr [18 x i8]* @.strAddFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double addition (3.5 + -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %sumd = add double %d1, %d2
+  %matchesd = fcmp oeq double %sumd, 0xBFE6666666666668
+  %err_msgd = getelementptr [19 x i8]* @.strAddDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test subtraction (fp and int since sub is polymorphic)
+define void @testSub() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer subtraction (3 - 4)
+  %subi = sub i32 3, 4
+  %matchesi = icmp eq i32 %subi, -1
+  %err_msgi = getelementptr [16 x i8]* @.strSubInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float subtraction (3.5 - 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %subf = sub float %f1, %f2
+  %matchesf = fcmp oeq float %subf, 0xBFE6666600000000
+  %err_msgf = getelementptr [18 x i8]* @.strSubFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double subtraction (3.5 - -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %subd = sub double %d1, %d2
+  %matchesd = fcmp oeq double %subd, 7.700000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strSubDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test multiplication (fp and int since mul is polymorphic)
+define void @testMul() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer multiplication (3 * 4)
+  %muli = mul i32 3, 4
+  %matchesi = icmp eq i32 %muli, 12
+  %err_msgi = getelementptr [16 x i8]* @.strMulInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float multiplication (3.5 * 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %mulf = mul float %f1, %f2
+  %matchesf = fcmp oeq float %mulf, 0x402D666640000000
+  %err_msgf = getelementptr [18 x i8]* @.strMulFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double multiplication (3.5 * -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %muld = mul double %d1, %d2
+  %matchesd = fcmp oeq double %muld, 0xC02D666666666667
+  %err_msgd = getelementptr [19 x i8]* @.strMulDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test float comparisons (ordered)
+define void @testFCmpFOrdered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true float %f1, %f2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false float %f1, %f2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [18 x i8]* @.strCmpOrdFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (ordered)
+define void @testFCmpDOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true double %d1, %d2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false double %d1, %d2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [19 x i8]* @.strCmpOrdDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (ordered)
+define void @testFCmpBothOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  call void @testFCmpDOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFOrdered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  ret void
+}
+
+; test float comparisons (unordered)
+define void @testFCmpFUnordered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [20 x i8]* @.strCmpUnoFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (unordered)
+define void @testFCmpDUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [21 x i8]* @.strCmpUnoDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::ueq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::uge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ugt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ule -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::ult -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::une -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (unordered)
+define void @testFCmpBothUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  call void @testFCmpDUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFUnordered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered)
+define void @testFCmpBoth(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord, i1 %uno) {
+entry:
+  call void @testFCmpBothOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+  call void @testFCmpBothUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered) with a variety of real numbers and NaNs as operands
+define void @testFCmp() {
+entry:
+  %x = alloca i64, align 8
+  %nan = alloca double, align 8
+
+  ; test FCmp on some real number inputs
+  call void @testFCmpBoth( double 0.000000e+00, double 0.000000e+00, i1 1, i1 1, i1 0, i1 1, i1 0, i1 0, i1 1, i1 0 )
+  call void @testFCmpBoth( double 0.000000e+00, double 1.000000e+00, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 0 )
+  call void @testFCmpBoth( double 1.000000e+00, double 0.000000e+00, i1 0, i1 1, i1 1, i1 0, i1 0, i1 1, i1 1, i1 0 )
+
+  ; build NaN
+  store i64 -1, i64* %x
+  %nan_as_i8 = bitcast double* %nan to i8*
+  %x_as_i8 = bitcast i64* %x to i8*
+  call void @llvm.memcpy.i32( i8* %nan_as_i8, i8* %x_as_i8, i32 8, i32 8 )
+
+  ; load two copies of our NaN
+  %nan1 = load double* %nan
+  %nan2 = load double* %nan
+
+  ; Warning: NaN comparisons with normal operators is BROKEN in LLVM JIT v2.0.  Fixed in v2.1.
+  ; NaNs do different things depending on ordered vs unordered
+;  call void @testFCmpBothOrdered( double %nan1, double 0.000000e+00, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothOrdered( double %nan1, double %nan2, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothUnordered( double %nan1, double 0.000000e+00, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+;  call void @testFCmpBothUnordered( double %nan1, double %nan2, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+
+  ret void
+}
+
+; tes all floating point instructions
+define i32 @main() {
+entry:
+  call void @testFPTrunc( )
+  call void @testFPExt( )
+  call void @testFPToUI( )
+  call void @testFPToSI( )
+  call void @testUIToFP( )
+  call void @testSIToFP( )
+
+  call void @testFDiv( )
+  call void @testFRem( )
+  call void @testAdd( )
+  call void @testSub( )
+  call void @testMul( )
+
+  call void @testFCmp( )
+
+  ; everything worked -- print a message saying so
+  %works_msg = getelementptr [20 x i8]* @.strWorks, i32 0, i32 0
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %works_msg )
+
+  ret i32 0
+}

Added: klee/trunk/test/Concrete/GlobalInitializers.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/GlobalInitializers.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/GlobalInitializers.ll (added)
+++ klee/trunk/test/Concrete/GlobalInitializers.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,47 @@
+; (cd .. && make) && ../llvm/Release/bin/llvm-as test.ll -o=- | ../Debug/bin/klee 
+
+declare void @print_i32(i32)
+
+%simple = type { i8, i16, i32, i64 }
+ at gInt = global i32 2
+ at gInts = global [2 x i32] [ i32 3, i32 5 ]
+ at gStruct = global %simple { i8 7, i16 11, i32 13, i64 17 }
+ at gZero = global %simple zeroinitializer
+
+define i32 @main() {
+entry:
+	%addr0 = getelementptr i32* @gInt, i32 0
+	%addr1 = getelementptr [2 x i32]* @gInts, i32 0, i32 0
+	%addr2 = getelementptr [2 x i32]* @gInts, i32 0, i32 1
+	%addr3 = getelementptr %simple* @gStruct, i32 0, i32 0
+	%addr4 = getelementptr %simple* @gStruct, i32 0, i32 1
+	%addr5 = getelementptr %simple* @gStruct, i32 0, i32 2
+	%addr6 = getelementptr %simple* @gStruct, i32 0, i32 3
+	%addr7 = getelementptr %simple* @gZero, i32 0, i32 2
+	%contents0 = load i32* %addr0
+	%contents1 = load i32* %addr1
+	%contents2 = load i32* %addr2
+	%contents3tmp = load i8* %addr3
+	%contents3 = zext i8 %contents3tmp to i32
+	%contents4tmp = load i16* %addr4
+	%contents4 = zext i16 %contents4tmp to i32
+	%contents5 = load i32* %addr5
+	%contents6tmp = load i64* %addr6
+	%contents6 = trunc i64 %contents6tmp to i32
+	%contents7 = load i32* %addr7
+	%tmp0 = mul i32 %contents0, %contents1
+	%tmp1 = mul i32 %tmp0, %contents2
+	%tmp2 = mul i32 %tmp1, %contents3
+	%tmp3 = mul i32 %tmp2, %contents4
+	%tmp4 = mul i32 %tmp3, %contents5
+	%tmp5 = mul i32 %tmp4, %contents6
+	%tmp6 = add i32 %tmp5, %contents7
+	%p = icmp eq i32 %tmp5, 510510
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Propchange: klee/trunk/test/Concrete/GlobalInitializers.ll

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/test/Concrete/GlobalVariable.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/GlobalVariable.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/GlobalVariable.ll (added)
+++ klee/trunk/test/Concrete/GlobalVariable.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,9 @@
+declare void @print_i32(i32)
+
+ at anInt = global i32 1
+ at aRef = global i32* @anInt
+
+define i32 @main() {
+        call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/ICmp.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/ICmp.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/ICmp.ll (added)
+++ klee/trunk/test/Concrete/ICmp.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,245 @@
+declare void @print_i32(i32)
+
+define i1 @checkSlt() {
+	%c0 = icmp slt i8 -1, 1		; 1
+	%c1 = icmp slt i8 0, 1		; 1
+	%c2 = icmp slt i8 1, 1		; 0
+	%c3 = icmp slt i8 1, -1		; 0
+	%c4 = icmp slt i8 1, 0		; 0
+	%c5 = icmp slt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 3	; 0bin000011
+	ret i1 %test
+}
+
+define i1 @checkSle() {
+	%c0 = icmp sle i8 -1, 1		; 1
+	%c1 = icmp sle i8 0, 1		; 1
+	%c2 = icmp sle i8 1, 1		; 1
+	%c3 = icmp sle i8 1, -1		; 0
+	%c4 = icmp sle i8 1, 0		; 0
+	%c5 = icmp sle i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 39	; 0bin100111
+	ret i1 %test
+}
+
+define i1 @checkSgt() {
+	%c0 = icmp sgt i8 -1, 1		; 0
+	%c1 = icmp sgt i8 0, 1		; 0
+	%c2 = icmp sgt i8 1, 1		; 0
+	%c3 = icmp sgt i8 1, -1		; 1
+	%c4 = icmp sgt i8 1, 0		; 1
+	%c5 = icmp sgt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 24	; 0bin011000
+	ret i1 %test
+}
+
+define i1 @checkSge() {
+	%c0 = icmp sge i8 -1, 1		; 0
+	%c1 = icmp sge i8 0, 1		; 0
+	%c2 = icmp sge i8 1, 1		; 1
+	%c3 = icmp sge i8 1, -1		; 1
+	%c4 = icmp sge i8 1, 0		; 1
+	%c5 = icmp sge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 60	; 0bin111100
+	ret i1 %test
+}
+
+define i1 @checkUlt() {
+	%c0 = icmp ult i8 -1, 1		; 0
+	%c1 = icmp ult i8 0, 1		; 1
+	%c2 = icmp ult i8 1, 1		; 0
+	%c3 = icmp ult i8 1, -1		; 1
+	%c4 = icmp ult i8 1, 0		; 0
+	%c5 = icmp ult i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 10	; 0bin001010
+	ret i1 %test
+}
+
+define i1 @checkUle() {
+	%c0 = icmp ule i8 -1, 1		; 0
+	%c1 = icmp ule i8 0, 1		; 1
+	%c2 = icmp ule i8 1, 1		; 1
+	%c3 = icmp ule i8 1, -1		; 1
+	%c4 = icmp ule i8 1, 0		; 0
+	%c5 = icmp ule i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 46	; 0bin101110
+	ret i1 %test
+}
+
+define i1 @checkUgt() {
+	%c0 = icmp ugt i8 -1, 1		; 1
+	%c1 = icmp ugt i8 0, 1		; 0
+	%c2 = icmp ugt i8 1, 1		; 0
+	%c3 = icmp ugt i8 1, -1		; 0
+	%c4 = icmp ugt i8 1, 0		; 1
+	%c5 = icmp ugt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 17	; 0bin010001
+	ret i1 %test
+}
+
+define i1 @checkUge() {
+	%c0 = icmp uge i8 -1, 1		; 1
+	%c1 = icmp uge i8 0, 1		; 0
+	%c2 = icmp uge i8 1, 1		; 1
+	%c3 = icmp uge i8 1, -1		; 0
+	%c4 = icmp uge i8 1, 0		; 1
+	%c5 = icmp uge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 53	; 0bin110101
+	ret i1 %test
+}
+
+define i1 @checkEq() {
+	%c0 = icmp eq i8 -1, 1		; 0
+	%c1 = icmp eq i8 1, 1		; 1
+	%c2 = icmp eq i8 1, -1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 2
+	ret i1 %test
+}
+
+define i1 @checkNe() {
+	%c0 = icmp ne i8 -1, 1		; 1
+	%c1 = icmp ne i8 1, 1		; 0
+	%c2 = icmp ne i8 1, -1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 5
+	ret i1 %test
+}
+
+define i32 @main() {
+	%c0 = call i1 @checkSlt ()
+	%c1 = call i1 @checkSle ()
+	%c2 = call i1 @checkSgt ()
+	%c3 = call i1 @checkSge ()
+	%c4 = call i1 @checkUlt ()
+	%c5 = call i1 @checkUle ()
+	%c6 = call i1 @checkUgt ()
+	%c7 = call i1 @checkUge ()
+	%c8 = call i1 @checkEq ()
+	%c9 = call i1 @checkNe ()
+	%a0 = select i1 %c0, i16 1, i16 0
+	%a1 = select i1 %c1, i16 2, i16 0
+	%a2 = select i1 %c2, i16 4, i16 0
+	%a3 = select i1 %c3, i16 8, i16 0
+	%a4 = select i1 %c4, i16 16, i16 0
+	%a5 = select i1 %c5, i16 32, i16 0
+	%a6 = select i1 %c6, i16 64, i16 0
+	%a7 = select i1 %c7, i16 128, i16 0
+	%a8 = select i1 %c8, i16 256, i16 0
+	%a9 = select i1 %c9, i16 512, i16 0
+	%sum0 = add i16 %a0, %a1
+	%sum1 = add i16 %sum0, %a2
+	%sum2 = add i16 %sum1, %a3
+	%sum3 = add i16 %sum2, %a4
+	%sum4 = add i16 %sum3, %a5
+	%sum5 = add i16 %sum4, %a6
+	%sum6 = add i16 %sum5, %a7
+	%sum7 = add i16 %sum6, %a8
+	%sum8 = add i16 %sum7, %a9
+	%t = shl i16 63, 10
+	%sum = add i16 %sum8, %t
+	%test = icmp eq i16 %sum, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/InvokeAndReturn.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/InvokeAndReturn.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/InvokeAndReturn.ll (added)
+++ klee/trunk/test/Concrete/InvokeAndReturn.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/InvokeAndUnwindOnce.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/InvokeAndUnwindOnce.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/InvokeAndUnwindOnce.ll (added)
+++ klee/trunk/test/Concrete/InvokeAndUnwindOnce.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	unwind
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/InvokeAndUnwindTwice.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/InvokeAndUnwindTwice.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/InvokeAndUnwindTwice.ll (added)
+++ klee/trunk/test/Concrete/InvokeAndUnwindTwice.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+declare void @print_i32(i32)
+
+define i8 @myadd(i8 %a, i8 %b) {
+	unwind
+}
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = call i8 @myadd(i8 %a, i8 %b)
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/Makefile (added)
+++ klee/trunk/test/Concrete/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,55 @@
+LEVEL = ../..
+
+# hard-coding bad. will get fixed.
+LCCFLAGS  += -O0 -Wall
+LCXXFLAGS += -O0 -Wall
+LLCFLAGS =
+
+test:
+	./ConcreteTest.py
+
+clean::
+	-rm -rf Output klee-last klee-out* test.log
+	-rm -rf *.bc
+
+# We do not want to make .d files for tests! 
+DISABLE_AUTO_DEPENDENCIES=1
+
+include ${LEVEL}/Makefile.common
+
+# Compile from X.c to Output/X.ll
+Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
+	$(LLVMGCCWITHPATH) --emit-llvm $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+
+# Compile from X.cpp to Output/X.ll
+Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# Compile from X.cc to Output/X.ll
+Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# LLVM Assemble from Output/X.ll to Output/X.bc.  Output/X.ll must have come
+# from GCC output, so use GCCAS.
+#
+Output/%.bc: Output/%.ll $(LLVMAS)
+	$(LLVMAS) -f $< -o $@
+
+# LLVM Assemble from X.ll to Output/X.bc.  Because we are coming directly from
+# LLVM source, use the non-transforming assembler.
+#
+Output/%.bc: %.ll $(LLVMAS) Output/.dir
+	$(LLVMAS) -f $< -o $@
+
+Output/linked_%.bc: Output/%.bc Output/_testingUtils.bc
+	$(LLVMLD) -disable-opt -link-as-library Output/_testingUtils.bc $< -o $@
+
+.PRECIOUS: Output/.dir
+
+## Cancel built-in implicit rules that override above rules
+%: %.s
+
+%: %.c
+
+%.o: %.c
+

Added: klee/trunk/test/Concrete/OneCall.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/OneCall.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/OneCall.ll (added)
+++ klee/trunk/test/Concrete/OneCall.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,12 @@
+declare void @print_i32(i32)
+
+define i32 @sum(i32 %a, i32 %b) {
+	%c = sub i32 %a, %b
+	ret i32 %c
+}
+
+define i32 @main() {
+	%a = call i32 @sum(i32 54, i32 2)
+	call void @print_i32(i32 %a)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/OverlappingPhiNodes.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/OverlappingPhiNodes.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/OverlappingPhiNodes.ll (added)
+++ klee/trunk/test/Concrete/OverlappingPhiNodes.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [20, %entry], [%a, %test]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/Select.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/Select.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/Select.ll (added)
+++ klee/trunk/test/Concrete/Select.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%ten = select i1 true, i32 10, i32 0
+	%five = select i1 false, i32 0, i32 5
+	%check = add i32 %ten, %five
+	%test = icmp eq i32 %check, 15
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/Shifts.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/Shifts.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/Shifts.ll (added)
+++ klee/trunk/test/Concrete/Shifts.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,21 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%amt = add i8 2, 5
+	%a = shl i8 1, 5
+	%b = lshr i8 %a, 5
+	%c = shl i8 %b, %amt
+	%d = lshr i8 %c, %amt
+	%e = shl i8 %d, 7
+	%f = ashr i8 %e, 7
+	%g = shl i8 %f, %amt
+	%h = ashr i8 %g, %amt
+	%test = icmp eq i8 %h, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/SimpleStoreAndLoad.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/SimpleStoreAndLoad.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/SimpleStoreAndLoad.ll (added)
+++ klee/trunk/test/Concrete/SimpleStoreAndLoad.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,17 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = alloca i32, i32 4
+	%tmp1 = getelementptr i32* %a, i32 0
+	store i32 0, i32* %tmp1
+	%tmp2 = load i32* %tmp1
+	%tmp3 = icmp eq i32 %tmp2, 0
+	br i1 %tmp3, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/UnconditionalBranch.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/UnconditionalBranch.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/UnconditionalBranch.ll (added)
+++ klee/trunk/test/Concrete/UnconditionalBranch.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+exit:
+	call void @print_i32(i32 %a)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/UnconditionalBranchWithSimplePhi.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/UnconditionalBranchWithSimplePhi.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/UnconditionalBranchWithSimplePhi.ll (added)
+++ klee/trunk/test/Concrete/UnconditionalBranchWithSimplePhi.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+unused:
+	%b = add i32 1, 2
+	br label %exit
+exit:
+	%c = phi i32 [%a, %entry], [%b, %unused]
+	call void @print_i32(i32 %c)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/UnorderedPhiNodes.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/UnorderedPhiNodes.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/UnorderedPhiNodes.ll (added)
+++ klee/trunk/test/Concrete/UnorderedPhiNodes.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [%a, %test], [20, %entry]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}

Added: klee/trunk/test/Concrete/_testingUtils.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/_testingUtils.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/_testingUtils.c (added)
+++ klee/trunk/test/Concrete/_testingUtils.c Wed May 20 23:36:41 2009
@@ -0,0 +1,32 @@
+int putchar(int x);
+
+void print_int(unsigned long long val);
+
+#define TYPED_PRINT(_name_type, _arg_type)  \
+    void print_ ## _name_type(_arg_type val) { print_int(val); }
+ 
+TYPED_PRINT(i1, unsigned char)
+TYPED_PRINT(i8, unsigned char)
+TYPED_PRINT(i16, unsigned short)
+TYPED_PRINT(i32, unsigned int)
+TYPED_PRINT(i64, unsigned long long)
+
+void print_int(unsigned long long val) {
+    int cur = 1;
+
+    // effectively do a log (can't call log because it returns floats)
+    // do the nasty divide to prevent overflow
+    while (cur <= val / 10)
+        cur *= 10;
+
+    while (cur) {
+        int digit = val / cur;
+
+        putchar(digit + '0');
+        
+        val = val % cur;
+        cur /= 10;
+    }
+    
+    putchar('\n');
+}

Added: klee/trunk/test/Concrete/ackermann.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/ackermann.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/ackermann.c (added)
+++ klee/trunk/test/Concrete/ackermann.c Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+// llvm-gcc -O2 --emit-llvm -c ackermann.c && ../../Debug/bin/klee ackermann.o 2 2
+
+#include <stdio.h>
+
+int ackermann(int m, int n) {
+   if (m == 0)
+     return n+1;
+   else
+     return ackermann(m-1, (n==0) ? 1 : ackermann(m, n-1));
+ }
+
+int main() {
+  printf("ackerman(%d, %d) = %d\n", 2, 2, ackermann(2, 2));
+
+  return 0;
+}

Added: klee/trunk/test/Concrete/arith_test.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Concrete/arith_test.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Concrete/arith_test.ll (added)
+++ klee/trunk/test/Concrete/arith_test.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,76 @@
+define void @"test_simple_arith"(i16 %i0, i16 %j0)
+begin
+  %t1 = add i16 %i0, %j0
+  %t2 = sub i16 %i0, %j0
+  %t3 = mul i16 %t1, %t2
+
+  call void @print_i16(i16 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"(i16 %op1, i16 %op2)
+begin
+  %t1 = udiv i16 %op1, %op2
+  %t2 = urem i16 %op1, %op2  
+  %t3 = sdiv i16 %op1, %op2  
+  %t4 = srem i16 %op1, %op2  
+
+  call void @print_i16(i16 %t1)
+  call void @print_i16(i16 %t2)
+  call void @print_i16(i16 %t3)
+  call void @print_i16(i16 %t4)
+
+  ret void     
+end
+        
+define void @test_cmp(i16 %op1, i16 %op2)
+begin
+  %t1 = icmp ule i16 %op1, %op2
+  %t2 = icmp ult i16 %op1, %op2  
+  %t3 = icmp uge i16 %op1, %op2  
+  %t4 = icmp ugt i16 %op1, %op2  
+  %t6 = icmp slt i16 %op1, %op2  
+  %t5 = icmp sle i16 %op1, %op2
+  %t7 = icmp sge i16 %op1, %op2  
+  %t8 = icmp sgt i16 %op1, %op2  
+  %t9 = icmp eq i16 %op1, %op2  
+  %t10 = icmp ne i16 %op1, %op2  
+
+  call void @print_i1(i1 %t1)
+  call void @print_i1(i1 %t2)
+  call void @print_i1(i1 %t3)
+  call void @print_i1(i1 %t4)
+  call void @print_i1(i1 %t5)
+  call void @print_i1(i1 %t6)
+  call void @print_i1(i1 %t7)
+  call void @print_i1(i1 %t8)
+  call void @print_i1(i1 %t9)
+  call void @print_i1(i1 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith(i16 111, i16 100)
+
+    call void @test_div_and_mod(i16 63331, i16 3123)
+    call void @test_div_and_mod(i16 1000, i16 55444)
+    call void @test_div_and_mod(i16 49012, i16 55444)
+    call void @test_div_and_mod(i16 1000, i16 25)
+
+    call void @test_cmp(i16 63331, i16 3123)
+    call void @test_cmp(i16 1000, i16 55444)
+    call void @test_cmp(i16 49012, i16 55444)
+    call void @test_cmp(i16 1000, i16 25)
+        
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i1)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)

Added: klee/trunk/test/Coverage/ReadArgs.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Coverage/ReadArgs.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Coverage/ReadArgs.c (added)
+++ klee/trunk/test/Coverage/ReadArgs.c Wed May 20 23:36:41 2009
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -rf xxx
+// RUN: echo " --output-dir=xxx " > %t1.args
+// RUN: %klee --read-args %t1.args %t1.bc
+// RUN: test -d xxx
+
+int main() {
+  return 0;
+}

Added: klee/trunk/test/Coverage/ReplayOutDir.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Coverage/ReplayOutDir.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Coverage/ReplayOutDir.c (added)
+++ klee/trunk/test/Coverage/ReplayOutDir.c Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -rf %t1.out %t1.replay
+// RUN: %klee --output-dir=%t1.out %t1.bc
+// RUN: %klee --output-dir=%t1.replay --replay-out-dir=%t1.out %t1.bc
+
+int main() {
+  int i;
+  klee_make_symbolic(&i, sizeof i);
+  klee_print_range("i", i);
+  return 0;
+}

Added: klee/trunk/test/Coverage/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Coverage/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Coverage/dg.exp (added)
+++ klee/trunk/test/Coverage/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/test/Dogfood/ImmutableSet.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Dogfood/ImmutableSet.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Dogfood/ImmutableSet.cpp (added)
+++ klee/trunk/test/Dogfood/ImmutableSet.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,134 @@
+// RUN: llvm-g++ -I../../../include -g -DMAX_ELEMENTS=4 -fno-exceptions --emit-llvm -c -o %t1.bc %s
+// RUN: %klee --libc=klee --max-forks=200 --no-output --exit-on-error --optimize --disable-inlining --use-non-uniform-random-search --use-cex-cache %t1.bc
+
+#include "klee/klee.h"
+#include "klee/Internal/ADT/ImmutableSet.h"
+
+using namespace klee;
+
+typedef ImmutableSet<unsigned> T;
+
+bool iff(bool a, bool b) {
+  return !!a == !!b;
+}
+
+template<typename InputIterator, typename T>
+bool contains(InputIterator begin, InputIterator end, T item) {
+  for (; begin!=end; ++begin)
+    if (*begin == item)
+      return true;
+  return false;
+}
+
+bool equal(T &a, T &b) {
+  T::iterator aIt=a.begin(), ae=a.end(), bIt=b.begin(), be=b.end();
+  for (; aIt!=ae && bIt!=be; ++aIt, ++bIt)
+    if (*aIt != *bIt)
+      return false;
+  if (aIt!=ae) return false;
+  if (bIt!=be) return false;
+  return true;
+}
+
+template<typename InputIterator, typename T>
+void remove(InputIterator begin, InputIterator end, T item) {
+  InputIterator out = begin;
+  for (; begin!=end; ++begin) {
+    if (*begin!=item) {
+      if (out!=begin)
+        *out = *begin;
+      ++out;
+    }
+  }
+}
+
+void check_set(T &set, unsigned num, unsigned *values) {
+  assert(set.size() == num);
+
+  // must contain only values
+  unsigned item = klee_range(0, 256, "range");
+  assert(iff(contains(values, values+num, item),
+             set.count(item)));
+
+  // each value must be findable, must be its own lower bound, and
+  // must be one behind its upper bound
+  for (unsigned i=0; i<num; i++) {
+    unsigned item = values[i];
+    assert(set.count(item));
+    T::iterator it = set.find(item);
+    T::iterator lb = set.lower_bound(item);
+    T::iterator ub = set.upper_bound(item);
+    assert(it != set.end());                // must exit
+    assert(*it == item);                    // must be itself
+    assert(lb == it);                       // must be own lower bound
+    assert(--ub == it);                     // must be one behind upper
+  }
+
+  // for items not in the set...
+  unsigned item2 = klee_range(0, 256, "range");
+  if (!set.count(item2)) {
+    assert(set.find(item2) == set.end());
+
+    T::iterator lb = set.lower_bound(item2);
+    for (T::iterator it=set.begin(); it!=lb; ++it)      
+      assert(*it < item2);
+    for (T::iterator it=lb, ie=set.end(); it!=ie; ++it)
+      assert(*it >= item2);
+
+    T::iterator ub = set.upper_bound(item2);
+    for (T::iterator it=set.begin(); it!=ub; ++it)
+      assert(*it <= item2);
+    for (T::iterator it=ub, ie=set.end(); it!=ie; ++it)
+      assert(*it > item2);
+  }
+}
+
+#ifndef MAX_ELEMENTS
+#define MAX_ELEMENTS 4
+#endif
+
+void test() {
+  unsigned num=0, values[MAX_ELEMENTS];
+  T set;
+
+  assert(MAX_ELEMENTS >= 0);
+  for (unsigned i=0; i<klee_range(0,MAX_ELEMENTS+1, "range"); i++) {
+    unsigned item = klee_range(0, 256, "range");
+    if (contains(values, values+num, item))
+      klee_silent_exit(0);
+
+    set = set.insert(item);
+    values[num++] = item;
+  }
+  
+  check_set(set, num, values);
+
+  unsigned item = klee_range(0, 256, "range");  
+  if (contains(values, values+num, item)) { // in tree
+    // insertion is invariant
+    T set2 = set.insert(item);
+    assert(equal(set2, set));
+
+    // check remove
+    T set3 = set.remove(item);
+    assert(!equal(set3, set)); // mostly just for coverage
+    assert(set3.size() + 1 == set.size());
+    assert(!set3.count(item));
+  } else { // not in tree
+    // removal is invariant
+    T set2 = set.remove(item);
+    assert(equal(set2, set));
+
+    // check insert
+    T set3 = set.insert(item);
+    assert(!equal(set3, set)); // mostly just for coverage
+    assert(set3.size() == set.size() + 1);
+    assert(set3.count(item));
+  }
+}
+
+int main(int argc, char **argv) {
+  test();
+  assert(T::getAllocated() == 0);
+  return 0;
+}

Added: klee/trunk/test/Dogfood/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Dogfood/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Dogfood/dg.exp (added)
+++ klee/trunk/test/Dogfood/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/test/Expr/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Expr/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Expr/dg.exp (added)
+++ klee/trunk/test/Expr/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/test/Feature/Alias.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/Alias.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/Alias.c (added)
+++ klee/trunk/test/Feature/Alias.c Wed May 20 23:36:41 2009
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+// Darwin does not have strong aliases.
+// XFAIL: darwin
+
+#include <assert.h>
+
+// alias for global
+int b = 52;
+extern int a __attribute__((alias("b")));
+
+// alias for function
+int __foo() { return 52; }
+extern int foo() __attribute__((alias("__foo")));
+
+int *c = &a;
+
+int main() { 
+  assert(a == 52);
+  assert(foo() == 52);
+  assert(*c == 52);
+  
+  return 0;
+}

Added: klee/trunk/test/Feature/AliasFunction.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/AliasFunction.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/AliasFunction.c (added)
+++ klee/trunk/test/Feature/AliasFunction.c Wed May 20 23:36:41 2009
@@ -0,0 +1,33 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c foo %t1.log | grep 5
+// RUN: grep -c bar %t1.log | grep 3
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void foo() { printf("  foo()\n"); }
+void bar() { printf("  bar()\n"); }
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  // no aliases
+  foo();
+
+  if (x > 10)
+  {
+    // foo -> bar
+    klee_alias_function("foo", "bar");    
+
+    if (x > 20)
+      foo();
+  }
+  
+  foo();
+
+  // undo
+  klee_alias_function("foo", "foo");
+  foo();
+}

Added: klee/trunk/test/Feature/AliasFunctionExit.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/AliasFunctionExit.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/AliasFunctionExit.c (added)
+++ klee/trunk/test/Feature/AliasFunctionExit.c Wed May 20 23:36:41 2009
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c START %t1.log | grep 1
+// RUN: grep -c END %t1.log | grep 2
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void start(int x) {
+  printf("START\n");
+  if (x == 53)
+    exit(1);
+}
+
+void end(int status) {
+  klee_alias_function("exit", "exit");
+  printf("END: status = %d\n", status);
+  exit(status);
+}
+
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  klee_alias_function("exit", "end");
+  start(x);
+  end(0);
+}

Added: klee/trunk/test/Feature/AsmAddresses.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/AsmAddresses.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/AsmAddresses.c (added)
+++ klee/trunk/test/Feature/AsmAddresses.c Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc -g -c -o %t.bc %s
+// RUN: %klee --exit-on-error --use-asm-addresses %t.bc
+// RUN: %llvmgcc -DOVERLAP -g -c -o %t.bc %s
+// RUN: not %klee --exit-on-error --use-asm-addresses %t.bc
+
+#include <assert.h>
+
+
+volatile unsigned char x0 __asm ("0x0021");
+volatile unsigned char whee __asm ("0x0WHEE");
+
+#ifdef OVERLAP
+volatile unsigned int y0 __asm ("0x0030");
+volatile unsigned int y1 __asm ("0x0032");
+#endif
+
+int main() {
+  assert(&x0 == (void*) 0x0021);
+  assert(&whee != (void*) 0x0);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/ByteSwap.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ByteSwap.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ByteSwap.c (added)
+++ klee/trunk/test/Feature/ByteSwap.c Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --exit-on-error %t1.bc
+
+#include <arpa/inet.h>
+#include <assert.h>
+
+int main() {
+  
+  uint32_t n = 0;
+  klee_make_symbolic(&n, sizeof(n));
+  
+  uint32_t h = ntohl(n);
+  assert(htonl(h) == n);
+  
+  return 0;
+}

Added: klee/trunk/test/Feature/CallToUndefinedExternal.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/CallToUndefinedExternal.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/CallToUndefinedExternal.cpp (added)
+++ klee/trunk/test/Feature/CallToUndefinedExternal.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.external.err
+
+extern "C" void poof(void);
+
+int main() {
+  poof();
+
+  return 0;
+}

Added: klee/trunk/test/Feature/CheckForImpliedValue.c.failing
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/CheckForImpliedValue.c.failing?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/CheckForImpliedValue.c.failing (added)
+++ klee/trunk/test/Feature/CheckForImpliedValue.c.failing Wed May 20 23:36:41 2009
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -f %t1.log
+// RUN: %klee --log-file %t1.log --debug-check-for-implied-values %t1.bc
+// RUN: grep "= 0 (ok)" %t1.log
+// RUN: grep "= 2 (missed)" %t1.log
+
+#define swap(x) (((x)>>16) | (((x)&0xFFFF)<<16))
+int main() {
+  unsigned x, y;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (!x) { // should give x = 0 hit by ivc
+    printf("ok\n");
+  } else {
+    if (swap(y) == 0x00020000) { // should give y = 2 missed by ivc
+      printf("ok\n");
+    }
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/CheckMemoryAccess.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/CheckMemoryAccess.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/CheckMemoryAccess.c (added)
+++ klee/trunk/test/Feature/CheckMemoryAccess.c Wed May 20 23:36:41 2009
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: grep -q "good" %t.log
+// RUN: not grep -q "bad" %t.log
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_check_memory_access(&buf, 1);
+  printf("good\n");
+  if (klee_range(0, 2, "range1")) {
+    klee_check_memory_access(0, 1);
+    printf("null pointer deref: bad\n");
+  }
+
+  if (klee_range(0, 2, "range2")) {
+    klee_check_memory_access(buf, 5);
+    printf("oversize access: bad\n");
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/CopyOnWrite.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/CopyOnWrite.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/CopyOnWrite.c (added)
+++ klee/trunk/test/Feature/CopyOnWrite.c Wed May 20 23:36:41 2009
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+#define N 5
+
+unsigned branches = 0;
+
+void explode(int *ap, int i, int *result) {
+  if (i<N) {
+    (*result)++;
+    if (ap[i]) // just cause a fork
+      branches++; 
+    return explode(ap, i+1, result);
+  }
+}
+
+int main() {
+  int result = 0;
+  int a[N];
+  klee_make_symbolic(a, sizeof a);
+  explode(a,0,&result);
+  assert(result==N);
+  return 0;
+}

Added: klee/trunk/test/Feature/DanglingConcreteReadExpr.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/DanglingConcreteReadExpr.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/DanglingConcreteReadExpr.c (added)
+++ klee/trunk/test/Feature/DanglingConcreteReadExpr.c Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: grep "total queries = 2" klee-last/info
+
+#include <assert.h>
+
+int main() {
+  unsigned char x, y;
+
+  klee_make_symbolic(&x, sizeof x);
+  
+  y = x;
+
+  // should be exactly two queries (prove x is/is not 10)
+  // eventually should be 0 when we have fast solver
+  if (x==10) {
+    assert(y==10);
+  }
+
+  klee_silent_exit(0);
+  return 0;
+}

Added: klee/trunk/test/Feature/DefineFixedObject.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/DefineFixedObject.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/DefineFixedObject.c (added)
+++ klee/trunk/test/Feature/DefineFixedObject.c Wed May 20 23:36:41 2009
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+
+#define ADDRESS ((int*) 0x0080)
+
+int main() {
+  klee_define_fixed_object(ADDRESS, 4);
+  
+  int *p = ADDRESS;
+
+  *p = 10;
+  printf("*p: %d\n", *p);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/DoubleFree.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/DoubleFree.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/DoubleFree.c (added)
+++ klee/trunk/test/Feature/DoubleFree.c Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  free(x);
+  return 0;
+}

Added: klee/trunk/test/Feature/DumpStatesOnHalt.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/DumpStatesOnHalt.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/DumpStatesOnHalt.c (added)
+++ klee/trunk/test/Feature/DumpStatesOnHalt.c Wed May 20 23:36:41 2009
@@ -0,0 +1,8 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --stop-after-n-instructions=1 --dump-states-on-halt=true %t1.bc
+// RUN: test -f klee-last/test000001.bout
+
+int main() {
+  int x = 10;
+  return x;
+}

Added: klee/trunk/test/Feature/Envp.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/Envp.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/Envp.c (added)
+++ klee/trunk/test/Feature/Envp.c Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main(int argc, char **argv, char **envp) {
+  unsigned i;
+  assert(argv[argc] == 0);
+  printf("argc: %d, argv: %p, envp: %p\n", argc, argv, envp);
+  printf("--environ--\n");
+  int haspwd = 0;
+  for (i=0; envp[i]; i++) {
+    printf("%d: %s\n", i, envp[i]);
+    haspwd |= strncmp(envp[i], "PWD=", 4)==0;
+  }
+  assert(haspwd);
+  return 0;
+}

Added: klee/trunk/test/Feature/ExprLogging.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ExprLogging.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ExprLogging.c (added)
+++ klee/trunk/test/Feature/ExprLogging.c Wed May 20 23:36:41 2009
@@ -0,0 +1,43 @@
+// RUN: %llvmgcc %s -emit-llvm -g -O0 -c -o %t1.bc
+// RUN: %klee --use-query-pc-log --write-pcs --write-cvcs %t1.bc 2> %t2.log
+// RUN: %kleaver -print-ast klee-last/test000001.pc
+
+// FIXME: Ideally we would verify a roundtrip that we parsed the pc
+// file and can dump it back out as the same file.
+
+#include <assert.h>
+
+int constantArr[16 ] = {
+  1 <<  0, 1 <<  1, 1 <<  2, 1 <<  3,
+  1 <<  4, 1 <<  5, 1 <<  6, 1 <<  7,
+  1 <<  8, 1 <<  9, 1 << 10, 1 << 11,
+  1 << 12, 1 << 13, 1 << 14, 1 << 15
+};
+
+
+int main() {
+  char buf[4];
+  klee_make_symbolic(buf, sizeof buf);
+
+  buf[1] = 'a';
+
+  constantArr[klee_range(0, 16, "idx.0")] = buf[0];
+
+  // Use this to trigger an interior update list usage.
+  int y = constantArr[klee_range(0, 16, "idx.1")];  
+
+  constantArr[klee_range(0, 16, "idx.2")] = buf[3];
+  
+  buf[klee_range(0, 4, "idx.3")] = 0;
+  klee_assume(buf[0] == 'h');
+  
+  int x = *((int*) buf);
+  klee_assume(x > 2);
+  klee_assume(x == constantArr[12]);
+
+  klee_assume(y != (1 << 5));
+
+  assert(0);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/ExternalWeakLinkage.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ExternalWeakLinkage.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ExternalWeakLinkage.c (added)
+++ klee/trunk/test/Feature/ExternalWeakLinkage.c Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+void __attribute__((weak)) IAmSoWeak(int);
+
+int main() {
+  assert(IAmSoWeak==0);
+  return 0;
+}

Added: klee/trunk/test/Feature/FunctionPointer.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/FunctionPointer.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/FunctionPointer.c (added)
+++ klee/trunk/test/Feature/FunctionPointer.c Wed May 20 23:36:41 2009
@@ -0,0 +1,36 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error %t1.bc
+
+#include <stdio.h>
+
+void foo(const char *msg) { printf("foo: %s\n", msg); }
+void baz(const char *msg) { printf("baz: %s\n", msg); }
+
+void (*xx)(const char *) = foo;
+
+void bar(void (*fp)(const char *)) { fp("called via bar"); }
+
+int main(int argc, char **argv) {
+  void (*fp)(const char *) = foo;
+
+  printf("going to call through fp\n");
+  fp("called via fp");
+
+  printf("calling via pass through\n");
+  bar(foo);
+        
+  fp = baz;
+  fp("called via fp");
+
+  xx("called via xx");
+
+#if 0
+  klee_make_symbolic(&fp, sizeof fp);
+  if(fp == baz) {
+    printf("fp = %p, baz = %p\n", fp, baz);
+    fp("calling via symbolic!");
+  }
+#endif
+
+  return 0;
+}

Added: klee/trunk/test/Feature/GetValue.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/GetValue.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/GetValue.c (added)
+++ klee/trunk/test/Feature/GetValue.c Wed May 20 23:36:41 2009
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+#include <assert.h>
+
+int main() {
+  int x = klee_int("x");
+  klee_assume(x > 10);
+  klee_assume(x < 20);
+
+  assert(!klee_is_symbolic(klee_get_value(x)));
+  assert(klee_get_value(x) > 10);
+  assert(klee_get_value(x) < 20);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/ImpliedValue.c.failing
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ImpliedValue.c.failing?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ImpliedValue.c.failing (added)
+++ klee/trunk/test/Feature/ImpliedValue.c.failing Wed May 20 23:36:41 2009
@@ -0,0 +1,147 @@
+// RUN: rm -f %t4.out %t4.err %t4.log
+// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc
+// RUN: llvm-as -f ../_utils._ll -o %t2.bc
+// RUN: llvm-ld -disable-opt -link-as-library %t1.bc %t2.bc -o %t3.bc
+// RUN: %klee --log-file %t4.log --debug-check-for-implied-values %t3.bc > %t4.out 2> %t4.err
+// RUN: ls klee-last | not grep .err
+// RUN: not grep "(missed)" %t4.log
+
+#include <assert.h>
+
+#include "utils.h"
+
+int main() {
+  unsigned char which;
+  volatile unsigned char a,b,c,d,e,f,g,h;
+
+  klee_make_symbolic(&which, sizeof which);
+  klee_make_symbolic(&a, sizeof a);
+  klee_make_symbolic(&b, sizeof b);
+  klee_make_symbolic(&c, sizeof c);
+  klee_make_symbolic(&d, sizeof d);
+  klee_make_symbolic(&e, sizeof e);
+  klee_make_symbolic(&f, sizeof f);
+  klee_make_symbolic(&g, sizeof g);
+  klee_make_symbolic(&h, sizeof h);
+
+  switch (which) {
+// RUN: grep "simple read(2) = value case" %t4.out
+  case 0:
+    if (a == 2) {
+      assert(!klee_is_symbolic(a));
+      printf("simple read(%d) = value case\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (false)" %t4.out
+  case 1:
+    if (util_make_select(a, 12, 14) == 14) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (false)\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (true)" %t4.out
+  case 2:
+    if (util_make_select(!a, 12, 14) == 12) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (true)\n", a);
+    }
+    break;
+
+// RUN: grep "concat2(0xBE,0xEF) = value case" %t4.out
+  case 3:
+    if (util_make_concat2(a,b) == 0xBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      printf("concat2(0x%X,0x%X) = value case\n",
+             a, b);
+    }
+    break;
+
+// RUN: grep "concat4(0xDE,0xAD,0xBE,0xEF) = value case" %t4.out
+  case 4:
+    if (util_make_concat4(a,b,c,d) == 0xDEADBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      printf("concat4(0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d);
+    }
+    break;
+
+// RUN: grep "concat8(0xDE,0xAD,0xBE,0xEF,0xAB,0xCD,0xAB,0xCD) = value case" %t4.out
+  case 5:
+    if (util_make_concat8(a,b,c,d,e,f,g,h) == 0xDEADBEEFABCDABCDLL) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      assert(!klee_is_symbolic(e));
+      assert(!klee_is_symbolic(f));
+      assert(!klee_is_symbolic(g));
+      assert(!klee_is_symbolic(h));
+      printf("concat8(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d, e, f, g, h);
+    }
+    break;
+
+// RUN: grep "and(0,0) = true case" %t4.out
+  case 6:
+    if (util_make_and_i1(!a, !b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("and(%d,%d) = true case\n", a, b);
+    }
+    break;
+
+// RUN: grep "or(0,0) = false case" %t4.out
+  case 7:
+    if (!util_make_or_i1(a, b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("or(%d,%d) = false case\n", a, b);
+    }
+    break;
+
+    // we use concat to prevent folding, will need to fix if that gets
+    // partial evaluated
+// RUN: grep "add constant case: 0xDE" %t4.out
+  case 8:
+    if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("add constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sub constant case: 0x60" %t4.out
+  case 9:
+    if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("sub constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "xor constant case: 0xA0" %t4.out
+  case 10:
+    if (util_make_concat2(0x0B ^ a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("xor constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sext constant case: 244" %t4.out
+  case 11:
+    if (! util_make_or_i1(((short) (signed char) a) + 12,b)) {
+      assert(!klee_is_symbolic(a));
+      printf("sext constant case: %d\n", a);
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/InAndOutOfBounds.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/InAndOutOfBounds.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/InAndOutOfBounds.c (added)
+++ klee/trunk/test/Feature/InAndOutOfBounds.c Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err -o -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000001.ptr.err -o ! -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000003.bout
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int main() {
+  int *x = malloc(4);
+  x[klee_urange(0,2)] = 1;
+  free(x);
+  return 0;
+}

Added: klee/trunk/test/Feature/IndirectCallToBuiltin.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/IndirectCallToBuiltin.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/IndirectCallToBuiltin.c (added)
+++ klee/trunk/test/Feature/IndirectCallToBuiltin.c Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  void *(*allocator)(size_t) = malloc;
+  int *mem = allocator(10);
+
+  printf("mem: %p\n", mem);
+  printf("mem[0]: %d\n", mem[0]);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/IndirectCallToExternal.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/IndirectCallToExternal.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/IndirectCallToExternal.c (added)
+++ klee/trunk/test/Feature/IndirectCallToExternal.c Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+int main() {
+  int (*scmp)(char*,char*) = strcmp;
+
+  assert(scmp("hello","hi") < 0);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/InvalidBitfieldAccess.c.failing
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/InvalidBitfieldAccess.c.failing?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/InvalidBitfieldAccess.c.failing (added)
+++ klee/trunk/test/Feature/InvalidBitfieldAccess.c.failing Wed May 20 23:36:41 2009
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+// This is a bug in llvm-gcc4.0 but seems to be fixed in llvm-gcc4.2,
+// its included here mostly as a reminder. 
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct foo {
+  unsigned int a : 5;
+  unsigned int b : 10;
+  unsigned int c : 1;
+} __attribute__((packed));
+
+int main() {
+  struct foo *a = malloc(sizeof *a);
+
+  a->b = 12; // problem here is that llvm-gcc emits a 4 byte access
+             // which is out of bounds.
+
+  int x = a->b;
+
+  assert(x == 12);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/IsSymbolic.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/IsSymbolic.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/IsSymbolic.c (added)
+++ klee/trunk/test/Feature/IsSymbolic.c Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int x, y, z = 0;
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+  if (x) {
+    assert(klee_is_symbolic(y));
+  } else {
+    assert(!klee_is_symbolic(z));
+  }
+  return 0;
+}

Added: klee/trunk/test/Feature/KleeReportError.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/KleeReportError.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/KleeReportError.c (added)
+++ klee/trunk/test/Feature/KleeReportError.c Wed May 20 23:36:41 2009
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --emit-all-errors %t2.bc > %t3.log
+// RUN: ls klee-last/ | grep .my.err | wc -l | grep 2
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  int x, y, *p = 0;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (x)
+    fprintf(stderr, "x\n");
+  else fprintf(stderr, "!x\n");
+
+  if (y) {
+    fprintf(stderr, "My error\n");
+    klee_report_error(__FILE__, __LINE__, "My error", "my.err");
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/LongDoubleSupport.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/LongDoubleSupport.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/LongDoubleSupport.c (added)
+++ klee/trunk/test/Feature/LongDoubleSupport.c Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc > %t2.out
+
+#include <stdio.h>
+#include <float.h>
+
+// FIXME: This doesn't really work at all, it just doesn't
+// crash. Until we have wide constant support, that is all we care
+// about; the only reason this comes up is in initialization of
+// constants, we don't actually end up seeing much code which uses long
+// double.
+int main() {
+  long double a = LDBL_MAX;
+  long double b = -1;
+  long double c = a + b;
+  printf("a = %Lg\n", a);
+  printf("b = %Lg\n", b);
+  printf("c = %Lg\n", c);
+  return 0;
+}

Added: klee/trunk/test/Feature/LowerSwitch.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/LowerSwitch.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/LowerSwitch.c (added)
+++ klee/trunk/test/Feature/LowerSwitch.c Wed May 20 23:36:41 2009
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t.bc
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=internal %t.bc
+// RUN: not test -f klee-last/test000010.bout
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=simple %t.bc
+// RUN: test -f klee-last/test000010.bout
+
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int c = klee_range(0, 256, "range");
+  
+  switch(c) {
+  case 0: printf("0\n"); break;
+  case 10: printf("10\n"); break;
+  case 16: printf("16\n"); break;
+  case 17: printf("17\n"); break;
+  case 18: printf("18\n"); break;
+  case 19: printf("19\n"); break;
+#define C(x) case x: case x+1: case x+2: case x+3
+#define C2(x) C(x): C(x+4): C(x+8): C(x+12)
+#define C3(x) C2(x): C2(x+16): C2(x+32): C2(x+48)
+  C3(128):
+    printf("bignums: %d\n", c); break;
+  default: 
+    printf("default\n");
+    break;
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/MakeConcreteSymbolic.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MakeConcreteSymbolic.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MakeConcreteSymbolic.c (added)
+++ klee/trunk/test/Feature/MakeConcreteSymbolic.c Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 0" klee-last/info
+// RUN: %klee --make-concrete-symbolic=1 --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 2" klee-last/info
+
+
+#include <assert.h>
+
+#define N 2
+int main() {
+  int i;
+  char a;
+  
+  a = 10;
+  assert(a == 10);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/MakeSymbolicName.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MakeSymbolicName.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MakeSymbolicName.c (added)
+++ klee/trunk/test/Feature/MakeSymbolicName.c Wed May 20 23:36:41 2009
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int a[4] = {1, 2, 3, 4};
+  unsigned i;
+
+  klee_make_symbolic_name(&i, sizeof(i), "index");  
+  if (i > 3)
+    klee_silent_exit(0);
+
+  assert(a[i] << 1 != 5);
+  if (a[i] << 1 == 6)
+    assert(i == 2);
+}

Added: klee/trunk/test/Feature/MemoryLimit.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MemoryLimit.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MemoryLimit.c (added)
+++ klee/trunk/test/Feature/MemoryLimit.c Wed May 20 23:36:41 2009
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc -DLITTLE_ALLOC -g -c %s -o %t.little.bc
+// RUN: %llvmgcc -g -c %s -o %t.big.bc
+// RUN: %klee --max-memory=20 %t.little.bc > %t.little.log
+// RUN: %klee --max-memory=20 %t.big.bc > %t.big.log
+// RUN: not grep -q "DONE" %t.little.log
+// RUN: not grep -q "DONE" %t.big.log
+
+#include <stdlib.h>
+
+int main() {
+  int i, j, x=0;
+  
+#ifdef LITTLE_ALLOC
+  printf("IN LITTLE ALLOC\n");
+    
+  // 200 MBs total (in 32 byte chunks)
+  for (i=0; i<100; i++) {
+    for (j=0; j<(1<<16); j++)
+      malloc(1<<5);
+  }
+#else
+  printf("IN BIG ALLOC\n");
+  
+  // 200 MBs total
+  for (i=0; i<100; i++) {
+    malloc(1<<21);
+    
+    // Ensure we hit the periodic check
+    for (j=0; j<10000; j++)
+      x++;
+  }
+#endif
+
+  printf("DONE!\n");
+
+  return x;
+}

Added: klee/trunk/test/Feature/MultipleFreeResolution.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MultipleFreeResolution.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MultipleFreeResolution.c (added)
+++ klee/trunk/test/Feature/MultipleFreeResolution.c Wed May 20 23:36:41 2009
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --emit-all-errors %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .err | wc -l | grep 3
+
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s;
+
+  for (i=0; i<3; i++)
+    buf[i] = make_int(i);
+  buf[3] = 0;
+
+  s = klee_urange(0,4);
+
+  free(buf[s]);
+
+  for (i=0; i<3; i++) {
+    printf("*buf[%d] = %d\n", i, *buf[i]);
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/MultipleReadResolution.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MultipleReadResolution.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MultipleReadResolution.c (added)
+++ klee/trunk/test/Feature/MultipleReadResolution.c Wed May 20 23:36:41 2009
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  int x = *buf[s];
+
+  if (x == 4)
+    if (s!=1)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/MultipleReallocResolution.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MultipleReallocResolution.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MultipleReallocResolution.c (added)
+++ klee/trunk/test/Feature/MultipleReallocResolution.c Wed May 20 23:36:41 2009
@@ -0,0 +1,63 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .err | wc -l | grep 2
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i, int N) {
+  int *x = malloc(sizeof(*x) * N);
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+
+  buf[0] = malloc(sizeof(int)*4);
+  buf[1] = malloc(sizeof(int));
+  buf[2] = 0; // gets malloc'd
+  buf[3] = (int*) 0xdeadbeef; // boom
+
+  buf[0][0] = 10;
+  buf[0][1] = 42;
+  buf[1][0] = 20;
+
+  int i = klee_urange(0,4);
+  int new_size = 2 * sizeof(int) * klee_urange(0,2); // 0 or 8
+
+  // whee, party time, needs to:
+  // Fork if size == 0, in which case all buffers get free'd and
+  // we will crash in prints below.
+  // Fork if buf[s] == 0, in which case the buffer gets malloc'd (for s==2)
+  // Fork on other buffers (s in [0,1]) and do realloc
+  //   for s==0 this is shrinking
+  //   for s==1 this is growing
+  buf[i] = realloc(buf[i], new_size);
+
+  if (new_size == 0) {
+    assert(!buf[2]); // free(0) is a no-op
+    if (i==0) assert(!buf[0] && buf[1]);
+    if (i==1) assert(buf[0] && !buf[1]);
+    assert(i != 3); // we should have crashed on free of invalid
+  } else {
+    assert(new_size == sizeof(int)*2);
+    assert(buf[0][0] == 10);
+    assert(buf[0][1] == 42); // make sure copied
+    assert(buf[1][0] == 20);
+    if (i==1) { int x = buf[1][1]; } // should be safe
+    if (i==2) { int x = buf[2][0]; } // should be safe
+    assert(i != 3); // we should have crashed on realloc of invalid
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/MultipleWriteResolution.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/MultipleWriteResolution.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/MultipleWriteResolution.c (added)
+++ klee/trunk/test/Feature/MultipleWriteResolution.c Wed May 20 23:36:41 2009
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  *buf[s] = 5;
+
+  if ((*buf[0] + *buf[1] + *buf[2] + *buf[3]) == 17)
+    if (s!=3)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/NamedSeedMatching.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/NamedSeedMatching.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/NamedSeedMatching.c (added)
+++ klee/trunk/test/Feature/NamedSeedMatching.c Wed May 20 23:36:41 2009
@@ -0,0 +1,41 @@
+// RUN: %llvmgcc -c -g %s -o %t.bc
+// RUN: rm -rf %t.out
+// RUN: %klee --output-dir=%t.out %t.bc "initial"
+// RUN: test -f %t.out/test000001.bout
+// RUN: not test -f %t.out/test000002.bout
+// RUN: %klee --only-replay-seeds --named-seed-matching --seed-out %t.out/test000001.bout %t.bc > %t.log
+// RUN: grep -q "a==3" %t.log
+// RUN: grep -q "b==4" %t.log
+// RUN: grep -q "c==5" %t.log
+// RUN: grep -q "x==6" %t.log
+
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int a, b, c, x;
+
+  if (argc==2 && strcmp(argv[1], "initial") == 0) {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+
+    klee_assume(a == 3);
+    klee_assume(b == 4);
+    klee_assume(c == 5);
+    klee_assume(x == 6);
+  } else {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+  }
+
+  if (a==3) printf("a==3\n");
+  if (b==4) printf("b==4\n");
+  if (c==5) printf("c==5\n");
+  if (x==6) printf("x==6\n");
+
+  return 0;
+}

Added: klee/trunk/test/Feature/OneFreeError.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/OneFreeError.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/OneFreeError.c (added)
+++ klee/trunk/test/Feature/OneFreeError.c Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  x[0] = 1;
+  return 0;
+}

Added: klee/trunk/test/Feature/OneOutOfBounds.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/OneOutOfBounds.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/OneOutOfBounds.c (added)
+++ klee/trunk/test/Feature/OneOutOfBounds.c Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  x[1] = 1;
+  free(x);
+  return 0;
+}

Added: klee/trunk/test/Feature/Optimize.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/Optimize.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/Optimize.c (added)
+++ klee/trunk/test/Feature/Optimize.c Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: rm -f %t2.log
+// RUN: %klee --stop-after-n-instructions=100 --optimize %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+// should complete by 100 instructions if opt is on
+
+int main() {
+  int i, res = 0;
+
+  for (i=1; i<=1000; i++)
+    res += i;
+
+  if (res == (1000*1001)/2) {
+    printf("good\n");
+  } else {
+    printf("bad\n");
+  }
+  
+  return 0;
+}

Added: klee/trunk/test/Feature/OverlappedError.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/OverlappedError.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/OverlappedError.c (added)
+++ klee/trunk/test/Feature/OverlappedError.c Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <stdlib.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(0,6, "range")]) = 1;
+    free(x);
+  } else {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(-1,5, "range")]) = 1;
+        free(x);
+  }
+  return 0;
+}

Added: klee/trunk/test/Feature/PreferCex.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/PreferCex.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/PreferCex.c (added)
+++ klee/trunk/test/Feature/PreferCex.c Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: klee-bout-tool klee-last/test000001.bout | grep -F 'Hi\x00\x00'
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_make_symbolic(buf, sizeof buf);
+  klee_prefer_cex(buf, buf[0]=='H');
+  klee_prefer_cex(buf, buf[1]=='i');
+  klee_prefer_cex(buf, buf[2]=='\0');
+
+  return 0;
+}

Added: klee/trunk/test/Feature/RaiseAsm.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/RaiseAsm.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/RaiseAsm.c (added)
+++ klee/trunk/test/Feature/RaiseAsm.c Wed May 20 23:36:41 2009
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+typedef unsigned short uint16;
+typedef unsigned int   uint32;
+
+uint16 byteswap_uint16(uint16 x) {
+  return (x << 8) | (x >> 8);
+}
+uint32 byteswap_uint32(uint32 x) {
+  return ((byteswap_uint16(x) << 16) |
+          (byteswap_uint16(x >> 16)));
+}
+
+uint16 byteswap_uint16_asm(uint16 x) {
+  uint16 res;
+  __asm__("rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+uint32 byteswap_uint32_asm(uint32 x) {
+  uint32 res;
+  __asm__("rorw $8, %w0;"
+          "rorl $16, %0;"
+          "rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+int main() {
+  uint16 ui16 = klee_int("ui16");
+  uint32 ui32 = klee_int("ui32");
+
+  assert(ui16 == byteswap_uint16(byteswap_uint16_asm(ui16)));
+  assert(ui32 == byteswap_uint32(byteswap_uint32_asm(ui32)));
+
+  return 0;
+}

Added: klee/trunk/test/Feature/ReallocFailure.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ReallocFailure.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ReallocFailure.c (added)
+++ klee/trunk/test/Feature/ReallocFailure.c Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  int *p = malloc(sizeof(int)*2);
+  assert(p);
+  p[1] = 52;
+
+  int *p2 = realloc(p, 1<<30);
+  assert(p2 == 0);
+  assert(p[1] == 52);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/ReplayPath.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/ReplayPath.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/ReplayPath.c (added)
+++ klee/trunk/test/Feature/ReplayPath.c Wed May 20 23:36:41 2009
@@ -0,0 +1,27 @@
+// RUN: echo "1" > %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --replay-path %t1.path %t2.bc > %t3.log
+// RUN: echo "res: 110" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  int res = 1;
+  int x;
+
+  klee_make_symbolic(&x, sizeof x);
+
+  if (x&1) res *= 2;
+  if (x&2) res *= 3;
+  if (x&4) res *= 5;
+
+  // get forced branch coverage
+  if (x&2) res *= 7;
+  if (!(x&2)) res *= 11;
+  printf("res: %d\n", res);
+ 
+  return 0;
+}

Added: klee/trunk/test/Feature/Searchers.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/Searchers.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/Searchers.c (added)
+++ klee/trunk/test/Feature/Searchers.c Wed May 20 23:36:41 2009
@@ -0,0 +1,52 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee %t2.bc
+// RUN: %klee --use-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-batching-search %t2.bc
+// RUN: %klee --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-merge --debug-log-merge --debug-log-state-merge %t2.bc
+// RUN: %klee --use-merge --use-batching-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+
+
+/* this test is basically just for coverage and doesn't really do any
+   correctness check (aside from testing that the various combinations
+   don't crash) */
+
+int validate(char *buf, int N) {
+
+  int i;
+
+  for (i=0; i<N; i++) {
+    if (buf[i]==0) {
+      klee_merge();
+      return 0;
+    }
+  }
+  
+  klee_merge();
+  return 1;
+}
+
+#ifndef SYMBOLIC_SIZE
+#define SYMBOLIC_SIZE 15
+#endif
+int main(int argc, char **argv) {
+  int N = SYMBOLIC_SIZE;
+  unsigned char *buf = malloc(N);
+  int i;
+  
+  klee_make_symbolic(buf, N);
+  if (validate(buf, N))
+    return buf[0];
+  return 0;
+}

Added: klee/trunk/test/Feature/SetForking.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/SetForking.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/SetForking.c (added)
+++ klee/trunk/test/Feature/SetForking.c Wed May 20 23:36:41 2009
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: sort %t.log | uniq -c > %t.uniq.log
+// RUN: grep "1 A" %t.uniq.log
+// RUN: grep "1 B" %t.uniq.log
+// RUN: grep "1 C" %t.uniq.log
+
+#include <stdio.h>
+
+int main() {
+  klee_set_forking(0);
+  
+  if (klee_range(0, 2, "range")) {
+    printf("A\n");
+  } else {
+    printf("A\n");
+  }
+
+  klee_set_forking(1);
+
+  if (klee_range(0, 2, "range")) {
+    printf("B\n");
+  } else {
+    printf("C\n");
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Feature/Vararg.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/Vararg.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/Vararg.c (added)
+++ klee/trunk/test/Feature/Vararg.c Wed May 20 23:36:41 2009
@@ -0,0 +1,82 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t2.out
+// RUN: grep "types: (52, 37, 2.00, (9,12,15))" %t2.out
+// RUN: test -f klee-last/test000001.ptr.err
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdio.h>
+
+struct triple {
+  int first, second, third;
+};
+
+int test1(int x, ...) {
+  va_list ap;
+  va_start(ap, x);
+  int i32 = va_arg(ap, int);
+  long long i64 = va_arg(ap, long long);
+  double d = va_arg(ap, double);
+  struct triple p = va_arg(ap, struct triple);
+  printf("types: (%d, %lld, %.2f, (%d,%d,%d))\n", i32, i64, d, p.first, p.second, p.third);
+  va_end(ap);
+}
+
+int sum(int N, ...) {
+  int i, res = 0;
+  va_list ap,ap2;
+  
+  va_start(ap, N);
+  for (i=0; i<N; i++) {
+    if (i==1)
+      va_copy(ap2, ap);
+    res += va_arg(ap, int);
+  }
+  for (i=0; i<N-1; i++)
+    res += va_arg(ap2, int);
+  va_end(ap);
+
+  return res;
+}
+
+// test using aps in an array (no multiple resolution
+// testing, though)
+int va_array(int N, ...) {
+  va_list aps[2];
+  unsigned i;
+  unsigned sum1 = 0, sum2 = 0;
+
+  for (i=0; i<2; i++)
+    va_start(aps[i], N);
+  
+  for (i=0; i<N; i++) {
+    unsigned cmd = va_arg(aps[0], int);
+
+    if (cmd==0) {
+      sum1 += va_arg(aps[0],int);
+    } else if (cmd==1) {
+      sum2 += va_arg(aps[1],int);
+    } else if (cmd==2) {
+      va_copy(aps[1], aps[0]);
+    }
+  }
+
+  for (i=0; i<2; i++)
+    va_end(aps[i]);
+
+  return 3*sum1 + 5*sum2;
+}
+
+int main() {
+  struct triple p = { 9, 12, 15 };
+  test1(-1, 52, 37ll, 2.0, p);
+
+  assert(sum(2, 3, 4) == 11);
+  assert(sum(0) == 0);
+  assert(va_array(5, 0, 5, 1, 1, 2, 1)==45); // 15 + 30
+
+  // should give memory error
+  test1(-1, 52, 37, 2.0, p);
+
+  return 0;
+}

Added: klee/trunk/test/Feature/WithLibc.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/WithLibc.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/WithLibc.c (added)
+++ klee/trunk/test/Feature/WithLibc.c Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --libc=klee %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  char buf[4];
+  char *s = "foo";
+
+  klee_make_symbolic(buf, sizeof buf);
+  buf[3] = 0;
+
+  if (strcmp(buf, s)==0) {
+    if (buf[0]=='f' && buf[1]=='o' && buf[2]=='o' && buf[3]==0) {
+      printf("good\n");
+    } else {
+      printf("bad\n");
+    }
+  }
+  
+  return 0;
+}

Added: klee/trunk/test/Feature/WriteCov.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/WriteCov.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/WriteCov.c (added)
+++ klee/trunk/test/Feature/WriteCov.c Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t2.bc
+// RUN: %klee --exit-on-error --write-cov %t2.bc
+// RUN: grep WriteCov.c:10 klee-last/test000002.cov
+// RUN: grep WriteCov.c:12 klee-last/test000001.cov
+
+#include <assert.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    assert(__LINE__ == 10); printf("__LINE__ = %d\n", __LINE__);
+  } else {
+    assert(__LINE__ == 12); printf("__LINE__ = %d\n", __LINE__);
+  }
+  return 0;
+}

Added: klee/trunk/test/Feature/_utils._ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/_utils._ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/_utils._ll (added)
+++ klee/trunk/test/Feature/_utils._ll Wed May 20 23:36:41 2009
@@ -0,0 +1,71 @@
+define i32 @util_make_and_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = and i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i32 @util_make_or_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = or i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i16 @util_make_concat2(i8 %a, i8 %b) {
+        %tmp = alloca i16
+        %tmp8 = bitcast i16* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        store i8 %b, i8* %p0
+        store i8 %a, i8* %p1
+        %concat = load i16* %tmp
+        ret i16 %concat
+}
+
+define i32 @util_make_concat4(i8 %a, i8 %b, i8 %c, i8 %d) {
+        %tmp = alloca i32
+        %tmp8 = bitcast i32* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        store i8 %d, i8* %p0
+        store i8 %c, i8* %p1
+        store i8 %b, i8* %p2
+        store i8 %a, i8* %p3
+        %concat = load i32* %tmp
+        ret i32 %concat
+}
+
+define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, 
+                              i8 %e, i8 %f, i8 %g, i8 %h) {
+        %tmp = alloca i64
+        %tmp8 = bitcast i64* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        %p4 = getelementptr i8* %tmp8, i32 4
+        %p5 = getelementptr i8* %tmp8, i32 5
+        %p6 = getelementptr i8* %tmp8, i32 6
+        %p7 = getelementptr i8* %tmp8, i32 7
+        store i8 %h, i8* %p0
+        store i8 %g, i8* %p1
+        store i8 %f, i8* %p2
+        store i8 %e, i8* %p3
+        store i8 %d, i8* %p4
+        store i8 %c, i8* %p5
+        store i8 %b, i8* %p6
+        store i8 %a, i8* %p7
+        %concat = load i64* %tmp
+        ret i64 %concat
+}
+
+define i32 @util_make_select(i32 %cond, i32 %t, i32 %f) {
+        %cond_i1 = icmp ne i32 %cond, 0
+        %res = select i1 %cond_i1, i32 %t, i32 %f
+        ret i32 %res
+}
\ No newline at end of file

Added: klee/trunk/test/Feature/const_array_opt1.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/const_array_opt1.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/const_array_opt1.c (added)
+++ klee/trunk/test/Feature/const_array_opt1.c Wed May 20 23:36:41 2009
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --const-array-opt --max-time=10 --only-output-states-covering-new %t.bc >%t.log
+// grep -q "Finished successfully!\n"
+
+/* This is testing the const array optimization.  On my 2.3GHz machine
+   this takes under 2 seconds w/ the optimization and almost 6 minutes
+   w/o.  So we kill it in 10 sec and check if it has finished
+   successfully. */
+
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+  
+int main() {
+#define N 8192
+#define N_IDX 16
+  unsigned char a[N];
+  unsigned i, k[N_IDX];
+
+  for (i=0; i<N; i++)
+    a[i] = i % 256;
+  
+  klee_make_symbolic_name(k, sizeof(k), "k");
+  
+  for (i=0; i<N_IDX; i++) {
+    if (k[i] >= N)
+      klee_silent_exit(0);
+
+    if (a[k[i]] == i)
+      assert(k[i] % 256 == i);
+    else klee_silent_exit(0);
+  }
+
+  printf("Finished successfully!\n");
+
+  return 0;
+}

Added: klee/trunk/test/Feature/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/dg.exp (added)
+++ klee/trunk/test/Feature/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/test/Feature/utils.h
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Feature/utils.h?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Feature/utils.h (added)
+++ klee/trunk/test/Feature/utils.h Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+uint32_t util_make_and_i1(uint32_t a, uint32_t b);
+uint32_t util_make_or_i1(uint32_t a, uint32_t b);
+
+uint16_t util_make_concat2(uint8_t a, uint8_t b);
+uint32_t util_make_concat4(uint8_t a, uint8_t b, 
+                           uint8_t c, uint8_t d);
+uint64_t util_make_concat8(uint8_t a, uint8_t b,
+                           uint8_t c, uint8_t d,
+                           uint8_t e, uint8_t f,
+                           uint8_t g, uint8_t h);
+uint32_t util_make_select(uint32_t cond, uint32_t true, uint32_t false);

Added: klee/trunk/test/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Makefile (added)
+++ klee/trunk/test/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,101 @@
+#===- test/Makefile ----------------------------------------*- Makefile -*--===#
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+# 
+#===------------------------------------------------------------------------===#
+
+LEVEL  = ..
+DIRS   = 
+
+#
+# Make Dejagnu the default for testing
+#
+all:: check-local
+
+# Include other test rules
+include Makefile.tests
+
+#===------------------------------------------------------------------------===#
+# DejaGNU testing support
+#===------------------------------------------------------------------------===#
+
+ifdef TESTSUITE
+CLEANED_TESTSUITE := $(patsubst %/,%,$(TESTSUITE))
+CLEANED_TESTSUITE := $(patsubst test/%,%,$(CLEANED_TESTSUITE))
+RUNTESTFLAGS := --tool $(CLEANED_TESTSUITE)
+endif
+
+ifneq ($(RUNTEST),)
+check-local:: site.exp
+	( ulimit -t 600 ; ulimit -d 512000 ; \
+	  PATH="$(ToolDir):$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+	  $(RUNTEST) $(RUNTESTFLAGS) ;  \
+	  ! grep FAIL testrun.log )
+else
+check-local:: site.exp
+	@echo "*** dejagnu not found.  Make sure runtest is in your PATH, then reconfigure llvm."
+endif
+
+ifdef TESTONE
+CLEANED_TESTONE := $(patsubst %/,%,$(TESTONE))
+CLEANED_TESTONE := $(patsubst test/%,%,$(CLEANED_TESTONE))
+SUBDIR := $(shell dirname $(CLEANED_TESTONE))
+TESTPATH := $(PROJ_SRC_ROOT)/test/$(CLEANED_TESTONE)
+check-one: site.exp $(TCLSH)
+	$(Verb)( echo "source $(PROJ_OBJ_ROOT)/test/site.exp" ; \
+	  echo "set subdir $(SUBDIR)" ; \
+	  echo "proc pass  { msg } { puts \"PASS: \$$msg\" } "; \
+	  echo "proc fail  { msg } { puts \"FAIL: \$$msg\" }" ; \
+	  echo "proc xfail { msg } { puts \"XFAIL: \$$msg\" }" ; \
+	  echo "proc xpass { msg } { puts \"XPASS: \$$msg\" }" ; \
+	  echo "source $(PROJ_SRC_ROOT)/test/lib/llvm.exp" ; \
+	  echo "RunLLVMTests $(TESTPATH)" ) | \
+	( ulimit -t 600 ; ulimit -d 512000 ; \
+	  PATH="$(ToolDir):$(LLVMToolDir):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+	  $(TCLSH) )
+endif
+
+clean::
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name Output -type d -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'ft-out*' -type d -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'ft-last' -print`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'klee-last'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name 'klee-out*'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name '*~'`
+	$(RM) -rf `find $(PROJ_OBJ_ROOT)/test -name test.log`
+	rm -f site.exp
+
+site.exp: Makefile $(LEVEL)/Makefile.config
+	@echo 'Making a new site.exp file...'
+	@echo '## these variables are automatically generated by make ##' >site.tmp
+	@echo '# Do not edit here.  If you wish to override these values' >>site.tmp
+	@echo '# edit the last section' >>site.tmp
+	@echo 'set target_triplet "$(TARGET_TRIPLE)"' >> site.tmp
+	@echo 'set ENABLE_UCLIBC "$(ENABLE_UCLIBC)"' >> site.tmp
+	@echo 'set ENABLE_POSIX_RUNTIME "$(ENABLE_POSIX_RUNTIME)"' >> site.tmp
+	@echo 'set TEST_FEATURE_LIST "$(TEST_FEATURE_LIST)"' >> site.tmp
+	@echo 'set prcontext "$(TCLSH) $(LLVM_SRC_ROOT)/test/Scripts/prcontext.tcl"' >> site.tmp
+	@echo 'set llvmtoolsdir "$(ToolDir)"' >>site.tmp
+	@echo 'set llvmlibsdir "$(LibDir)"' >>site.tmp
+	@echo 'set srcroot "$(PROJ_SRC_ROOT)"' >>site.tmp
+	@echo 'set objroot "$(PROJ_OBJ_ROOT)"' >>site.tmp
+	@echo 'set srcdir "$(PROJ_SRC_ROOT)/test"' >>site.tmp
+	@echo 'set objdir "$(PROJ_OBJ_ROOT)/test"' >>site.tmp
+	@echo 'set gccpath "$(CC)"' >>site.tmp
+	@echo 'set gxxpath "$(CXX)"' >>site.tmp
+	@echo 'set compile_c "$(CC) $(CPP.Flags) $(C.Flags) $(CompileCommonOpts) -c "' >>site.tmp
+	@echo 'set compile_cxx "$(CXX) $(CPP.Flags) $(CXX.Flags) $(CompileCommonOpts) - c"' >> site.tmp
+	@echo 'set link "$(CXX) $(CPP.Flags) $(CXX.Flags) $(CompileCommonOpts) $(LD.Flags)"' >>site.tmp
+	@echo 'set llvmgcc "$(LLVMGCC)"' >> site.tmp
+	@echo 'set llvmgxx "$(LLVMGCC)"' >> site.tmp
+	@echo 'set llvmgccmajvers "$(LLVMGCC_MAJVERS)"' >> site.tmp
+	@echo 'set shlibext "$(SHLIBEXT)"' >> site.tmp
+	@echo '## All variables above are generated by configure. Do Not Edit ## ' >>site.tmp
+	@test ! -f site.exp || \
+	sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+	@-rm -f site.bak
+	@test ! -f site.exp || mv site.exp site.bak
+	@mv site.tmp site.exp

Added: klee/trunk/test/Makefile.tests
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Makefile.tests?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Makefile.tests (added)
+++ klee/trunk/test/Makefile.tests Wed May 20 23:36:41 2009
@@ -0,0 +1,80 @@
+##----------------------------------------------------------*- Makefile -*-===##
+##
+## Common rules for generating, linking, and compiling via LLVM.  This is
+## used to implement a robust testing framework for LLVM
+##
+##-------------------------------------------------------------------------===##
+
+# If the user specified a TEST= option on the command line, we do not want to do
+# the default testing type.  Instead, we change the default target to be the
+# test:: target.
+#
+ifdef TEST
+test::
+endif
+
+# We do not want to make .d files for tests! 
+DISABLE_AUTO_DEPENDENCIES=1
+
+include ${LEVEL}/Makefile.common
+
+# Specify ENABLE_STATS on the command line to enable -stats and -time-passes
+# output from gccas and gccld.
+ifdef ENABLE_STATS
+STATS = -stats -time-passes
+endif
+
+.PHONY: clean default
+
+# These files, which might be intermediate results, should not be deleted by
+# make
+.PRECIOUS: Output/%.bc  Output/%.ll
+.PRECIOUS: Output/%.tbc Output/%.tll
+.PRECIOUS: Output/.dir
+.PRECIOUS: Output/%.llvm.bc
+.PRECIOUS: Output/%.llvm
+
+LCCFLAGS  += -O2 -Wall
+LCXXFLAGS += -O2 -Wall
+LLCFLAGS =
+TESTRUNR = @echo Running test: $<; \
+             PATH="$(LLVMTOOLCURRENT):$(LLVM_SRC_ROOT)/test/Scripts:$(PATH)" \
+                  $(LLVM_SRC_ROOT)/test/TestRunner.sh
+
+LLCLIBS := $(LLCLIBS) -lm
+
+clean::
+	$(RM) -f a.out core
+	$(RM) -rf Output/
+
+# Compile from X.c to Output/X.ll
+Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
+	-$(LLVMGCCWITHPATH) $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+
+# Compile from X.cpp to Output/X.ll
+Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
+	-$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# Compile from X.cc to Output/X.ll
+Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
+	-$(LLVMGXXWITHPATH) $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# LLVM Assemble from Output/X.ll to Output/X.bc.  Output/X.ll must have come
+# from GCC output, so use GCCAS.
+#
+Output/%.bc: Output/%.ll $(LGCCAS)
+	-$(LGCCAS) $(STATS) $< -o $@
+
+# LLVM Assemble from X.ll to Output/X.bc.  Because we are coming directly from
+# LLVM source, use the non-transforming assembler.
+#
+Output/%.bc: %.ll $(LLVMAS) Output/.dir
+	-$(LLVMAS) -f $< -o $@
+
+## Cancel built-in implicit rules that override above rules
+%: %.s
+
+%: %.c
+
+%.o: %.c
+

Added: klee/trunk/test/README
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/README?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/README (added)
+++ klee/trunk/test/README Wed May 20 23:36:41 2009
@@ -0,0 +1 @@
+about tests....

Added: klee/trunk/test/Runtime/POSIX/DirConsistency.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/DirConsistency.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/DirConsistency.c (added)
+++ klee/trunk/test/Runtime/POSIX/DirConsistency.c Wed May 20 23:36:41 2009
@@ -0,0 +1,64 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --run-in=/tmp --use-random-search --init-env --libc=uclibc --posix-runtime --exit-on-error %t.bc --sym-files 1 1 > %t1.log
+// RUN: %llvmgcc -D_FILE_OFFSET_BITS=64 %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --run-in=/tmp --use-random-search --init-env --libc=uclibc --posix-runtime --exit-on-error %t.bc --sym-files 1 1 > %t2.log
+// RUN: sort %t1.log %t2.log | uniq -c > %t3.log
+// RUN: grep -q "4 COUNT" %t3.log
+
+// For this test really to work as intended it needs to be run in a
+// directory large enough to cause uclibc to do multiple getdents
+// calls (otherwise uclibc will handle the seeks itself). We should
+// create a bunch of files or something.
+//
+// It is even more important for this test because it requires the
+// directory not to change while running, which might be a lot to
+// demand of /tmp.
+
+#define _LARGEFILE64_SOURCE
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+  int res = stat("A", &s);
+  int hasA = !(res!=0 && errno==ENOENT);
+
+  //printf("sizeof(dirent) = %d\n", sizeof(struct dirent));
+  //printf("sizeof(dirent64) = %d\n", sizeof(struct dirent64));
+
+  //printf("\"A\" exists: %d\n", hasA);
+
+  DIR *d = opendir(".");
+  assert(d);
+
+  int snum = 1;
+  if (klee_range(0,2,"range")) {
+    snum = 2;
+    printf("state%d\n", snum);
+  }
+
+  int foundA = 0, count = 0;
+  struct dirent *de;
+  while ((de = readdir(d))) {
+    //    printf("state%d: dirent: %s\n", snum, de->d_name);
+    if (strcmp(de->d_name, "A") == 0)
+      foundA = 1;
+    count++;
+  }
+  
+  closedir(d);
+
+  //printf("found A: %d\n", foundA);
+
+  // Ensure atomic write
+  char buf[64];
+  sprintf(buf, "COUNT: %d\n", count);
+  fputs(buf, stdout);
+  assert(hasA == foundA);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/DirSeek.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/DirSeek.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/DirSeek.c (added)
+++ klee/trunk/test/Runtime/POSIX/DirSeek.c Wed May 20 23:36:41 2009
@@ -0,0 +1,57 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 2 2
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 1 2
+// RUN: %klee --run-in=/tmp --init-env --libc=uclibc --posix-runtime --exit-on-error %t2.bc --sym-files 0 2
+
+// For this test really to work as intended it needs to be run in a
+// directory large enough to cause uclibc to do multiple getdents
+// calls (otherwise uclibc will handle the seeks itself). We should
+// create a bunch of files or something.
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+
+  char first[256], second[256];
+  DIR *d = opendir(".");
+  struct dirent *de = readdir(d);
+  assert(de);
+  strcpy(first, de->d_name);
+  off_t pos = telldir(d);
+  printf("pos: %d\n", telldir(d));
+  de = readdir(d);
+  assert(de);
+  strcpy(second, de->d_name);
+
+  // Go back to second and check
+  seekdir(d, pos);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, second) == 0);
+
+  // Go to end, then back to 2nd
+  while (de)
+    de = readdir(d);
+  assert(!errno);
+  seekdir(d, pos);
+  assert(telldir(d) == pos);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, second) == 0);
+
+  // Go to beginning and check
+  rewinddir(d);
+  de = readdir(d);
+  assert(de);
+  assert(strcmp(de->d_name, first) == 0);  
+  closedir(d);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/FDNumbers.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/FDNumbers.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/FDNumbers.c (added)
+++ klee/trunk/test/Runtime/POSIX/FDNumbers.c Wed May 20 23:36:41 2009
@@ -0,0 +1,24 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int main(int argc, char **argv) {
+  int fd = open("A", O_TRUNC);
+  assert(fd == 3);
+  assert(!close(0));
+  assert(!close(1));
+  assert(close(0) == -1);
+  assert(close(1) == -1);
+  assert(open("A", O_TRUNC) == 0);  
+  assert(dup(0) == 1);
+  assert(open("A", O_TRUNC) == 4);
+  assert(!close(1));
+  assert(open("A", O_TRUNC) == 1);
+  assert(dup(0) != 1);
+  assert(dup2(0,1) == 1);
+  
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/FD_Fail.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/FD_Fail.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/FD_Fail.c (added)
+++ klee/trunk/test/Runtime/POSIX/FD_Fail.c Wed May 20 23:36:41 2009
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t1.bc --sym-files 0 0 --max-fail 1 > %t.log
+// RUN: grep -q "fread(): ok" %t.log
+// RUN: grep -q "fread(): fail" %t.log
+// RUN: grep -q "fclose(): ok" %t.log
+// RUN: grep -q "fclose(): fail" %t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[1024];  
+  FILE* f = fopen("/etc/fstab", "r");
+  assert(f);
+    
+  int r = fread(buf, 1, 100, f);
+  printf("fread(): %s\n", 
+         r ? "ok" : "fail");
+
+  r = fclose(f);
+  printf("fclose(): %s\n", 
+         r ? "ok" : "fail");
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/FD_Fail2.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/FD_Fail2.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/FD_Fail2.c (added)
+++ klee/trunk/test/Runtime/POSIX/FD_Fail2.c Wed May 20 23:36:41 2009
@@ -0,0 +1,34 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t1.bc --sym-files 0 0 --max-fail 1
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+// RUN: test -f klee-last/test000004.bout
+// RUN: test -f klee-last/test000005.bout
+// RUN: test -f klee-last/test000006.bout
+// RUN: test -f klee-last/test000007.bout
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, char** argv) {
+  char buf[1024];  
+  int fd = open("/etc/fstab", O_RDONLY);
+  assert(fd != -1);
+    
+  int r = read(fd, buf, 1, 100);
+  if (r != -1)
+    printf("read() succeeded\n");
+  else printf("read() failed with errno %s\n", strerror(errno));
+
+  r = close(fd);
+  if (r != -1)
+    printf("close() succeeded\n");
+  else printf("close() failed with errno %s\n", strerror(errno));
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Fcntl.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Fcntl.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Fcntl.c (added)
+++ klee/trunk/test/Runtime/POSIX/Fcntl.c Wed May 20 23:36:41 2009
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+#include <fcntl.h>
+
+int main(int argc, char **argv) {
+  int fd = open("A", O_RDWR|O_TRUNC);
+  if (fd == -1)
+    klee_silent_exit(0);
+  assert(fd == 3);
+  assert((fcntl(fd, F_GETFD) & FD_CLOEXEC) == 0);
+  assert(fcntl(fd, F_SETFD, FD_CLOEXEC, 1) == 0);
+  assert((fcntl(fd, F_GETFD) & FD_CLOEXEC) != 0);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/FilePerm.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/FilePerm.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/FilePerm.c (added)
+++ klee/trunk/test/Runtime/POSIX/FilePerm.c Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log 
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+
+#include <stdio.h>       
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, char** argv) {
+  int fd = open("A", O_RDWR);
+  if (fd != -1)
+    fprintf(stderr, "File 'A' opened successfully\n");
+  else fprintf(stderr, "Cannot open file 'A'\n");
+
+  if (fd != -1)
+    close(fd);
+}

Added: klee/trunk/test/Runtime/POSIX/FreeArgv.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/FreeArgv.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/FreeArgv.c (added)
+++ klee/trunk/test/Runtime/POSIX/FreeArgv.c Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --posix-runtime %t.bc --sym-args 1 1 1
+// RUN: test -f klee-last/test000001.free.err
+// RUN: test -f klee-last/test000002.free.err
+// RUN: test -f klee-last/test000003.free.err
+
+int main(int argc, char **argv) {
+  switch(klee_range(0, 3, "range")) {
+  case 0:
+    free(argv);
+    break;
+  case 1:
+    free(argv[0]);
+    break;
+  case 2:
+    free(argv[1]);
+    break;
+  }
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Getenv.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Getenv.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Getenv.c (added)
+++ klee/trunk/test/Runtime/POSIX/Getenv.c Wed May 20 23:36:41 2009
@@ -0,0 +1,21 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --libc=klee --posix-runtime --exit-on-error %t2.bc --sym-files 1 10
+
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  char *g = getenv("PWD");
+  if (g) {
+    printf("have PWD\n");
+  } else {
+    printf("have no PWD\n");
+  }
+
+  g = getenv("HELLO");
+  if (!g || strcmp(g, "nice")==0) {
+    printf("getenv(\"HELLO\") = %p\n", g);
+    if (g) assert(strcmp(getenv("HELLO"),"nice") == 0);
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Ioctl.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Ioctl.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Ioctl.c (added)
+++ klee/trunk/test/Runtime/POSIX/Ioctl.c Wed May 20 23:36:41 2009
@@ -0,0 +1,31 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t.bc --sym-files 0 4
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <asm/ioctls.h>
+#include <errno.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  struct stat s;
+  struct termios ts;
+
+  assert(fstat(0, &s) == 0);
+
+  assert(ioctl(10, FIONREAD, &ts) == -1 && errno == EBADF);
+
+  if (S_ISCHR(s.st_mode)) {
+    printf("is chr\n");
+    assert(ioctl(0, TIOCGWINSZ, &ts) == 0);
+  } else {
+    printf("not chr\n");
+    // I think TC* ioctls basically always fail on nonchr?
+    assert(ioctl(0, TIOCGWINSZ, &ts) == -1);
+    assert(errno == ENOTTY);
+  }
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Isatty.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Isatty.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Isatty.c (added)
+++ klee/trunk/test/Runtime/POSIX/Isatty.c Wed May 20 23:36:41 2009
@@ -0,0 +1,33 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 0 10 --sym-stdout 2>%t.log
+
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: test -f klee-last/test000003.bout
+// RUN: test -f klee-last/test000004.bout
+
+// RUN: grep -q "stdin is a tty" %t.log
+// RUN: grep -q "stdin is NOT a tty" %t.log
+// RUN: grep -q "stdout is a tty" %t.log
+// RUN: grep -q "stdout is NOT a tty" %t.log
+
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  int fd0 = 0; // stdin
+  int fd1 = 1; // stdout
+
+  int r = isatty(fd0);
+  if (r) 
+    fprintf(stderr, "stdin is a tty\n");
+  else fprintf(stderr, "stdin is NOT a tty\n");
+  
+  r = isatty(fd1);
+  if (r) 
+    fprintf(stderr, "stdout is a tty\n");
+  else fprintf(stderr, "stdout is NOT a tty\n");
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/PrgName.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/PrgName.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/PrgName.c (added)
+++ klee/trunk/test/Runtime/POSIX/PrgName.c Wed May 20 23:36:41 2009
@@ -0,0 +1,31 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --init-env --posix-runtime --exit-on-error %t2.bc --sym-arg 10 >%t.log
+// RUN: test -f klee-last/test000001.bout
+// RUN: test -f klee-last/test000002.bout
+// RUN: grep -q "No" %t.log
+// RUN: grep -qv "Yes" %t.log
+
+
+/* Simple test for argv[0] */
+
+#include <stdio.h>
+
+int f(int argc, char **argv) {
+
+  if (argv[0][5] == '7')
+    printf("Yes\n");
+  else printf("No\n");
+
+  printf("%c\n", argv[0][5]);
+
+  if (argv[1][1] == 4)
+    printf("4\n");
+  printf("not 4\n");
+
+  return 0;
+}
+
+
+int main(int argc, char **argv) {
+  f(argc, argv);
+}

Added: klee/trunk/test/Runtime/POSIX/Read1.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Read1.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Read1.c (added)
+++ klee/trunk/test/Runtime/POSIX/Read1.c Wed May 20 23:36:41 2009
@@ -0,0 +1,34 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --posix-runtime --init-env %t.bc --sym-files 1 8 >%t.log
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[32];
+
+  // If count is zero, read() returns zero and has  no  other  results. (man page)
+  int x = read(0, 0, 0);
+  assert(x == 0);
+  
+  int fd = open("A", O_RDONLY);
+  assert(fd != -1);
+
+  // EFAULT buf is outside your accessible address space. (man page)
+  x = read(fd, 0, 1);
+  assert(x == -1 && errno == EFAULT);
+ 
+  // EBADF  fd is not a valid file descriptor (man page)
+  x = read(-1, buf, 1);
+  assert(x == -1 && errno == EBADF);
+
+  fd = open("A", O_RDONLY);
+  assert(fd != -1);
+  x = read(fd, buf, 1);
+  assert(x == 1);  
+}
+

Added: klee/trunk/test/Runtime/POSIX/SELinux.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/SELinux.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/SELinux.c (added)
+++ klee/trunk/test/Runtime/POSIX/SELinux.c Wed May 20 23:36:41 2009
@@ -0,0 +1,30 @@
+/* Very basic test, as right now SELinux support is extremely basic */
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --posix-runtime --exit-on-error %t1.bc --sym-arg 2 > %t.log
+// XFAIL: no-selinux
+
+#include <selinux/selinux.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+
+  security_context_t con;
+
+  assert(argc == 2);
+
+  int selinux = is_selinux_enabled();
+  printf("selinux enabled = %d\n", selinux);
+  
+  if (setfscreatecon(argv[1]) < 0)
+    printf("Error: set\n");
+  else printf("Success: set\n");
+  
+  if (getfscreatecon(&con) < 0)
+    printf("Error: get\n");
+  else printf("Success: get\n");
+
+  printf("create_con = %s\n", con);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/SeedAndFail.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/SeedAndFail.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/SeedAndFail.c (added)
+++ klee/trunk/test/Runtime/POSIX/SeedAndFail.c Wed May 20 23:36:41 2009
@@ -0,0 +1,38 @@
+// RUN: %llvmgcc %s -emit-llvm -g -O0 -c -o %t.bc
+// RUN: rm -rf tmp-123
+// RUN: %klee --libc=klee --output-dir=tmp-123 --posix-runtime --init-env %t.bc --sym-files 1 10  2>%t.log
+// RUN: klee --seed-out-dir=tmp-123 --zero-seed-extension --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --max-fail 1
+// RUN: ls klee-last | grep -c assert | grep 4
+
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+int main(int argc, char** argv) {
+  char buf[32];
+  
+  int fd = open("A", O_RDWR | O_CREAT, S_IRWXU);
+  assert(fd != -1);
+  int nbytes = write(fd, "Hello", sizeof("Hello"));
+  assert(nbytes == sizeof("Hello"));
+
+  off_t off = lseek(fd, 0, SEEK_SET);
+  assert(off != (off_t) -1);
+
+  nbytes = read(fd, buf, sizeof("Hello"));
+  assert(nbytes == sizeof("Hello"));
+  
+  int r = close(fd);
+  assert(r == 0);
+
+  r = memcmp(buf, "Hello", sizeof("Hello"));
+  assert(r == 0);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Stdin.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Stdin.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Stdin.c (added)
+++ klee/trunk/test/Runtime/POSIX/Stdin.c Wed May 20 23:36:41 2009
@@ -0,0 +1,56 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --init-env --libc=klee --posix-runtime --exit-on-error %t.bc --sym-files 0 4 > %t.log
+// RUN: grep "mode:file" %t.log
+// RUN: grep "mode:dir" %t.log
+// RUN: grep "mode:chr" %t.log
+// RUN: grep "mode:blk" %t.log
+// RUN: grep "mode:fifo" %t.log
+// RUN: grep "mode:lnk" %t.log
+// RUN: grep "read:sym:yes" %t.log
+// RUN: grep "read:sym:no" %t.log
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  struct stat stats;
+  assert(fstat(0, &stats) == 0);
+
+  if (S_ISREG(stats.st_mode)) {
+    printf("mode:file\n");
+  } else if (S_ISDIR(stats.st_mode)) {
+    printf("mode:dir\n");
+  } else if (S_ISCHR(stats.st_mode)) {
+    printf("mode:chr\n");
+  } else if (S_ISBLK(stats.st_mode)) {
+    printf("mode:blk\n");
+  } else if (S_ISFIFO(stats.st_mode)) {
+    printf("mode:fifo\n");
+  } else if (S_ISLNK(stats.st_mode)) {
+    printf("mode:lnk\n");
+  } else if (S_ISSOCK(stats.st_mode)) {
+    printf("mode:sock\n");
+  } else {
+    printf("unknown mode\n");
+  }
+
+  assert(stats.st_size==4);
+
+  if (S_ISREG(stats.st_mode)) {
+    char buf[10];
+    int n = read(0, buf, 5);
+    assert(n == 4);
+    
+    if (strcmp(buf, "HI!")) {
+      printf("read:sym:yes\n");
+    } else {
+      printf("read:sym:no\n");
+    }
+  }
+
+  fflush(stdout);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Write1.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Write1.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Write1.c (added)
+++ klee/trunk/test/Runtime/POSIX/Write1.c Wed May 20 23:36:41 2009
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  char buf[32];
+  
+  FILE* f = fopen("A", "w");
+  if (!f)
+    klee_silent_exit(0);
+  fwrite("Hello", sizeof("Hello"), 1, f);
+  fclose(f);
+  
+  f = fopen("A", "r");
+  fread(buf, sizeof("Hello"), 1, f);
+  fclose(f);
+
+  assert(memcmp(buf, "Hello", sizeof("Hello")) == 0);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/Write2.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/Write2.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/Write2.c (added)
+++ klee/trunk/test/Runtime/POSIX/Write2.c Wed May 20 23:36:41 2009
@@ -0,0 +1,21 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --exit-on-error --libc=uclibc --posix-runtime --init-env %t.bc --sym-files 1 10 --sym-stdout 2>%t.log
+
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  const char* msg = "This will eventually overflow stdout. ";
+  char buf[32];
+  int i;
+  
+  FILE* f = stdout;//fopen("A", "w");
+  if (!f)
+    klee_silent_exit(0);
+
+  for (i = 0; i < 300; i++)
+    fwrite(msg, sizeof(msg), 1, f);
+  fclose(f);
+
+  return 0;
+}

Added: klee/trunk/test/Runtime/POSIX/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/POSIX/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/POSIX/dg.exp (added)
+++ klee/trunk/test/Runtime/POSIX/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [klee_supports_posix_runtime] } {
+    RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
+}

Added: klee/trunk/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c (added)
+++ klee/trunk/test/Runtime/Uclibc/2007-10-08-optimization-calls-wrong-libc-functions.c Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error --optimize --libc=uclibc %t1.bc
+
+#include <string.h>
+#include <assert.h>
+
+int main() {
+  int a;
+
+  klee_make_symbolic(&a, sizeof a);
+
+  memset(&a, 0, sizeof a);
+
+  if (a) {
+    assert(0);
+  }
+  
+  return 0;
+}

Added: klee/trunk/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c (added)
+++ klee/trunk/test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c Wed May 20 23:36:41 2009
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error --libc=uclibc %t1.bc
+
+// just make sure atexit works ok
+
+void boo() {
+}
+
+int main() {
+  atexit(boo);
+  return 0;
+}

Added: klee/trunk/test/Runtime/Uclibc/Environ.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/Uclibc/Environ.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/Uclibc/Environ.c (added)
+++ klee/trunk/test/Runtime/Uclibc/Environ.c Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --libc=uclibc --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main() {
+  printf("HOME: %s\n", getenv("HOME"));
+  assert(getenv("HOME") != 0);
+  return 0;
+}

Added: klee/trunk/test/Runtime/Uclibc/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/Runtime/Uclibc/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/Runtime/Uclibc/dg.exp (added)
+++ klee/trunk/test/Runtime/Uclibc/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,5 @@
+load_lib llvm.exp
+
+if { [klee_supports_uclibc] } {
+    RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
+}

Added: klee/trunk/test/TestRunner.sh
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/TestRunner.sh?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/TestRunner.sh (added)
+++ klee/trunk/test/TestRunner.sh Wed May 20 23:36:41 2009
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+#  TestRunner.sh - This script is used to run the deja-gnu tests exactly like
+#  deja-gnu does, by executing the Tcl script specified in the test case's 
+#  RUN: lines. This is made possible by a simple make target supported by the
+#  test/Makefile. All this script does is invoke that make target. 
+#
+#  Usage:
+#     TestRunner.sh {script_names}
+#
+#     This script is typically used by cd'ing to a test directory and then
+#     running TestRunner.sh with a list of test file names you want to run.
+#
+TESTPATH=`pwd`
+SUBDIR=""
+if test `dirname $1` = "." ; then
+  while test `basename $TESTPATH` != "test" -a ! -z "$TESTPATH" ; do
+    tmp=`basename $TESTPATH`
+    SUBDIR="$tmp/$SUBDIR"
+    TESTPATH=`dirname $TESTPATH`
+  done
+fi
+
+for TESTFILE in "$@" ; do 
+  if test `dirname $TESTFILE` = . ; then
+    if test -d "$TESTPATH" ; then
+      cd $TESTPATH
+      make check-one TESTONE="$SUBDIR$TESTFILE"
+      cd $PWD
+    else
+      echo "Can't find klee/test directory in " `pwd`
+    fi
+  else
+    make check-one TESTONE=$TESTFILE
+  fi
+done

Propchange: klee/trunk/test/TestRunner.sh

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/test/lib/llvm.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/lib/llvm.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/lib/llvm.exp (added)
+++ klee/trunk/test/lib/llvm.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,213 @@
+# This procedure executes one line of a test case's execution script.
+proc execOneLine { test PRS outcome lineno line } {
+  set status 0
+  set resultmsg ""
+  set retval [ catch { eval exec -keepnewline -- $line } errmsg ]
+  if { $retval != 0 } {
+    set code [lindex $::errorCode 0]
+    set lineno [expr $lineno + 1]
+    if { $PRS != ""} {
+      set PRS " for $PRS" 
+    }
+    set errmsg " at line $lineno\nwhile running: $line\n$errmsg"
+    switch "$code" {
+      CHILDSTATUS {
+        set status [lindex $::errorCode 2]
+        if { $status != 0 } {
+          set resultmsg "$test$PRS\nFailed with exit($status)$errmsg"
+        }
+      }
+      CHILDKILLED {
+        set signal [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with signal($signal)$errmsg"
+      }
+      CHILDSUSP {
+        set signal [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with suspend($signal)$errmsg"
+      }
+      POSIX {
+        set posixNum [lindex $::errorCode 1]
+        set posixMsg [lindex $::errorCode 2]
+        set resultmsg "$test$PRS\nFailed with posix($posixNum,$posixMsg)$errmsg"
+      }
+      NONE {
+      }
+      default {
+      }
+    }
+  } 
+  return $resultmsg
+}
+
+# This procedure performs variable substitutions on the RUN: lines of a test
+# cases.
+proc substitute { line test tmpFile } {
+  global srcroot objroot srcdir objdir subdir target_triplet prcontext 
+  global llvmgcc llvmgxx llvmgcc_version llvmgccmajvers 
+  global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir
+  global llvmtoolsdir
+  set path [file join $srcdir $subdir]
+
+  # Substitute all Tcl variables.
+  set new_line [subst $line ]
+
+  #replace %prcontext with prcontext.tcl (Must replace before %p)
+  regsub -all {%prcontext} $new_line $prcontext new_line
+  #replace %llvmgcc with actual path to llvmgcc
+  regsub -all {%llvmgcc} $new_line "$llvmgcc -emit-llvm" new_line
+  #replace %llvmgxx with actual path to llvmg++
+  regsub -all {%llvmgxx} $new_line "$llvmgxx -emit-llvm" new_line
+  #replace %compile_c with C compilation command
+  regsub -all {%compile_c} $new_line "$compile_c" new_line
+  #replace %compile_cxx with C++ compilation command
+  regsub -all {%compile_cxx} $new_line "$compile_cxx" new_line
+  #replace %link with C++ link command
+  regsub -all {%link} $new_line "$link" new_line
+  #replace %shlibext with shared library extension
+  regsub -all {%shlibext} $new_line "$shlibext" new_line
+  #replace %llvmlibsdir with configure library directory
+  regsub -all {%llvmlibsdir} $new_line "$llvmlibsdir" new_line
+  #replace %klee with klee binary
+  regsub -all {%klee} $new_line "klee" new_line
+  #replace %kleaver with kleaver binary
+  regsub -all {%kleaver} $new_line "kleaver" new_line
+  #replace %p with path to source, 
+  regsub -all {%p} $new_line [file join $srcdir $subdir] new_line
+  #replace %s with filename
+  regsub -all {%s} $new_line $test new_line
+  #replace %t with temp filenames
+  regsub -all {%t} $new_line $tmpFile new_line
+  #replace %% with %
+  regsub -all {%%} $new_line % new_line
+  return $new_line
+}
+
+# This procedure runs the set of tests for the test_source_files array.
+proc RunLLVMTests { test_source_files } {
+  global srcroot objroot srcdir objdir subdir TEST_FEATURE_LIST target_triplet
+  set timeout 60
+
+  set path [file join $objdir $subdir]
+  
+  #Make Output Directory if it does not exist already
+  if { [file exists path] } {
+    cd $path
+  } else {
+    file mkdir $path
+    cd $path
+  }
+  
+  file mkdir Output
+  cd Output
+
+  foreach test $test_source_files {
+    #Should figure out best way to set the timeout
+    #set timeout 40
+    
+    set filename [file tail $test]
+    set outcome PASS
+    set tmpFile "$filename.tmp"
+
+    #set hasRunline bool to check if testcase has a runline
+    set numLines 0
+
+    # Open the test file and start reading lines
+    set testFileId [ open $test r]
+    set runline ""
+    set PRNUMS ""
+    foreach line [split [read $testFileId] \n] {
+
+      # if its the END. line then stop parsing (optimization for big files)
+      if {[regexp {END.[ *]$} $line match endofscript]} {
+        break
+
+      # if the line is continued, concatenate and continue the loop
+      } elseif {[regexp {RUN: *(.+)(\\)$} $line match oneline suffix]} {
+        set runline "$runline$oneline "
+
+      # if its a terminating RUN: line then do substitution on the whole line
+      # and then save the line.
+      } elseif {[regexp {RUN: *([^&]+)(&&)?} $line match oneline suffix]} {
+        set runline "$runline$oneline"
+        set runline [ substitute $runline $test $tmpFile ]
+        set lines($numLines) $runline
+        set numLines [expr $numLines + 1]
+        set runline ""
+
+      # if its an PR line, save the problem report number
+      } elseif {[regexp {PR([0-9]+)} $line match prnum]} {
+        if {$PRNUMS == ""} {
+          set PRNUMS "PR$prnum"
+        } else {
+          set PRNUMS "$PRNUMS,$prnum"
+        }
+      # if its an XFAIL line, see if we should be XFAILing or not.
+      } elseif {[regexp {XFAIL:[ *](.+)} $line match features]} {
+        set features
+
+        foreach feature [split $features ,] {
+          if { [regexp {\*} $feature match] } {
+              set outcome XFAIL
+          } elseif { [regexp $feature $target_triplet match] } {
+              set outcome XFAIL
+          } elseif { [regexp $feature $TEST_FEATURE_LIST match] } {
+              set outcome XFAIL
+          }
+        }
+      }
+    }
+    
+    # Done reading the script
+    close $testFileId
+    
+    
+    if { $numLines == 0 } {
+      fail "$test: \nDoes not have a RUN line\n"
+    } else {
+      set failed 0
+      for { set i 0 } { $i < $numLines } { set i [ expr $i + 1 ] } {
+        regsub ^.*RUN:(.*) $lines($i) \1 theLine
+        set resultmsg [execOneLine $test $PRNUMS $outcome $i $theLine ]
+        if { $resultmsg != "" } {
+          if { $outcome == "XFAIL" } {
+            xfail "$resultmsg"
+          } else {
+            fail "$resultmsg"
+          }
+          set failed 1
+          break
+        }
+      }
+      if { $failed } {
+        continue
+      } else {
+        if { $PRNUMS != "" } {
+          set PRNUMS " for $PRNUMS"
+        }
+        if { $outcome == "XFAIL" } {
+          xpass "$test$PRNUMS"
+        } else {
+          pass "$test$PRNUMS"
+        }
+      }
+    }
+  }
+}
+
+# Check if klee was configured with POSIX runtime support.
+proc klee_supports_posix_runtime { } {
+    global ENABLE_POSIX_RUNTIME
+    if { $ENABLE_POSIX_RUNTIME == "1" } {
+        return 1
+    }
+    return 0
+}
+
+# Check if klee was configured with uclibc support.
+proc klee_supports_uclibc { } {
+    global ENABLE_UCLIBC
+    if { $ENABLE_UCLIBC == "1" } {
+        return 1
+    }
+    return 0
+}

Added: klee/trunk/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c (added)
+++ klee/trunk/test/regression/2007-07-25-invalid-stp-array-binding-to-objectstate.c Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main(void) {
+  char c[2];
+
+  klee_make_symbolic(&c, sizeof(c));
+
+  if (c[0] > 10) {
+    int x;
+
+    c[1] = 1; // copy object state
+
+    assert(c[0] > 10);
+  }
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-07-30-unflushed-byte.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-07-30-unflushed-byte.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-07-30-unflushed-byte.c (added)
+++ klee/trunk/test/regression/2007-07-30-unflushed-byte.c Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  char i, x[3];
+
+  klee_make_symbolic(&i, sizeof i);
+
+  x[0] = i;
+
+  // DEMAND FAILED:Memory.cpp:read8:199: <isByteFlushed(offset)> is false: "unflushed byte without cache value"
+  char y =  x[1];
+
+  return 0;
+}
+

Added: klee/trunk/test/regression/2007-08-01-bool-zext-in-call.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-01-bool-zext-in-call.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-01-bool-zext-in-call.ll (added)
+++ klee/trunk/test/regression/2007-08-01-bool-zext-in-call.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+; RUN: llvm-as -f %s -o - | %klee 2> %t1.log
+; RUN: not test -f klee-last/test0001.abort.err
+
+declare void @klee_abort()
+
+define i32 @foo(i8 signext %val) {
+        %tmp = zext i8 %val to i32
+	ret i32 %tmp
+}
+
+define i32 @main() {
+	%res = call i32 bitcast (i32 (i8 signext)* @foo to i32 (i1)*)( i1 1 )
+        %check = icmp ne i32 %res, 255
+        br i1 %check, label %error, label %exit
+
+error:
+        call void @klee_abort()
+        unreachable
+
+exit:
+	ret i32 0
+}

Added: klee/trunk/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c (added)
+++ klee/trunk/test/regression/2007-08-01-cache-unclear-on-overwrite-flushed.c Wed May 20 23:36:41 2009
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+#include <stdio.h>
+
+int main() {  
+  unsigned char x;
+
+  klee_make_symbolic(&x, sizeof x);
+  if (x >= 2) klee_silent_exit(0);
+
+  char delete[2] = {0,1};
+
+  char tmp = delete[ x ];
+  char tmp2 = delete[0];
+  delete[ x ] = tmp2;
+
+  if (x==1) {
+    assert(delete[1] == 0);
+    return 0;
+  }
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-08-06-64bit-shift.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-06-64bit-shift.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-06-64bit-shift.c (added)
+++ klee/trunk/test/regression/2007-08-06-64bit-shift.c Wed May 20 23:36:41 2009
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int d;
+  
+  klee_make_symbolic( &d, sizeof(d) );
+
+  int l = d - 1;
+  unsigned long long m = ((unsigned long long) l << 32) / d;
+  if (d==2) {
+    assert(m == 2147483648u);
+  }
+
+  klee_silent_exit(0);
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-08-06-access-after-free.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-06-access-after-free.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-06-access-after-free.c (added)
+++ klee/trunk/test/regression/2007-08-06-access-after-free.c Wed May 20 23:36:41 2009
@@ -0,0 +1,29 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int a;
+  unsigned char *p = malloc(4);
+
+  klee_make_symbolic(&a, sizeof a);
+  klee_make_symbolic(p, sizeof p);
+
+  p[0] |= 16;
+
+  if (a) {
+    free(p);
+
+    // this should give an error instead of
+    // pulling the state from the parent, where
+    // it is not free
+    assert(p[0] > 10);
+   
+    return 0;
+  }
+  
+  assert(p[0] > 10);
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-08-08-free-zero.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-08-free-zero.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-08-free-zero.c (added)
+++ klee/trunk/test/regression/2007-08-08-free-zero.c Wed May 20 23:36:41 2009
@@ -0,0 +1,8 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last | not grep *.err
+
+int main() {
+  free(0);
+  return 0;
+}

Added: klee/trunk/test/regression/2007-08-16-invalid-constant-value.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-16-invalid-constant-value.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-16-invalid-constant-value.c (added)
+++ klee/trunk/test/regression/2007-08-16-invalid-constant-value.c Wed May 20 23:36:41 2009
@@ -0,0 +1,31 @@
+// RUN: rm -f %t4.out %t4.err %t4.log
+// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc
+// RUN: llvm-as -f ../../Feature/_utils._ll -o %t2.bc
+// RUN: llvm-ld -disable-opt %t1.bc %t2.bc -o %t3
+// RUN: %klee %t3.bc
+
+#include <assert.h>
+
+#include "../Feature/utils.h"
+
+int main() {
+  unsigned char a;
+
+  klee_make_symbolic(&a, sizeof a);
+
+  // demand was firing here because an invalid constant
+  // value was being created when implied value did not
+  // subtract using the proper type (so overflowed into
+  // invalid bits)
+  if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { 
+    assert(!klee_is_symbolic(a));
+    printf("add constant case: %d\n", a);
+  }
+
+  if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { 
+    assert(!klee_is_symbolic(a));
+    printf("sub constant case: %d\n", a);
+  }
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-08-16-valid-write-to-freed-object.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-08-16-valid-write-to-freed-object.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-08-16-valid-write-to-freed-object.c (added)
+++ klee/trunk/test/regression/2007-08-16-valid-write-to-freed-object.c Wed May 20 23:36:41 2009
@@ -0,0 +1,24 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+unsigned sym() {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  return x;
+}
+
+int main() {
+  unsigned x, y;
+
+  // sym returns a symbolic object, but because it is
+  // alloca'd it is freed on sym()s return. thats fine,
+  // but the problem is that IVC is going to try to write
+  // into the object right here.
+  //
+  // to support this we need to have a facility for making
+  // state local copies of a freed object.
+  if (sym() == 0) 
+    printf("ok\n");
+
+  return 0;
+}

Added: klee/trunk/test/regression/2007-10-11-free-of-alloca.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-10-11-free-of-alloca.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-10-11-free-of-alloca.c (added)
+++ klee/trunk/test/regression/2007-10-11-free-of-alloca.c Wed May 20 23:36:41 2009
@@ -0,0 +1,9 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.free.err
+
+int main() {
+  int buf[4];
+  free(buf); // this should give runtime error, not crash
+  return 0;
+}

Added: klee/trunk/test/regression/2007-10-11-illegal-access-after-free-and-branch.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-10-11-illegal-access-after-free-and-branch.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-10-11-illegal-access-after-free-and-branch.c (added)
+++ klee/trunk/test/regression/2007-10-11-illegal-access-after-free-and-branch.c Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --optimize %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char **argv) {
+  unsigned char *buf = malloc(3);
+  klee_make_symbolic(buf, 3);
+  if (buf[0]>4) klee_silent_exit(0);
+  unsigned char x = buf[1];
+  free(buf);
+  if (x)
+    return buf[2];
+  klee_silent_exit(0);
+  return 0;
+}

Added: klee/trunk/test/regression/2007-10-12-failed-make-symbolic-after-copy.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2007-10-12-failed-make-symbolic-after-copy.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2007-10-12-failed-make-symbolic-after-copy.c (added)
+++ klee/trunk/test/regression/2007-10-12-failed-make-symbolic-after-copy.c Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.bout
+
+int main() {
+  unsigned x, y[4];
+
+  klee_make_symbolic(&x,sizeof x);
+  if (x>=4) klee_silent_exit(0);
+  
+  y[x] = 0;
+
+  if (x) { // force branch so y is copied
+    klee_make_symbolic(&y, sizeof y);
+    if (y[x]==0) klee_silent_exit(0);
+    return 0; // should be reachable
+  } else {
+    // force read here in case we try to optimize copies smartly later
+    if (y[x]==0) klee_silent_exit(0);
+    return 0; // not reachable
+  }
+}

Added: klee/trunk/test/regression/2008-02-11-phi-nodes-after-invoke.ll
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2008-02-11-phi-nodes-after-invoke.ll?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2008-02-11-phi-nodes-after-invoke.ll (added)
+++ klee/trunk/test/regression/2008-02-11-phi-nodes-after-invoke.ll Wed May 20 23:36:41 2009
@@ -0,0 +1,47 @@
+; RUN: llvm-as -f %s -o - | %klee --no-output --exit-on-error
+
+declare void @klee_abort()
+
+define i32 @foo(i32 %val, i32 %fail) {
+        %code = icmp ne i32 0, %fail
+        br i1 %code, label %failing, label %return
+failing:   
+        unwind        
+return:        
+	ret i32 %val
+}
+
+define void @test(i32 %should_fail) {
+entry:  
+	%res0 = invoke i32 (i32, i32)* @foo(i32 0, i32 %should_fail) 
+                        to label %check_phi unwind label %error
+        
+error:
+        %res1 = zext i8 1 to i32
+        br label %check_phi
+
+check_phi:
+        %val = phi i32 [%never_used, %never_used_label], [%res0, %entry], [%res1, %error]
+        %ok = icmp eq i32 %val, %should_fail
+        br i1 %ok, label %exit, label %on_error
+        call void @klee_abort()
+        unreachable
+
+on_error:
+        call void @klee_abort()
+        unreachable
+            
+exit:
+	ret void
+
+        ;; this is so we hopefully fail if incomingBBIndex isn't set properly
+never_used_label:       
+        %never_used = zext i8 undef to i32
+        br label %check_phi
+}
+
+define i32 @main() {
+        call void (i32)* @test(i32 0)
+        call void (i32)* @test(i32 1)
+	ret i32 0
+}

Added: klee/trunk/test/regression/2008-03-04-free-of-global.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2008-03-04-free-of-global.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2008-03-04-free-of-global.c (added)
+++ klee/trunk/test/regression/2008-03-04-free-of-global.c Wed May 20 23:36:41 2009
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.free.err
+
+int buf[4];
+
+int main() {
+  free(buf); // this should give runtime error, not crash
+  return 0;
+}

Added: klee/trunk/test/regression/2008-03-11-free-of-malloc-zero.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2008-03-11-free-of-malloc-zero.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2008-03-11-free-of-malloc-zero.c (added)
+++ klee/trunk/test/regression/2008-03-11-free-of-malloc-zero.c Wed May 20 23:36:41 2009
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdlib.h>
+
+int main() {
+  // concrete case
+  void *p = malloc(0);
+  free(p);
+
+  p = malloc(0);
+  void *arr[4] = { p, 0, 0, 0 };
+
+  // symbolic case
+  free(arr[klee_range(0, 4, "range")]);
+}

Added: klee/trunk/test/regression/2008-04-10-bad-alloca-free.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2008-04-10-bad-alloca-free.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2008-04-10-bad-alloca-free.c (added)
+++ klee/trunk/test/regression/2008-04-10-bad-alloca-free.c Wed May 20 23:36:41 2009
@@ -0,0 +1,12 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+void f(int *addr) {
+  klee_make_symbolic_name(addr, sizeof *addr, "moo");
+}
+
+int main() {
+  int x;
+  f(&x);
+  return x;
+}

Added: klee/trunk/test/regression/2008-05-23-gep-with-global-const.c
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/2008-05-23-gep-with-global-const.c?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/2008-05-23-gep-with-global-const.c (added)
+++ klee/trunk/test/regression/2008-05-23-gep-with-global-const.c Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc -O0 -c -o %t.bc %s
+// RUN: %klee --exit-on-error %t.bc
+
+#include <assert.h>
+
+int a;
+
+int main() {
+  void *p1 = &((char*) 0)[(long) &a];
+  void *p2 = &a;
+
+  assert(p1 == p2);
+
+  return 0;
+}

Added: klee/trunk/test/regression/dg.exp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/test/regression/dg.exp?rev=72205&view=auto

==============================================================================
--- klee/trunk/test/regression/dg.exp (added)
+++ klee/trunk/test/regression/dg.exp Wed May 20 23:36:41 2009
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]

Added: klee/trunk/tools/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/Makefile (added)
+++ klee/trunk/tools/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,21 @@
+#===-- tools/Makefile --------------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+#
+# Relative path to the top of the source tree.
+#
+LEVEL=..
+
+#
+# List all of the subdirectories that we will compile.
+#
+PARALLEL_DIRS=klee kleaver klee-bout-tool gen-random-bout
+# FIXME: Move qplayer functionality into kleaver
+
+include $(LEVEL)/Makefile.common

Added: klee/trunk/tools/gen-random-bout/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/gen-random-bout/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/gen-random-bout/Makefile (added)
+++ klee/trunk/tools/gen-random-bout/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,7 @@
+##===- tools/klee/Makefile ---------------*- Makefile -*-===##
+
+LEVEL=../..
+TOOLNAME = gen-random-bout
+USEDLIBS = kleeBasic.a
+
+include $(LEVEL)/Makefile.common

Added: klee/trunk/tools/gen-random-bout/gen-random-bout.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/gen-random-bout/gen-random-bout.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/gen-random-bout/gen-random-bout.cpp (added)
+++ klee/trunk/tools/gen-random-bout/gen-random-bout.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,124 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "klee/Internal/ADT/BOut.h"
+
+// --sym-args 0 1 10 --sym-args 0 2 2 --sym-files 1 8 --sym-stdout
+static int getint(char *i) {
+  if(!i) {
+    fprintf(stderr, "ran out of arguments!\n");
+    assert(i);
+  }
+  return atoi(i);
+}
+
+#define MAX 64
+static void push_obj(BOut *b, const char *name, unsigned non_zero_bytes, 
+                     unsigned total_bytes) {
+  BOutObject *o = &b->objects[b->numObjects++];
+  assert(b->numObjects < MAX);
+
+  o->name = strdup(name);
+  o->numBytes = total_bytes;
+  o->bytes = (unsigned char *)malloc(o->numBytes);
+
+  unsigned i;
+  for(i = 0; i < non_zero_bytes; i++)
+    o->bytes[i] = random();
+
+  for(i = non_zero_bytes; i < total_bytes; i++)
+    o->bytes[i] = 0;
+}
+
+
+static void push_range(BOut *b, const char *name, unsigned value) {
+  BOutObject *o = &b->objects[b->numObjects++];
+  assert(b->numObjects < MAX);
+
+  o->name = strdup(name);
+  o->numBytes = 4;
+  o->bytes = (unsigned char *)malloc(o->numBytes);
+
+  *(unsigned*)o->bytes = value;
+}
+
+int main(int argc, char *argv[]) {
+  unsigned i, narg;
+  unsigned sym_stdout = 0;
+
+  if (argc < 2) {
+    fprintf(stderr, "Usage: %s <random-seed> <argument-types>\n", argv[0]);
+    fprintf(stderr, "       If <random-seed> is 0, time(NULL)*getpid() is used as a seed\n");
+    fprintf(stderr, "       <argument-types> are the ones accepted by KLEE: --sym-args, --sym-files etc.\n");
+    fprintf(stderr, "   Ex: %s 100 --sym-args 0 2 2 --sym-files 1 8\n", argv[0]);
+    exit(1);
+  }
+
+  unsigned seed = atoi(argv[1]);
+  if (seed)
+    srandom(seed);
+  else srandom(time(NULL) * getpid());
+
+  BOut b;
+  b.numArgs = argc;
+  b.args = argv;
+  b.symArgvs = 0;
+  b.symArgvLen = 0;
+
+  b.numObjects = 0;
+  b.objects = (BOutObject *)malloc(MAX * sizeof *b.objects);
+
+  for(i = 2; i < (unsigned)argc; i++) {
+    if(strcmp(argv[i], "--sym-args") == 0) {
+      unsigned lb = getint(argv[++i]);
+      unsigned ub = getint(argv[++i]);
+      unsigned nbytes = getint(argv[++i]);
+
+      narg = random() % (ub - lb) + lb;
+      push_range(&b, "range", narg);
+
+      while(narg-- > 0) {
+        unsigned x = random() % (nbytes + 1);
+
+        // A little different than how klee does it but more natural
+        // for random.
+        static int total_args;
+        char arg[1024];
+
+        sprintf(arg, "arg%d", total_args++);
+        push_obj(&b, arg, x, nbytes+1);
+      }
+    } else if(strcmp(argv[i], "--sym-stdout") == 0) {
+      if(!sym_stdout) {
+        sym_stdout = 1;
+        push_obj(&b, "stdout", 1024, 1024);
+        push_obj(&b, "stdout-stat", sizeof(struct stat64), 
+                 sizeof(struct stat64));
+      }
+    } else if(strcmp(argv[i], "--sym-files") == 0) {
+      unsigned nfiles = getint(argv[++i]);
+      unsigned nbytes = getint(argv[++i]);
+
+      while(nfiles-- > 0) {
+        push_obj(&b, "file", nbytes, nbytes);
+        push_obj(&b, "file-stat", sizeof(struct stat64), sizeof(struct stat64));
+      }
+
+      push_obj(&b, "stdin", nbytes, nbytes);
+      push_obj(&b, "stdin-stat", sizeof(struct stat64), sizeof(struct stat64));
+    } else {
+      fprintf(stderr, "unexpected option <%s>\n", argv[i]);
+      assert(0);
+    }
+  }
+
+  if (!bOut_toFile(&b, "file.bout"))
+    assert(0);
+  return 0;
+}

Added: klee/trunk/tools/kleaver/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/kleaver/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/kleaver/Makefile (added)
+++ klee/trunk/tools/kleaver/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,19 @@
+#===-- tools/kleaver/Makefile ------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+TOOLNAME = kleaver
+# FIXME: Ideally we wouldn't have any LLVM dependencies here, which
+# means kicking out klee's Support.
+USEDLIBS = kleaverExpr.a kleaverSolver.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS = support
+
+include $(LEVEL)/Makefile.common
+
+LIBS += -lstp

Added: klee/trunk/tools/kleaver/main.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/kleaver/main.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/kleaver/main.cpp (added)
+++ klee/trunk/tools/kleaver/main.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,120 @@
+#include "expr/Lexer.h"
+#include "expr/Parser.h"
+
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+#include "klee/util/ExprPPrinter.h"
+#include "klee/util/ExprVisitor.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/System/Signals.h"
+
+#include <iomanip>
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+using namespace klee::expr;
+
+namespace {
+  llvm::cl::opt<std::string>
+  InputFile(llvm::cl::desc("<input query log>"), llvm::cl::Positional,
+            llvm::cl::init("-"));
+
+  enum ToolActions {
+    PrintTokens,
+    PrintAST
+  };
+
+  static llvm::cl::opt<ToolActions> 
+  ToolAction(llvm::cl::desc("Tool actions:"),
+             llvm::cl::init(PrintTokens),
+             llvm::cl::values(
+             clEnumValN(PrintTokens, "print-tokens",
+                        "Print tokens from the input file."),
+             clEnumValN(PrintAST, "print-ast",
+                        "Print parsed AST nodes from the input file."),
+             clEnumValEnd));
+}
+
+static std::string escapedString(const char *start, unsigned length) {
+  std::stringstream s;
+  for (unsigned i=0; i<length; ++i) {
+    char c = start[i];
+    if (isprint(c)) {
+      s << c;
+    } else if (c == '\n') {
+      s << "\\n";
+    } else {
+      s << "\\x" << hexdigit(((unsigned char) c >> 4) & 0xF) << hexdigit((unsigned char) c & 0xF);
+    }
+  }
+  return s.str();
+}
+
+static void PrintInputTokens(const MemoryBuffer *MB) {
+  Lexer L(MB);
+  Token T;
+  do {
+    L.Lex(T);
+    llvm::cout << "(Token \"" << T.getKindName() << "\" "
+               << "\"" << escapedString(T.start, T.length) << "\" "
+               << T.length << " "
+               << T.line << " " << T.column << ")\n";
+  } while (T.kind != Token::EndOfFile);
+}
+
+static bool PrintInputAST(const char *Filename,
+                          const MemoryBuffer *MB) {
+  Parser *P = Parser::Create(Filename, MB);
+  P->SetMaxErrors(20);
+  while (Decl *D = P->ParseTopLevelDecl()) {
+    if (!P->GetNumErrors())
+      D->dump();
+    delete D;
+  }
+
+  bool success = true;
+  if (unsigned N = P->GetNumErrors()) {
+    llvm::cerr << Filename << ": parse failure: "
+               << N << " errors.\n";
+    success = false;
+  }
+  delete P;
+
+  return success;
+}
+
+int main(int argc, char **argv) {
+  bool success = true;
+
+  llvm::sys::PrintStackTraceOnErrorSignal();
+  llvm::cl::ParseCommandLineOptions(argc, argv);
+
+  std::string ErrorStr;
+  MemoryBuffer *MB = MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), &ErrorStr);
+  if (!MB) {
+    llvm::cerr << argv[0] << ": ERROR: " << ErrorStr << "\n";
+    return 1;
+  }
+
+  switch (ToolAction) {
+  case PrintTokens:
+    PrintInputTokens(MB);
+    break;
+  case PrintAST:
+    success = PrintInputAST(InputFile=="-" ? "<stdin>" : InputFile.c_str(), MB);
+    break;
+  default:
+    llvm::cerr << argv[0] << ": ERROR: Unknown program action!\n";
+  }
+
+  delete MB;
+
+  llvm::llvm_shutdown();
+  return success ? 0 : 1;
+}

Added: klee/trunk/tools/klee-bout-tool/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/klee-bout-tool/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/klee-bout-tool/Makefile (added)
+++ klee/trunk/tools/klee-bout-tool/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,46 @@
+#===-- tools/klee-bout-tool/Makefile -----------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL = ../..
+
+TOOLSCRIPTNAME := klee-bout-tool
+
+include $(LEVEL)/Makefile.common
+
+# FIXME: Move this stuff (to "build" a script) into Makefile.rules.
+
+ToolBuildPath := $(ToolDir)/$(TOOLSCRIPTNAME)
+
+all-local:: $(ToolBuildPath)
+
+$(ToolBuildPath): $(ToolDir)/.dir
+
+$(ToolBuildPath): $(TOOLSCRIPTNAME)
+	$(Echo) Copying $(BuildMode) script $(TOOLSCRIPTNAME)
+	$(Verb) $(CP) -f $(TOOLSCRIPTNAME) "$@"
+	$(Verb) chmod 0755 "$@"
+
+ifdef NO_INSTALL
+install-local::
+	$(Echo) Install circumvented with NO_INSTALL
+uninstall-local::
+	$(Echo) Uninstall circumvented with NO_INSTALL
+else
+DestTool = $(PROJ_bindir)/$(TOOLSCRIPTNAME)
+
+install-local:: $(DestTool)
+
+$(DestTool): $(ToolBuildPath) $(PROJ_bindir)
+	$(Echo) Installing $(BuildMode) $(DestTool)
+	$(Verb) $(ProgInstall) $(ToolBuildPath) $(DestTool)
+
+uninstall-local::
+	$(Echo) Uninstalling $(BuildMode) $(DestTool)
+	-$(Verb) $(RM) -f $(DestTool)
+endif

Added: klee/trunk/tools/klee-bout-tool/klee-bout-tool
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/klee-bout-tool/klee-bout-tool?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/klee-bout-tool/klee-bout-tool (added)
+++ klee/trunk/tools/klee-bout-tool/klee-bout-tool Wed May 20 23:36:41 2009
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+
+import os
+import struct
+import sys
+
+version_no=2
+
+class BOutError(Exception):
+    pass
+
+class BOut:
+    @staticmethod
+    def fromfile(path):
+        if not os.path.exists(path):
+            print "ERROR: file %s not found" % (path)
+            sys.exit(1)
+            
+        f = open(path,'rb')
+        hdr = f.read(5)
+        if len(hdr)!=5 or hdr!='BOUT\n':
+            raise BOutError,'unrecognized file'
+        version, = struct.unpack('>i', f.read(4))
+        if version > version_no:
+            raise BOutError,'unrecognized version'
+        numArgs, = struct.unpack('>i', f.read(4))
+        args = []
+        for i in range(numArgs):
+            size, = struct.unpack('>i', f.read(4))
+            args.append(f.read(size))
+            
+        if version >= 2:
+            symArgvs, = struct.unpack('>i', f.read(4))
+            symArgvLen, = struct.unpack('>i', f.read(4))
+        else:
+            symArgvs = 0
+            symArgvLen = 0
+
+        numObjects, = struct.unpack('>i', f.read(4))
+        objects = []
+        for i in range(numObjects):
+            size, = struct.unpack('>i', f.read(4))
+            name = f.read(size)
+            size, = struct.unpack('>i', f.read(4))
+            bytes = f.read(size)
+            objects.append( (name,bytes) )
+
+        # Create an instance
+        b = BOut(version, args, symArgvs, symArgvLen, objects)
+        # Augment with extra filename field
+        b.filename = path
+        return b
+    
+    def __init__(self, version, args, symArgvs, symArgvLen, objects):
+        self.version = version
+        self.symArgvs = symArgvs
+        self.symArgvLen = symArgvLen
+        self.args = args
+        self.objects = objects
+
+        # add a field that represents the name of the program used to
+        # generate this .bout file:
+        program_full_path = self.args[0]
+        program_name = os.path.basename(program_full_path)
+        # sometimes program names end in .bc, so strip them
+        if program_name.endswith('.bc'):
+          program_name = program_name[:-3]
+        self.programName = program_name
+        
+def trimZeros(str):
+    for i in range(len(str))[::-1]:
+        if str[i] != '\x00':
+            return str[:i+1]
+    return ''
+    
+def main(args):
+    from optparse import OptionParser
+    op = OptionParser("usage: %prog [options] files")
+    op.add_option('','--trim-zeros', dest='trimZeros', action='store_true', 
+                  default=False,
+                  help='trim trailing zeros')
+    
+    opts,args = op.parse_args()
+    if not args:
+        op.error("incorrect number of arguments")
+
+    for file in args:
+        b = BOut.fromfile(file)
+        pos = 0
+        print 'bout file  : %r' % file
+        print 'args       : %r' % b.args
+        print 'num objects: %r' % len(b.objects)
+        for i,(name,data) in enumerate(b.objects):
+            if opts.trimZeros:
+                str = trimZeros(data)
+            else:
+                str = data
+
+            print 'object %4d: name: %r' % (i, name)
+            print 'object %4d: size: %r' % (i, len(data))
+            print 'object %4d: data: %r' % (i, str)
+        if file != args[-1]:
+            print
+
+if __name__=='__main__':
+    main(sys.argv)

Propchange: klee/trunk/tools/klee-bout-tool/klee-bout-tool

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/tools/klee/Debug.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/klee/Debug.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/klee/Debug.cpp (added)
+++ klee/trunk/tools/klee/Debug.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,12 @@
+#include <klee/Expr.h>
+#include <iostream>
+
+void kdb_printExpr(klee::Expr *e) {
+  llvm::cerr << "expr: " << e << " -- ";
+  if (e) {
+    llvm::cerr << *e;
+  } else {
+    llvm::cerr << "(null)";
+  }
+  llvm::cerr << "\n";
+}

Added: klee/trunk/tools/klee/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/klee/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/klee/Makefile (added)
+++ klee/trunk/tools/klee/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,22 @@
+#===-- tools/klee/Makefile ---------------------------------*- Makefile -*--===#
+#
+#                     The KLEE Symbolic Virtual Machine
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+LEVEL=../..
+TOOLNAME = klee
+USEDLIBS = kleeCore.a kleeModule.a kleaverSolver.a kleaverExpr.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS = bitreader bitwriter ipo linker engine
+
+include $(LEVEL)/Makefile.common
+
+ifeq ($(ENABLE_STPLOG), 1)
+	LIBS += -lstplog
+endif
+
+LIBS += -lstp 
+#-ltcmalloc

Added: klee/trunk/tools/klee/main.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/tools/klee/main.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/tools/klee/main.cpp (added)
+++ klee/trunk/tools/klee/main.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,1422 @@
+/* -*- mode: c++; c-basic-offset: 2; -*- */
+
+// FIXME: This does not belong here.
+#include "../lib/Core/Common.h"
+
+#include "klee/ExecutionState.h"
+#include "klee/Expr.h"
+#include "klee/Interpreter.h"
+#include "klee/Statistics.h"
+#include "klee/Config/config.h"
+#include "klee/Internal/ADT/BOut.h"
+#include "klee/Internal/ADT/TreeStream.h"
+#include "klee/Internal/Support/ModuleUtil.h"
+#include "klee/Internal/System/Time.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Type.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Signals.h"
+#include <iostream>
+#include <fstream>
+#include <cerrno>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#include <iostream>
+#include <iterator>
+#include <fstream>
+#include <sstream>
+
+using namespace llvm;
+using namespace klee;
+
+namespace {
+  cl::opt<std::string>
+  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));
+
+  cl::opt<std::string>
+  RunInDir("run-in", cl::desc("Change to the given directory prior to executing"));
+
+  cl::opt<std::string>
+  Environ("environ", cl::desc("Parse environ from given file (in \"env\" format)"));
+
+  cl::list<std::string>
+  InputArgv(cl::ConsumeAfter, 
+            cl::desc("<program arguments>..."));
+
+  cl::opt<bool>
+  NoOutput("no-output", 
+           cl::desc("Don't generate test files"));
+    
+  cl::opt<bool>
+  WarnAllExternals("warn-all-externals", 
+                   cl::desc("Give initial warning for all externals."));
+    
+  cl::opt<bool>
+  WriteCVCs("write-cvcs", 
+            cl::desc("Write .cvc files for each test case"));
+
+  cl::opt<bool>
+  WritePCs("write-pcs", 
+            cl::desc("Write .pc files for each test case"));
+  
+  cl::opt<bool>
+  WriteCov("write-cov", 
+           cl::desc("Write coverage information for each test case"));
+  
+  cl::opt<bool>
+  WriteTestInfo("write-test-info", 
+                cl::desc("Write additional test case information"));
+  
+  cl::opt<bool>
+  WritePaths("write-paths", 
+                cl::desc("Write .path files for each test case"));
+    
+  cl::opt<bool>
+  WriteSymPaths("write-sym-paths", 
+                cl::desc("Write .sym.path files for each test case"));
+    
+  cl::opt<bool>
+  ExitOnError("exit-on-error", 
+              cl::desc("Exit if errors occur"));
+    
+
+  enum LibcType {
+    NoLibc, KleeLibc, UcLibc
+  };
+
+  cl::opt<LibcType>
+  Libc("libc", 
+       cl::desc("Choose libc version (none by default)."),
+       cl::values(clEnumValN(NoLibc, "none", "Don't link in a libc"),
+                  clEnumValN(KleeLibc, "klee", "Link in klee libc"),
+		  clEnumValN(UcLibc, "uclibc", "Link in uclibc (adapted for klee)"),
+		  clEnumValEnd),
+       cl::init(NoLibc));
+
+    
+  cl::opt<bool>
+  WithPOSIXRuntime("posix-runtime", 
+		cl::desc("Link with POSIX runtime"),
+		cl::init(false));
+    
+  cl::opt<bool>
+  OptimizeModule("optimize", 
+                 cl::desc("Optimize before execution"));
+
+  cl::opt<bool>
+  CheckDivZero("check-div-zero", 
+               cl::desc("Inject checks for division-by-zero"),
+               cl::init(true));
+    
+  cl::opt<std::string>
+  OutputDir("output-dir", 
+            cl::desc("Directory to write results in (defaults to klee-out-N)"),
+            cl::init(""));
+
+  // this is a fake entry, its automagically handled
+  cl::list<std::string>
+  ReadArgsFilesFake("read-args", 
+                    cl::desc("File to read arguments from (one arg per line)"));
+    
+  cl::opt<bool>
+  ReplayKeepSymbolic("replay-keep-symbolic", 
+                     cl::desc("Replay the test cases only by asserting"
+                              "the bytes, not necessarily making them concrete."));
+    
+  cl::list<std::string>
+  ReplayOutFile("replay-out",
+                cl::desc("Specify an out file to replay"),
+                cl::value_desc("out file"));
+
+  cl::list<std::string>
+  ReplayOutDir("replay-out-dir",
+	       cl::desc("Specify a directory to replay .out files from"),
+	       cl::value_desc("output directory"));
+
+  cl::opt<std::string>
+  ReplayPathFile("replay-path",
+                 cl::desc("Specify a path file to replay"),
+                 cl::value_desc("path file"));
+
+  cl::list<std::string>
+  SeedOutFile("seed-out");
+  
+  cl::list<std::string>
+  SeedOutDir("seed-out-dir");
+  
+  cl::opt<unsigned>
+  MakeConcreteSymbolic("make-concrete-symbolic",
+                       cl::desc("Rate at which to make concrete reads symbolic (0=off)"),
+                       cl::init(0));
+
+  cl::opt<bool>
+  InitEnv("init-env",
+	  cl::desc("Create custom environment.  Options that can be passed as arguments to the programs are: --sym-argv <max-len>  --sym-argvs <min-argvs> <max-argvs> <max-len> + file model options"));
+ 
+  cl::opt<unsigned>
+  StopAfterNTests("stop-after-n-tests",
+	     cl::desc("Stop execution after generating the given number of tests.  Extra tests corresponding to partially explored paths will also be dumped."),
+	     cl::init(0));
+
+  cl::opt<bool>
+  Watchdog("watchdog",
+           cl::desc("Use a watchdog process to enforce --max-time."),
+           cl::init(0));
+}
+
+extern bool WriteTraces;
+extern cl::opt<double> MaxTime;
+
+/***/
+
+class KleeHandler : public InterpreterHandler {
+private:
+  Interpreter *m_interpreter;
+  TreeStreamWriter *m_pathWriter, *m_symPathWriter;
+  std::ostream *m_infoFile;
+
+  char m_outputDirectory[1024];
+  unsigned m_testIndex;  // number of tests written so far
+  unsigned m_pathsExplored; // number of paths explored so far
+
+  // used for writing .bout files
+  int m_argc;
+  char **m_argv;
+
+public:
+  KleeHandler(int argc, char **argv);
+  ~KleeHandler();
+
+  std::ostream &getInfoStream() const { return *m_infoFile; }
+  unsigned getNumTestCases() { return m_testIndex; }
+  unsigned getNumPathsExplored() { return m_pathsExplored; }
+  void incPathsExplored() { m_pathsExplored++; }
+
+  void setInterpreter(Interpreter *i);
+
+  void processTestCase(const ExecutionState  &state,
+                       const char *errorMessage, 
+                       const char *errorSuffix);
+
+  std::string getOutputFilename(const std::string &filename);
+  std::ostream *openOutputFile(const std::string &filename);
+  std::string getTestFilename(const std::string &suffix, unsigned id);
+  std::ostream *openTestFile(const std::string &suffix, unsigned id);
+
+  // load a .out file
+  static void loadOutFile(std::string name, 
+                          std::vector<unsigned char> &buffer);
+
+  // load a .path file
+  static void loadPathFile(std::string name, 
+                           std::vector<bool> &buffer);
+
+  static void getOutFiles(std::string path,
+			  std::vector<std::string> &results);
+};
+
+KleeHandler::KleeHandler(int argc, char **argv) 
+  : m_interpreter(0),
+    m_pathWriter(0),
+    m_symPathWriter(0),
+    m_infoFile(0),
+    m_testIndex(0),
+    m_pathsExplored(0),
+    m_argc(argc),
+    m_argv(argv) {
+  std::string theDir;
+
+  if (OutputDir=="") {
+    llvm::sys::Path directory(InputFile);
+    std::string dirname = "";
+    directory.eraseComponent();
+    
+    if (directory.isEmpty())
+      directory.set(".");
+    
+    for (int i = 0; ; i++) {
+      char buf[256], tmp[64];
+      sprintf(tmp, "klee-out-%d", i);
+      dirname = tmp;
+      sprintf(buf, "%s/%s", directory.c_str(), tmp);
+      theDir = buf;
+      
+      if (DIR *dir = opendir(theDir.c_str())) {
+        closedir(dir);
+      } else {
+        break;
+      }
+    }    
+
+    llvm::cerr << "KLEE: output directory = \"" << dirname << "\"\n";
+
+    llvm::sys::Path klee_last(directory);
+    klee_last.appendComponent("klee-last");
+      
+    if ((unlink(klee_last.c_str()) < 0) && (errno != ENOENT)) {
+      perror("Cannot unlink klee-last");
+      assert(0 && "exiting.");
+    }
+    
+    if (symlink(dirname.c_str(), klee_last.c_str()) < 0) {
+      perror("Cannot make symlink");
+      assert(0 && "exiting.");
+    }
+  } else {
+    theDir = OutputDir;
+  }
+  
+  sys::Path p(theDir);
+  if (!p.isAbsolute()) {
+    sys::Path cwd = sys::Path::GetCurrentDirectory();
+    cwd.appendComponent(theDir);
+    p = cwd;
+  }
+  strcpy(m_outputDirectory, p.c_str());
+
+  if (mkdir(m_outputDirectory, 0775) < 0) {
+    llvm::cerr << "KLEE: ERROR: Unable to make output directory: \"" 
+               << m_outputDirectory 
+               << "\", refusing to overwrite.\n";
+    exit(1);
+  }
+
+  char fname[1024];
+  snprintf(fname, sizeof(fname), "%s/warnings.txt", m_outputDirectory);
+  klee_warning_file = fopen(fname, "w");
+  assert(klee_warning_file);
+
+  snprintf(fname, sizeof(fname), "%s/messages.txt", m_outputDirectory);
+  klee_message_file = fopen(fname, "w");
+  assert(klee_message_file);
+
+  m_infoFile = openOutputFile("info");
+}
+
+KleeHandler::~KleeHandler() {
+  if (m_pathWriter) delete m_pathWriter;
+  if (m_symPathWriter) delete m_symPathWriter;
+  delete m_infoFile;
+}
+
+void KleeHandler::setInterpreter(Interpreter *i) {
+  m_interpreter = i;
+
+  if (WritePaths) {
+    m_pathWriter = new TreeStreamWriter(getOutputFilename("paths.ts"));
+    assert(m_pathWriter->good());
+    m_interpreter->setPathWriter(m_pathWriter);
+  }
+
+  if (WriteSymPaths) {
+    m_symPathWriter = new TreeStreamWriter(getOutputFilename("symPaths.ts"));
+    assert(m_symPathWriter->good());
+    m_interpreter->setSymbolicPathWriter(m_symPathWriter);
+  }
+}
+
+std::string KleeHandler::getOutputFilename(const std::string &filename) {
+  char outfile[1024];
+  sprintf(outfile, "%s/%s", m_outputDirectory, filename.c_str());
+  return outfile;
+}
+
+std::ostream *KleeHandler::openOutputFile(const std::string &filename) {
+  std::ios::openmode io_mode = std::ios::out | std::ios::trunc 
+                             | std::ios::binary;
+  std::ostream *f;
+  std::string path = getOutputFilename(filename);
+  f = new std::ofstream(path.c_str(), io_mode);
+  if (!f) {
+    klee_warning("out of memory");
+  } else if (!f->good()) {
+    klee_warning("error opening: %s", filename.c_str());
+    delete f;
+    f = NULL;
+  }
+
+  return f;
+}
+
+std::string KleeHandler::getTestFilename(const std::string &suffix, unsigned id) {
+  char filename[1024];
+  sprintf(filename, "test%06d.%s", id, suffix.c_str());
+  return getOutputFilename(filename);
+}
+
+std::ostream *KleeHandler::openTestFile(const std::string &suffix, unsigned id) {
+  char filename[1024];
+  sprintf(filename, "test%06d.%s", id, suffix.c_str());
+  return openOutputFile(filename);
+}
+
+
+/* Outputs all files (.bout, .pc, .cov etc.) describing a test case */
+void KleeHandler::processTestCase(const ExecutionState &state,
+                                  const char *errorMessage, 
+                                  const char *errorSuffix) {
+  if (errorMessage && ExitOnError) {
+    llvm::cerr << "EXITING ON ERROR: " << errorMessage << "\n";
+    abort();
+  }
+
+  if (!NoOutput) {
+    std::vector< std::pair<std::string, std::vector<unsigned char> > > out;
+    bool success = m_interpreter->getSymbolicSolution(state, out);
+
+    if (!success)
+      klee_warning("unable to get symbolic solution, losing test case");
+
+    double start_time = util::getWallTime();
+
+    unsigned id = ++m_testIndex;
+
+    if (success) {
+      BOut b;      
+      b.numArgs = m_argc;
+      b.args = m_argv;
+      b.symArgvs = 0;
+      b.symArgvLen = 0;
+      b.numObjects = out.size();
+      b.objects = new BOutObject[b.numObjects];
+      assert(b.objects);
+      for (unsigned i=0; i<b.numObjects; i++) {
+        BOutObject *o = &b.objects[i];
+        o->name = const_cast<char*>(out[i].first.c_str());
+        o->numBytes = out[i].second.size();
+        o->bytes = new unsigned char[o->numBytes];
+        assert(o->bytes);
+        std::copy(out[i].second.begin(), out[i].second.end(), o->bytes);
+      }
+      
+      if (!bOut_toFile(&b, getTestFilename("bout", id).c_str())) {
+        klee_warning("unable to write output test case, losing it");
+      }
+      
+      for (unsigned i=0; i<b.numObjects; i++)
+        delete[] b.objects[i].bytes;
+      delete[] b.objects;
+    }
+
+    if (errorMessage) {
+      std::ostream *f = openTestFile(errorSuffix, id);
+      *f << errorMessage;
+      delete f;
+    }
+    
+    if (m_pathWriter) {
+      std::vector<unsigned char> concreteBranches;
+      m_pathWriter->readStream(m_interpreter->getPathStreamID(state),
+                               concreteBranches);
+      std::ostream *f = openTestFile("path", id);
+      std::copy(concreteBranches.begin(), concreteBranches.end(), 
+                std::ostream_iterator<unsigned char>(*f, "\n"));
+      delete f;
+    }
+   
+    if (errorMessage || WritePCs) {
+      std::string constraints;
+      m_interpreter->getConstraintLog(state, constraints);
+      std::ostream *f = openTestFile("pc", id);
+      *f << constraints;
+      delete f;
+    }
+
+    if (WriteCVCs) {
+      std::string constraints;
+      m_interpreter->getConstraintLog(state, constraints, true);
+      std::ostream *f = openTestFile("cvc", id);
+      *f << constraints;
+      delete f;
+    }
+    
+    if (m_symPathWriter) {
+      std::vector<unsigned char> symbolicBranches;
+      m_symPathWriter->readStream(m_interpreter->getSymbolicPathStreamID(state),
+                                  symbolicBranches);
+      std::ostream *f = openTestFile("sym.path", id);
+      std::copy(symbolicBranches.begin(), symbolicBranches.end(), 
+                std::ostream_iterator<unsigned char>(*f, "\n"));
+      delete f;
+    }
+
+    if (WriteCov) {
+      std::map<const std::string*, std::set<unsigned> > cov;
+      m_interpreter->getCoveredLines(state, cov);
+      std::ostream *f = openTestFile("cov", id);
+      for (std::map<const std::string*, std::set<unsigned> >::iterator
+             it = cov.begin(), ie = cov.end();
+           it != ie; ++it) {
+        for (std::set<unsigned>::iterator
+               it2 = it->second.begin(), ie = it->second.end();
+             it2 != ie; ++it2)
+          *f << *it->first << ":" << *it2 << "\n";
+      }
+      delete f;
+    }
+
+    if (WriteTraces) {
+      std::ostream *f = openTestFile("trace", id);
+      state.exeTraceMgr.printAllEvents(*f);
+      delete f;
+    }
+
+    if (m_testIndex == StopAfterNTests)
+      m_interpreter->setHaltExecution(true);
+
+    if (WriteTestInfo) {
+      double elapsed_time = util::getWallTime() - start_time;
+      std::ostream *f = openTestFile("info", id);
+      *f << "Time to generate test case: " 
+         << elapsed_time << "s\n";
+      delete f;
+    }
+  }
+}
+
+  // load a .path file
+void KleeHandler::loadPathFile(std::string name, 
+                                     std::vector<bool> &buffer) {
+  std::ifstream f(name.c_str(), std::ios::in | std::ios::binary);
+
+  if (!f.good())
+    assert(0 && "unable to open path file");
+
+  while (f.good()) {
+    unsigned value;
+    f >> value;
+    buffer.push_back(!!value);
+    f.get();
+  }
+}
+
+void KleeHandler::getOutFiles(std::string path,
+			      std::vector<std::string> &results) {
+  llvm::sys::Path p(path);
+  std::set<llvm::sys::Path> contents;
+  std::string error;
+  if (p.getDirectoryContents(contents, &error)) {
+    llvm::cerr << "ERROR: unable to read output directory: " << path << ": " << error << "\n";
+    exit(1);
+  }
+  for (std::set<llvm::sys::Path>::iterator it = contents.begin(),
+         ie = contents.end(); it != ie; ++it) {
+    std::string f = it->toString();
+    if (f.substr(f.size()-5,f.size()) == ".bout") {
+      results.push_back(f);
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// main Driver function
+//
+#if ENABLE_STPLOG == 1
+extern "C" void STPLOG_init(const char *);
+#endif
+
+static std::string strip(std::string &in) {
+  unsigned len = in.size();
+  unsigned lead = 0, trail = len;
+  while (lead<len && isspace(in[lead]))
+    ++lead;
+  while (trail>lead && isspace(in[trail-1]))
+    --trail;
+  return in.substr(lead, trail-lead);
+}
+
+static void readArgumentsFromFile(char *file, std::vector<std::string> &results) {
+  std::ifstream f(file);
+  assert(f.is_open() && "unable to open input for reading arguments");
+  while (!f.eof()) {
+    std::string line;
+    std::getline(f, line);
+    line = strip(line);
+    if (!line.empty())
+      results.push_back(line);
+  }
+  f.close();
+}
+
+static void parseArguments(int argc, char **argv) {
+  std::vector<std::string> arguments;
+
+  for (int i=1; i<argc; i++) {
+    if (!strcmp(argv[i],"--read-args") && i+1<argc) {
+      readArgumentsFromFile(argv[++i], arguments);
+    } else {
+      arguments.push_back(argv[i]);
+    }
+  }
+    
+  int numArgs = arguments.size() + 1;
+  const char **argArray = new const char*[numArgs+1];
+  argArray[0] = argv[0];
+  argArray[numArgs] = 0;
+  for (int i=1; i<numArgs; i++) {
+    argArray[i] = arguments[i-1].c_str();
+  }
+
+  cl::ParseCommandLineOptions(numArgs, (char**) argArray, " klee\n");
+  delete[] argArray;
+}
+
+
+
+static int initEnv(Module *mainModule) {
+
+  /*
+    nArgcP = alloc oldArgc->getType()
+    nArgvV = alloc oldArgv->getType()
+    store oldArgc nArgcP
+    store oldArgv nArgvP
+    klee_init_environment(nArgcP, nArgvP)
+    nArgc = load nArgcP
+    nArgv = load nArgvP
+    oldArgc->replaceAllUsesWith(nArgc)
+    oldArgv->replaceAllUsesWith(nArgv)
+  */
+
+  Function *mainFn = mainModule->getFunction("main");
+    
+  if (mainFn->arg_size() < 2) {
+    llvm::cerr << "Cannot handle ""-init-env"" when main() has less than two arguments.\n";
+    return -1;
+  }
+
+  Instruction* firstInst = mainFn->begin()->begin();
+
+  Value* oldArgc = mainFn->arg_begin();
+  Value* oldArgv = ++mainFn->arg_begin();
+  
+  AllocaInst* argcPtr = new AllocaInst(oldArgc->getType(), "argcPtr", firstInst);
+  AllocaInst* argvPtr = new AllocaInst(oldArgv->getType(), "argvPtr", firstInst);
+
+  /* Insert void klee_init_env(int* argc, char*** argv) */
+  std::vector<const Type*> params;
+  params.push_back(Type::Int32Ty);
+  params.push_back(Type::Int32Ty);
+  Function* initEnvFn = 
+    cast<Function>(mainModule->getOrInsertFunction("klee_init_env",
+                                                   Type::VoidTy,
+                                                   argcPtr->getType(),
+                                                   argvPtr->getType(),
+                                                   NULL));
+  assert(initEnvFn);    
+  std::vector<Value*> args;
+  args.push_back(argcPtr);
+  args.push_back(argvPtr);
+  Instruction* initEnvCall = CallInst::Create(initEnvFn, args.begin(), args.end(), 
+					      "", firstInst);
+  Value *argc = new LoadInst(argcPtr, "newArgc", firstInst);
+  Value *argv = new LoadInst(argvPtr, "newArgv", firstInst);
+  
+  oldArgc->replaceAllUsesWith(argc);
+  oldArgv->replaceAllUsesWith(argv);
+
+  new StoreInst(oldArgc, argcPtr, initEnvCall);
+  new StoreInst(oldArgv, argvPtr, initEnvCall);
+
+  return 0;
+}
+
+
+// This is a terrible hack until we get some real modelling of the
+// system. All we do is check the undefined symbols and m and warn about
+// any "unrecognized" externals and about any obviously unsafe ones.
+
+// Symbols we explicitly support
+static const char *modelledExternals[] = {
+  "_ZTVN10__cxxabiv117__class_type_infoE",
+  "_ZTVN10__cxxabiv120__si_class_type_infoE",
+  "_ZTVN10__cxxabiv121__vmi_class_type_infoE",
+
+  // special functions
+  "_assert", 
+  "__assert_fail", 
+  "__assert_rtn", 
+  "calloc", 
+  "_exit", 
+  "exit", 
+  "free", 
+  "abort", 
+  "klee_abort", 
+  "klee_assume", 
+  "klee_check_memory_access",
+  "klee_define_fixed_object",
+  "klee_get_errno", 
+  "klee_get_value",
+  "klee_get_obj_size", 
+  "klee_is_symbolic", 
+  "klee_make_symbolic_name", 
+  "klee_mark_global", 
+  "klee_malloc_n", 
+  "klee_merge", 
+  "klee_prefer_cex",
+  "klee_print_expr", 
+  "klee_print_range", 
+  "klee_report_error", 
+  "klee_revirt_objects", 
+  "klee_set_forking",
+  "klee_silent_exit", 
+  "klee_under_constrained", 
+  "klee_warning", 
+  "klee_warning_once", 
+  "klee_alias_function",
+  "llvm.dbg.stoppoint", 
+  "llvm.va_start", 
+  "llvm.va_end", 
+  "malloc", 
+  "realloc", 
+  "_ZdaPv", 
+  "_ZdlPv", 
+  "_Znaj", 
+  "_Znwj", 
+  "_Znam", 
+  "_Znwm", 
+};
+// Symbols we aren't going to warn about
+static const char *dontCareExternals[] = {
+#if 0
+  // stdio
+  "fprintf",
+  "fflush",
+  "fopen",
+  "fclose",
+  "fputs_unlocked",
+  "putchar_unlocked",
+  "vfprintf",
+  "fwrite",
+  "puts",
+  "printf",
+  "stdin",
+  "stdout",
+  "stderr",
+  "_stdio_term",
+  "__errno_location",
+  "fstat",
+#endif
+
+  // static information, pretty ok to return
+  "getegid",
+  "geteuid",
+  "getgid",
+  "getuid",
+  "getpid",
+  "gethostname",
+  "getpgrp",
+  "getppid",
+  "getpagesize",
+  "getpriority",
+  "getgroups",
+  "getdtablesize",
+  "getrlimit",
+  "getrlimit64",
+  "getcwd",
+  "getwd",
+  "gettimeofday",
+  "uname",
+
+  // fp stuff we just don't worry about yet
+  "frexp",  
+  "ldexp",
+  "__isnan",
+  "__signbit",
+};
+// Extra symbols we aren't going to warn about with klee-libc
+static const char *dontCareKlee[] = {
+  "__ctype_b_loc",
+  "__ctype_get_mb_cur_max",
+
+  // io system calls
+  "open",
+  "write",
+  "read",
+  "close",
+};
+// Extra symbols we aren't going to warn about with uclibc
+static const char *dontCareUclibc[] = {
+  "__dso_handle",
+
+  // Don't warn about these since we explicitly commented them out of
+  // uclibc.
+  "printf",
+  "vprintf"
+};
+// Symbols we consider unsafe
+static const char *unsafeExternals[] = {
+  "fork", // oh lord
+  "exec", // heaven help us
+  "error", // calls _exit
+  "raise", // yeah
+  "kill", // mmmhmmm
+};
+#define NELEMS(array) (sizeof(array)/sizeof(array[0]))
+void externalsAndGlobalsCheck(const Module *m) {
+  std::map<std::string, bool> externals;
+  std::set<std::string> modelled(modelledExternals, 
+                                 modelledExternals+NELEMS(modelledExternals));
+  std::set<std::string> dontCare(dontCareExternals, 
+                                 dontCareExternals+NELEMS(dontCareExternals));
+  std::set<std::string> unsafe(unsafeExternals, 
+                               unsafeExternals+NELEMS(unsafeExternals));
+
+  switch (Libc) {
+  case KleeLibc: 
+    dontCare.insert(dontCareKlee, dontCareKlee+NELEMS(dontCareKlee));
+    break;
+  case UcLibc:
+    dontCare.insert(dontCareUclibc,
+                    dontCareUclibc+NELEMS(dontCareUclibc));
+    break;
+  case NoLibc: /* silence compiler warning */
+    break;
+  }
+  
+
+  if (WithPOSIXRuntime)
+    dontCare.insert("syscall");
+
+  for (Module::const_iterator fnIt = m->begin(), fn_ie = m->end(); 
+       fnIt != fn_ie; ++fnIt) {
+    if (fnIt->isDeclaration() && !fnIt->use_empty())
+      externals.insert(std::make_pair(fnIt->getName(), false));
+    for (Function::const_iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
+         bbIt != bb_ie; ++bbIt) {
+      for (BasicBlock::const_iterator it = bbIt->begin(), ie = bbIt->end(); 
+           it != it; ++it) {
+        if (const CallInst *ci = dyn_cast<CallInst>(it)) {
+          if (isa<InlineAsm>(ci->getCalledValue())) {
+            klee_warning_once(&*fnIt,
+                              "function \"%s\" has inline asm", 
+                              fnIt->getName().c_str());
+          }
+        }
+      }
+    }
+  }
+  for (Module::const_global_iterator 
+         it = m->global_begin(), ie = m->global_end(); 
+       it != ie; ++it)
+    if (it->isDeclaration() && !it->use_empty())
+      externals.insert(std::make_pair(it->getName(), true));
+  // and remove aliases (they define the symbol after global
+  // initialization)
+  for (Module::const_alias_iterator 
+         it = m->alias_begin(), ie = m->alias_end(); 
+       it != ie; ++it) {
+    std::map<std::string, bool>::iterator it2 = 
+      externals.find(it->getName());
+    if (it2!=externals.end())
+      externals.erase(it2);
+  }
+
+  std::map<std::string, bool> foundUnsafe;
+  for (std::map<std::string, bool>::iterator
+         it = externals.begin(), ie = externals.end();
+       it != ie; ++it) {
+    const std::string &ext = it->first;
+    if (!modelled.count(ext) && (WarnAllExternals || 
+                                 !dontCare.count(ext))) {
+      if (unsafe.count(ext)) {
+        foundUnsafe.insert(*it);
+      } else {
+        klee_warning("undefined reference to %s: %s",
+                     it->second ? "variable" : "function",
+                     ext.c_str());
+      }
+    }
+  }
+
+  for (std::map<std::string, bool>::iterator
+         it = foundUnsafe.begin(), ie = foundUnsafe.end();
+       it != ie; ++it) {
+    const std::string &ext = it->first;
+    klee_warning("undefined reference to %s: %s (UNSAFE)!",
+                 it->second ? "variable" : "function",
+                 ext.c_str());
+  }
+}
+
+static Interpreter *theInterpreter = 0;
+
+static bool interrupted = false;
+
+// Pulled out so it can be easily called from a debugger.
+extern "C"
+void halt_execution() {
+  theInterpreter->setHaltExecution(true);
+}
+
+extern "C"
+void stop_forking() {
+  theInterpreter->setInhibitForking(true);
+}
+
+static void interrupt_handle() {
+  if (!interrupted && theInterpreter) {
+    llvm::cerr << "KLEE: ctrl-c detected, requesting interpreter to halt.\n";
+    halt_execution();
+    sys::SetInterruptFunction(interrupt_handle);
+  } else {
+    llvm::cerr << "KLEE: ctrl-c detected, exiting.\n";
+    exit(1);
+  }
+  interrupted = true;
+}
+
+// This is a temporary hack. If the running process has access to
+// externals then it can disable interrupts, which screws up the
+// normal "nice" watchdog termination process. We try to request the
+// interpreter to halt using this mechanism as a last resort to save
+// the state data before going ahead and killing it.
+static void halt_via_gdb(int pid) {
+  char buffer[256];
+  sprintf(buffer, 
+          "gdb --batch --eval-command=\"p halt_execution()\" "
+          "--eval-command=detach --pid=%d &> /dev/null",
+          pid);
+  //  fprintf(stderr, "KLEE: WATCHDOG: running: %s\n", buffer);
+  if (system(buffer)==-1) 
+    perror("system");
+}
+
+// returns the end of the string put in buf
+static char *format_tdiff(char *buf, long seconds)
+{
+  assert(seconds >= 0);
+
+  long minutes = seconds / 60;  seconds %= 60;
+  long hours   = minutes / 60;  minutes %= 60;
+  long days    = hours   / 24;  hours   %= 24;
+
+  buf = strrchr(buf, '\0');
+  if (days > 0) buf += sprintf(buf, "%ld days, ", days);
+  buf += sprintf(buf, "%02ld:%02ld:%02ld", hours, minutes, seconds);
+  return buf;
+}
+
+#ifndef KLEE_UCLIBC
+static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
+  fprintf(stderr, "error: invalid libc, no uclibc support!\n");
+  exit(1);
+  return 0;
+}
+#else
+static llvm::Module *linkWithUclibc(llvm::Module *mainModule) {
+  Function *f;
+  // force import of __uClibc_main
+  mainModule->getOrInsertFunction("__uClibc_main",
+                                  FunctionType::get(Type::VoidTy,
+                                                    std::vector<const Type*>(),
+                                                    true));
+  
+  // force various imports
+  if (WithPOSIXRuntime) {
+    mainModule->getOrInsertFunction("realpath",
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("getutent",
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("__fgetc_unlocked",
+                                    Type::Int32Ty,
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+    mainModule->getOrInsertFunction("__fputc_unlocked",
+                                    Type::Int32Ty,
+                                    Type::Int32Ty,
+                                    PointerType::getUnqual(Type::Int8Ty),
+                                    NULL);
+  }
+
+  f = mainModule->getFunction("__ctype_get_mb_cur_max");
+  if (f) f->setName("_stdlib_mb_cur_max");
+
+  // Strip of asm prefixes for 64 bit versions because they are not
+  // present in uclibc and we want to make sure stuff will get
+  // linked. In the off chance that both prefixed and unprefixed
+  // versions are present in the module, make sure we don't create a
+  // naming conflict.
+  for (Module::iterator fi = mainModule->begin(), fe = mainModule->end();
+       fi != fe;) {
+    Function *f = fi;
+    ++fi;
+    const std::string &name = f->getName();
+    if (name[0]=='\01') {
+      unsigned size = name.size();
+      if (name[size-2]=='6' && name[size-1]=='4') {
+        std::string unprefixed = name.substr(1);
+
+        // See if the unprefixed version exists.
+        if (Function *f2 = mainModule->getFunction(unprefixed)) {
+          f->replaceAllUsesWith(f2);
+          f->eraseFromParent();
+        } else {
+          f->setName(unprefixed);
+        }
+      }
+    }
+  }
+  
+  mainModule = klee::linkWithLibrary(mainModule, 
+                                     KLEE_UCLIBC "/lib/libc.a");
+  assert(mainModule && "unable to link with uclibc");
+
+  // more sighs, this is horrible but just a temp hack
+  //    f = mainModule->getFunction("__fputc_unlocked");
+  //    if (f) f->setName("fputc_unlocked");
+  //    f = mainModule->getFunction("__fgetc_unlocked");
+  //    if (f) f->setName("fgetc_unlocked");
+  
+  Function *f2;
+  f = mainModule->getFunction("open");
+  f2 = mainModule->getFunction("__libc_open");
+  if (f2) {
+    if (f) {
+      f2->replaceAllUsesWith(f);
+      f2->eraseFromParent();
+    } else {
+      f2->setName("open");
+      assert(f2->getName() == "open");
+    }
+  }
+
+  f = mainModule->getFunction("fcntl");
+  f2 = mainModule->getFunction("__libc_fcntl");
+  if (f2) {
+    if (f) {
+      f2->replaceAllUsesWith(f);
+      f2->eraseFromParent();
+    } else {
+      f2->setName("fcntl");
+      assert(f2->getName() == "fcntl");
+    }
+  }
+
+  // XXX we need to rearchitect so this can also be used with
+  // programs externally linked with uclibc.
+
+  // We now need to swap things so that __uClibc_main is the entry
+  // point, in such a way that the arguments are passed to
+  // __uClibc_main correctly. We do this by renaming the user main
+  // and generating a stub function to call __uClibc_main. There is
+  // also an implicit cooperation in that runFunctionAsMain sets up
+  // the environment arguments to what uclibc expects (following
+  // argv), since it does not explicitly take an envp argument.
+  Function *userMainFn = mainModule->getFunction("main");
+  assert(userMainFn && "unable to get user main");    
+  Function *uclibcMainFn = mainModule->getFunction("__uClibc_main");
+  assert(uclibcMainFn && "unable to get uclibc main");    
+  userMainFn->setName("__user_main");
+
+  const FunctionType *ft = uclibcMainFn->getFunctionType();
+  assert(ft->getNumParams() == 7);
+
+  std::vector<const Type*> fArgs;
+  fArgs.push_back(ft->getParamType(1)); // argc
+  fArgs.push_back(ft->getParamType(2)); // argv
+  Function *stub = Function::Create(FunctionType::get(Type::Int32Ty, fArgs, false),
+      			      GlobalVariable::ExternalLinkage,
+      			      "main",
+      			      mainModule);
+  BasicBlock *bb = BasicBlock::Create("entry", stub);
+
+  std::vector<llvm::Value*> args;
+  args.push_back(llvm::ConstantExpr::getBitCast(userMainFn, 
+                                                ft->getParamType(0)));
+  args.push_back(stub->arg_begin()); // argc
+  args.push_back(++stub->arg_begin()); // argv    
+  args.push_back(Constant::getNullValue(ft->getParamType(3))); // app_init
+  args.push_back(Constant::getNullValue(ft->getParamType(4))); // app_fini
+  args.push_back(Constant::getNullValue(ft->getParamType(5))); // rtld_fini
+  args.push_back(Constant::getNullValue(ft->getParamType(6))); // stack_end
+  CallInst::Create(uclibcMainFn, args.begin(), args.end(), "", bb);
+  
+  new UnreachableInst(bb);
+
+  return mainModule;
+}
+#endif
+
+int main(int argc, char **argv, char **envp) {  
+#if ENABLE_STPLOG == 1
+  STPLOG_init("stplog.c");
+#endif
+
+  atexit(llvm_shutdown);  // Call llvm_shutdown() on exit.
+  parseArguments(argc, argv);
+  sys::PrintStackTraceOnErrorSignal();
+
+  if (Watchdog) {
+    if (MaxTime==0) {
+      klee_error("--watchdog used without --max-time");
+    }
+
+    int pid = fork();
+    if (pid<0) {
+      klee_error("unable to fork watchdog");
+    } else if (pid) {
+      fprintf(stderr, "KLEE: WATCHDOG: watching %d\n", pid);
+      fflush(stderr);
+
+      double nextStep = util::getWallTime() + MaxTime*1.1;
+      int level = 0;
+
+      // Simple stupid code...
+      while (1) {
+        sleep(1);
+
+        int status, res = waitpid(pid, &status, WNOHANG);
+
+        if (res < 0) {
+          if (errno==ECHILD) { // No child, no need to watch but
+                               // return error since we didn't catch
+                               // the exit.
+            fprintf(stderr, "KLEE: watchdog exiting (no child)\n");
+            return 1;
+          } else if (errno!=EINTR) {
+            perror("watchdog waitpid");
+            exit(1);
+          }
+        } else if (res==pid && WIFEXITED(status)) {
+          return WEXITSTATUS(status);
+        } else {
+          double time = util::getWallTime();
+
+          if (time > nextStep) {
+            ++level;
+            
+            if (level==1) {
+              fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via INT\n");
+              kill(pid, SIGINT);
+            } else if (level==2) {
+              fprintf(stderr, "KLEE: WATCHDOG: time expired, attempting halt via gdb\n");
+              halt_via_gdb(pid);
+            } else {
+              fprintf(stderr, "KLEE: WATCHDOG: kill(9)ing child (I tried to be nice)\n");
+              kill(pid, SIGKILL);
+              return 1; // what more can we do
+            }
+
+            // Ideally this triggers a dump, which may take a while,
+            // so try and give the process extra time to clean up.
+            nextStep = util::getWallTime() + std::max(15., MaxTime*.1);
+          }
+        }
+      }
+
+      return 0;
+    }
+  }
+
+  sys::SetInterruptFunction(interrupt_handle);
+
+  // Load the bytecode...
+  std::string ErrorMsg;
+  ModuleProvider *MP = 0;
+  if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFile, &ErrorMsg)) {
+    MP = getBitcodeModuleProvider(Buffer, &ErrorMsg);
+    if (!MP) delete Buffer;
+  }
+  
+  if (!MP)
+    klee_error("error loading program '%s': %s", InputFile.c_str(), ErrorMsg.c_str());
+
+  Module *mainModule = MP->materializeModule();
+  MP->releaseModule();
+  delete MP;
+
+  assert(mainModule && "unable to materialize");
+  
+  if (WithPOSIXRuntime)
+    InitEnv = true;
+
+  if (InitEnv) {
+    int r = initEnv(mainModule);
+    if (r != 0)
+      return r;
+  }
+
+  llvm::sys::Path LibraryDir(KLEE_DIR "/" RUNTIME_CONFIGURATION "/lib");
+  Interpreter::ModuleOptions Opts(LibraryDir.c_str(),
+                                  /*Optimize=*/OptimizeModule, 
+                                  /*CheckDivZero=*/CheckDivZero);
+  
+  switch (Libc) {
+  case NoLibc: /* silence compiler warning */
+    break;
+
+  case KleeLibc: {
+    // FIXME: Find a reasonable solution for this.
+    llvm::sys::Path Path(Opts.LibraryDir);
+    Path.appendComponent("libklee-libc.bca");
+    mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
+    assert(mainModule && "unable to link with klee-libc");
+    break;
+  }
+
+  case UcLibc:
+    mainModule = linkWithUclibc(mainModule);
+    break;
+  }
+
+  if (WithPOSIXRuntime) {
+    llvm::sys::Path Path(Opts.LibraryDir);
+    Path.appendComponent("libkleeRuntimePOSIX.bca");
+    klee_message("NOTE: Using model: %s", Path.c_str());
+    mainModule = klee::linkWithLibrary(mainModule, Path.c_str());
+    assert(mainModule && "unable to link with simple model");
+  }  
+
+  // Get the desired main function.  klee_main initializes uClibc
+  // locale and other data and then calls main.
+  Function *mainFn = mainModule->getFunction("main");
+  if (!mainFn) {
+    llvm::cerr << "'main' function not found in module.\n";
+    return -1;
+  }
+
+  // FIXME: Change me to std types.
+  int pArgc;
+  char **pArgv;
+  char **pEnvp;
+  if (Environ != "") {
+    std::vector<std::string> items;
+    std::ifstream f(Environ.c_str());
+    if (!f.good())
+      klee_error("unable to open --environ file: %s", Environ.c_str());
+    while (!f.eof()) {
+      std::string line;
+      std::getline(f, line);
+      line = strip(line);
+      if (!line.empty())
+        items.push_back(line);
+    }
+    f.close();
+    pEnvp = new char *[items.size()+1];
+    unsigned i=0;
+    for (; i != items.size(); ++i)
+      pEnvp[i] = strdup(items[i].c_str());
+    pEnvp[i] = 0;
+  } else {
+    pEnvp = envp;
+  }
+
+  pArgc = InputArgv.size() + 1; 
+  pArgv = new char *[pArgc];
+  for (unsigned i=0; i<InputArgv.size()+1; i++) {
+    std::string &arg = (i==0 ? InputFile : InputArgv[i-1]);
+    unsigned size = arg.size() + 1;
+    char *pArg = new char[size];
+    
+    std::copy(arg.begin(), arg.end(), pArg);
+    pArg[size - 1] = 0;
+    
+    pArgv[i] = pArg;
+  }
+
+  std::vector<bool> replayPath;
+
+  if (ReplayPathFile != "") {
+    KleeHandler::loadPathFile(ReplayPathFile, replayPath);
+  }
+
+  Interpreter::InterpreterOptions IOpts;
+  IOpts.MakeConcreteSymbolic = MakeConcreteSymbolic;
+  KleeHandler *handler = new KleeHandler(pArgc, pArgv);
+  Interpreter *interpreter = 
+    theInterpreter = Interpreter::create(IOpts, handler);
+  handler->setInterpreter(interpreter);
+  
+  std::ostream &infoFile = handler->getInfoStream();
+  for (int i=0; i<argc; i++) {
+    infoFile << argv[i] << (i+1<argc ? " ":"\n");
+  }
+  infoFile << "PID: " << getpid() << "\n";
+
+  const Module *finalModule = 
+    interpreter->setModule(mainModule, Opts);
+  externalsAndGlobalsCheck(finalModule);
+
+  if (ReplayPathFile != "") {
+    interpreter->setReplayPath(&replayPath);
+  }
+
+  char buf[256];
+  time_t t[2];
+  t[0] = time(NULL);
+  strftime(buf, sizeof(buf), "Started: %Y-%m-%d %H:%M:%S\n", localtime(&t[0]));
+  infoFile << buf;
+  infoFile.flush();
+
+  if (!ReplayOutDir.empty() || !ReplayOutFile.empty()) {
+    assert(SeedOutFile.empty());
+    assert(SeedOutDir.empty());
+
+    std::vector<std::string> outFiles = ReplayOutFile;
+    for (std::vector<std::string>::iterator
+           it = ReplayOutDir.begin(), ie = ReplayOutDir.end();
+         it != ie; ++it)
+      KleeHandler::getOutFiles(*it, outFiles);    
+    std::vector<BOut*> bOuts;
+    for (std::vector<std::string>::iterator
+           it = outFiles.begin(), ie = outFiles.end();
+         it != ie; ++it) {
+      BOut *out = bOut_fromFile(it->c_str());
+      if (out) {
+        bOuts.push_back(out);
+      } else {
+        llvm::cerr << "KLEE: unable to open: " << *it << "\n";
+      }
+    }
+
+    if (RunInDir != "") {
+      int res = chdir(RunInDir.c_str());
+      if (res < 0) {
+        klee_error("Unable to change directory to: %s", RunInDir.c_str());
+      }
+    }
+
+    unsigned i=0;
+    for (std::vector<BOut*>::iterator
+           it = bOuts.begin(), ie = bOuts.end();
+         it != ie; ++it) {
+      BOut *out = *it;
+      interpreter->setReplayOut(out);
+      llvm::cerr << "KLEE: replaying: " << *it << " (" << bOut_numBytes(out) << " bytes)"
+                 << " (" << ++i << "/" << outFiles.size() << ")\n";
+      // XXX should put envp in .bout ?
+      interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp);
+      if (interrupted) break;
+    }
+    interpreter->setReplayOut(0);
+    while (!bOuts.empty()) {
+      bOut_free(bOuts.back());
+      bOuts.pop_back();
+    }
+  } else {
+    std::vector<BOut *> seeds;
+    for (std::vector<std::string>::iterator
+           it = SeedOutFile.begin(), ie = SeedOutFile.end();
+         it != ie; ++it) {
+      BOut *out = bOut_fromFile(it->c_str());
+      if (!out) {
+        llvm::cerr << "KLEE: unable to open: " << *it << "\n";
+        exit(1);
+      }
+      seeds.push_back(out);
+    } 
+    for (std::vector<std::string>::iterator
+           it = SeedOutDir.begin(), ie = SeedOutDir.end();
+         it != ie; ++it) {
+      std::vector<std::string> outFiles;
+      KleeHandler::getOutFiles(*it, outFiles);
+      for (std::vector<std::string>::iterator
+             it2 = outFiles.begin(), ie = outFiles.end();
+           it2 != ie; ++it2) {
+        BOut *out = bOut_fromFile(it2->c_str());
+        if (!out) {
+          llvm::cerr << "KLEE: unable to open: " << *it2 << "\n";
+          exit(1);
+        }
+        seeds.push_back(out);
+      }
+      if (outFiles.empty()) {
+        llvm::cerr << "KLEE: seeds directory is empty: " << *it << "\n";
+        exit(1);
+      }
+    }
+       
+    if (!seeds.empty()) {
+      llvm::cerr << "KLEE: using " << seeds.size() << " seeds\n";
+      interpreter->useSeeds(&seeds);
+    }
+    if (RunInDir != "") {
+      int res = chdir(RunInDir.c_str());
+      if (res < 0) {
+        klee_error("Unable to change directory to: %s", RunInDir.c_str());
+      }
+    }
+    interpreter->runFunctionAsMain(mainFn, pArgc, pArgv, pEnvp);
+
+    while (!seeds.empty()) {
+      bOut_free(seeds.back());
+      seeds.pop_back();
+    }
+  }
+      
+  t[1] = time(NULL);
+  strftime(buf, sizeof(buf), "Finished: %Y-%m-%d %H:%M:%S\n", localtime(&t[1]));
+  infoFile << buf;
+
+  strcpy(buf, "Elapsed: ");
+  strcpy(format_tdiff(buf, t[1] - t[0]), "\n");
+  infoFile << buf;
+
+  // Free all the args.
+  for (unsigned i=0; i<InputArgv.size()+1; i++)
+    delete[] pArgv[i];
+  delete[] pArgv;
+
+  delete interpreter;
+
+  uint64_t queries = 
+    *theStatisticManager->getStatisticByName("Queries");
+  uint64_t queriesValid = 
+    *theStatisticManager->getStatisticByName("QueriesValid");
+  uint64_t queriesInvalid = 
+    *theStatisticManager->getStatisticByName("QueriesInvalid");
+  uint64_t queryCounterexamples = 
+    *theStatisticManager->getStatisticByName("QueriesCEX");
+  uint64_t queryConstructs = 
+    *theStatisticManager->getStatisticByName("QueriesConstructs");
+  uint64_t instructions = 
+    *theStatisticManager->getStatisticByName("Instructions");
+  uint64_t forks = 
+    *theStatisticManager->getStatisticByName("Forks");
+
+  handler->getInfoStream() 
+    << "KLEE: done: explored paths = " << 1 + forks << "\n";
+
+  // Write some extra information in the info file which users won't
+  // necessarily care about or understand.
+  if (queries)
+    handler->getInfoStream() 
+      << "KLEE: done: avg. constructs per query = " 
+                             << queryConstructs / queries << "\n";  
+  handler->getInfoStream() 
+    << "KLEE: done: total queries = " << queries << "\n"
+    << "KLEE: done: valid queries = " << queriesValid << "\n"
+    << "KLEE: done: invalid queriers = " << queriesInvalid << "\n"
+    << "KLEE: done: query cex = " << queryCounterexamples << "\n";
+
+  std::stringstream stats;
+  stats << "KLEE: done: total instructions = " 
+             << instructions << "\n";
+  stats << "KLEE: done: completed paths = " 
+             << handler->getNumPathsExplored() << "\n";
+  stats << "KLEE: done: generated tests = " 
+             << handler->getNumTestCases() << "\n";
+  llvm::cerr << stats.str();
+  handler->getInfoStream() << stats.str();
+
+  delete handler;
+
+  return 0;
+}

Added: klee/trunk/unittests/Expr/ExprTest.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/Expr/ExprTest.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/Expr/ExprTest.cpp (added)
+++ klee/trunk/unittests/Expr/ExprTest.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,112 @@
+//===-- ExprTest.cpp ------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "klee/Expr.h"
+
+using namespace klee;
+
+namespace {
+
+ref<Expr> getConstant(int value, Expr::Width width) {
+  int64_t ext = value;
+  uint64_t trunc = ext & (((uint64_t) -1LL) >> (64 - width));
+  return ConstantExpr::create(trunc, width);
+}
+
+TEST(ExprTest, BasicConstruction) {
+  EXPECT_EQ(ref<Expr>(0, 32),
+            SubExpr::create(ref<Expr>(10, 32),
+                            ref<Expr>(10, 32)));
+}
+
+TEST(ExprTest, ConcatExtract) {
+  Array *array = new Array(0, 1, 256);
+  ref<Expr> read8 = Expr::createTempRead(array, 8);
+  Array *array2 = new Array(0, 2, 256);
+  ref<Expr> read8_2 = Expr::createTempRead(array2, 8);
+  ref<Expr> c100 = getConstant(100, 8);
+
+  ref<Expr> concat1 = ConcatExpr::create4(read8, read8, c100, read8_2);
+  EXPECT_EQ(2U, concat1.getNumKids());
+  EXPECT_EQ(2U, concat1.getKid(1).getNumKids());
+  EXPECT_EQ(2U, concat1.getKid(1).getKid(1).getNumKids());
+
+  ref<Expr> extract1 = ExtractExpr::create(concat1, 8, 16);
+  EXPECT_EQ(Expr::Concat, extract1.getKind());
+  EXPECT_EQ(read8, extract1.getKid(0));
+  EXPECT_EQ(c100, extract1.getKid(1));
+
+  ref<Expr> extract2 = ExtractExpr::create(concat1, 6, 26);
+  EXPECT_EQ( Expr::Concat, extract2.getKind());
+  EXPECT_EQ( read8, extract2.getKid(0));
+  EXPECT_EQ( Expr::Concat, extract2.getKid(1).getKind());
+  EXPECT_EQ( read8, extract2.getKid(1).getKid(0));
+  EXPECT_EQ( Expr::Concat, extract2.getKid(1).getKid(1).getKind());
+  EXPECT_EQ( c100, extract2.getKid(1).getKid(1).getKid(0));
+  EXPECT_EQ( Expr::Extract, extract2.getKid(1).getKid(1).getKid(1).getKind());
+  
+  ref<Expr> extract3 = ExtractExpr::create(concat1, 24, 1);
+  EXPECT_EQ(Expr::Extract, extract3.getKind());
+
+  ref<Expr> extract4 = ExtractExpr::create(concat1, 27, 2);
+  EXPECT_EQ(Expr::Extract, extract4.getKind());
+  const ExtractExpr* tmp = dyn_ref_cast<ExtractExpr>(extract4);
+  EXPECT_EQ(3U, tmp->offset);
+  EXPECT_EQ(2U, tmp->getWidth());
+
+  ref<Expr> extract5 = ExtractExpr::create(concat1, 17, 5);
+  EXPECT_EQ(Expr::Extract, extract5.getKind());
+
+  ref<Expr> extract6 = ExtractExpr::create(concat1, 3, 26);
+  EXPECT_EQ(Expr::Concat, extract6.getKind());
+  EXPECT_EQ(Expr::Extract, extract6.getKid(0).getKind());
+  EXPECT_EQ(Expr::Concat, extract6.getKid(1).getKind());
+  EXPECT_EQ(read8, extract6.getKid(1).getKid(0));
+  EXPECT_EQ(Expr::Concat, extract6.getKid(1).getKid(1).getKind());
+  EXPECT_EQ(c100, extract6.getKid(1).getKid(1).getKid(0));
+  EXPECT_EQ(Expr::Extract, extract6.getKid(1).getKid(1).getKid(1).getKind());
+
+  ref<Expr> concat10 = ConcatExpr::create4(read8, c100, c100, read8);    
+  ref<Expr> extract10 = ExtractExpr::create(concat10, 8, 16);
+  EXPECT_EQ(Expr::Constant, extract10.getKind());
+}
+
+TEST(ExprTest, ExtractConcat) {
+  Array *array = new Array(0, 3, 256);
+  ref<Expr> read64 = Expr::createTempRead(array, 64);
+
+  Array *array2 = new Array(0, 4, 256);
+  ref<Expr> read8_2 = Expr::createTempRead(array2, 8);
+  
+  ref<Expr> extract1 = ExtractExpr::create(read64, 36, 4);
+  ref<Expr> extract2 = ExtractExpr::create(read64, 32, 4);
+  
+  ref<Expr> extract3 = ExtractExpr::create(read64, 12, 3);
+  ref<Expr> extract4 = ExtractExpr::create(read64, 10, 2);
+  ref<Expr> extract5 = ExtractExpr::create(read64, 2, 8);
+   
+  ref<Expr> kids1[6] = { extract1, extract2,
+			 read8_2,
+			 extract3, extract4, extract5 };
+  ref<Expr> concat1 = ConcatExpr::createN(6, kids1);
+  EXPECT_EQ(29U, concat1.getWidth());
+  
+  ref<Expr> extract6 = ExtractExpr::create(read8_2, 2, 5);
+  ref<Expr> extract7 = ExtractExpr::create(read8_2, 1, 1);
+  
+  ref<Expr> kids2[3] = { extract1, extract6, extract7 };
+  ref<Expr> concat2 = ConcatExpr::createN(3, kids2);
+  EXPECT_EQ(10U, concat2.getWidth());
+  EXPECT_EQ(Expr::Extract, concat2.getKid(0).getKind());
+  EXPECT_EQ(Expr::Extract, concat2.getKid(1).getKind());
+}
+
+}

Added: klee/trunk/unittests/Expr/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/Expr/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/Expr/Makefile (added)
+++ klee/trunk/unittests/Expr/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+##===- unittests/Expr/Makefile -----------------------------*- Makefile -*-===##
+
+LEVEL := ../..
+TESTNAME := Expr
+USEDLIBS := kleaverExpr.a kleeBasic.a
+LINK_COMPONENTS := support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
+LIBS += -lstp 

Added: klee/trunk/unittests/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/Makefile (added)
+++ klee/trunk/unittests/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,18 @@
+##===- unittests/Makefile ----------------------------------*- Makefile -*-===##
+
+LEVEL = ..
+
+include $(LEVEL)/Makefile.config
+
+LIBRARYNAME = UnitTestMain
+BUILD_ARCHIVE = 1
+CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/
+CPP.Flags += -Wno-variadic-macros
+
+# FIXME: Parallel dirs is broken?
+DIRS = Expr Solver
+
+include $(LEVEL)/Makefile.common
+
+clean::
+	$(Verb) $(RM) -f *Tests

Propchange: klee/trunk/unittests/Makefile

------------------------------------------------------------------------------
    svn:executable = *

Added: klee/trunk/unittests/Solver/Makefile
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/Solver/Makefile?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/Solver/Makefile (added)
+++ klee/trunk/unittests/Solver/Makefile Wed May 20 23:36:41 2009
@@ -0,0 +1,11 @@
+##===- unittests/Solver/Makefile ---------------------------*- Makefile -*-===##
+
+LEVEL := ../..
+TESTNAME := Solver
+USEDLIBS := kleaverSolver.a kleaverExpr.a kleeSupport.a kleeBasic.a
+LINK_COMPONENTS := support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
+LIBS += -lstp 

Added: klee/trunk/unittests/Solver/SolverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/Solver/SolverTest.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/Solver/SolverTest.cpp (added)
+++ klee/trunk/unittests/Solver/SolverTest.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,164 @@
+//===-- SolverTest.cpp ----------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "klee/Constraints.h"
+#include "klee/Expr.h"
+#include "klee/Solver.h"
+
+using namespace klee;
+
+namespace {
+
+const int g_constants[] = { -1, 1, 4, 17, 0 };
+const Expr::Width g_types[] = { Expr::Bool,
+				Expr::Int8,
+				Expr::Int16,
+				Expr::Int32,
+				Expr::Int64 };
+
+ref<Expr> getConstant(int value, Expr::Width width) {
+  int64_t ext = value;
+  uint64_t trunc = ext & (((uint64_t) -1LL) >> (64 - width));
+  return ConstantExpr::create(trunc, width);
+}
+
+
+template<class T>
+void testOperation(Solver &solver,
+                   int value,
+                   Expr::Width operandWidth,
+                   Expr::Width resultWidth) {
+  std::vector<Expr::CreateArg> symbolicArgs;
+  
+  for (unsigned i = 0; i < T::numKids; i++) {
+    if (!T::isValidKidWidth(i, operandWidth))
+      return;
+
+    unsigned size = Expr::getMinBytesForWidth(operandWidth);
+    static unsigned id = 0;
+    Array *array = new Array(0, ++id, size);
+    symbolicArgs.push_back(Expr::CreateArg(Expr::createTempRead(array, 
+                                                                operandWidth)));
+  }
+  
+  if (T::needsResultType())
+    symbolicArgs.push_back(Expr::CreateArg(resultWidth));
+  
+  ref<Expr> fullySymbolicExpr = Expr::createFromKind(T::kind, symbolicArgs);
+
+  // For each kid, replace the kid with a constant value and verify
+  // that the fully symbolic expression is equivalent to it when the
+  // replaced value is appropriated constrained.
+  for (unsigned kid = 0; kid < T::numKids; kid++) {
+    std::vector<Expr::CreateArg> partiallyConstantArgs(symbolicArgs);
+    for (unsigned i = 0; i < T::numKids; i++)
+      if (i==kid)
+        partiallyConstantArgs[i] = getConstant(value, operandWidth);
+
+    ref<Expr> expr = 
+      NotOptimizedExpr::create(EqExpr::create(partiallyConstantArgs[kid].expr,
+                                              symbolicArgs[kid].expr));
+    
+    ref<Expr> partiallyConstantExpr =
+      Expr::createFromKind(T::kind, partiallyConstantArgs);
+    
+    ref<Expr> queryExpr = EqExpr::create(fullySymbolicExpr, 
+                                         partiallyConstantExpr);
+    
+    ConstraintManager constraints;
+    constraints.addConstraint(expr);
+    bool res;
+    bool success = solver.mustBeTrue(Query(constraints, queryExpr), res);
+    EXPECT_EQ(true, success) << "Constraint solving failed";
+
+    if (success) {
+      EXPECT_EQ(true, res) << "Evaluation failed!\n" 
+                           << "query " << queryExpr 
+                           << " with " << expr;
+    }
+  }
+}
+
+template<class T>
+void testOpcode(Solver &solver, bool tryBool = true, bool tryZero = true, 
+                unsigned maxWidth = 64) {
+  for (unsigned j=0; j<sizeof(g_types)/sizeof(g_types[0]); j++) {
+    Expr::Width type = g_types[j]; 
+
+    if (type > maxWidth) continue;
+
+    for (unsigned i=0; i<sizeof(g_constants)/sizeof(g_constants[0]); i++) {
+      int value = g_constants[i];
+      if (!tryZero && !value) continue;
+      if (type == Expr::Bool && !tryBool) continue;
+
+      if (!T::needsResultType()) {
+        testOperation<T>(solver, value, type, type);
+        continue;
+      }
+
+      for (unsigned k=0; k<sizeof(g_types)/sizeof(g_types[0]); k++) {
+        Expr::Width resultType = g_types[k];
+          
+        // nasty hack to give only Trunc/ZExt/SExt the right types
+        if (T::kind == Expr::SExt || T::kind == Expr::ZExt) {
+          if (Expr::getMinBytesForWidth(type) >= 
+              Expr::getMinBytesForWidth(resultType)) 
+            continue;
+        }
+            
+        testOperation<T>(solver, value, type, resultType);
+      }
+    }
+  }
+}
+
+TEST(SolverTest, Evaluation) {
+  STPSolver *stpSolver = new STPSolver(true); 
+  Solver *solver = stpSolver;
+
+  solver = createCexCachingSolver(solver);
+  solver = createCachingSolver(solver);
+  solver = createIndependentSolver(solver);
+
+  testOpcode<SelectExpr>(*solver);
+  testOpcode<ZExtExpr>(*solver);
+  testOpcode<SExtExpr>(*solver);
+  
+  testOpcode<AddExpr>(*solver);
+  testOpcode<SubExpr>(*solver);
+  testOpcode<MulExpr>(*solver, false, true, 8);
+  testOpcode<SDivExpr>(*solver, false, false, 8);
+  testOpcode<UDivExpr>(*solver, false, false, 8);
+  testOpcode<SRemExpr>(*solver, false, false, 8);
+  testOpcode<URemExpr>(*solver, false, false, 8);
+  testOpcode<ShlExpr>(*solver, false);
+  testOpcode<LShrExpr>(*solver, false);
+  testOpcode<AShrExpr>(*solver, false);
+  testOpcode<AndExpr>(*solver);
+  testOpcode<OrExpr>(*solver);
+  testOpcode<XorExpr>(*solver);
+
+  testOpcode<EqExpr>(*solver);
+  testOpcode<NeExpr>(*solver);
+  testOpcode<UltExpr>(*solver);
+  testOpcode<UleExpr>(*solver);
+  testOpcode<UgtExpr>(*solver);
+  testOpcode<UgeExpr>(*solver);
+  testOpcode<SltExpr>(*solver);
+  testOpcode<SleExpr>(*solver);
+  testOpcode<SgtExpr>(*solver);
+  testOpcode<SgeExpr>(*solver);
+
+  delete solver;
+}
+
+}

Added: klee/trunk/unittests/TestMain.cpp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/unittests/TestMain.cpp?rev=72205&view=auto

==============================================================================
--- klee/trunk/unittests/TestMain.cpp (added)
+++ klee/trunk/unittests/TestMain.cpp Wed May 20 23:36:41 2009
@@ -0,0 +1,15 @@
+//===--- unittests/TestMain.cpp - unittest driver -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}

Added: klee/trunk/utils/emacs/klee-pc-mode.el
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/utils/emacs/klee-pc-mode.el?rev=72205&view=auto

==============================================================================
--- klee/trunk/utils/emacs/klee-pc-mode.el (added)
+++ klee/trunk/utils/emacs/klee-pc-mode.el Wed May 20 23:36:41 2009
@@ -0,0 +1,64 @@
+(provide 'klee-pc-mode)
+
+(require 'font-lock)
+
+(defvar klee-pc-mode-syntax-table nil 
+  "Syntax table used while in ft-bt mode.")
+
+;;; --------------------------------------------------
+;;;setup the syntax table
+;;; --------------------------------------------------
+(unless klee-pc-mode-syntax-table
+  (setq klee-pc-mode-syntax-table (make-syntax-table))
+  ;;misc
+  (modify-syntax-entry ?\_   "w"       klee-pc-mode-syntax-table)
+  (modify-syntax-entry ?\.   "."       klee-pc-mode-syntax-table))
+
+;;;------------------------------------------------------------
+;;; local keymap
+;;;------------------------------------------------------------
+
+(defvar klee-pc-local-keymap nil)
+
+;;; --------------------------------------------------
+;;; set keywords
+;;; --------------------------------------------------
+
+(defvar klee-pc-mode-font-lock-keywords
+  (list
+   ;; Comments
+   '("#.*" . font-lock-comment-face)
+   ;; Identifiers
+   '("%[_a-zA-Z][a-zA-Z_.0-9]*" . font-lock-variable-name-face)
+   ;; Numbers
+   '("[+-]?0b[01_]+" . font-lock-preprocessor-face)
+   '("[+-]?0o[0-7_]+" . font-lock-preprocessor-face)
+   '("[+-]?0x[a-zA-Z0-9_]+" . font-lock-preprocessor-face)
+   '("[+-]?[0-9]+" . font-lock-preprocessor-face)
+   ;; Keywords
+   '("\\bdef\\b\\|\\bvar\\b\\|\\btrue\\b\\|\\barray\\b\\|\\bfalse\\b\\|\\bquery\\b\\|\\bdefine\\b\\|\\bdeclare\\b" . font-lock-keyword-face)
+   )
+  "klee-PC mode keywords")
+
+;;; --------------------------------------------------
+;;; major mode function
+;;; --------------------------------------------------
+(defun klee-pc-mode ()
+  "Switch to the klee-pc major mode"
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'klee-pc-mode)
+  (setq mode-name "klee-pc")
+
+  ;; handle keymap
+  (use-local-map klee-pc-local-keymap)
+
+  ;;handle syntax table
+  (set-syntax-table klee-pc-mode-syntax-table)
+  ;;handle fontlock
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(klee-pc-mode-font-lock-keywords
+			     nil t))
+
+  ;;handle hook
+  (run-hooks 'klee-pc-mode-hook))

Added: klee/trunk/utils/valgrind/README.txt
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/utils/valgrind/README.txt?rev=72205&view=auto

==============================================================================
--- klee/trunk/utils/valgrind/README.txt (added)
+++ klee/trunk/utils/valgrind/README.txt Wed May 20 23:36:41 2009
@@ -0,0 +1,2 @@
+A few valgrind suppression files for known leaks. The LLVM ones may be
+fixed by now.

Added: klee/trunk/utils/valgrind/valgrind-llvm.supp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/utils/valgrind/valgrind-llvm.supp?rev=72205&view=auto

==============================================================================
--- klee/trunk/utils/valgrind/valgrind-llvm.supp (added)
+++ klee/trunk/utils/valgrind/valgrind-llvm.supp Wed May 20 23:36:41 2009
@@ -0,0 +1,24 @@
+{ 
+   LLVM:Tmp1
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4llvm*
+}
+{ 
+   LLVM:Tmp2
+   Memcheck:Leak
+   fun:_vgrZU_libcZdsoZa_malloc
+   fun:_ZN4llvm*
+}
+{ 
+   LLVM:Tmp3
+   Memcheck:Leak
+   fun:*nwj*
+   fun:*llvm*
+}
+{ 
+   LLVM:Tmp4
+   Memcheck:Leak
+   fun:malloc
+   fun:*llvm*
+}

Added: klee/trunk/utils/valgrind/valgrind-stp.supp
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/utils/valgrind/valgrind-stp.supp?rev=72205&view=auto

==============================================================================
--- klee/trunk/utils/valgrind/valgrind-stp.supp (added)
+++ klee/trunk/utils/valgrind/valgrind-stp.supp Wed May 20 23:36:41 2009
@@ -0,0 +1,32 @@
+{
+   STP:BeevMgr
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4BEEV7BeevMgr*
+}
+{
+   STP:BeevMgr:strdup
+   Memcheck:Leak
+   fun:_vgrZU_libcZdsoZa_malloc
+   fun:strdup
+   fun:_ZN4BEEV7BeevMgr*
+}
+{
+   STP:c_interface
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:vc_*
+}
+{
+   STP:BeevMgr:vector
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZNSt6vector*
+   fun:_ZN4BEEV7BeevMgr*
+}
+{ 
+   LLVM:Tmp1
+   Memcheck:Leak
+   fun:_vgrZU_libstdcZpZpZa__Znwj
+   fun:_ZN4llvm*
+}

Added: klee/trunk/www/Examples.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/Examples.html?rev=72205&view=auto

==============================================================================
--- klee/trunk/www/Examples.html (added)
+++ klee/trunk/www/Examples.html Wed May 20 23:36:41 2009
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>KLEE - Examples</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>KLEE Examples</h1>
+
+<p>FIXME: Intro.</p>
+
+<h2>Basic Sort Example</h2>
+
+<p>FIXME: Write.</p>
+
+<h2>FIXME: More complicated example</h2>
+
+<p>FIXME: Write: show the important klee.h functions.</p>
+
+<p>FIXME: Write: show the important klee tools.</p>
+
+<p>FIXME: Write: show the important klee options.</p>
+
+</div>
+</body>
+</html>

Added: klee/trunk/www/GetInvolved.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/GetInvolved.html?rev=72205&view=auto

==============================================================================
--- klee/trunk/www/GetInvolved.html (added)
+++ klee/trunk/www/GetInvolved.html Wed May 20 23:36:41 2009
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>klee - Get Involved</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Involved with the klee Project</h1>
+
+<p>FIXME: Intro.</p>
+
+<h2>Mailing Lists</h2>
+
+<p>klee-dev</p>
+
+<p>klee-commits</p>
+
+<h2>Working with the Code</h2>
+
+<p>FIXME: Point at pertinent LLVM docs.</p>
+ 
+<p>FIXME: Point at doxygen.</p>
+
+</div>
+</body>
+</html>

Added: klee/trunk/www/GetStarted.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/GetStarted.html?rev=72205&view=auto

==============================================================================
--- klee/trunk/www/GetStarted.html (added)
+++ klee/trunk/www/GetStarted.html Wed May 20 23:36:41 2009
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>KLEE - Getting Started</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Started: Building and Running KLEE</h1>
+
+<!-- <p>FIXME: Intro and disclaimer.</p> -->
+
+<h2 id="build">Building KLEE and Working with the Code</h2>
+
+<p>If you would like to check out and build KLEE, the current procedure is as
+follows:</p>
+
+KLEE is built on LLVM; the first steps are to get a working LLVM
+installation. See <a href="http://llvm.org/docs/GettingStarted.html">Getting
+Started with the LLVM System</a> for more information.
+
+<ol>
+<li>Install llvm-gcc:</li>
+<ul>
+<li>Download and install the LLVM 2.5 release of <tt>llvm-gcc</tt>
+  from <a href="http://llvm.org/releases/download.html">here</a>. It
+  is important to do this first so that it is found in
+  subsequent <tt>configure</tt> steps. <tt>llvm-gcc</tt> will be used
+  later to compile programs that KLEE can execute.</li>
+</ul>
+
+<li><a href="http://www.llvm.org/docs/GettingStarted.html#checkout">Checkout
+    and build LLVM</a> from SVN head:
+    
+  <code class="instr"> <code>
+    svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
+    cd llvm
+    ./configure --enable-optimized
+    make
+  </code></code>
+
+(the <tt>--enable-optimized</tt> configure argument is not
+necessary, but KLEE runs very slowly in Debug mode).
+  </li>
+
+  <li>Checkout KLEE (to any path you like):
+    <div class="instr">
+      svn co http://llvm.org/svn/llvm-project/klee/trunk klee
+    </div>
+  </li>
+  
+  <li>Configure KLEE (from the KLEE source directory): 
+    <div class="instr">
+      ./configure --with-llvm=<i>path/to/llvm</i>
+    </div>
+    
+    <p>This assumes that you compiled LLVM in-place.  If you used a
+      different directory for the object files then use:
+      <div class="instr">
+	./configure --with-llvmsrc=<i>path/to/llvm/src</i>--with-llvmobj=<i>path/to/llvm/obj</i>
+      </div>
+  </li>
+
+  <li>Build KLEE (from the KLEE source directory):
+    <div class="instr">
+      make
+    </div>
+  </li>
+
+  <li>Run DejaGNU and unit tests to verify your build:
+    <div class="instr">
+      make check<br>
+      make unittests<br>
+    </div>
+  </li>
+
+  <li>You're ready to go!  Go to the <a href="tutorials.html">Tutorials</a> page
+  to try KLEE.</li>
+</ol>
+
+<!--   <h2> Full Installation </h2> -->
+  
+<!--   If you need uCLibc and/or POSIX support add <i>-with-uclibc</i> -->
+<!--   and <i>-enable-posix-runtime</i> to configure.  Thus, to enable -->
+<!--   both, replace step 3 above with: -->
+  
+<!--   <div class="instr"> -->
+<!--     ./configure -with-llvm=<i>path/to/llvm</i> -with-uclibc -enable-posix-runtime ENABLE_OPTIMIZED=1 -->
+<!--   </div> -->
+<!--   However, note that... -->
+
+</div>
+</body>
+</html>

Modified: klee/trunk/www/bugs.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/bugs.html?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/bugs.html (original)
+++ klee/trunk/www/bugs.html Wed May 20 23:36:41 2009
@@ -9,7 +9,7 @@
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Bug Reports</h1>

Modified: klee/trunk/www/content.css
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/content.css?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/content.css (original)
+++ klee/trunk/www/content.css Wed May 20 23:36:41 2009
@@ -1,6 +1,8 @@
 html, body {
   padding:0px;
-  font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
+  font-size:small; 
+  font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; 
+  background-color: #fff; color: #222;
   line-height:1.5;
 }
 
@@ -24,11 +26,23 @@
 /* Tables */
 tr { vertical-align:top }
 
-/* Code */
-div.code{
+/* Instructions */
+div.instr{
     border: 1px solid LightSteelBlue ;
     font-family: Courier New;
     background-color: #E3E3E3;
     padding: 7px;
     margin: 7px;
 }
+
+/* Code */
+pre.code{
+    display:table;
+    text-align: left;
+    border: 1px solid LightSteelBlue ;
+    font-family: Courier New;
+    background-color: #E3E3E3;
+    margin: 10px;
+    padding: 10px;
+}
+

Modified: klee/trunk/www/index.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/index.html?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/index.html (original)
+++ klee/trunk/www/index.html Wed May 20 23:36:41 2009
@@ -27,7 +27,9 @@
   the <a href="http://llvm.org/pubs/2008-12-OSDI-KLEE.html">OSDI
   2008</a> paper.</p>
 
+<!--  <p>FIXME: Somewhere need to describe what KLEE can do well and what
+      is more "experimental" or research level. This should also address
+      how KLEE could be used by outside groups (i.e. kleaver).</p> -->
 </div>
-
 </body>
 </html>

Modified: klee/trunk/www/install.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/install.html?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/install.html (original)
+++ klee/trunk/www/install.html Wed May 20 23:36:41 2009
@@ -9,7 +9,7 @@
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Installation Guide</h1>

Modified: klee/trunk/www/menu.html.incl
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/menu.html.incl?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/menu.html.incl (original)
+++ klee/trunk/www/menu.html.incl Wed May 20 23:36:41 2009
@@ -6,7 +6,10 @@
   <div class="submenu">
     <label>klee Info</label>
     <a href="index.html">About</a>
-    <a href="install.html">Download & Install</a>
+    <a href="GetStarted.html">Get Started</a>
+    <a href="GetInvolved.html">Get Involved</a>
+    <a href="tutorials.html">Tutorials</a>
+    <a href="Examples.html">Examples</a>
   </div>
 
   <div class="submenu">
@@ -14,5 +17,7 @@
     <a href="http://keeda.stanford.edu/mailman/listinfo/klee-dev">klee-dev</a>
     <a href="http://llvm.org/svn/llvm-project/klee/trunk/">Browse SVN</a>
     <a href="http://llvm.org/viewvc/llvm-project/klee/trunk/">Browse ViewVC</a>
+    <a href="http://t1.minormatter.com/~ddunbar/klee-doxygen/index.html">doxygen</a>
+    <a href="http://t1.minormatter.com/~ddunbar/klee-cov/index.html">Testing Coverage</a>
   </div>
 </div>

Modified: klee/trunk/www/tutorials.html
URL: http://llvm.org/viewvc/llvm-project/klee/trunk/www/tutorials.html?rev=72205&r1=72204&r2=72205&view=diff

==============================================================================
--- klee/trunk/www/tutorials.html (original)
+++ klee/trunk/www/tutorials.html Wed May 20 23:36:41 2009
@@ -4,12 +4,12 @@
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <title>The klee Symbolic Virtual Machine</title>
+  <title>The KLEE Symbolic Virtual Machine</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
 </head>
 <body>
-<include virtual="menu.html.incl">
+<!--#include virtual="menu.html.incl"-->
 <div id="content">
   <!--*********************************************************************-->
   <h1>KLEE Tutorials</h1>





More information about the llvm-commits mailing list