// File: akinanop[P]mvl-solver/src/Formula.cc
// Function: Formula::BuildFormula(CommandLine*)
void Formula::BuildFormula ( CommandLine* cline ) {
	//local variables
	ifstream infile;
	char line_buffer[3000];
	char word_buffer[3000];
	int clause_num = 0;
	int atom_num = 0;
	int var, val;
	char ch;
	char ch1;
	string str;
	Variable * temp_var = NULL;
	Literal temp_atom;
	Clause * temp_clause = NULL;

	//to start variable from 1 and not from 0 we need this
	VARLIST.push_back( new Variable(0, 0));
	VARLIST[0]->VAL = 0;

	TIME_S = GetTime();
	//opening infile to read and checking if it opens
	infile.open(cline->FILE, ios::in);
	if(!infile)
	{
		cout<<endl;
		cout<<"**** ERROR ****"<<endl;
		cout<<"Could not open input file : "<<endl;
		cout<<endl;
		exit(1);
	}

	//now reading each line from the infile and if needed to convert
	//then converting it and writing to outfile or just writing directly
	while(infile.getline(line_buffer, 3000))
	{
		temp_clause = new Clause(cline->CLAUSE_SIZE);
		//if line is comment - just write
		if(line_buffer[0] == 'c')
		{
			//do nothing
			;
		}
		//else if line is p cnf var_num clause_num - just write
		else if(line_buffer[0] == 'p')
		{
			sscanf(line_buffer, "p cnf %d %d", &var, &val);

		}
		//else if line is d var# domsize
		else if(line_buffer[0] == 'd')
		{
			sscanf(line_buffer, "d %d %d", &var, &val);
			temp_var = new Variable(var, val);
			VARLIST.push_back(temp_var);
		}
		//else its clause lines
		else
		{
			char * lp = line_buffer;
			do
			{
				char * wp = word_buffer;
				//erasing all leading space/tabs
				while (*lp && ((*lp == ' ') || (*lp == '\t')))
				{
					lp++;
				}
				//reading each value into word buffer
				while (*lp && (*lp != ' ') && (*lp != '\t') && (*lp != '\n'))
				{
					*(wp++) = *(lp++);
				}
				*wp = '\0';
				//converting into int and writing to file
				if(strlen(word_buffer) != 0)
				{
					sscanf(word_buffer, "%d %c %d", &var, &ch, &val);
					if(ch == '!')
						sscanf(word_buffer, "%d %c %c %d", &var, &ch, &ch1, &val);
					//checking if variable = 0 i.e end of line
					if(var != 0)
					{
						//add it to clause_list's atom_list
						temp_atom = Literal(var, ch, val);
						temp_clause->addAtom(temp_atom);

						//increment the index representing value so that
						//we can keep track of number of occurrences of each
						//variable and its domain value, if ch is = then increment
						//the value count, else increment others count
						if(ch == '=')
						{
							if (heuristic==Heuristic::VSIDS || heuristic==Heuristic::VSIDS_pos)
								VARLIST[var]->VSIDS_SCORE[val]++;
							else if (heuristic == Heuristic::BK)
								VARLIST[var]->ATOMCNTPOS[val]++;
							if (!WATCH)
								VARLIST[var]->ATOMRECPOS[val].push_back(clause_num);
						}
						else
						{
							if (heuristic==Heuristic::VSIDS) {
								VARLIST[var]->VSIDS_SCORE_NEG[val]++;
							} else if (heuristic == Heuristic::BK)
								VARLIST[var]->ATOMCNTNEG[val]++;
							else if (heuristic == Heuristic::VSIDS_pos) {
								for (int j=0;j<VARLIST[var] -> DOMAINSIZE;j++) {
									if (j!=val)
										VARLIST[var]->VSIDS_SCORE[j]++;
								}
							}
							if (!WATCH)
								VARLIST[var]->ATOMRECNEG[val].push_back(clause_num);
						}
						atom_num++;
					}
				}
			}while(*lp);
			CLAUSELIST.push_back(temp_clause);

			if (temp_clause->ATOM_LIST.size() == 1) {
				UNITLIST.push_back(clause_num);
			}

			// with watched literals option, assign first two literals in the clause to watched1 and watched2


			if ( WATCH ) {

				Literal watched1 = temp_clause -> ATOM_LIST[0];
				temp_clause -> WATCHED[0] = watched1;
				VARLIST[watched1.VAR]->addRecord(clause_num, watched1.VAL, watched1.EQUAL);

				if ( temp_clause -> ATOM_LIST.size() > 1 ) {

					Literal watched2 = temp_clause -> ATOM_LIST[1];
					temp_clause -> WATCHED[1] = watched2;
					VARLIST[watched2.VAR]->addRecord(clause_num, watched2.VAL, watched2.EQUAL);

				}
			}


			atom_num = 0;
			++clause_num;
		}
	}

	//closing file
	infile.close();
	TIME_E = GetTime();
}

