// File: akinanop[P]mvl-solver/src/Formula.cc
// Function: Formula::ChronoBacktrack(int)
int Formula::ChronoBacktrack(int level)
{
	//start of finite domain extended dpll
	// return 0 : if theory satisfied
	// return 1 : if time out
	// return 2 : if conflict and later used as unsatisfied

	//set LEVEL
	LEVEL = level;

	//check if time out
	TIME_E = GetTime();
	if((TIME_E - TIME_S) > TIMELIMIT)
		return 1;

	//check unit literal
	if(!UNITLIST.empty())
		unitPropagation();

	//check if time out
	TIME_E = GetTime();
	if((TIME_E - TIME_S) > TIMELIMIT)
		return 1;

	//check if conflict
	if(CONFLICT)
	{
		BACKTRACKS++;
		CONFLICT = false;
		undoTheory(LEVEL-1);
		UNITLIST.clear();
		LEVEL = LEVEL-1;
		return 2;
	}

	//since all is fine, now need to choose a literal
	//to branch on
	Literal atom;

	switch(heuristic) {
		case Heuristic::BK  : atom = chooseLiteral (); break;
		case Heuristic::lazy  : atom = lazyChooseLiteral (); break;
	}

	if(atom.VAR != -1)
	{
		DECISIONS++;
		LEVEL++;
		if (LOG) cout << "Decision: " << atom . VAR << ( atom . EQUAL ? '=' : '!' ) << atom . VAL << endl;
		reduceTheory(atom.VAR, atom.EQUAL, atom.VAL);
		int result = ChronoBacktrack(LEVEL);
		if(result == 0)
			return 0;
		else if(result == 1)
			return 1;
		else if((result == 2) && (LEVEL >= 0))
		{
			if (LOG) cout << "Conflict: Propagating " << atom . VAR << ( !atom . EQUAL ? '=' : '!' ) << atom . VAL << endl;
			reduceTheory(atom.VAR, !atom.EQUAL, atom.VAL);
			return ChronoBacktrack(LEVEL);
		}
		else
			return 2;
	}
	else
	{
		// The theory is satisfied if all variables are assigned and there is no conflict
		return 0;
	}
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movl %esi, 0x84(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x28(%rsp)
movl 0x84(%rsp), %ecx
movl %ecx, 0x48(%rax)
callq 0x2ec0
movq 0x28(%rsp), %rax
movsd %xmm0, 0x40(%rax)
movsd 0x40(%rax), %xmm0
subsd 0x38(%rax), %xmm0
cvtsi2sdl 0x30(%rax), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x127e1
movl $0x1, 0x94(%rsp)
jmp 0x12b07
movq 0x28(%rsp), %rdi
addq $0x60, %rdi
callq 0x13e10
testb $0x1, %al
jne 0x127fd
movq 0x28(%rsp), %rdi
callq 0x125b0
callq 0x2ec0
movq 0x28(%rsp), %rax
movsd %xmm0, 0x40(%rax)
movsd 0x40(%rax), %xmm0
subsd 0x38(%rax), %xmm0
cvtsi2sdl 0x30(%rax), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x12831
movl $0x1, 0x94(%rsp)
jmp 0x12b07
movq 0x28(%rsp), %rax
testb $0x1, 0x7c(%rax)
je 0x12885
movq 0x28(%rsp), %rdi
movl 0x4c(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rdi)
movb $0x0, 0x7c(%rdi)
movl 0x48(%rdi), %esi
subl $0x1, %esi
callq 0xfb30
movq 0x28(%rsp), %rdi
addq $0x60, %rdi
callq 0x141e0
movq 0x28(%rsp), %rax
movl 0x48(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0x48(%rax)
movl $0x2, 0x94(%rsp)
jmp 0x12b07
leaq 0x78(%rsp), %rdi
callq 0x59f0
movq 0x28(%rsp), %rax
movl 0xa8(%rax), %eax
movl %eax, 0x24(%rsp)
testl %eax, %eax
je 0x128af
jmp 0x128a4
movl 0x24(%rsp), %eax
subl $0x2, %eax
je 0x128eb
jmp 0x12925
movq 0x28(%rsp), %rdi
callq 0xdf30
movb %dl, 0x60(%rsp)
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x6c(%rsp)
movb 0x60(%rsp), %al
movb %al, 0x74(%rsp)
movq 0x6c(%rsp), %rax
movq %rax, 0x78(%rsp)
movb 0x74(%rsp), %al
movb %al, 0x80(%rsp)
jmp 0x12925
movq 0x28(%rsp), %rdi
callq 0x116e0
movb %dl, 0x40(%rsp)
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x4c(%rsp)
movb 0x40(%rsp), %al
movb %al, 0x54(%rsp)
movq 0x4c(%rsp), %rax
movq %rax, 0x78(%rsp)
movb 0x54(%rsp), %al
movb %al, 0x80(%rsp)
cmpl $-0x1, 0x78(%rsp)
je 0x12afc
movq 0x28(%rsp), %rax
movl 0x50(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x50(%rax)
movl 0x48(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x48(%rax)
testb $0x1, 0xa4(%rax)
je 0x129c0
movq 0xb679(%rip), %rdi      # 0x1dfd0
leaq 0x54ad(%rip), %rsi      # 0x17e0b
callq 0x2220
movq %rax, %rdi
movl 0x78(%rsp), %esi
callq 0x2400
movq %rax, 0x18(%rsp)
movb 0x80(%rsp), %cl
movb $0x3d, %al
movb $0x21, %dl
movb %dl, 0x22(%rsp)
testb $0x1, %cl
movb %al, 0x23(%rsp)
jne 0x12994
movb 0x22(%rsp), %al
movb %al, 0x23(%rsp)
movq 0x18(%rsp), %rdi
movb 0x23(%rsp), %al
movsbl %al, %esi
callq 0x22d0
movq %rax, %rdi
movl 0x7c(%rsp), %esi
callq 0x2400
movq %rax, %rdi
movq 0xb605(%rip), %rsi      # 0x1dfc0
callq 0x2260
movq 0x28(%rsp), %rdi
movl 0x78(%rsp), %esi
movb 0x80(%rsp), %al
movl 0x7c(%rsp), %ecx
andb $0x1, %al
movzbl %al, %edx
callq 0xe470
movq 0x28(%rsp), %rdi
movl 0x48(%rdi), %esi
callq 0x12780
movl %eax, 0x34(%rsp)
cmpl $0x0, 0x34(%rsp)
jne 0x12a06
movl $0x0, 0x94(%rsp)
jmp 0x12b07
cmpl $0x1, 0x34(%rsp)
jne 0x12a1d
movl $0x1, 0x94(%rsp)
jmp 0x12b07
cmpl $0x2, 0x34(%rsp)
jne 0x12aef
movq 0x28(%rsp), %rax
cmpl $0x0, 0x48(%rax)
jl 0x12aef
movq 0x28(%rsp), %rax
testb $0x1, 0xa4(%rax)
je 0x12ab8
movq 0xb584(%rip), %rdi      # 0x1dfd0
leaq 0x53c3(%rip), %rsi      # 0x17e16
callq 0x2220
movq %rax, %rdi
movl 0x78(%rsp), %esi
callq 0x2400
movq %rax, 0x8(%rsp)
movb 0x80(%rsp), %cl
xorb $-0x1, %cl
movb $0x3d, %al
movb $0x21, %dl
movb %dl, 0x16(%rsp)
testb $0x1, %cl
movb %al, 0x17(%rsp)
jne 0x12a8c
movb 0x16(%rsp), %al
movb %al, 0x17(%rsp)
movq 0x8(%rsp), %rdi
movb 0x17(%rsp), %al
movsbl %al, %esi
callq 0x22d0
movq %rax, %rdi
movl 0x7c(%rsp), %esi
callq 0x2400
movq %rax, %rdi
movq 0xb50d(%rip), %rsi      # 0x1dfc0
callq 0x2260
movq 0x28(%rsp), %rdi
movl 0x78(%rsp), %esi
movb 0x80(%rsp), %al
xorb $-0x1, %al
movl 0x7c(%rsp), %ecx
movzbl %al, %edx
andl $0x1, %edx
callq 0xe470
movq 0x28(%rsp), %rdi
movl 0x48(%rdi), %esi
callq 0x12780
movl %eax, 0x94(%rsp)
jmp 0x12b07
movl $0x2, 0x94(%rsp)
jmp 0x12b07
movl $0x0, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)