// File: /workspace/github_cpp_makefile_star2_O3/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 $0x28, %rsp
movl %edx, %r12d
movq %rsi, %r13
movq %rdi, %rbx
callq 0x9156
testb %al, %al
jne 0x9e2f
cmpb $0x1, 0xa5(%rbx)
jne 0x9b42
movb 0x28(%r13), %al
movb %al, 0x10(%rsp)
movq 0x20(%r13), %rax
movq %rax, 0x8(%rsp)
jmp 0x9b68
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9e54
cltq
movq (%r13), %rcx
leaq (%rax,%rax,2), %rax
movq (%rcx,%rax,4), %rdx
movq %rdx, 0x8(%rsp)
movb 0x8(%rcx,%rax,4), %al
movb %al, 0x10(%rsp)
movslq 0x8(%rsp), %rbp
movslq 0xc(%rsp), %rcx
cmpb $0x0, 0xa4(%rbx)
je 0x9c4d
movq 0x744a(%rip), %r15      # 0x10fd0
leaq 0x424d(%rip), %rsi      # 0xddda
movl $0x1a, %edx
movq %r15, %rdi
movq %rcx, %r14
callq 0x2270
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2200
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2180
leaq 0x8(%rsp), %rdi
callq 0x7052
leaq 0x4220(%rip), %rsi      # 0xddf5
movl $0xd, %edx
movq %r15, %rdi
callq 0x2270
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2200
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2180
movq (%rbx), %rax
movq (%rax,%rbp,8), %rax
movq 0x48(%rax), %rax
movl (%rax,%r14,4), %esi
movq %r15, %rdi
callq 0x2390
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2200
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2180
movq %r14, %rcx
movq (%rbx), %rax
movq (%rax,%rbp,8), %r14
movq 0x48(%r14), %rax
movslq (%rax,%rcx,4), %rax
cmpq $-0x2, %rax
movl %r12d, 0x14(%rsp)
movq %rcx, 0x20(%rsp)
je 0x9cd1
cmpl $-0x1, %eax
jne 0x9d39
movq 0x10(%r14), %rax
movslq (%rax,%rcx,4), %rax
movq 0x88(%rbx), %rcx
leaq (%rax,%rax,2), %rax
movl (%rcx,%rax,4), %r14d
movl 0x4(%rcx,%rax,4), %r12d
movl $0x38, %edi
callq 0x2230
movq %rax, %r15
movq %rax, %rdi
movl $0x2, %esi
callq 0x6e34
shlq $0x20, %r12
orq %r14, %r12
movq %r15, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x6ec8
movq %r15, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6ec8
jmp 0x9d41
movl $0x38, %edi
callq 0x2230
movq %rax, %r15
movl 0x8(%r14), %esi
movq %rax, %rdi
callq 0x6e34
movq (%rbx), %rax
movq (%rax,%rbp,8), %rax
cmpl $0x0, 0x8(%rax)
jle 0x9d41
movq %r13, 0x18(%rsp)
movl %ebp, %r12d
xorl %r13d, %r13d
movabsq $0x100000000, %r14      # imm = 0x100000000
movq %r15, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x6ec8
incq %r13
movq (%rbx), %rax
movq (%rax,%rbp,8), %rax
movslq 0x8(%rax), %rax
addq %r14, %r12
cmpq %rax, %r13
jl 0x9d0c
movq 0x18(%rsp), %r13
jmp 0x9d41
movq 0x18(%rbx), %rcx
movq (%rcx,%rax,8), %r15
movq 0x8(%rsp), %rdx
movl 0x10(%rsp), %ecx
movq %r13, %rsi
movq %r15, %r8
callq 0x8fa4
movq %rax, %r12
cmpb $0x1, 0xa5(%rbx)
jne 0x9d6c
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9eb6
cmpb $0x0, 0x14(%rsp)
je 0x9d8d
testq %r13, %r13
je 0x9d80
movq %r13, %rdi
callq 0x6ea6
movl $0x38, %esi
movq %r13, %rdi
callq 0x2240
movq (%rbx), %rax
movq (%rax,%rbp,8), %rax
movq 0x48(%rax), %rax
movq 0x20(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jns 0x9dbd
testq %r15, %r15
je 0x9db0
movq %r15, %rdi
callq 0x6ea6
movl $0x38, %esi
movq %r15, %rdi
callq 0x2240
cmpb $0x1, 0xa4(%rbx)
jne 0x9e10
movq 0x7203(%rip), %r14      # 0x10fd0
leaq 0x402f(%rip), %rsi      # 0xde03
movl $0xa, %edx
movq %r14, %rdi
callq 0x2270
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2200
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2180
movq %r12, %rdi
callq 0x6f0c
movq %rbx, %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x9b02
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9204
jmp 0x9e3c
movq %rax, %rbx
movl $0x38, %esi
movq %r15, %rdi
callq 0x2240
movq %rbx, %rdi
callq 0x23a0