// Assembly:
subq $0x1ac8, %rsp           # imm = 0x1AC8
movq %rdi, 0x1ac0(%rsp)
movq %rsi, 0x1ab8(%rsp)
movq 0x1ac0(%rsp), %rax
movq %rax, 0x60(%rsp)
leaq 0x18b0(%rsp), %rdi
callq 0x22b0
movl $0x0, 0x12c(%rsp)
movl $0x0, 0x128(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x2330
movq $0x0, 0xf0(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x59f0
jmp 0xd08f
movq 0x60(%rsp), %rax
movq $0x0, 0xc8(%rsp)
movq %rax, 0x50(%rsp)
movl $0x70, %edi
callq 0x2230
movq %rax, 0x58(%rsp)
jmp 0xd0b6
movq 0x58(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0xc4a0
jmp 0xd0c6
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rax
movq %rax, 0xc0(%rsp)
leaq 0xc0(%rsp), %rsi
callq 0x12dd0
jmp 0xd0e7
movq 0x60(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xaab0
movq (%rax), %rax
movl $0x0, 0x4(%rax)
callq 0x2ec0
movsd %xmm0, 0x48(%rsp)
jmp 0xd10c
movq 0x60(%rsp), %rax
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x38(%rax)
movq 0x1ab8(%rsp), %rax
movq 0x20(%rax), %rsi
leaq 0x18b0(%rsp), %rdi
movl $0x8, %edx
callq 0x2180
jmp 0xd13c
movq 0x18b0(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x18b0(%rsp,%rax), %rdi
callq 0x2130
movb %al, 0x47(%rsp)
jmp 0xd15b
movb 0x47(%rsp), %al
testb $0x1, %al
jne 0xd168
jmp 0xd237
movq 0x10e61(%rip), %rdi     # 0x1dfd0
movq 0x10e4a(%rip), %rsi     # 0x1dfc0
callq 0x2260
jmp 0xd17d
movq 0x10e4c(%rip), %rdi     # 0x1dfd0
leaq 0xa949(%rip), %rsi      # 0x17ad4
callq 0x2220
movq %rax, 0x38(%rsp)
jmp 0xd197
movq 0x38(%rsp), %rdi
movq 0x10e1d(%rip), %rsi     # 0x1dfc0
callq 0x2260
jmp 0xd1aa
movq 0x10e1f(%rip), %rdi     # 0x1dfd0
leaq 0xa9ab(%rip), %rsi      # 0x17b63
callq 0x2220
movq %rax, 0x30(%rsp)
jmp 0xd1c4
movq 0x30(%rsp), %rdi
movq 0x10df0(%rip), %rsi     # 0x1dfc0
callq 0x2260
jmp 0xd1d7
movq 0x10df2(%rip), %rdi     # 0x1dfd0
movq 0x10ddb(%rip), %rsi     # 0x1dfc0
callq 0x2260
jmp 0xd1ec
movl $0x1, %edi
callq 0x22e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
jmp 0xda6a
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
movl $0x70, %esi
callq 0x2240
jmp 0xda6a
jmp 0xd239
leaq 0x18b0(%rsp), %rdi
leaq 0xcf0(%rsp), %rsi
movl $0xbb8, %edx            # imm = 0xBB8
callq 0x20f0
movq %rax, 0x28(%rsp)
jmp 0xd25a
movq 0x28(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x2300
movb %al, 0x27(%rsp)
jmp 0xd274
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0xd281
jmp 0xda1e
movl $0x38, %edi
callq 0x2230
movq %rax, 0x18(%rsp)
jmp 0xd292
movq 0x18(%rsp), %rdi
movq 0x1ab8(%rsp), %rax
movl 0xc(%rax), %esi
callq 0xb4d0
jmp 0xd2a9
movq 0x18(%rsp), %rax
movq %rax, 0xc8(%rsp)
movsbl 0xcf0(%rsp), %eax
cmpl $0x63, %eax
jne 0xd2f0
jmp 0xda19
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
movl $0x38, %esi
callq 0x2240
jmp 0xda6a
movsbl 0xcf0(%rsp), %eax
cmpl $0x70, %eax
jne 0xd328
leaq 0xcf0(%rsp), %rdi
leaq 0xa892(%rip), %rsi      # 0x17b9e
leaq 0x124(%rsp), %rdx
leaq 0x120(%rsp), %rcx
movb $0x0, %al
callq 0x2210
jmp 0xda17
movsbl 0xcf0(%rsp), %eax
cmpl $0x64, %eax
jne 0xd3d8
leaq 0xa86a(%rip), %rsi      # 0x17baa
xorl %eax, %eax
leaq 0xcf0(%rsp), %rdi
leaq 0x124(%rsp), %rdx
leaq 0x120(%rsp), %rcx
callq 0x2210
movl $0x70, %edi
callq 0x2230
movq %rax, 0x10(%rsp)
jmp 0xd370
movq 0x10(%rsp), %rdi
movl 0x124(%rsp), %esi
movl 0x120(%rsp), %edx
callq 0xc4a0
jmp 0xd38a
movq 0x60(%rsp), %rdi
movq 0x10(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0xf0(%rsp), %rsi
callq 0xa9d0
jmp 0xd3ab
jmp 0xda15
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd8(%rsp)
movl %eax, 0xd4(%rsp)
movl $0x70, %esi
callq 0x2240
jmp 0xda6a
leaq 0xcf0(%rsp), %rax
movq %rax, 0xb8(%rsp)
leaq 0x130(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rcx
xorl %eax, %eax
cmpb $0x0, (%rcx)
movb %al, 0xf(%rsp)
je 0xd43e
movq 0xb8(%rsp), %rax
movsbl (%rax), %ecx
movb $0x1, %al
cmpl $0x20, %ecx
movb %al, 0xe(%rsp)
je 0xd436
movq 0xb8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x9, %eax
sete %al
movb %al, 0xe(%rsp)
movb 0xe(%rsp), %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0xd448
jmp 0xd45e
movq 0xb8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xb8(%rsp)
jmp 0xd3f8
jmp 0xd460
movq 0xb8(%rsp), %rcx
xorl %eax, %eax
cmpb $0x0, (%rcx)
movb %al, 0xd(%rsp)
je 0xd4b4
movq 0xb8(%rsp), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x20, %ecx
movb %al, 0xd(%rsp)
je 0xd4b4
movq 0xb8(%rsp), %rax
movsbl (%rax), %ecx
xorl %eax, %eax
cmpl $0x9, %ecx
movb %al, 0xd(%rsp)
je 0xd4b4
movq 0xb8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0xa, %eax
setne %al
movb %al, 0xd(%rsp)
movb 0xd(%rsp), %al
testb $0x1, %al
jne 0xd4be
jmp 0xd4f5
movq 0xb8(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0xb8(%rsp)
movb (%rax), %cl
movq 0xb0(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0xb0(%rsp)
movb %cl, (%rax)
jmp 0xd460
movq 0xb0(%rsp), %rax
movb $0x0, (%rax)
leaq 0x130(%rsp), %rdi
callq 0x2120
cmpq $0x0, %rax
je 0xd8a6
leaq 0x130(%rsp), %rdi
leaq 0xa693(%rip), %rsi      # 0x17bb9
leaq 0x124(%rsp), %rdx
leaq 0x11f(%rsp), %rcx
leaq 0x120(%rsp), %r8
movb $0x0, %al
callq 0x2210
movsbl 0x11f(%rsp), %eax
cmpl $0x21, %eax
jne 0xd588
leaq 0x130(%rsp), %rdi
leaq 0xa661(%rip), %rsi      # 0x17bc2
leaq 0x124(%rsp), %rdx
leaq 0x11f(%rsp), %rcx
leaq 0x11e(%rsp), %r8
leaq 0x120(%rsp), %r9
movb $0x0, %al
callq 0x2210
cmpl $0x0, 0x124(%rsp)
je 0xd8a4
movl 0x124(%rsp), %esi
movsbl 0x11f(%rsp), %edx
movl 0x120(%rsp), %ecx
leaq 0xa4(%rsp), %rdi
callq 0x12e00
jmp 0xd5bb
movb 0xac(%rsp), %al
movb %al, 0xe8(%rsp)
movq 0xa4(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xc8(%rsp), %rdi
movl 0xe8(%rsp), %eax
movl %eax, 0xa0(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0x98(%rsp)
movl 0xa0(%rsp), %eax
movl %eax, 0x90(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rsi
movl 0x90(%rsp), %edx
callq 0xb5b0
jmp 0xd633
movsbl 0x11f(%rsp), %eax
cmpl $0x3d, %eax
jne 0xd71c
movq 0x60(%rsp), %rax
cmpl $0x1, 0xa8(%rax)
je 0xd660
movq 0x60(%rsp), %rax
cmpl $0x3, 0xa8(%rax)
jne 0xd695
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x38(%rax), %rax
movslq 0x120(%rsp), %rcx
movsd 0xa567(%rip), %xmm0     # 0x17bf0
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0xd6cf
movq 0x60(%rsp), %rax
cmpl $0x0, 0xa8(%rax)
jne 0xd6cd
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x28(%rax), %rax
movslq 0x120(%rsp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0xd6cf
movq 0x60(%rsp), %rax
testb $0x1, 0xa5(%rax)
jne 0xd717
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x60(%rax), %rax
movslq 0x120(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rdi
leaq 0x12c(%rsp), %rsi
callq 0x6340
jmp 0xd715
jmp 0xd717
jmp 0xd893
movq 0x60(%rsp), %rax
cmpl $0x1, 0xa8(%rax)
jne 0xd762
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x40(%rax), %rax
movslq 0x120(%rsp), %rcx
movsd 0xa49d(%rip), %xmm0     # 0x17bf0
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0xd849
movq 0x60(%rsp), %rax
cmpl $0x0, 0xa8(%rax)
jne 0xd79f
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x30(%rax), %rax
movslq 0x120(%rsp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0xd847
movq 0x60(%rsp), %rax
cmpl $0x3, 0xa8(%rax)
jne 0xd845
movl $0x0, 0x84(%rsp)
movq 0x60(%rsp), %rdi
movl 0x84(%rsp), %eax
movl %eax, 0x8(%rsp)
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq %rax, %rcx
movl 0x8(%rsp), %eax
movq (%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0xd843
movl 0x84(%rsp), %eax
cmpl 0x120(%rsp), %eax
je 0xd82b
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x38(%rax), %rax
movslq 0x84(%rsp), %rcx
movsd 0xa3cf(%rip), %xmm0     # 0x17bf0
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, (%rax,%rcx,8)
jmp 0xd82d
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0xd7bc
jmp 0xd845
jmp 0xd847
jmp 0xd849
movq 0x60(%rsp), %rax
testb $0x1, 0xa5(%rax)
jne 0xd891
movq 0x60(%rsp), %rdi
movslq 0x124(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x68(%rax), %rax
movslq 0x120(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rdi
leaq 0x12c(%rsp), %rsi
callq 0x6340
jmp 0xd88f
jmp 0xd891
jmp 0xd893
movl 0x128(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x128(%rsp)
jmp 0xd8a6
jmp 0xd8a8
movq 0xb8(%rsp), %rax
cmpb $0x0, (%rax)
jne 0xd3e8
movq 0x60(%rsp), %rdi
addq $0x18, %rdi
leaq 0xc8(%rsp), %rsi
callq 0x12e50
jmp 0xd8d1
movq 0xc8(%rsp), %rdi
callq 0xb890
cmpq $0x1, %rax
jne 0xd8fe
movq 0x60(%rsp), %rdi
addq $0x60, %rdi
leaq 0x12c(%rsp), %rsi
callq 0x12ec0
jmp 0xd8fc
jmp 0xd8fe
movq 0x60(%rsp), %rax
testb $0x1, 0xa5(%rax)
je 0xd9f9
movq 0xc8(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xb8b0
movq 0x60(%rsp), %rdi
movl 0x8(%rax), %ecx
movl %ecx, 0x80(%rsp)
movq (%rax), %rax
movq %rax, 0x78(%rsp)
movq 0xc8(%rsp), %rax
movb 0x80(%rsp), %cl
movb %cl, 0x28(%rax)
movq 0x78(%rsp), %rcx
movq %rcx, 0x20(%rax)
movslq 0x78(%rsp), %rsi
callq 0xaab0
movq (%rax), %rdi
movl 0x12c(%rsp), %esi
movl 0x7c(%rsp), %edx
movzbl 0x80(%rsp), %ecx
andl $0x1, %ecx
callq 0xcb10
jmp 0xd97d
movq 0xc8(%rsp), %rdi
callq 0xb890
cmpq $0x1, %rax
jbe 0xd9f7
movq 0xc8(%rsp), %rdi
movl $0x1, %esi
callq 0xb8b0
movq 0x60(%rsp), %rdi
movl 0x8(%rax), %ecx
movl %ecx, 0x70(%rsp)
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq 0xc8(%rsp), %rax
movb 0x70(%rsp), %cl
movb %cl, 0x34(%rax)
movq 0x68(%rsp), %rcx
movq %rcx, 0x2c(%rax)
movslq 0x68(%rsp), %rsi
callq 0xaab0
movq (%rax), %rdi
movl 0x12c(%rsp), %esi
movl 0x6c(%rsp), %edx
movzbl 0x70(%rsp), %ecx
andl $0x1, %ecx
callq 0xcb10
jmp 0xd9f5
jmp 0xd9f7
jmp 0xd9f9
movl $0x0, 0x128(%rsp)
movl 0x12c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rsp)
jmp 0xda17
jmp 0xda19
jmp 0xd239
leaq 0x18b0(%rsp), %rdi
callq 0x20a0
jmp 0xda2d
callq 0x2ec0
movsd %xmm0, (%rsp)
jmp 0xda39
movq 0x60(%rsp), %rax
movsd (%rsp), %xmm0
movsd %xmm0, 0x40(%rax)
leaq 0xf8(%rsp), %rdi
callq 0x2170
leaq 0x18b0(%rsp), %rdi
callq 0x20b0
addq $0x1ac8, %rsp           # imm = 0x1AC8
retq
leaq 0xf8(%rsp), %rdi
callq 0x2170
leaq 0x18b0(%rsp), %rdi
callq 0x20b0
movq 0xd8(%rsp), %rdi
callq 0x2410
nopw %cs:(%rax,%rax)