// File: /workspace/github_cpp_makefile_star2_O1/vsklad[P]cgen/commands.cpp
// Function: variable_generate_value(bal::Formula const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CGenVariableInfo const&, bal::VariablesArray const&, bool, bool)
bal::VariablesArray variable_generate_value(const bal::Formula& formula,
                             const std::string name,
                             const CGenVariableInfo& src,
                             const bal::VariablesArray& dst_template,
                             const bool apply_except,
                             const bool reassign_in_formula) {
    bal::VariablesArray dst(dst_template.size() / dst_template.element_size(), dst_template.element_size());
    dst.assign_unassigned();
    
    // ensure that the value is provided/generated/computed
    if (src.data.size() != dst.size()) {
        std::stringstream error_message;
        error_message << "Invalid value for " << name;
        error_message << std::dec << "[" << dst.size() / dst.element_size() << "][" << dst.element_size() << "]";
        error_message << " due to wrong dimensions ";
        error_message << std::dec << "[" << src.data.size() / src.data.element_size() << "][" << src.data.element_size() << "]";
        throw std::invalid_argument(error_message.str());
    };
    
    _assert_level_0(src.data.size() > 0);
    bal::variables_size_t dst_changes_count = 0;
    
    const bal::literalid_t* p_src = src.data.data();
    const bal::literalid_t* p_tmp = dst_template.data();
    bal::literalid_t* p_dst = dst.data();
    
    if ((src.except_count > 0 || src.except_range_size > 0) && apply_except) {
        // generate list of element indexes to assign
        std::vector<unsigned int> assignable_indexes;

        // assignable are non-constant dst elements with corresponding constants in src
        // except for the exclusion range
        for (auto i = 0; i < src.data.size(); i++) {
            if ((src.except_range_size == 0 ||
                 i < src.except_range_first || i >= src.except_range_first + src.except_range_size)) {
                if ((literal_t__is_constant(p_src[i]) && literal_t__is_variable(p_tmp[i]) && reassign_in_formula) ||
                    (!literal_t__is_unassigned(p_src[i]) && literal_t__is_unassigned(p_tmp[i]))) {
                    assignable_indexes.push_back(i);
                } else if (literal_t__is_constant(p_src[i]) && literal_t__is_variable(p_tmp[i])) {
                    const bal::literalid_t formula_value = formula.get_variable_value(literal_t__variable_id(p_tmp[i]));
                    if (p_src[i] != literal_t__substitute_literal(p_tmp[i], formula_value)) {
                        assignable_indexes.push_back(i);
                    };
                } else if (!literal_t__is_unassigned(p_src[i]) && p_tmp[i] != p_src[i]) {
                    assignable_indexes.push_back(i);
                };
            };
        };
        
        if (src.except_count > 0) {
            if (assignable_indexes.size() > src.except_count) {
                // pick except_count elements randomly and remove them
                std::random_device rd;
                for (auto i = 0; i < src.except_count; i++) {
                    std::uniform_int_distribution<size_t> index_distribution(0, assignable_indexes.size() - i - 1);
                    size_t random_index = index_distribution(rd);
                    assignable_indexes[random_index] = assignable_indexes[assignable_indexes.size() - i - 1];
                };
                assignable_indexes.resize(assignable_indexes.size() - src.except_count);
            } else if (assignable_indexes.size() == src.except_count) {
                assignable_indexes.clear();
            } else {
                throw std::invalid_argument(ERROR_EXCEPT_NO_VARIABLES);
            };
        };
        
        if (assignable_indexes.size() > 0) {
            for (auto index: assignable_indexes) {
                _assert_level_0(literal_t__is_constant(p_src[index]) && !literal_t__is_constant(p_tmp[index]));
                p_dst[index] = p_src[index];
            };
            dst_changes_count = (bal::variables_size_t)assignable_indexes.size();
        };
    } else {
        // no except, simply copy the values, ignore unassigned src
        for (auto i = 0; i < src.data.size(); i++) {
            if ((literal_t__is_constant(p_src[i]) && literal_t__is_variable(p_tmp[i]) && reassign_in_formula) ||
                (!literal_t__is_unassigned(p_src[i]) && literal_t__is_unassigned(p_tmp[i]))) {
                p_dst[i] = p_src[i];
                dst_changes_count++;
            } else if (literal_t__is_constant(p_src[i]) && literal_t__is_variable(p_tmp[i])) {
                const bal::literalid_t formula_value = formula.get_variable_value(literal_t__variable_id(p_tmp[i]));
                if (p_src[i] != literal_t__substitute_literal(p_tmp[i], formula_value)) {
                    p_dst[i] = p_src[i];
                    dst_changes_count++;
                };
            } else if (!literal_t__is_unassigned(p_src[i]) && p_tmp[i] != p_src[i]) {
                p_dst[i] = p_src[i];
                dst_changes_count++;
            };
        };
    };
    
    if (dst_changes_count > 0) {
        std::cout << "Assigned " << std::dec << dst_changes_count << " bit(s) in \"" << name << "\"" << std::endl;
        std::cout << name << " = " << dst << std::endl;
    };
    
    return dst;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x13e8, %rsp           # imm = 0x13E8
movl %r9d, %r13d
movq %r8, %r14
movq %rcx, %r15
movq %rdx, -0x68(%rbp)
movq %rsi, -0x70(%rbp)
movq %rdi, %rbx
movl 0x8(%r8), %eax
movl 0x1c(%r8), %ecx
xorl %edx, %edx
divl %ecx
movl %eax, %esi
movl %ecx, %edx
callq 0xf76c
cmpl $0x0, 0x8(%rbx)
je 0x2096e
movq (%rbx), %rax
xorl %ecx, %ecx
movl $0xffffffff, (%rax,%rcx,4) # imm = 0xFFFFFFFF
incq %rcx
movl 0x8(%rbx), %edx
cmpq %rdx, %rcx
jb 0x2095c
movl 0x20(%r15), %eax
cmpl 0x8(%rbx), %eax
movq %rbx, -0x60(%rbp)
jne 0x20e02
testl %eax, %eax
je 0x20f98
movb 0x10(%rbp), %al
movb %al, -0x58(%rbp)
movq 0x18(%r15), %r12
movq (%r14), %r14
movq (%rbx), %rax
movq %rax, -0x78(%rbp)
movl 0x10(%r15), %eax
orl 0x8(%r15), %eax
setne %al
testb %r13b, %al
je 0x20bbe
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
cmpl $0x0, 0x20(%r15)
je 0x20ae0
xorl %r13d, %r13d
xorb $0x1, -0x58(%rbp)
movl 0x10(%r15), %eax
testl %eax, %eax
je 0x209f2
movl 0xc(%r15), %ecx
cmpq %rcx, %r13
setae %dl
addl %ecx, %eax
cmpq %rax, %r13
setb %al
testb %al, %dl
jne 0x20ad0
movl (%r12,%r13,4), %eax
cmpl $0x2, %eax
setae %cl
orb -0x58(%rbp), %cl
jne 0x20a0c
movl (%r14,%r13,4), %ecx
incl %ecx
cmpl $0x2, %ecx
ja 0x20a5f
cmpl $-0x1, %eax
je 0x20a18
cmpl $-0x1, (%r14,%r13,4)
je 0x20a5f
cmpl $0x1, %eax
ja 0x20a29
movl (%r14,%r13,4), %esi
leal 0x1(%rsi), %ecx
cmpl $0x3, %ecx
jae 0x20a8f
cmpl $-0x1, %eax
je 0x20ad0
cmpl %eax, (%r14,%r13,4)
je 0x20ad0
movl %r13d, -0x1410(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
jne 0x20a70
leaq -0x50(%rbp), %rdi
leaq -0x1410(%rbp), %rdx
callq 0xfb44
jmp 0x20ad0
movl %r13d, -0x1410(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x20a7d
movl %r13d, (%rsi)
addq $0x4, %rsi
movq %rsi, -0x48(%rbp)
jmp 0x20ad0
leaq -0x50(%rbp), %rdi
leaq -0x1410(%rbp), %rdx
callq 0xfb44
jmp 0x20ad0
shrl %esi
decl %esi
movq -0x70(%rbp), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
movl (%r14,%r13,4), %ecx
andl $0x1, %ecx
xorl (%r12,%r13,4), %eax
xorl %ecx, %eax
cmpl $0x1, %eax
je 0x20ad0
movl %r13d, -0x1410(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
jne 0x20a70
leaq -0x50(%rbp), %rdi
leaq -0x1410(%rbp), %rdx
callq 0xfb44
incq %r13
movl 0x20(%r15), %eax
cmpq %rax, %r13
jb 0x209d0
movl 0x8(%r15), %ecx
testq %rcx, %rcx
je 0x20c6c
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rdx
movq %rdx, %rsi
subq %rax, %rsi
sarq $0x2, %rsi
cmpq %rcx, %rsi
jbe 0x20c5d
movq %r12, -0x58(%rbp)
leaq -0x1410(%rbp), %rdi
callq 0x22f6c
movl 0x8(%r15), %eax
testl %eax, %eax
je 0x20b90
xorl %r13d, %r13d
movabsq $-0x100000000, %rbx     # imm = 0xFFFFFFFF00000000
movq -0x48(%rbp), %rax
subq -0x50(%rbp), %rax
sarq $0x2, %rax
movq %rbx, %r12
sarq $0x20, %r12
addq %r12, %rax
movq $0x0, -0x88(%rbp)
movq %rax, -0x80(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0x1410(%rbp), %rsi
movq %rdi, %rdx
callq 0x2dffe
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %rdx
movl (%rdx,%r12,4), %edx
movl %edx, (%rcx,%rax,4)
movl 0x8(%r15), %eax
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
addq %rcx, %rbx
incl %r13d
cmpl %r13d, %eax
ja 0x20b2d
leaq -0x50(%rbp), %rdi
movq 0x8(%rdi), %rsi
subq (%rdi), %rsi
sarq $0x2, %rsi
movl %eax, %eax
subq %rax, %rsi
callq 0x23056
leaq -0x1410(%rbp), %rdi
callq 0xc270
movq -0x58(%rbp), %r12
jmp 0x20c6c
cmpl $0x0, 0x20(%r15)
je 0x20c58
movq %r12, %rbx
xorl %r12d, %r12d
xorb $0x1, -0x58(%rbp)
xorl %r13d, %r13d
movl (%rbx,%r12,4), %ecx
cmpl $0x2, %ecx
setae %al
orb -0x58(%rbp), %al
jne 0x20bf0
movl (%r14,%r12,4), %eax
incl %eax
cmpl $0x2, %eax
ja 0x20c18
cmpl $-0x1, %ecx
je 0x20bfc
cmpl $-0x1, (%r14,%r12,4)
je 0x20c18
cmpl $0x1, %ecx
ja 0x20c0d
movl (%r14,%r12,4), %esi
leal 0x1(%rsi), %eax
cmpl $0x3, %eax
jae 0x20c34
cmpl $-0x1, %ecx
je 0x20c23
cmpl %ecx, (%r14,%r12,4)
je 0x20c23
movq -0x78(%rbp), %rax
movl %ecx, (%rax,%r12,4)
incl %r13d
incq %r12
movl 0x20(%r15), %eax
cmpq %rax, %r12
jb 0x20bd6
jmp 0x20cbd
shrl %esi
decl %esi
movq -0x70(%rbp), %rdi
movq (%rdi), %rax
callq *0x60(%rax)
movl (%rbx,%r12,4), %ecx
movl (%r14,%r12,4), %edx
andl $0x1, %edx
xorl %ecx, %edx
xorl %edx, %eax
cmpl $0x1, %eax
jne 0x20c18
jmp 0x20c23
xorl %r13d, %r13d
jmp 0x20cbd
jne 0x20fb7
cmpq %rax, %rdx
je 0x20c6c
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rax
movq %rax, %r13
subq %rdi, %r13
je 0x20cb0
shrq $0x2, %r13
movq %rdi, %rcx
movq -0x78(%rbp), %r8
movl (%rcx), %edx
movl (%r12,%rdx,4), %esi
cmpl $0x1, %esi
ja 0x20de3
cmpl $0x1, (%r14,%rdx,4)
jbe 0x20de3
movl %esi, (%r8,%rdx,4)
addq $0x4, %rcx
cmpq %rax, %rcx
jne 0x20c87
jmp 0x20cb3
xorl %r13d, %r13d
testq %rdi, %rdi
je 0x20cbd
callq 0xc280
testl %r13d, %r13d
movq -0x68(%rbp), %r15
movq -0x60(%rbp), %rbx
je 0x20dce
movq 0x3e2d3(%rip), %r14     # 0x5efa8
leaq 0x27a84(%rip), %rsi     # 0x48760
movl $0x9, %edx
movq %r14, %rdi
callq 0xc320
movq (%r14), %rax
movq -0x18(%rax), %rax
movl 0x18(%r14,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%r14,%rax)
movl %r13d, %esi
movq %r14, %rdi
callq 0xc190
movq %rax, %r14
leaq 0x27a55(%rip), %rsi     # 0x4876a
movl $0xc, %edx
movq %rax, %rdi
callq 0xc320
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r14, %rdi
callq 0xc320
movq %rax, %r14
leaq 0x2bd9f(%rip), %rsi     # 0x4cada
movl $0x1, %edx
movq %rax, %rdi
callq 0xc320
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0xc2a0
movsbl %al, %esi
movq %r14, %rdi
callq 0xc030
movq %rax, %rdi
callq 0xc1a0
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq 0x3e22b(%rip), %rdi     # 0x5efa8
callq 0xc320
movq %rax, %r14
leaq 0x2100a(%rip), %rsi     # 0x41d96
movl $0x3, %edx
movq %rax, %rdi
callq 0xc320
movq %r14, %rdi
movq %rbx, %rsi
callq 0x3f449
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0xc2a0
movsbl %al, %esi
movq %r14, %rdi
callq 0xc030
movq %rax, %rdi
callq 0xc1a0
movq %rbx, %rax
addq $0x13e8, %rsp           # imm = 0x13E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x27914(%rip), %rdi     # 0x486fe
leaq 0x276a4(%rip), %rsi     # 0x48495
leaq 0x277dc(%rip), %rcx     # 0x485d4
movl $0x13f, %edx            # imm = 0x13F
callq 0xc180
leaq -0x1410(%rbp), %rdi
callq 0xc1c0
leaq -0x1400(%rbp), %r12
leaq 0x27774(%rip), %rsi     # 0x48590
movl $0x12, %edx
movq %r12, %rdi
callq 0xc320
movq -0x68(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
movq %r12, %rdi
callq 0xc320
movq -0x1400(%rbp), %rax
movq -0x18(%rax), %rax
movl -0x13e8(%rbp,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, -0x13e8(%rbp,%rax)
leaq 0x27742(%rip), %rsi     # 0x485a4
movl $0x1, %edx
movq %r12, %rdi
callq 0xc320
movq -0x60(%rbp), %rcx
movl 0x8(%rcx), %eax
xorl %edx, %edx
divl 0x1c(%rcx)
movq %r12, %rdi
movq %rax, %rsi
callq 0xc190
movq %rax, %r14
leaq 0x27713(%rip), %rsi     # 0x485a3
movl $0x2, %edx
movq %rax, %rdi
callq 0xc320
movq -0x60(%rbp), %rax
movl 0x1c(%rax), %esi
movq %r14, %rdi
callq 0xc190
leaq 0x2420c(%rip), %rsi     # 0x450bf
movl $0x1, %edx
movq %rax, %rdi
callq 0xc320
leaq 0x276df(%rip), %rsi     # 0x485a6
movl $0x19, %edx
movq %r12, %rdi
callq 0xc320
movq -0x1400(%rbp), %rax
movq -0x18(%rax), %rax
movl -0x13e8(%rbp,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, -0x13e8(%rbp,%rax)
leaq 0x276aa(%rip), %rsi     # 0x485a4
movl $0x1, %edx
movq %r12, %rdi
callq 0xc320
movl 0x20(%r15), %eax
xorl %edx, %edx
divl 0x34(%r15)
movq %r12, %rdi
movq %rax, %rsi
callq 0xc190
movq %rax, %r14
leaq 0x2767d(%rip), %rsi     # 0x485a3
movl $0x2, %edx
movq %rax, %rdi
callq 0xc320
movl 0x34(%r15), %esi
movq %r14, %rdi
callq 0xc190
leaq 0x24179(%rip), %rsi     # 0x450bf
movl $0x1, %edx
movq %rax, %rdi
callq 0xc320
movl $0x10, %edi
callq 0xc130
movq %rax, %r15
leaq -0x13f8(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xc430
movb $0x1, %bl
leaq -0x50(%rbp), %rsi
movq %r15, %rdi
callq 0xc4d0
xorl %ebx, %ebx
movq 0x3e049(%rip), %rsi     # 0x5efd0
movq 0x3e02a(%rip), %rdx     # 0x5efb8
movq %r15, %rdi
callq 0xc4b0
jmp 0x20fe9
leaq 0x27621(%rip), %rdi     # 0x485c0
leaq 0x274ef(%rip), %rsi     # 0x48495
leaq 0x27627(%rip), %rcx     # 0x485d4
movl $0x10e, %edx            # imm = 0x10E
callq 0xc180
movl $0x10, %edi
callq 0xc130
movq %rax, %r15
leaq 0x276ad(%rip), %rsi     # 0x48678
movq %rax, %rdi
callq 0xc520
movq 0x3dff6(%rip), %rsi     # 0x5efd0
movq 0x3dfd7(%rip), %rdx     # 0x5efb8
movq %r15, %rdi
callq 0xc4b0
movq %rax, %r14
leaq -0x40(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x21005
callq 0xc280
jmp 0x21005
movq %rax, %r14
movb $0x1, %bl
testb %bl, %bl
je 0x2102f
movq %r15, %rdi
callq 0xc1e0
jmp 0x2102f
jmp 0x21056
movq %rax, %r14
movq %r15, %rdi
callq 0xc1e0
jmp 0x2106a
jmp 0x21056
jmp 0x2107a
jmp 0x2105b
jmp 0x21056
jmp 0x21056
movq %rax, %r14
movq 0x3df42(%rip), %rsi     # 0x5ef78
leaq -0x1410(%rbp), %rdi
callq 0xc1f0
leaq -0x1390(%rbp), %rdi
callq 0xc0d0
jmp 0x21085
jmp 0x21082
jmp 0x21056
jmp 0x21082
movq %rax, %r14
jmp 0x2106a
movq %rax, %r14
leaq -0x1410(%rbp), %rdi
callq 0xc270
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x21085
callq 0xc280
jmp 0x21085
movq %rax, %rdi
callq 0x1f0db
movq %rax, %r14
movq -0x60(%rbp), %rdi
callq 0x2912e
movq %r14, %rdi
callq 0xc4e0