// File: /workspace/github_cpp_makefile_star2_O2/akinanop[P]mvl-solver/src/Formula.cc
// Function: Formula::reduceTheory(int, bool, int)
void Formula::reduceTheory ( int var, bool equals, int val ) {

	if ( equals ) {

		if ( LOG ) {
			cout << "Reducing literal: " << var << "="<< val << " at level " << LEVEL << endl;
			cout << "The reason for the literal: " << endl;
			if ( UNITCLAUSE > -1 ) CLAUSELIST[UNITCLAUSE] -> Print(); else cout << UNITCLAUSE << endl;
		}

		//Add literal to the Decision Stack
		DECSTACK.push_back ( Literal ( var, '=', val ) );

		if (heuristic==Heuristic::BK) {
			VARLIST[var] -> ATOMCNTPOS[val] = 0;
			VARLIST[var] -> ATOMCNTNEG[val] = 0;
		}
		VARLIST[var] -> ATOMASSIGN[val] = 1;
		VARLIST[var] -> ATOMLEVEL[val] = LEVEL;
		VARLIST[var] -> VAL = val;
		VARLIST[var] -> CLAUSEID[val] = UNITCLAUSE;
		VARLIST[var] -> ATOMINDEX[val] = DECSTACK.size() - 1; // to use in maxLit

		// satisfy all clauses with the literal, and remove the complement literal from clauses
		satisfyClauses ( var, equals, val );
		removeLiteral ( var, !equals, val );



		//foreach domain value x from dom(v) which is not assigned assign it
		for ( int i = 0; i < val && ! CONFLICT; i++ ) {

			if ( VARLIST[var] -> ATOMASSIGN[i] == 0 ) {

				if (heuristic==Heuristic::BK) {
					VARLIST[var] -> ATOMCNTPOS[i] = 0;
					VARLIST[var] -> ATOMCNTNEG[i] = 0;
				}
				VARLIST[var] -> ATOMASSIGN[i] = -1;
				VARLIST[var]->ATOMLEVEL[i] = LEVEL;
				VARLIST[var]->CLAUSEID[i] = UNITCLAUSE;
				VARLIST[var]->ATOMINDEX[i] = DECSTACK.size() - 1;

				satisfyClauses ( var, !equals, i );
				removeLiteral ( var, equals, i );
			}
		}

		for ( int i = val+1; i < VARLIST[var] -> DOMAINSIZE && ! CONFLICT; i++ ) {
			if ( VARLIST[var] -> ATOMASSIGN[i] == 0 ) {

				if (heuristic==Heuristic::BK) {
					VARLIST[var] -> ATOMCNTPOS[i] = 0;
					VARLIST[var] -> ATOMCNTNEG[i] = 0;
				}

				VARLIST[var] -> ATOMASSIGN[i] = -1;
				VARLIST[var] -> ATOMLEVEL[i] = LEVEL;
				VARLIST[var] -> CLAUSEID[i] = UNITCLAUSE;
				VARLIST[var] -> ATOMINDEX[i] = DECSTACK.size() - 1;

				satisfyClauses ( var, !equals, i );
				removeLiteral ( var, equals, i );
			}
		}
	}
	else {
		if ( LOG ) {
			cout << "Reducing literal: " << var << "!="<< val << " at level " << LEVEL << endl;
			cout << "The reason for the literal: " << endl;
			if ( UNITCLAUSE > -1 ) CLAUSELIST[UNITCLAUSE] -> Print(); else cout << UNITCLAUSE << endl;
		}
		DECSTACK.push_back ( Literal ( var, '!', val ) );

		if (heuristic==Heuristic::BK) {
			VARLIST[var] -> ATOMCNTPOS[val] = 0;
			VARLIST[var] -> ATOMCNTNEG[val] = 0;
		}
		VARLIST[var] -> ATOMASSIGN[val] = -1;
		VARLIST[var] -> ATOMLEVEL[val] = LEVEL;
		VARLIST[var] -> CLAUSEID[val] = UNITCLAUSE;
		VARLIST[var] -> ATOMINDEX[val] = DECSTACK.size() - 1;

		satisfyClauses ( var, equals, val );
		removeLiteral ( var, !equals, val );

		// Check entailment on this variable

		int entailVal = checkEntail ( var );
		if ( entailVal != -1 ) {

			ENTAILS++;
			if ( LOG ) cout << "Entailment... " << var << "=" << entailVal << endl;
			UNITCLAUSE = -2;
			reduceTheory ( var, true, entailVal );
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %ecx, %r15d
movl %esi, %ebx
movq %rdi, %r14
movb 0xa4(%rdi), %al
testl %edx, %edx
je 0x6aab
testb %al, %al
je 0x6b5a
movq 0x85b1(%rip), %r12      # 0xefd0
leaq 0x42ac(%rip), %rsi      # 0xacd2
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
movl %ebx, %esi
callq 0x2380
leaq 0x41ae(%rip), %rsi      # 0xabed
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movl %r15d, %esi
callq 0x2380
leaq 0x428c(%rip), %rsi      # 0xace5
movq %rax, %rdi
callq 0x2210
movl 0x48(%r14), %esi
movq %rax, %rdi
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x4274(%rip), %rsi      # 0xacf0
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
movslq 0x78(%r14), %rsi
testq %rsi, %rsi
js 0x6b46
movq 0x18(%r14), %rax
movq (%rax,%rsi,8), %rdi
callq 0x5814
jmp 0x6b5a
testb %al, %al
je 0x6d7f
movq 0x8516(%rip), %r12      # 0xefd0
leaq 0x4211(%rip), %rsi      # 0xacd2
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
movl %ebx, %esi
callq 0x2380
leaq 0x4112(%rip), %rsi      # 0xabec
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movl %r15d, %esi
callq 0x2380
leaq 0x41f1(%rip), %rsi      # 0xace5
movq %rax, %rdi
callq 0x2210
movl 0x48(%r14), %esi
movq %rax, %rdi
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x41d9(%rip), %rsi      # 0xacf0
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
movslq 0x78(%r14), %rsi
testq %rsi, %rsi
js 0x6d6b
movq 0x18(%r14), %rax
movq (%rax,%rsi,8), %rdi
callq 0x5814
jmp 0x6d7f
movq 0x8483(%rip), %rdi      # 0xefd0
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x88(%r14), %rdi
leaq 0xc(%rsp), %rsi
movl %ebx, (%rsi)
movl %r15d, 0x4(%rsi)
movb $0x1, 0x8(%rsi)
callq 0x93a8
cmpl $0x0, 0xa8(%r14)
movq (%r14), %rax
movslq %ebx, %rbp
movq (%rax,%rbp,8), %rcx
je 0x6b8e
movslq %r15d, %r12
jmp 0x6ba3
movq 0x28(%rcx), %rax
movslq %r15d, %r12
andl $0x0, (%rax,%r12,4)
movq 0x30(%rcx), %rax
andl $0x0, (%rax,%r12,4)
movq 0x20(%rcx), %rax
movl $0x1, (%rax,%r12,4)
movl 0x48(%r14), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r12,4)
movl %r15d, 0x4(%rcx)
movl 0x78(%r14), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r12,4)
movq 0x90(%r14), %rax
subq 0x88(%r14), %rax
pushq $0xc
popq %rsi
cqto
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r12,4)
pushq $0x1
popq %rdx
movq %r14, %rdi
movl %ebx, %esi
movl %r15d, %ecx
callq 0x8bb0
xorl %r13d, %r13d
movq %r14, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl %r15d, %ecx
callq 0x8c92
testl %r15d, %r15d
cmovlel %r13d, %r15d
cmpq %r13, %r15
je 0x6cba
cmpb $0x1, 0x7c(%r14)
je 0x6cba
movq (%r14), %rax
movq (%rax,%rbp,8), %rcx
movq 0x20(%rcx), %rax
cmpl $0x0, (%rax,%r13,4)
jne 0x6cb2
cmpl $0x0, 0xa8(%r14)
jne 0x6c56
movq 0x28(%rcx), %rdx
andl $0x0, (%rdx,%r13,4)
movq 0x30(%rcx), %rdx
andl $0x0, (%rdx,%r13,4)
orl $-0x1, (%rax,%r13,4)
movl 0x48(%r14), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r13,4)
movl 0x78(%r14), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r13,4)
movq 0x90(%r14), %rax
subq 0x88(%r14), %rax
cqto
pushq $0xc
popq %rsi
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r13,4)
movq %r14, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl %r13d, %ecx
callq 0x8bb0
movq %r14, %rdi
movl %ebx, %esi
pushq $0x1
popq %rdx
movl %r13d, %ecx
callq 0x8c92
incq %r13
jmp 0x6c14
incq %r12
pushq $0x1
popq %r15
movq (%r14), %rax
movq (%rax,%rbp,8), %rcx
movslq 0x8(%rcx), %rax
cmpq %rax, %r12
jge 0x6e96
cmpb $0x0, 0x7c(%r14)
jne 0x6e96
movq 0x20(%rcx), %rax
cmpl $0x0, (%rax,%r12,4)
jne 0x6d63
cmpl $0x0, 0xa8(%r14)
jne 0x6d07
movq 0x28(%rcx), %rdx
andl $0x0, (%rdx,%r12,4)
movq 0x30(%rcx), %rdx
andl $0x0, (%rdx,%r12,4)
orl $-0x1, (%rax,%r12,4)
movl 0x48(%r14), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r12,4)
movl 0x78(%r14), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r12,4)
movq 0x90(%r14), %rax
subq 0x88(%r14), %rax
cqto
pushq $0xc
popq %rsi
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r12,4)
movq %r14, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl %r12d, %ecx
callq 0x8bb0
movq %r14, %rdi
movl %ebx, %esi
movl %r15d, %edx
movl %r12d, %ecx
callq 0x8c92
incq %r12
jmp 0x6cc1
movq 0x825e(%rip), %rdi      # 0xefd0
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x88(%r14), %rdi
leaq 0xc(%rsp), %rsi
movl %ebx, (%rsi)
movl %r15d, 0x4(%rsi)
movb $0x0, 0x8(%rsi)
callq 0x93a8
cmpl $0x0, 0xa8(%r14)
movq (%r14), %rax
movslq %ebx, %rcx
movq (%rax,%rcx,8), %rcx
je 0x6db3
movslq %r15d, %rsi
jmp 0x6dc6
movq 0x28(%rcx), %rax
movslq %r15d, %rsi
andl $0x0, (%rax,%rsi,4)
movq 0x30(%rcx), %rax
andl $0x0, (%rax,%rsi,4)
movq 0x20(%rcx), %rax
orl $-0x1, (%rax,%rsi,4)
movl 0x48(%r14), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%rsi,4)
movl 0x78(%r14), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%rsi,4)
movq 0x90(%r14), %rax
subq 0x88(%r14), %rax
pushq $0xc
popq %rdi
cqto
idivq %rdi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%rsi,4)
movq %r14, %rdi
movl %ebx, %esi
xorl %edx, %edx
movl %r15d, %ecx
callq 0x8bb0
pushq $0x1
popq %rdx
movq %r14, %rdi
movl %ebx, %esi
movl %r15d, %ecx
callq 0x8c92
movq %r14, %rdi
movl %ebx, %esi
callq 0x67dc
cmpl $-0x1, %eax
je 0x6e96
movl %eax, %ebp
incl 0x58(%r14)
cmpb $0x1, 0xa4(%r14)
jne 0x6e7f
movq 0x8188(%rip), %rdi      # 0xefd0
leaq 0x3ebe(%rip), %rsi      # 0xad0d
callq 0x2210
movq %rax, %rdi
movl %ebx, %esi
callq 0x2380
leaq 0x3d88(%rip), %rsi      # 0xabed
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movl %ebp, %esi
callq 0x2380
movq %rax, %rdi
callq 0x2140
movl $0xfffffffe, 0x78(%r14) # imm = 0xFFFFFFFE
pushq $0x1
popq %rdx
movq %r14, %rdi
movl %ebx, %esi
movl %ebp, %ecx
callq 0x69ec
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop