// File: 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:
subq $0x148, %rsp            # imm = 0x148
movb %dl, %al
movq %rdi, 0x138(%rsp)
movq %rsi, 0x130(%rsp)
andb $0x1, %al
movb %al, 0x12f(%rsp)
movq 0x138(%rsp), %rdi
movq %rdi, 0x68(%rsp)
movq 0x130(%rsp), %rsi
callq 0xf400
testb $0x1, %al
jne 0x10152
jmp 0x10179
movq 0x68(%rsp), %rdi
movq 0x130(%rsp), %rsi
callq 0xf560
movq 0x130(%rsp), %rax
movq %rax, 0x140(%rsp)
jmp 0x1075b
leaq 0x120(%rsp), %rdi
callq 0x59f0
movq 0x68(%rsp), %rax
testb $0x1, 0xa5(%rax)
je 0x101b4
movq 0x130(%rsp), %rax
movq 0x20(%rax), %rcx
movq %rcx, 0x120(%rsp)
movb 0x28(%rax), %al
movb %al, 0x128(%rsp)
jmp 0x101f5
movq 0x68(%rsp), %rdi
movq 0x130(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x130(%rsp), %rsi
callq 0x10780
movq 0x60(%rsp), %rdi
movslq %eax, %rsi
callq 0xb8b0
movq (%rax), %rcx
movq %rcx, 0x120(%rsp)
movb 0x8(%rax), %al
movb %al, 0x128(%rsp)
movq 0x68(%rsp), %rax
movl 0x120(%rsp), %ecx
movl %ecx, 0x11c(%rsp)
movl 0x124(%rsp), %ecx
movl %ecx, 0x118(%rsp)
testb $0x1, 0xa4(%rax)
je 0x102b3
movq 0xdda6(%rip), %rdi      # 0x1dfd0
leaq 0x7af9(%rip), %rsi      # 0x17d2a
callq 0x2220
movq %rax, %rdi
movq 0xdd80(%rip), %rsi      # 0x1dfc0
callq 0x2260
leaq 0x120(%rsp), %rdi
callq 0xb8d0
movq 0xdd77(%rip), %rdi      # 0x1dfd0
leaq 0x7ae5(%rip), %rsi      # 0x17d45
callq 0x2220
movq %rax, %rdi
movq 0xdd51(%rip), %rsi      # 0x1dfc0
callq 0x2260
movq 0x68(%rsp), %rdi
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x48(%rax), %rax
movslq 0x118(%rsp), %rcx
movl (%rax,%rcx,4), %esi
movq 0xdd31(%rip), %rdi      # 0x1dfd0
callq 0x2400
movq %rax, %rdi
movq 0xdd12(%rip), %rsi      # 0x1dfc0
callq 0x2260
movq 0x68(%rsp), %rdi
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x48(%rax), %rax
movslq 0x118(%rsp), %rcx
cmpl $-0x1, (%rax,%rcx,4)
jne 0x10455
movq 0x68(%rsp), %rdi
movq %rdi, %rax
addq $0x88, %rax
movq %rax, 0x50(%rsp)
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq 0x50(%rsp), %rdi
movq (%rax), %rax
movq 0x10(%rax), %rax
movslq 0x118(%rsp), %rcx
movslq (%rax,%rcx,4), %rsi
callq 0xb8b0
movl 0x8(%rax), %ecx
movl %ecx, 0x108(%rsp)
movq (%rax), %rax
movq %rax, 0x100(%rsp)
movl $0x38, %edi
callq 0x2230
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x58(%rsp)
movl $0x2, %esi
callq 0xb4d0
jmp 0x10351
movq 0x58(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x40(%rsp)
movl 0x100(%rsp), %esi
movl 0x104(%rsp), %ecx
leaq 0xe8(%rsp), %rdi
movl $0x3d, %edx
callq 0x12e00
movq 0x40(%rsp), %rdi
movq 0xe8(%rsp), %rax
movq %rax, 0xd8(%rsp)
movl 0xf0(%rsp), %eax
movl %eax, 0xe0(%rsp)
movq 0xd8(%rsp), %rsi
movzbl 0xe0(%rsp), %edx
callq 0xb5b0
movq 0x110(%rsp), %rax
movq %rax, 0x48(%rsp)
movl 0x100(%rsp), %esi
movl 0x104(%rsp), %ecx
leaq 0xcc(%rsp), %rdi
movl $0x21, %edx
callq 0x12e00
movq 0x48(%rsp), %rdi
movq 0xcc(%rsp), %rax
movq %rax, 0xbc(%rsp)
movl 0xd4(%rsp), %eax
movl %eax, 0xc4(%rsp)
movq 0xbc(%rsp), %rsi
movzbl 0xc4(%rsp), %edx
callq 0xb5b0
jmp 0x105ed
movq 0x58(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
movl $0x38, %esi
callq 0x2240
jmp 0x1076b
movq 0x68(%rsp), %rdi
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x48(%rax), %rax
movslq 0x118(%rsp), %rcx
cmpl $-0x2, (%rax,%rcx,4)
jne 0x105a5
movl $0x38, %edi
callq 0x2230
movq 0x68(%rsp), %rdi
movq %rax, 0x38(%rsp)
movq %rax, 0x30(%rsp)
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq 0x38(%rsp), %rdi
movq (%rax), %rax
movl 0x8(%rax), %esi
callq 0xb4d0
jmp 0x104b8
movq 0x30(%rsp), %rax
movq %rax, 0x110(%rsp)
movl $0x0, 0xb8(%rsp)
movq 0x68(%rsp), %rdi
movl 0xb8(%rsp), %eax
movl %eax, 0x2c(%rsp)
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq %rax, %rcx
movl 0x2c(%rsp), %eax
movq (%rcx), %rcx
cmpl 0x8(%rcx), %eax
jge 0x105a3
movq 0x110(%rsp), %rax
movq %rax, 0x20(%rsp)
movl 0x11c(%rsp), %esi
movl 0xb8(%rsp), %ecx
leaq 0xac(%rsp), %rdi
movl $0x3d, %edx
callq 0x12e00
movq 0x20(%rsp), %rdi
movq 0xac(%rsp), %rax
movq %rax, 0x9c(%rsp)
movl 0xb4(%rsp), %eax
movl %eax, 0xa4(%rsp)
movq 0x9c(%rsp), %rsi
movzbl 0xa4(%rsp), %edx
callq 0xb5b0
movl 0xb8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb8(%rsp)
jmp 0x104d0
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
movl $0x38, %esi
callq 0x2240
jmp 0x1076b
jmp 0x105eb
movq 0x68(%rsp), %rdi
movq %rdi, %rax
addq $0x18, %rax
movq %rax, 0x18(%rsp)
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq 0x18(%rsp), %rdi
movq (%rax), %rax
movq 0x48(%rax), %rax
movslq 0x118(%rsp), %rcx
movslq (%rax,%rcx,4), %rsi
callq 0x12f20
movq (%rax), %rax
movq %rax, 0x110(%rsp)
jmp 0x105ed
movq 0x68(%rsp), %rdi
movq 0x130(%rsp), %rsi
movq 0x120(%rsp), %rax
movq %rax, 0x84(%rsp)
movl 0x128(%rsp), %eax
movl %eax, 0x8c(%rsp)
movq 0x110(%rsp), %r8
movq 0x84(%rsp), %rax
movq %rax, 0x74(%rsp)
movl 0x8c(%rsp), %eax
movl %eax, 0x7c(%rsp)
movq 0x74(%rsp), %rdx
movzbl 0x7c(%rsp), %ecx
callq 0xef30
movq %rax, %rcx
movq 0x68(%rsp), %rax
movq %rcx, 0x90(%rsp)
testb $0x1, 0xa5(%rax)
je 0x10672
movq 0x68(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x10850
testb $0x1, 0x12f(%rsp)
je 0x106aa
movq 0x130(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x106a8
movq 0x10(%rsp), %rdi
callq 0xb580
movq 0x10(%rsp), %rdi
movl $0x38, %esi
callq 0x2240
jmp 0x106aa
movq 0x68(%rsp), %rdi
movslq 0x11c(%rsp), %rsi
callq 0xaab0
movq (%rax), %rax
movq 0x48(%rax), %rax
movslq 0x118(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jge 0x106ff
movq 0x110(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x106fd
movq 0x8(%rsp), %rdi
callq 0xb580
movq 0x8(%rsp), %rdi
movl $0x38, %esi
callq 0x2240
jmp 0x106ff
movq 0x68(%rsp), %rax
testb $0x1, 0xa4(%rax)
je 0x1073c
movq 0xd8bc(%rip), %rdi      # 0x1dfd0
leaq 0x7638(%rip), %rsi      # 0x17d53
callq 0x2220
movq %rax, %rdi
movq 0xd896(%rip), %rsi      # 0x1dfc0
callq 0x2260
movq 0x90(%rsp), %rdi
callq 0xb600
movq 0x68(%rsp), %rdi
movq 0x90(%rsp), %rsi
movl $0x1, %edx
callq 0x10110
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rax
addq $0x148, %rsp            # imm = 0x148
retq
movq 0xf8(%rsp), %rdi
callq 0x2410
nopl (%rax,%rax)