// File: vsklad[P]cgen/./bal/cnf/processor/cnfoptimizer.cpp
// Function: bal::CnfOptimizer::normalize_cu(unsigned int const*, unsigned int*) const
inline processor_result_t CnfOptimizer::normalize_cu(const uint32_t* const p_src, uint32_t* const p_dst) const {
        processor_result_t result = erUndetermined;
        
        const literalid_t* literals = _clause_literals(p_src);
        const clause_size_t clause_size = _clause_size(p_src);
        const literalid_t* const var_values = variables_.data();
            
        // an unaggregated clause indeed
        _assert_level_1(!_clause_size_is_aggregated(clause_size));
        
        literalid_t* new_literals = _clause_literals(p_dst);
        clause_size_t new_clause_size = 0;
        
        for (auto i = 0; i < clause_size; i++) {
            const literalid_t original_value = literals[i]; // because p_src may == p_dst
            const literalid_t new_value = literal_t::resolve(var_values, original_value);
            // count resolved literal if not a constant
            if (literal_t__is_variable(new_value)) {
                if (new_value != original_value) {
                    __TRACE_ASSIGN_LITERAL;
                    if (result == erUndetermined || result == erChangedC) {
                        result = erChangedV;
                    };
                };
                // insert into the sorted sequence
                auto j = new_clause_size;
                while (j > 0) {
                    if (new_value >= new_literals[j - 1]) {
                        new_literals[j] = new_value;
                        break;
                    } else {
                        new_literals[j] = new_literals[j - 1];
                        j--;
                    };
                };
                if (j == 0) {
                    new_literals[0] = new_value;
                    new_clause_size++;
                } else if (new_value == new_literals[j - 1]) {
                    // check duplicate; should be rare
                    for (auto k = j; k < new_clause_size; k++) {
                        new_literals[k] = new_literals[k + 1];
                    };
                } else {
                    // check presence of a variable together with its negation
                    if (literal_t__is_same_variable(new_value, new_literals[j - 1])) {
                        result = erSatisfied;
                        break;
                    };
                    new_clause_size++;
                };
                // check presence of a variable together with its negation
                if (j < new_clause_size - 1 && literal_t__is_same_variable(new_value, new_literals[j + 1])) {
                    result = erSatisfied;
                    break;
                };
            } else if (literal_t__is_constant_1(new_value)) {
                result = erSatisfied;
                break;
            } else {
                // a literal is 0; the clause is shortened
                __TRACE_ASSIGN_LITERAL;
                if (result == erUndetermined) {
                    result = erChangedC;
                };
            };
        };
        
        if (result != erSatisfied) {
            if (_clause_size_is_aggregated(new_clause_size)) {
                // the clause has become aggregated; unnegate literals and build flags
                uint16_t flags = 0x1;
                for (auto i = 0; i < new_clause_size; i++) {
                    if (literal_t__is_negation(new_literals[i])) {
                        literal_t__unnegate(new_literals[i]);
                    } else {
                        flags <<= (0x1 << i);
                    };
                };
                _clause_header_set(p_dst, flags, new_clause_size);
            } else {
                _clause_header_set(p_dst, 0, new_clause_size);
            }
        } else {
            _clause_header_set(p_dst, 0, 0);
        };
    
        return result;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movl $0x0, -0x1c(%rbp)
movq -0x10(%rbp), %rcx
addq $0x4, %rcx
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rcx
movl (%rcx), %ecx
andl $0x7fff, %ecx           # imm = 0x7FFF
movw %cx, -0x2a(%rbp)
movq 0xb8(%rax), %rdi
callq 0x10310
movq %rax, -0x38(%rbp)
movzwl -0x2a(%rbp), %eax
cmpl $0x4, %eax
setle %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1845d
jmp 0x1845f
jmp 0x1847e
leaq 0x461a4(%rip), %rdi     # 0x5e60a
leaq 0x45aa7(%rip), %rsi     # 0x5df14
movl $0x12a, %edx            # imm = 0x12A
leaq 0x461a5(%rip), %rcx     # 0x5e61e
callq 0xd1c0
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x40(%rbp)
movw $0x0, -0x42(%rbp)
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
movzwl -0x2a(%rbp), %ecx
cmpl %ecx, %eax
jge 0x18732
movq -0x28(%rbp), %rax
movslq -0x48(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x4c(%rbp)
movq -0x38(%rbp), %rdi
movl -0x4c(%rbp), %esi
callq 0x12cc0
movl %eax, -0x50(%rbp)
xorl %eax, %eax
cmpl $0x1, -0x50(%rbp)
movb %al, -0x5d(%rbp)
jbe 0x184d8
cmpl $-0x2, -0x50(%rbp)
setbe %al
movb %al, -0x5d(%rbp)
movb -0x5d(%rbp), %al
testb $0x1, %al
jne 0x184e4
jmp 0x186a5
movl -0x50(%rbp), %eax
cmpl -0x4c(%rbp), %eax
je 0x1855e
leaq 0x6ae9d(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x18549
movl -0x4c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1852c
leaq 0x6ae80(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movl -0x4c(%rbp), %esi
xorl $0x1, %esi
movl -0x50(%rbp), %edx
xorl $0x1, %edx
movq (%rdi), %rax
callq *0x48(%rax)
jmp 0x18547
leaq 0x6ae5d(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movl -0x4c(%rbp), %esi
movl -0x50(%rbp), %edx
movq (%rdi), %rax
callq *0x48(%rax)
jmp 0x18549
cmpl $0x0, -0x1c(%rbp)
je 0x18555
cmpl $0x1, -0x1c(%rbp)
jne 0x1855c
movl $0x2, -0x1c(%rbp)
jmp 0x1855e
movw -0x42(%rbp), %ax
movw %ax, -0x52(%rbp)
movzwl -0x52(%rbp), %eax
cmpl $0x0, %eax
jle 0x185bf
movl -0x50(%rbp), %eax
movq -0x40(%rbp), %rcx
movzwl -0x52(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
cmpl (%rcx,%rdx,4), %eax
jb 0x18595
movl -0x50(%rbp), %edx
movq -0x40(%rbp), %rax
movzwl -0x52(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
jmp 0x185bf
movq -0x40(%rbp), %rax
movzwl -0x52(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x40(%rbp), %rax
movzwl -0x52(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movw -0x52(%rbp), %ax
addw $-0x1, %ax
movw %ax, -0x52(%rbp)
jmp 0x18566
movzwl -0x52(%rbp), %eax
cmpl $0x0, %eax
jne 0x185e2
movl -0x50(%rbp), %ecx
movq -0x40(%rbp), %rax
movl %ecx, (%rax)
movw -0x42(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x42(%rbp)
jmp 0x1866d
movl -0x50(%rbp), %eax
movq -0x40(%rbp), %rcx
movzwl -0x52(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
cmpl (%rcx,%rdx,4), %eax
jne 0x18638
movw -0x52(%rbp), %ax
movw %ax, -0x54(%rbp)
movzwl -0x54(%rbp), %eax
movzwl -0x42(%rbp), %ecx
cmpl %ecx, %eax
jge 0x18636
movq -0x40(%rbp), %rax
movzwl -0x54(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x40(%rbp), %rax
movzwl -0x54(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movw -0x54(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x54(%rbp)
jmp 0x18600
jmp 0x1866b
movl -0x50(%rbp), %eax
movq -0x40(%rbp), %rcx
movzwl -0x52(%rbp), %edx
subl $0x1, %edx
movslq %edx, %rdx
xorl (%rcx,%rdx,4), %eax
shrl %eax
cmpl $0x0, %eax
jne 0x1865f
movl $0x3, -0x1c(%rbp)
jmp 0x18732
movw -0x42(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x42(%rbp)
jmp 0x1866d
movzwl -0x52(%rbp), %eax
movzwl -0x42(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x186a3
movl -0x50(%rbp), %eax
movq -0x40(%rbp), %rcx
movzwl -0x52(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
xorl (%rcx,%rdx,4), %eax
shrl %eax
cmpl $0x0, %eax
jne 0x186a3
movl $0x3, -0x1c(%rbp)
jmp 0x18732
jmp 0x18722
cmpl $0x1, -0x50(%rbp)
jne 0x186b4
movl $0x3, -0x1c(%rbp)
jmp 0x18732
leaq 0x6acd5(%rip), %rdi     # 0x83390
callq 0x16210
cmpq $0x0, %rax
je 0x18711
movl -0x4c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x186f4
leaq 0x6acb8(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movl -0x4c(%rbp), %esi
xorl $0x1, %esi
movl -0x50(%rbp), %edx
xorl $0x1, %edx
movq (%rdi), %rax
callq *0x48(%rax)
jmp 0x1870f
leaq 0x6ac95(%rip), %rdi     # 0x83390
callq 0x178d0
movq %rax, %rdi
movl -0x4c(%rbp), %esi
movl -0x50(%rbp), %edx
movq (%rdi), %rax
callq *0x48(%rax)
jmp 0x18711
cmpl $0x0, -0x1c(%rbp)
jne 0x1871e
movl $0x1, -0x1c(%rbp)
jmp 0x18720
jmp 0x18722
jmp 0x18724
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x18497
cmpl $0x3, -0x1c(%rbp)
je 0x187ca
movzwl -0x42(%rbp), %eax
cmpl $0x4, %eax
jg 0x187bb
movw $0x1, -0x56(%rbp)
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movzwl -0x42(%rbp), %ecx
cmpl %ecx, %eax
jge 0x187a6
movq -0x40(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x18783
movq -0x40(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl (%rax,%rcx,4), %edx
orl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0x18799
movl -0x5c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movzwl -0x56(%rbp), %eax
shll %cl, %eax
movw %ax, -0x56(%rbp)
jmp 0x1879b
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x18752
movzwl -0x56(%rbp), %ecx
shll $0x10, %ecx
movzwl -0x42(%rbp), %eax
orl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
jmp 0x187c8
movzwl -0x42(%rbp), %ecx
orl $0x0, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
jmp 0x187d4
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
movl -0x1c(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)