// File: vsklad[P]cgen/./bal/cnf/processor/cnfoptimizer.cpp
// Function: bal::CnfOptimizer::assign_literal_value(unsigned int, unsigned int)
inline processor_result_t CnfOptimizer::assign_literal_value(const literalid_t literal_id, const literalid_t value) {
        variables_assigned_++;
        _assert_level_1(literal_t__is_variable(literal_id) && !literal_t__is_negation(literal_id));
        
        processor_result_t result = erSatisfied;
        const variableid_t variable_id = literal_t__variable_id(literal_id);
        TRACE_LEVEL_NEXT;
        TRACE_VARIABLE_ASSIGNMENT(variable_id, value);
        TRACE_LEVEL_NEXT;
        
        const literalid_t old_value = variables_.data()[variable_id];
        if (literal_t__is_variable(old_value)) {
            // if variable then the new value must be other than self
            _assert_level_2(!literal_t__is_variable(value) || !literal_t__is_same_variable(old_value, value));
            // can reference preceding variables only
            _assert_level_1(!literal_t__is_variable(value) || literal_t__variable_id(value) <= variable_id);
            // the referenced variable must point to self
            // note the same is fine for old_value since eliminated variables are not updated
            // until post-processing
            _assert_level_1(!literal_t__is_variable(value) ||
                            literal_t__unnegated(value) == variables_.data()[literal_t__variable_id(value)]);
            
            if (variable_id != literal_t__variable_id(old_value)) {
                // a variable is pointing to some other variable already
                // can happen during recursion; resolve the pair of values
                // TPDO: the only known reason for thsi situation is when pair of variables resolves to two values
                // and the second varianble is resolved while assigning the first one;
                // a more optimal solution would be to assign both at once and iterate clauses for both at the same time
                if (literal_t__is_variable(value) && value > old_value) {
                    result = assign_literal_value(literal_t__unnegated(value), literal_t__substitute_literal(value, old_value));
                } else {
                    result = assign_literal_value(literal_t__unnegated(old_value), literal_t__substitute_literal(old_value, value));
                    if (result != erConflict) {
                        // the clauses are handled where the variable was assigned from earlier
                        // all that remains is to update the reference value
                        variables_.data()[variable_id] = value;
                    };
                };
            } else {
                // assign the value immediately to prevent recursive evaluation
                variables_.data()[variable_id] = value;
                
                // go through all clauses that the variable is in
                // exclude the original clause
                // if not satisfied:
                //   remove the old clause from the indexes of all variables
                //   prepare a simplified copy
                //     note this may simplify the flags if an aggregate
                //   append afresh with validation check and merging
                //     note this may be an aggregate
                
                // there is no need to optimize the index since it will not be used again
                CnfProcessor::nonoptimizing_clauses_iterator_t iterator(clauses_index_, *this);
                container_offset_t offset = iterator.first(variable_id);
                while (offset != CONTAINER_END) {
                    if (evaluate_clause(offset) == erConflict) {
                        result = erConflict;
                        break;
                    };
                    offset = iterator.next();
                };
            };
        } else {
            // the same constant can be assigned again while updating indexes recursively
            _assert_level_0(old_value == value);
        };
        TRACE_LEVEL_PREV;
        TRACE_LEVEL_PREV;
        return result;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq 0xd0(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0xd0(%rax)
xorl %eax, %eax
cmpl $0x1, -0xc(%rbp)
movb %al, -0x3d(%rbp)
jbe 0x1c961
cmpl $-0x2, -0xc(%rbp)
setbe %al
movb %al, -0x3d(%rbp)
movb -0x3d(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x49(%rbp)
jne 0x1c970
jmp 0x1c981
movl -0xc(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
sete %al
xorb $-0x1, %al
movb %al, -0x49(%rbp)
movb -0x49(%rbp), %al
testb $0x1, %al
jne 0x1c98a
jmp 0x1c98c
jmp 0x1c9ab
leaq 0x42c3d(%rip), %rdi     # 0x5f5d0
leaq 0x4157a(%rip), %rsi     # 0x5df14
movl $0x2a5, %edx            # imm = 0x2A5
leaq 0x42ca0(%rip), %rcx     # 0x5f646
callq 0xd1c0
movl $0x3, -0x14(%rbp)
movl -0xc(%rbp), %eax
shrl %eax
subl $0x1, %eax
movl %eax, -0x18(%rbp)
leaq 0x669cc(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x1c9e4
leaq 0x669ba(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movq (%rdi), %rax
callq *0x20(%rax)
leaq 0x669a5(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x1ca11
leaq 0x66993(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movl -0x18(%rbp), %esi
movl -0x10(%rbp), %edx
movq (%rdi), %rax
callq *0x30(%rax)
leaq 0x66978(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x1ca38
leaq 0x66966(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movq (%rdi), %rax
callq *0x20(%rax)
movq -0x48(%rbp), %rax
movq 0xb8(%rax), %rdi
callq 0x10310
movl -0x18(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x1c(%rbp)
xorl %eax, %eax
cmpl $0x1, -0x1c(%rbp)
movb %al, -0x4a(%rbp)
jbe 0x1ca66
cmpl $-0x2, -0x1c(%rbp)
setbe %al
movb %al, -0x4a(%rbp)
movb -0x4a(%rbp), %al
testb $0x1, %al
jne 0x1ca72
jmp 0x1ccec
xorl %eax, %eax
cmpl $0x1, -0x10(%rbp)
movb %al, -0x4b(%rbp)
jbe 0x1ca87
cmpl $-0x2, -0x10(%rbp)
setbe %al
movb %al, -0x4b(%rbp)
movb -0x4b(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x4c(%rbp)
jne 0x1ca96
jmp 0x1caa9
movl -0x1c(%rbp), %eax
xorl -0x10(%rbp), %eax
shrl %eax
cmpl $0x0, %eax
sete %al
xorb $-0x1, %al
movb %al, -0x4c(%rbp)
movb -0x4c(%rbp), %al
testb $0x1, %al
jne 0x1cab2
jmp 0x1cab4
jmp 0x1cad3
leaq 0x42bec(%rip), %rdi     # 0x5f6a7
leaq 0x41452(%rip), %rsi     # 0x5df14
movl $0x2b0, %edx            # imm = 0x2B0
leaq 0x42b78(%rip), %rcx     # 0x5f646
callq 0xd1c0
xorl %eax, %eax
cmpl $0x1, -0x10(%rbp)
movb %al, -0x4d(%rbp)
jbe 0x1cae8
cmpl $-0x2, -0x10(%rbp)
setbe %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x4e(%rbp)
jne 0x1caf7
jmp 0x1cb08
movl -0x10(%rbp), %eax
shrl %eax
subl $0x1, %eax
cmpl -0x18(%rbp), %eax
setbe %al
movb %al, -0x4e(%rbp)
movb -0x4e(%rbp), %al
testb $0x1, %al
jne 0x1cb11
jmp 0x1cb13
jmp 0x1cb32
leaq 0x42c06(%rip), %rdi     # 0x5f720
leaq 0x413f3(%rip), %rsi     # 0x5df14
movl $0x2b2, %edx            # imm = 0x2B2
leaq 0x42b19(%rip), %rcx     # 0x5f646
callq 0xd1c0
xorl %eax, %eax
cmpl $0x1, -0x10(%rbp)
movb %al, -0x4f(%rbp)
jbe 0x1cb47
cmpl $-0x2, -0x10(%rbp)
setbe %al
movb %al, -0x4f(%rbp)
movb -0x4f(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x50(%rbp)
jne 0x1cb56
jmp 0x1cb88
movq -0x48(%rbp), %rax
movl -0x10(%rbp), %ecx
orl $0x1, %ecx
movl %ecx, -0x54(%rbp)
movq 0xb8(%rax), %rdi
callq 0x10310
movq %rax, %rcx
movl -0x54(%rbp), %eax
movl -0x10(%rbp), %edx
shrl %edx
subl $0x1, %edx
movl %edx, %edx
cmpl (%rcx,%rdx,4), %eax
sete %al
movb %al, -0x50(%rbp)
movb -0x50(%rbp), %al
testb $0x1, %al
jne 0x1cb91
jmp 0x1cb93
jmp 0x1cbb2
leaq 0x42c09(%rip), %rdi     # 0x5f7a3
leaq 0x41373(%rip), %rsi     # 0x5df14
movl $0x2b7, %edx            # imm = 0x2B7
leaq 0x42a99(%rip), %rcx     # 0x5f646
callq 0xd1c0
movl -0x18(%rbp), %eax
movl -0x1c(%rbp), %ecx
shrl %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x1cc78
xorl %eax, %eax
cmpl $0x1, -0x10(%rbp)
movb %al, -0x55(%rbp)
jbe 0x1cbda
cmpl $-0x2, -0x10(%rbp)
setbe %al
movb %al, -0x55(%rbp)
movb -0x55(%rbp), %al
testb $0x1, %al
jne 0x1cbe3
jmp 0x1cc1e
movl -0x10(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jbe 0x1cc1e
movq -0x48(%rbp), %rdi
movl -0x10(%rbp), %esi
orl $0x1, %esi
movl -0x1c(%rbp), %edx
movl -0x10(%rbp), %r8d
xorl $-0x1, %r8d
andl $0x1, %r8d
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %r8d
cmovnel %ecx, %eax
xorl %eax, %edx
callq 0x1c920
movl %eax, -0x14(%rbp)
jmp 0x1cc76
movq -0x48(%rbp), %rdi
movl -0x1c(%rbp), %esi
orl $0x1, %esi
movl -0x10(%rbp), %edx
movl -0x1c(%rbp), %r8d
xorl $-0x1, %r8d
andl $0x1, %r8d
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %r8d
cmovnel %ecx, %eax
xorl %eax, %edx
callq 0x1c920
movl %eax, -0x14(%rbp)
cmpl $0x4, -0x14(%rbp)
je 0x1cc74
movq -0x48(%rbp), %rax
movl -0x10(%rbp), %ecx
movl %ecx, -0x5c(%rbp)
movq 0xb8(%rax), %rdi
callq 0x10310
movl -0x5c(%rbp), %edx
movl -0x18(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
jmp 0x1cc76
jmp 0x1ccea
movq -0x48(%rbp), %rax
movl -0x10(%rbp), %ecx
movl %ecx, -0x60(%rbp)
movq 0xb8(%rax), %rdi
callq 0x10310
movl -0x60(%rbp), %esi
movq -0x48(%rbp), %rdx
movl -0x18(%rbp), %ecx
movl %esi, (%rax,%rcx,4)
movq %rdx, %rsi
addq $0x30, %rsi
leaq -0x38(%rbp), %rdi
callq 0x1e670
movl -0x18(%rbp), %esi
leaq -0x38(%rbp), %rdi
callq 0x1e6b0
movl %eax, -0x3c(%rbp)
cmpl $-0x1, -0x3c(%rbp)
je 0x1cce8
movq -0x48(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0x1ada0
cmpl $0x4, %eax
jne 0x1ccda
movl $0x4, -0x14(%rbp)
jmp 0x1cce8
leaq -0x38(%rbp), %rdi
callq 0x1e7b0
movl %eax, -0x3c(%rbp)
jmp 0x1ccba
jmp 0x1ccea
jmp 0x1cd17
movl -0x1c(%rbp), %eax
cmpl -0x10(%rbp), %eax
jne 0x1ccf6
jmp 0x1cd15
leaq 0x42b3e(%rip), %rdi     # 0x5f83b
leaq 0x41210(%rip), %rsi     # 0x5df14
movl $0x2e3, %edx            # imm = 0x2E3
leaq 0x42936(%rip), %rcx     # 0x5f646
callq 0xd1c0
jmp 0x1cd17
leaq 0x66672(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x1cd3e
leaq 0x66660(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movq (%rdi), %rax
callq *0x28(%rax)
leaq 0x6664b(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x1cd65
leaq 0x66639(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movq (%rdi), %rax
callq *0x28(%rax)
movl -0x14(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nop