// File: vsklad[P]cgen/./bal/anf/anf.cpp
// Function: bal::Anf::append_equation_term(unsigned int const*, unsigned long)
void Anf::append_equation_term(const literalid_t* const symbols, const std::size_t symbols_size) {
        is_incomplete_last_equation_();
        const size_t equation_terms_size = terms_size_(equations_.size() - 1);
        
        // while 1, the term is valid even if becomes 1
        literalid_t constant = literal_t__constant(1);
        
        // validate the term itself
        // build sorted array of unique variable numbers
        // the rest is optimized out
        literalid_t validated_symbols[symbols_size];
        std::size_t validated_symbols_size = 0;
        std::size_t first_negation_index = symbols_size;
        
        for (auto i = 0; i < symbols_size && literal_t__is_constant_1(constant); i++) {
            if (literal_t__is_constant_0(symbols[i])) {
                constant = literal_t__constant(0);
                validated_symbols_size = 0;
                break;
            } else if (literal_t__is_constant_1(symbols[i])) {
                continue;
            } else {
                // adjust number of variables if necessary
                if (VariableGenerator::next() <= literal_t__variable_id(symbols[i])) {
                    VariableGenerator::reset(literal_t__variable_id(symbols[i]) + 1);
                };
                
                unsigned int j = 0;
                while (j < validated_symbols_size) {
                    if (literal_t__is_negation_of(symbols[i], validated_symbols[j])) {
                        // x & ~x == 0
                        constant = literal_t__constant(0);
                        validated_symbols_size = 0;
                        break;
                    } else if (symbols[i] == validated_symbols[j]) {
                        // x & x == x
                        break;
                    } else if (symbols[i] > validated_symbols[j]) {
                        // found the sorted insertion point
                        break;
                    };
                    j++;
                };
                if (j == validated_symbols_size || symbols[i] > validated_symbols[j]) {
                    if (j < validated_symbols_size) {
                        j++;
                        for (auto k = j; k < validated_symbols_size; k++) {
                            validated_symbols[k + 1] = validated_symbols[k];
                        };
                    };
                    validated_symbols[j] = symbols[i];
                    validated_symbols_size++;
                    
                    if (literal_t__is_negation(validated_symbols[j]) && first_negation_index > j) {
                        first_negation_index = j;
                    };
                };
            };
        };
        
        if (literal_t__is_constant_1(constant)) {
            if (validated_symbols_size > 0) {
                // handle negations
                // the first negation should be processed recursively replacing the negated variable with 1
                // then the second time unnegated
                if (first_negation_index < validated_symbols_size) {
                    literalid_t first_negated_literal = validated_symbols[first_negation_index];
                    validated_symbols[first_negation_index] = literal_t__constant(1);
                    append_equation_term(validated_symbols, validated_symbols_size); // recursive call
                    validated_symbols[first_negation_index] = literal_t__unnegated(first_negated_literal);
                    append_equation_term(validated_symbols, validated_symbols_size); // recursive call
                } else {
                    // now there is a sorted list of unique unnegated literals
                    // go through existing terms and check if there is a matching one
                    size_t term_index = terms_.size();
                    if (equation_terms_size > 1) {
                        const auto first_term_index = equations_[equations_.size() - 1] + 1; // skip the constant
                        for (auto i = first_term_index; i < first_term_index + equation_terms_size - 1; i++) {
                            const auto term_symbols_size = symbols_size_(i);
                            if (term_symbols_size == validated_symbols_size) {
                                term_index = i;
                                const auto first_symbol_index = terms_[i];
                                for (auto j = 0; j < validated_symbols_size; j++) {
                                    if (symbols_[first_symbol_index + j] != validated_symbols[j]) {
                                        term_index = terms_.size();
                                        break;
                                    };
                                };
                                if (term_index < terms_.size()) {
                                    break;
                                };
                            };
                        };
                    };
                    
                    if (term_index < terms_.size()) {
                        // term == terms_[term_index], i.e. <term> + <term>, remove the term_[term_index]
                        last_equation_remove_term_(term_index);
                    } else {
                        // append the new term
                        assert(symbols_.size() < UINT32_MAX);
                        terms_.push_back((uint32_t)symbols_.size());
                        for (auto i = 0; i < validated_symbols_size; i++) {
                            symbols_.push_back(validated_symbols[i]);
                        };
                    };
                };
            } else {
                // the term is the constant 1
                // find the first term of size 1 and attach to it
                auto term_index = equations_[equations_.size() - 1];
                const auto term_index_end = term_index + equation_terms_size;
                while (term_index < term_index_end && symbols_size_(term_index) > 1) {
                    term_index++;
                };
                _assert_level_1(term_index < term_index_end);
                literal_t__negate(symbols_[terms_[term_index]]);
            };
        };
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xa0(%rbp)
callq 0xfab0
movq -0xa0(%rbp), %rdi
addq $0xa8, %rdi
callq 0xf9f0
movq -0xa0(%rbp), %rdi
movq %rax, %rsi
decq %rsi
callq 0xfc30
movq %rax, -0x20(%rbp)
movl $0x1, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq %rsp, %rcx
movq %rcx, -0x30(%rbp)
leaq 0xf(,%rax,4), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x98(%rbp)
movq %rcx, %rsp
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movslq -0x4c(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0xa1(%rbp)
jae 0xdfe8
cmpl $0x1, -0x24(%rbp)
sete %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0xdff7
jmp 0xe1b8
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jne 0xe019
movl $0x0, -0x24(%rbp)
movq $0x0, -0x40(%rbp)
jmp 0xe1b8
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
cmpl $0x1, (%rax,%rcx,4)
jne 0xe02c
jmp 0xe1aa
movq -0xa0(%rbp), %rdi
callq 0xfcd0
movq -0x10(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
shrl %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
ja 0xe06b
movq -0xa0(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %esi
shrl %esi
subl $0x1, %esi
addl $0x1, %esi
callq 0xfcf0
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0x40(%rbp), %rax
jae 0xe0f0
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl -0x50(%rbp), %edx
xorl (%rcx,%rdx,4), %eax
cmpl $0x1, %eax
jne 0xe0a9
movl $0x0, -0x24(%rbp)
movq $0x0, -0x40(%rbp)
jmp 0xe0f0
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl -0x50(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jne 0xe0c5
jmp 0xe0f0
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl -0x50(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jbe 0xe0e1
jmp 0xe0f0
jmp 0xe0e3
jmp 0xe0e5
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0xe072
movl -0x50(%rbp), %eax
cmpq -0x40(%rbp), %rax
je 0xe117
movq -0x98(%rbp), %rcx
movq -0x10(%rbp), %rax
movslq -0x4c(%rbp), %rdx
movl (%rax,%rdx,4), %eax
movl -0x50(%rbp), %edx
cmpl (%rcx,%rdx,4), %eax
jbe 0xe1a4
movl -0x50(%rbp), %eax
cmpq -0x40(%rbp), %rax
jae 0xe15d
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %eax
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpq -0x40(%rbp), %rax
jae 0xe15b
movq -0x98(%rbp), %rax
movl -0x54(%rbp), %ecx
movl (%rax,%rcx,4), %edx
movl -0x54(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, %ecx
movl %edx, (%rax,%rcx,4)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0xe12f
jmp 0xe15d
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq -0x4c(%rbp), %rdx
movl (%rcx,%rdx,4), %edx
movl -0x50(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movq -0x40(%rbp), %rcx
addq $0x1, %rcx
movq %rcx, -0x40(%rbp)
movl -0x50(%rbp), %ecx
movl (%rax,%rcx,4), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0xe1a2
movq -0x48(%rbp), %rax
movl -0x50(%rbp), %ecx
cmpq %rcx, %rax
jbe 0xe1a2
movl -0x50(%rbp), %eax
movq %rax, -0x48(%rbp)
jmp 0xe1a4
jmp 0xe1a6
jmp 0xe1a8
jmp 0xe1aa
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0xdfc9
cmpl $0x1, -0x24(%rbp)
jne 0xe5ea
cmpq $0x0, -0x40(%rbp)
jbe 0xe48d
movq -0x48(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0xe22c
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdi
movq -0x48(%rbp), %rax
movl (%rsi,%rax,4), %eax
movl %eax, -0x58(%rbp)
movq -0x48(%rbp), %rax
movl $0x1, (%rsi,%rax,4)
movq -0x40(%rbp), %rdx
callq 0xdf30
movq -0xa0(%rbp), %rdi
movq -0x98(%rbp), %rsi
movl -0x58(%rbp), %ecx
orl $0x1, %ecx
movq -0x48(%rbp), %rax
movl %ecx, (%rsi,%rax,4)
movq -0x40(%rbp), %rdx
callq 0xdf30
jmp 0xe488
movq -0xa0(%rbp), %rdi
addq $0x90, %rdi
callq 0xf9f0
movq %rax, -0x60(%rbp)
cmpq $0x1, -0x20(%rbp)
jbe 0xe396
movq -0xa0(%rbp), %rdi
movq %rdi, %rax
addq $0xa8, %rax
movq %rax, -0xb0(%rbp)
addq $0xa8, %rdi
callq 0xf9f0
movq -0xb0(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0xfd50
movl (%rax), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl -0x64(%rbp), %ecx
addq -0x20(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0xe394
movq -0xa0(%rbp), %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0xfd70
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x40(%rbp), %rax
jne 0xe384
movq -0xa0(%rbp), %rdi
movl -0x68(%rbp), %eax
movq %rax, -0x60(%rbp)
addq $0x90, %rdi
movl -0x68(%rbp), %eax
movl %eax, %esi
callq 0xfd50
movl (%rax), %eax
movl %eax, -0x74(%rbp)
movl $0x0, -0x78(%rbp)
movslq -0x78(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0xe353
movq -0xa0(%rbp), %rdi
addq $0x78, %rdi
movl -0x74(%rbp), %eax
addl -0x78(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
callq 0xfd50
movq -0x98(%rbp), %rcx
movl (%rax), %eax
movslq -0x78(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
je 0xe346
movq -0xa0(%rbp), %rdi
addq $0x90, %rdi
callq 0xf9f0
movq %rax, -0x60(%rbp)
jmp 0xe353
jmp 0xe348
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0xe2f7
movq -0xa0(%rbp), %rdi
movq -0x60(%rbp), %rax
movq %rax, -0xb8(%rbp)
addq $0x90, %rdi
callq 0xf9f0
movq %rax, %rcx
movq -0xb8(%rbp), %rax
cmpq %rcx, %rax
jae 0xe382
jmp 0xe394
jmp 0xe384
jmp 0xe386
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0xe292
jmp 0xe396
movq -0xa0(%rbp), %rdi
movq -0x60(%rbp), %rax
movq %rax, -0xc0(%rbp)
addq $0x90, %rdi
callq 0xf9f0
movq %rax, %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
jae 0xe3d8
movq -0xa0(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0xfe10
jmp 0xe486
movq -0xa0(%rbp), %rdi
addq $0x78, %rdi
callq 0xf9f0
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jae 0xe3f4
jmp 0xe413
leaq 0x4cc57(%rip), %rdi     # 0x5b052
leaq 0x4cc1d(%rip), %rsi     # 0x5b01f
movl $0x9f, %edx
leaq 0x4cc61(%rip), %rcx     # 0x5b06f
callq 0xd1c0
movq -0xa0(%rbp), %rdi
movq %rdi, %rax
addq $0x90, %rax
movq %rax, -0xc8(%rbp)
addq $0x78, %rdi
callq 0xf9f0
movq -0xc8(%rbp), %rdi
movl %eax, -0x7c(%rbp)
leaq -0x7c(%rbp), %rsi
callq 0xfa10
movl $0x0, -0x80(%rbp)
movslq -0x80(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0xe484
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdi
addq $0x78, %rdi
movslq -0x80(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
callq 0xfa40
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0xe44d
jmp 0xe486
jmp 0xe488
jmp 0xe5e8
movq -0xa0(%rbp), %rdi
movq %rdi, %rax
addq $0xa8, %rax
movq %rax, -0xd0(%rbp)
addq $0xa8, %rdi
callq 0xf9f0
movq -0xd0(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0xfd50
movl (%rax), %eax
movl %eax, -0x84(%rbp)
movl -0x84(%rbp), %eax
addq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movl -0x84(%rbp), %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x90(%rbp), %rcx
movb %al, -0xd1(%rbp)
jae 0xe516
movq -0xa0(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, %esi
callq 0xfd70
cmpq $0x1, %rax
seta %al
movb %al, -0xd1(%rbp)
movb -0xd1(%rbp), %al
testb $0x1, %al
jne 0xe522
jmp 0xe533
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0xe4dc
movl -0x84(%rbp), %eax
cmpq -0x90(%rbp), %rax
jae 0xe544
jmp 0xe563
leaq 0x4cb75(%rip), %rdi     # 0x5b0c0
leaq 0x4cacd(%rip), %rsi     # 0x5b01f
movl $0xae, %edx
leaq 0x4cb11(%rip), %rcx     # 0x5b06f
callq 0xd1c0
movq -0xa0(%rbp), %rdi
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xe8(%rbp)
addq $0x90, %rdi
movl -0x84(%rbp), %eax
movl %eax, %esi
callq 0xfd50
movq -0xe8(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movq -0xa0(%rbp), %rdi
movl (%rax), %eax
xorl $0x1, %eax
movl %eax, -0xd8(%rbp)
movq %rdi, %rax
addq $0x78, %rax
movq %rax, -0xe0(%rbp)
addq $0x90, %rdi
movl -0x84(%rbp), %eax
movl %eax, %esi
callq 0xfd50
movq -0xe0(%rbp), %rdi
movl (%rax), %eax
movl %eax, %esi
callq 0xfd50
movl -0xd8(%rbp), %ecx
movl %ecx, (%rax)
jmp 0xe5ea
movq -0x30(%rbp), %rax
movq %rax, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)