// File: /workspace/github_cpp_makefile_star2_O2/akinanop[P]mvl-solver/src/Formula.cc
// Function: Formula::analyzeConflict(Clause*, bool)
Clause* Formula::analyzeConflict ( Clause * clause, bool freeClauseAfterUse ) {

	/*
    First check if there is exactly one atom falsified at the current level.
    If yes, learn the clause: this way upon backtrack it becomes unit. Otherwise
    continue analyzing the conflict.
	 */

	if ( potent ( clause ) ) {
		learnClause(clause);
		return clause;
	}

	// Resolve the clause and its latest falsified literal's reason
	// Latest falsified literal in the clause:
	Literal lastFalse;
	if (WATCH)
		lastFalse = clause->WATCHED[0];
	else
		lastFalse = clause -> ATOM_LIST[maxLit ( clause )];
	int var = lastFalse . VAR;
	int val = lastFalse . VAL;


	if ( LOG ) {
		cout << "Latest falsified literal: " << endl;
		lastFalse . Print ();
		cout << "It's reason: " << endl;
		cout << VARLIST[var]-> CLAUSEID[val] << endl;
	}

	// Generate reasons for decision and entail reasons:
	Clause* reason;

	if ( VARLIST[var]-> CLAUSEID[val] == -1 ) {
		// Take literal in the decstack that falsified lastFalse
		Literal falsifier = DECSTACK[VARLIST[var]->ATOMINDEX[val]];

		// Generate the reason clause:
		reason = new Clause(2);
		reason -> addAtom ( Literal ( falsifier . VAR, '=', falsifier . VAL ) );
		reason -> addAtom ( Literal ( falsifier . VAR, '!', falsifier . VAL ) );

	} else if ( VARLIST[var] -> CLAUSEID[val] == -2 ) {

		reason = new Clause(VARLIST[var] -> DOMAINSIZE);
		for ( int i = 0; i < VARLIST[var] -> DOMAINSIZE; i++ ) {
			reason -> addAtom ( Literal ( var, '=', i ) );
		}
	} else {
		reason = (CLAUSELIST[VARLIST[var] -> CLAUSEID[val]]);
	}

	// resolve:
	Clause * resolvent = resolve ( clause, lastFalse, reason );

	if (WATCH) {
		assignWatched(resolvent);
	}


	/*
	The parameter clause is kept if analyzeConflict was called with a conflict 
	clause that is part of the formula and deleted if it was called recursively 
	with a temporary resolvent
	*/
	if (freeClauseAfterUse) {
		delete clause;
	}
	// Created reason clauses for reason -1 or -2 are deleted
	if (VARLIST[var] -> CLAUSEID[val] <0) {
		delete reason;
	}

	//cout << "Clause size: " << resolvent -> ATOM_LIST.size() << endl;

	if (LOG) {
		cout << "Resolvent:" << endl;
		resolvent -> Print();
	}
	return analyzeConflict ( resolvent, true );
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %edx, %r15d
movq %rsi, %r13
movq %rdi, %rbx
callq 0x703e
testb %al, %al
jne 0x7895
cmpb $0x1, 0xa5(%rbx)
jne 0x7634
movb 0x28(%r13), %al
movb %al, 0x10(%rsp)
movq 0x20(%r13), %rax
movq %rax, 0x8(%rsp)
jmp 0x765a
movq %rbx, %rdi
movq %r13, %rsi
callq 0x78b8
cltq
movq (%r13), %rcx
imulq $0xc, %rax, %rax
movq (%rcx,%rax), %rdx
movq %rdx, 0x8(%rsp)
movb 0x8(%rcx,%rax), %al
movb %al, 0x10(%rsp)
movq %rbx, %rbp
movslq 0x8(%rsp), %r14
movslq 0xc(%rsp), %r12
cmpb $0x0, 0xa4(%rbx)
je 0x76cf
movq 0x7959(%rip), %rbx      # 0xefd0
leaq 0x36cc(%rip), %rsi      # 0xad4a
movq %rbx, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
leaq 0x8(%rsp), %rdi
callq 0x5950
leaq 0x36c6(%rip), %rsi      # 0xad65
movq %rbx, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
movq (%rbp), %rax
movq (%rax,%r14,8), %rax
movq 0x48(%rax), %rax
movl (%rax,%r12,4), %esi
movq %rbx, %rdi
callq 0x2380
movq %rax, %rdi
callq 0x2140
movq %rbp, %rbx
movq (%rbp), %rax
movq %r14, 0x18(%rsp)
movq (%rax,%r14,8), %r14
movq 0x48(%r14), %rax
movslq (%rax,%r12,4), %rax
cmpq $-0x2, %rax
movq %r12, 0x30(%rsp)
je 0x7754
cmpl $-0x1, %eax
movl %r15d, %ebp
jne 0x77b6
movq 0x10(%r14), %rax
movslq (%rax,%r12,4), %rax
movq 0x88(%rbx), %rcx
imulq $0xc, %rax, %rax
movl (%rcx,%rax), %r14d
movl 0x4(%rcx,%rax), %r12d
pushq $0x38
popq %rdi
callq 0x2220
movq %rax, %r15
pushq $0x2
popq %rsi
movq %rax, %rdi
callq 0x577e
shlq $0x20, %r12
orq %r14, %r12
pushq $0x1
popq %rdx
movq %r15, %rdi
movq %r12, %rsi
callq 0x57f2
movq %r15, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x57f2
jmp 0x77cc
movl %r15d, 0x24(%rsp)
movq %r13, 0x28(%rsp)
pushq $0x38
popq %rdi
callq 0x2220
movl 0x8(%r14), %esi
movq %rax, %r15
movq %rax, %rdi
callq 0x577e
movl 0x18(%rsp), %r12d
xorl %r14d, %r14d
pushq $0x1
popq %r13
movabsq $0x100000000, %rbp      # imm = 0x100000000
movq (%rbx), %rax
movq 0x18(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x8(%rax), %rax
cmpq %rax, %r14
jge 0x77c3
movq %r15, %rdi
movq %r12, %rsi
movl %r13d, %edx
callq 0x57f2
incq %r14
addq %rbp, %r12
jmp 0x778b
movq %rbx, %r14
movq 0x18(%rbx), %rcx
movq (%rcx,%rax,8), %r15
jmp 0x77cf
movq 0x28(%rsp), %r13
movl 0x24(%rsp), %ebp
movq %rbx, %r14
movq 0x8(%rsp), %rdx
movl 0x10(%rsp), %ecx
movq %r13, %rsi
movq %r15, %r8
callq 0x6eee
movq %rax, %r12
cmpb $0x1, 0xa5(%r14)
movq 0x18(%rsp), %rbx
jne 0x7800
movq %r14, %rdi
movq %r12, %rsi
callq 0x7906
testb %bpl, %bpl
je 0x781d
testq %r13, %r13
je 0x7812
movq %r13, %rdi
callq 0x57dc
pushq $0x38
popq %rsi
movq %r13, %rdi
callq 0x2230
movq (%r14), %rax
movq (%rax,%rbx,8), %rax
movq 0x48(%rax), %rax
movq 0x30(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jns 0x784b
testq %r15, %r15
je 0x7840
movq %r15, %rdi
callq 0x57dc
pushq $0x38
popq %rsi
movq %r15, %rdi
callq 0x2230
cmpb $0x1, 0xa4(%r14)
jne 0x7878
movq 0x7774(%rip), %rdi      # 0xefd0
leaq 0x3510(%rip), %rsi      # 0xad73
callq 0x2210
movq %rax, %rdi
callq 0x2140
movq %r12, %rdi
callq 0x5814
pushq $0x1
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x75f4
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %r13, %rsi
callq 0x70d6
jmp 0x78a2
movq %rax, %rbx
pushq $0x38
popq %rsi
movq %r15, %rdi
callq 0x2230
movq %rbx, %rdi
callq 0x2390