// File: vsklad[P]cgen/./bal/anf/anf.cpp
// Function: bal::Anf::complete_equation(unsigned int, bool)
literalid_t Anf::complete_equation(const literalid_t r, const bool optimize_negation) {
        is_incomplete_last_equation_();
        
        const size_t equation_terms_size = terms_size_(equations_.size() - 1);
        const size_t const_term_index = equations_[equations_.size() - 1];
        
        literalid_t result = symbols_[terms_[const_term_index]];
        _assert_level_1(literal_t__is_constant(result));
        
        if (equation_terms_size == 1) {
            _assert_level_1(literal_t__is_unassigned(r));
            remove_last_equation_();
        } else if (optimize_negation && equation_terms_size == 2 && symbols_size_(const_term_index + 1) == 1) {
            // one term one one variable
            // negated because 1 means + 1 which means "1 negated"
            _assert_level_1(literal_t__is_unassigned(r));
            result = literal_t__substitute_literal(literal_t__negated(result), symbols_[terms_[const_term_index + 1]]);
            remove_last_equation_();
        } else if (literal_t__is_constant(r) && equation_terms_size == 2 && symbols_size_(const_term_index + 1) == 1) {
            // one term one one variable
            // unit clause
            _assert_level_1(!optimize_negation);
            _assert_level_1(literal_t__is_variable(symbols_[terms_[const_term_index + 1]]));
            result = symbols_[terms_[const_term_index + 1]];
            result = literal_t__substitute_literal(literal_t__negated(r), result);
            result = literal_t__substitute_literal(literal_t__negated(symbols_[terms_[const_term_index]]), result);
            last_equation_remove_term_(const_term_index + 1);
            symbols_[terms_[const_term_index]] = result;
            // variable value, negation because the equation (result == 0)
            result = literal_t__is_negation(result) ? 0b1 : 0b0;
        } else {
            // multiple terms
            literalid_t last_literal;
            if (literal_t__is_variable(r) || literal_t__is_constant(r)) {
                _assert_level_1(!optimize_negation);
                last_literal = r;
                if (literal_t__is_constant(last_literal)) {
                    // try to find a single variable term and merge with it
                    for (auto i = const_term_index + 1; i < const_term_index + equation_terms_size - 1; i++) {
                        if (symbols_size_(i) == 1) {
                            _assert_level_1(literal_t__is_variable(symbols_[terms_[i]]));
                            last_literal = literal_t__substitute_literal(literal_t__negated(r), symbols_[terms_[i]]);
                            last_equation_remove_term_(i);
                            break;
                        };
                    };
                };
            } else {
                _assert_level_1(literal_t__is_unassigned(r));
                last_literal = VariableGenerator::new_variable_literal();
            };
            
            // 1 + x = ~x, therefore apply negated sign to the last_literal
            result = literal_t__substitute_literal(literal_t__negated(result), last_literal);
            
            if (optimize_negation) {
                // negation is within the result, the equation should include the same unnegated
                symbols_[terms_[const_term_index]] = last_literal;
            } else {
                symbols_[terms_[const_term_index]] = result;
                result = last_literal;
            };
        };
        
        return result;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
andb $0x1, %al
movb %al, -0xd(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x40(%rbp)
callq 0xfab0
movq -0x40(%rbp), %rdi
addq $0xa8, %rdi
callq 0xf9f0
movq -0x40(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0xfc30
movq -0x40(%rbp), %rdi
movq %rax, -0x18(%rbp)
movq %rdi, %rax
addq $0xa8, %rax
movq %rax, -0x48(%rbp)
addq $0xa8, %rdi
callq 0xf9f0
movq -0x48(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0xfd50
movq -0x40(%rbp), %rdi
movl (%rax), %eax
movq %rax, -0x20(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x38(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
callq 0xfd50
movq -0x38(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movl (%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $0x1, -0x24(%rbp)
ja 0xe726
jmp 0xe745
leaq 0x4c9af(%rip), %rdi     # 0x5b0dc
leaq 0x4c8eb(%rip), %rsi     # 0x5b01f
movl $0xc5, %edx
leaq 0x4c9c5(%rip), %rcx     # 0x5b105
callq 0xd1c0
cmpq $0x1, -0x18(%rbp)
jne 0xe781
cmpl $-0x1, -0xc(%rbp)
jne 0xe754
jmp 0xe773
leaq 0x4d2da(%rip), %rdi     # 0x5ba35
leaq 0x4c8bd(%rip), %rsi     # 0x5b01f
movl $0xc8, %edx
leaq 0x4c997(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
callq 0x10090
jmp 0xed06
testb $0x1, -0xd(%rbp)
je 0xe836
cmpq $0x2, -0x18(%rbp)
jne 0xe836
movq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd70
cmpq $0x1, %rax
jne 0xe836
cmpl $-0x1, -0xc(%rbp)
jne 0xe7b9
jmp 0xe7d8
leaq 0x4d275(%rip), %rdi     # 0x5ba35
leaq 0x4c858(%rip), %rsi     # 0x5b01f
movl $0xcd, %edx
leaq 0x4c932(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x50(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd50
movq -0x50(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq -0x40(%rbp), %rdi
movl (%rax), %eax
movl -0x24(%rbp), %esi
xorl $0x1, %esi
xorl $-0x1, %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovnel %edx, %ecx
xorl %ecx, %eax
movl %eax, -0x24(%rbp)
callq 0x10090
jmp 0xed04
cmpl $0x1, -0xc(%rbp)
ja 0xea4c
cmpq $0x2, -0x18(%rbp)
jne 0xea4c
movq -0x40(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd70
cmpq $0x1, %rax
jne 0xea4c
movb -0xd(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xe871
jmp 0xe873
jmp 0xe892
leaq 0x4c8d2(%rip), %rdi     # 0x5b14c
leaq 0x4c79e(%rip), %rsi     # 0x5b01f
movl $0xd3, %edx
leaq 0x4c878(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x60(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd50
movq -0x60(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq %rax, %rcx
xorl %eax, %eax
cmpl $0x1, (%rcx)
movb %al, -0x51(%rbp)
jbe 0xe908
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x68(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd50
movq -0x68(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
cmpl $-0x2, (%rax)
setbe %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0xe911
jmp 0xe913
jmp 0xe932
leaq 0x4c845(%rip), %rdi     # 0x5b15f
leaq 0x4c6fe(%rip), %rsi     # 0x5b01f
movl $0xd4, %edx
leaq 0x4c7d8(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x90(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfd50
movq -0x90(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq -0x40(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl -0xc(%rbp), %esi
xorl $0x1, %esi
xorl $-0x1, %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovnel %edx, %ecx
xorl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x7c(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x88(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
callq 0xfd50
movq -0x88(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq -0x40(%rbp), %rdi
movq %rax, %rcx
movl -0x7c(%rbp), %eax
movl (%rcx), %esi
xorl $0x1, %esi
xorl $-0x1, %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovnel %edx, %ecx
xorl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x20(%rbp), %rsi
addq $0x1, %rsi
callq 0xfe10
movq -0x40(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, -0x6c(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0x78(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
callq 0xfd50
movq -0x78(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movl -0x6c(%rbp), %ecx
movl %ecx, (%rax)
movl -0x24(%rbp), %edx
andl $0x1, %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0xed02
xorl %eax, %eax
cmpl $0x1, -0xc(%rbp)
movb %al, -0x91(%rbp)
jbe 0xea67
cmpl $-0x2, -0xc(%rbp)
setbe %al
movb %al, -0x91(%rbp)
movb -0x91(%rbp), %al
testb $0x1, %al
jne 0xea7b
cmpl $0x1, -0xc(%rbp)
ja 0xec18
movb -0xd(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xea86
jmp 0xea88
jmp 0xeaa7
leaq 0x4c6bd(%rip), %rdi     # 0x5b14c
leaq 0x4c589(%rip), %rsi     # 0x5b01f
movl $0xe0, %edx
leaq 0x4c663(%rip), %rcx     # 0x5b105
callq 0xd1c0
movl -0xc(%rbp), %eax
movl %eax, -0x28(%rbp)
cmpl $0x1, -0x28(%rbp)
ja 0xec16
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
addq -0x18(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0xec14
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0xfd70
cmpq $0x1, %rax
jne 0xec01
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xa0(%rbp)
addq $0x90, %rdi
movq -0x30(%rbp), %rsi
callq 0xfd50
movq -0xa0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq %rax, %rcx
xorl %eax, %eax
cmpl $0x1, (%rcx)
movb %al, -0x92(%rbp)
jbe 0xeb73
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xa8(%rbp)
addq $0x90, %rdi
movq -0x30(%rbp), %rsi
callq 0xfd50
movq -0xa8(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
cmpl $-0x2, (%rax)
setbe %al
movb %al, -0x92(%rbp)
movb -0x92(%rbp), %al
testb $0x1, %al
jne 0xeb7f
jmp 0xeb81
jmp 0xeba0
leaq 0x4c661(%rip), %rdi     # 0x5b1e9
leaq 0x4c490(%rip), %rsi     # 0x5b01f
movl $0xe6, %edx
leaq 0x4c56a(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xb0(%rbp)
addq $0x90, %rdi
movq -0x30(%rbp), %rsi
callq 0xfd50
movq -0xb0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq -0x40(%rbp), %rdi
movl (%rax), %eax
movl -0xc(%rbp), %esi
xorl $0x1, %esi
xorl $-0x1, %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovnel %edx, %ecx
xorl %ecx, %eax
movl %eax, -0x28(%rbp)
movq -0x30(%rbp), %rsi
callq 0xfe10
jmp 0xec14
jmp 0xec03
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xeac3
jmp 0xec16
jmp 0xec4b
cmpl $-0x1, -0xc(%rbp)
jne 0xec20
jmp 0xec3f
leaq 0x4ce0e(%rip), %rdi     # 0x5ba35
leaq 0x4c3f1(%rip), %rsi     # 0x5b01f
movl $0xee, %edx
leaq 0x4c4cb(%rip), %rcx     # 0x5b105
callq 0xd1c0
movq -0x40(%rbp), %rdi
callq 0x10270
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl -0x24(%rbp), %esi
xorl $0x1, %esi
xorl $-0x1, %esi
andl $0x1, %esi
xorl %ecx, %ecx
movl $0x1, %edx
cmpl $0x0, %esi
cmovnel %edx, %ecx
xorl %ecx, %eax
movl %eax, -0x24(%rbp)
testb $0x1, -0xd(%rbp)
je 0xecb7
movq -0x40(%rbp), %rdi
movl -0x28(%rbp), %eax
movl %eax, -0xb4(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xc0(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
callq 0xfd50
movq -0xc0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movl -0xb4(%rbp), %ecx
movl %ecx, (%rax)
jmp 0xed00
movq -0x40(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, -0xc4(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xd0(%rbp)
addq $0x90, %rdi
movq -0x20(%rbp), %rsi
callq 0xfd50
movq -0xd0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movl -0xc4(%rbp), %ecx
movl %ecx, (%rax)
movl -0x28(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0xed02
jmp 0xed04
jmp 0xed06
movl -0x24(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)