// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x60(%rdi), %r14
movl %esi, 0x48(%rbx)
callq 0x290a
movsd %xmm0, 0x40(%rbx)
subsd 0x38(%rbx), %xmm0
cvtsi2sdl 0x30(%rbx), %xmm1
ucomisd %xmm1, %xmm0
ja 0x8a1b
cmpq %r14, (%r14)
je 0x88b8
movq %rbx, %rdi
callq 0x87e4
callq 0x290a
movsd %xmm0, 0x40(%rbx)
subsd 0x38(%rbx), %xmm0
cvtsi2sdl 0x30(%rbx), %xmm1
ucomisd %xmm1, %xmm0
ja 0x8a1b
cmpb $0x1, 0x7c(%rbx)
je 0x8a1f
movl 0xa8(%rbx), %eax
xorl %r15d, %r15d
cmpl $0x2, %eax
je 0x8900
testl %eax, %eax
jne 0x8a42
movq %rbx, %rdi
callq 0x6826
jmp 0x8908
movq %rbx, %rdi
callq 0x7f9a
movq %rax, %r12
movl %edx, %r13d
cmpl $-0x1, %r12d
je 0x8a42
incl 0x50(%rbx)
incl 0x48(%rbx)
cmpb $0x0, 0xa4(%rbx)
je 0x8975
movq 0x66a2(%rip), %rdi      # 0xefd0
leaq 0x24f6(%rip), %rsi      # 0xae2b
callq 0x2210
movq %rax, %rdi
movl %r12d, %esi
callq 0x2380
testb $0x1, %r13b
pushq $0x21
popq %rsi
pushq $0x3d
popq %rcx
cmovnel %ecx, %esi
movq %rax, %rdi
callq 0x2270
movq %r12, %rbp
shrq $0x20, %rbp
movq %rax, %rdi
movl %ebp, %esi
callq 0x2380
movq %rax, %rdi
callq 0x2140
jmp 0x897c
movq %r12, %rbp
shrq $0x20, %rbp
movzbl %r13b, %edx
andl $0x1, %edx
movq %rbx, %rdi
movl %r12d, %esi
movl %ebp, %ecx
callq 0x69ec
movl 0x48(%rbx), %esi
movq %rbx, %rdi
callq 0x8878
cmpl $0x2, %eax
jb 0x8a54
cmpl $0x0, 0x48(%rbx)
js 0x8a3e
cmpb $0x1, 0xa4(%rbx)
jne 0x89fc
movq 0x6612(%rip), %rdi      # 0xefd0
leaq 0x2471(%rip), %rsi      # 0xae36
callq 0x2210
movq %rax, %rdi
movl %r12d, %esi
callq 0x2380
testb $0x1, %r13b
pushq $0x3d
popq %rsi
pushq $0x21
popq %rcx
cmovnel %ecx, %esi
movq %rax, %rdi
callq 0x2270
movq %rax, %rdi
movl %ebp, %esi
callq 0x2380
movq %rax, %rdi
callq 0x2140
notb %r13b
movzbl %r13b, %edx
andl $0x1, %edx
movq %rbx, %rdi
movl %r12d, %esi
movl %ebp, %ecx
callq 0x69ec
movl 0x48(%rbx), %esi
jmp 0x888a
pushq $0x1
jmp 0x8a40
incl 0x4c(%rbx)
movb $0x0, 0x7c(%rbx)
movl 0x48(%rbx), %esi
decl %esi
movq %rbx, %rdi
callq 0x73ca
movq %r14, %rdi
callq 0x902c
decl 0x48(%rbx)
pushq $0x2
popq %r15
movl %r15d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %r15d
jmp 0x8a42
nop