// File: /workspace/github_cpp_makefile_star2_O2/akinanop[P]mvl-solver/src/Formula.cc
// Function: Formula::watchedReduceTheory(Literal)
void Formula::watchedReduceTheory ( Literal lit ) {

	if ( lit.EQUAL ) {

		if ( LOG ) {
			cout << "Reducing literal: " << lit.VAR << "="<< lit.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(lit.VAR, lit.EQUAL, lit.VAL)); 		// Add literal to the decision stack

		VARLIST[lit.VAR] -> ATOMASSIGN[lit.VAL] = 1;
		VARLIST[lit.VAR] -> ATOMLEVEL[lit.VAL] = LEVEL;
		VARLIST[lit.VAR] -> VAL = lit.VAL;
		VARLIST[lit.VAR] -> CLAUSEID[lit.VAL] = UNITCLAUSE; 		// Set the reason for the literal
		VARLIST[lit.VAR] -> ATOMINDEX[lit.VAL] = DECSTACK.size() - 1; // to use in maxLit

		// update watched literals:
		watchedFalsifyLiteral ( Literal(lit.VAR, ! lit.EQUAL, lit.VAL) ); // if one of the watched literals falsified, swap watched literals


		//for each different domain value x from dom(lit.VAR) which is not assigned (0) assign it

		for ( int i = 0; i < lit.VAL && ! CONFLICT; i++ ) {

			if ( VARLIST[lit.VAR] -> ATOMASSIGN[i] == 0 ) {

				VARLIST[lit.VAR]->ATOMASSIGN[i] = -1;
				VARLIST[lit.VAR]->ATOMLEVEL[i] = LEVEL;

				// Set the same reason:
				VARLIST[lit.VAR]->CLAUSEID[i] = UNITCLAUSE;
				VARLIST[lit.VAR] -> ATOMINDEX[i] = DECSTACK.size() - 1; // to use in maxLit


				watchedFalsifyLiteral ( Literal(lit.VAR, lit.EQUAL, i) ); // if one of the watched literals falsified, swap watched literals

			}
		}

		for ( int i = lit.VAL + 1; i < VARLIST[lit.VAR] -> DOMAINSIZE && ! CONFLICT; i++ ) {

			if ( VARLIST[lit.VAR] -> ATOMASSIGN[i] == 0 ) {

				VARLIST[lit.VAR]->ATOMASSIGN[i] = -1;
				VARLIST[lit.VAR]->ATOMLEVEL[i] = LEVEL;

				VARLIST[lit.VAR] -> CLAUSEID[i] = UNITCLAUSE;
				VARLIST[lit.VAR] -> ATOMINDEX[i] = DECSTACK.size() - 1; // to use in maxLit

				watchedFalsifyLiteral ( Literal(lit.VAR, lit.EQUAL, i) ); // if one of the watched literals falsified, swap watched literals
			}
		}
	} else {

		if ( LOG ) {
			cout << "Reducing literal: " << lit.VAR << "!="<< lit.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 decision stack:
		DECSTACK.push_back ( Literal(lit.VAR, lit.EQUAL, lit.VAL) );

		VARLIST[lit.VAR] -> ATOMASSIGN[lit.VAL] = -1;
		VARLIST[lit.VAR] -> ATOMLEVEL[lit.VAL] = LEVEL;
		// Set the reason:
		VARLIST[lit.VAR] -> CLAUSEID[lit.VAL] = UNITCLAUSE;
		VARLIST[lit.VAR] -> ATOMINDEX[lit.VAL] = DECSTACK.size() - 1; // to use in maxLit

		watchedFalsifyLiteral ( Literal(lit.VAR, ! lit.EQUAL, lit.VAL) );


		//check Entailment on this variable
		int entailVal = checkEntail ( lit.VAR );
		if ( entailVal != -1 ) {
			if ( LOG ) cout << "Entailment... " << lit.VAR << "=" << entailVal << endl;
			ENTAILS++;
			// Set the reason:
			UNITCLAUSE = -2;
			watchedReduceTheory ( Literal(lit.VAR, true, entailVal) );
		}

	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movq %rsi, %r14
shrq $0x20, %r14
movb 0xa4(%rdi), %al
testb $0x1, %dl
je 0x7b8b
testb %al, %al
je 0x7c46
movq 0x74d7(%rip), %r12      # 0xefd0
leaq 0x31d2(%rip), %rsi      # 0xacd2
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
movq %r15, %rbp
movl %r15d, %esi
callq 0x2380
leaq 0x30d0(%rip), %rsi      # 0xabed
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movq %r14, %r13
movl %r14d, %esi
callq 0x2380
leaq 0x31ab(%rip), %rsi      # 0xace5
movq %rax, %rdi
callq 0x2210
movl 0x48(%rbx), %esi
movq %rax, %rdi
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x3194(%rip), %rsi      # 0xacf0
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
movslq 0x78(%rbx), %rsi
testq %rsi, %rsi
js 0x7c2c
movq 0x18(%rbx), %rax
movq (%rax,%rsi,8), %rdi
callq 0x5814
jmp 0x7c40
testb %al, %al
je 0x7e2f
movq 0x7436(%rip), %r12      # 0xefd0
leaq 0x3131(%rip), %rsi      # 0xacd2
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
movq %r15, %rbp
movl %r15d, %esi
callq 0x2380
leaq 0x302e(%rip), %rsi      # 0xabec
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movq %r14, %r13
movl %r14d, %esi
callq 0x2380
leaq 0x310a(%rip), %rsi      # 0xace5
movq %rax, %rdi
callq 0x2210
movl 0x48(%rbx), %esi
movq %rax, %rdi
callq 0x2380
movq %rax, %rdi
callq 0x2140
leaq 0x30f3(%rip), %rsi      # 0xacf0
movq %r12, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x2140
movslq 0x78(%rbx), %rsi
testq %rsi, %rsi
js 0x7e15
movq 0x18(%rbx), %rax
movq (%rax,%rsi,8), %rdi
callq 0x5814
jmp 0x7e29
movq 0x739d(%rip), %rdi      # 0xefd0
callq 0x2380
movq %rax, %rdi
callq 0x2140
movq %r13, %r14
movq %rbp, %r15
movq %r14, 0x8(%rsp)
leaq 0x88(%rbx), %rdi
leaq 0x1c(%rsp), %rsi
movl %r15d, (%rsi)
movl %r14d, 0x4(%rsi)
movb $0x1, 0x8(%rsi)
callq 0x93a8
movslq %r15d, %rbp
movq (%rbx), %rax
movq (%rax,%rbp,8), %rcx
movq 0x20(%rcx), %rax
movq %r15, %r14
sarq $0x20, %r14
movl $0x1, (%rax,%r14,4)
movl 0x48(%rbx), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r14,4)
movq 0x8(%rsp), %rax
movl %eax, 0x4(%rcx)
movl 0x78(%rbx), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r14,4)
movq 0x90(%rbx), %rax
subq 0x88(%rbx), %rax
pushq $0xc
popq %rsi
cqto
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r14,4)
movl %ebp, %r12d
xorl %r13d, %r13d
movq %rbx, %rdi
movq %r15, 0x10(%rsp)
movq %r15, %rsi
xorl %edx, %edx
callq 0x8ede
movabsq $0x100000000, %rdx      # imm = 0x100000000
movq 0x8(%rsp), %r15
testl %r15d, %r15d
cmovlel %r13d, %r15d
movq %r12, 0x8(%rsp)
cmpq %r13, %r15
je 0x7d6d
cmpb $0x1, 0x7c(%rbx)
je 0x7d6d
movq (%rbx), %rax
movq (%rax,%rbp,8), %rcx
movq 0x20(%rcx), %rax
cmpl $0x0, (%rax,%r13,4)
jne 0x7d65
orl $-0x1, (%rax,%r13,4)
movl 0x48(%rbx), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r13,4)
movl 0x78(%rbx), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r13,4)
movq 0x90(%rbx), %rax
subq 0x88(%rbx), %rax
cqto
pushq $0xc
popq %rsi
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r13,4)
movq %rbx, %rdi
movq %r12, %rsi
pushq $0x1
popq %rdx
callq 0x8ede
movabsq $0x100000000, %rdx      # imm = 0x100000000
incq %r13
addq %rdx, %r12
jmp 0x7cf5
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
movq 0x10(%rsp), %r15
andq %rax, %r15
addq 0x8(%rsp), %r15
addq %rdx, %r15
incq %r14
pushq $0x1
popq %r12
movq (%rbx), %rax
movq (%rax,%rbp,8), %rcx
movslq 0x8(%rcx), %rax
cmpq %rax, %r14
jge 0x7f23
cmpb $0x0, 0x7c(%rbx)
jne 0x7f23
movq 0x20(%rcx), %rax
cmpl $0x0, (%rax,%r14,4)
jne 0x7e0a
orl $-0x1, (%rax,%r14,4)
movl 0x48(%rbx), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%r14,4)
movl 0x78(%rbx), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%r14,4)
movq 0x90(%rbx), %rax
subq 0x88(%rbx), %rax
cqto
pushq $0xc
popq %rsi
idivq %rsi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%r14,4)
movq %rbx, %rdi
movq %r15, %rsi
movl %r12d, %edx
callq 0x8ede
movabsq $0x100000000, %rdx      # imm = 0x100000000
addq %rdx, %r15
incq %r14
jmp 0x7d8e
movq 0x71b4(%rip), %rdi      # 0xefd0
callq 0x2380
movq %rax, %rdi
callq 0x2140
movq %r13, %r14
movq %rbp, %r15
leaq 0x88(%rbx), %rdi
leaq 0x1c(%rsp), %rsi
movl %r15d, (%rsi)
movl %r14d, 0x4(%rsi)
movb $0x0, 0x8(%rsi)
callq 0x93a8
movq (%rbx), %rax
movslq %r15d, %rcx
movq (%rax,%rcx,8), %rcx
movq 0x20(%rcx), %rax
movq %r15, %rsi
sarq $0x20, %rsi
orl $-0x1, (%rax,%rsi,4)
movl 0x48(%rbx), %eax
movq 0x18(%rcx), %rdx
movl %eax, (%rdx,%rsi,4)
movl 0x78(%rbx), %eax
movq 0x48(%rcx), %rdx
movl %eax, (%rdx,%rsi,4)
movq 0x90(%rbx), %rax
subq 0x88(%rbx), %rax
pushq $0xc
popq %rdi
cqto
idivq %rdi
decl %eax
movq 0x10(%rcx), %rcx
movl %eax, (%rcx,%rsi,4)
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x8ede
movq %rbx, %rdi
movl %r15d, %esi
callq 0x67dc
cmpl $-0x1, %eax
je 0x7f23
movl %eax, %r14d
movl %r15d, %r12d
cmpb $0x1, 0xa4(%rbx)
jne 0x7f04
movq 0x7105(%rip), %rdi      # 0xefd0
leaq 0x2e3b(%rip), %rsi      # 0xad0d
callq 0x2210
movq %rax, %rdi
movl %r15d, %esi
callq 0x2380
leaq 0x2d04(%rip), %rsi      # 0xabed
movq %rax, %rdi
callq 0x2210
movq %rax, %rdi
movl %r14d, %esi
callq 0x2380
movq %rax, %rdi
callq 0x2140
incl 0x58(%rbx)
movl $0xfffffffe, 0x78(%rbx) # imm = 0xFFFFFFFE
shlq $0x20, %r14
orq %r12, %r14
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x7ac0
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq