// File: /workspace/github_cpp_makefile_star2_O2/pfnet-research[P]pml/src/translate_to_mdp.cpp
// Function: calc_binop_bound(value_info_t const&, value_info_t const&, ast::expr_kind_t)
value_info_t calc_binop_bound(
        value_info_t const& lhs,
        value_info_t const& rhs,
        ast::expr_kind_t op) {
    switch (op) {
    case ast::expr_kind_t::Add:
        return value_info_t {
            format("({}+{})", lhs.name, rhs.name),
            *lhs.bound + *rhs.bound
        };
    case ast::expr_kind_t::Sub:
        return value_info_t {
            format("({}-{})", lhs.name, rhs.name),
            *lhs.bound - *rhs.bound
        };
    case ast::expr_kind_t::Mul:
        return value_info_t {
            format("({}*{})", lhs.name, rhs.name),
            *lhs.bound * *rhs.bound
        };
    case ast::expr_kind_t::Div:
        return value_info_t {
            format("({}/{})", lhs.name, rhs.name),
            *lhs.bound / *rhs.bound
        };
    case ast::expr_kind_t::Eq:
        return value_info_t {
            format("{}={}", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Neq:
        return value_info_t {
            format("({}!={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Leq:
        return value_info_t {
            format("({}<={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Geq:
        return value_info_t {
            format("({}>={})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::And:
        return value_info_t {
            format("({}&{})", lhs.name, rhs.name),
            util::nullopt
        };
    case ast::expr_kind_t::Or:
        return value_info_t {
            format("({}|{})", lhs.name, rhs.name),
            util::nullopt
        };
    default:
        throw std::logic_error{"invalid binop"};
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x30, %rsp
addl $-0x6, %ecx
cmpl $0xa, %ecx
ja 0x317cb
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
leaq 0xb4c6(%rip), %rax      # 0x3ca50
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
leaq 0xb598(%rip), %rsi      # 0x3cb32
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
movl 0x20(%r14), %eax
movl 0x24(%r14), %ecx
addl 0x20(%r15), %eax
addl 0x24(%r15), %ecx
jmp 0x316ff
leaq 0xb5a3(%rip), %rsi      # 0x3cb7b
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
jmp 0x317b0
leaq 0xb56d(%rip), %rsi      # 0x3cb73
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
jmp 0x317b0
leaq 0xb51e(%rip), %rsi      # 0x3cb52
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
jmp 0x317b0
leaq 0xb4d8(%rip), %rsi      # 0x3cb3a
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
movl 0x20(%r15), %eax
movl 0x24(%r15), %ecx
subl 0x24(%r14), %eax
subl 0x20(%r14), %ecx
jmp 0x316ff
leaq 0xb4bb(%rip), %rsi      # 0x3cb58
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
jmp 0x317b0
leaq 0xb477(%rip), %rsi      # 0x3cb42
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
movl 0x20(%r14), %eax
movl 0x24(%r14), %ecx
imull 0x20(%r15), %eax
imull 0x24(%r15), %ecx
shlq $0x20, %rcx
orq %rcx, %rax
movq %rax, 0x20(%rbx)
jmp 0x31781
leaq 0xb457(%rip), %rsi      # 0x3cb6a
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
jmp 0x317b0
leaq 0xb40c(%rip), %rsi      # 0x3cb4a
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
movl 0x24(%r14), %edi
movl 0x20(%r15), %eax
movl 0x24(%r15), %ecx
cltd
idivl %edi
movl %eax, %esi
movl %ecx, %eax
cltd
idivl %edi
shlq $0x20, %rax
orq %rax, %rsi
movq %rsi, 0x20(%rbx)
movb $0x1, 0x28(%rbx)
jmp 0x317b4
leaq 0xb3d3(%rip), %rsi      # 0x3cb61
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0xeb2e
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r14, %rcx
callq 0x31846
movb $0x0, 0x28(%rbx)
leaq 0x10(%rsp), %rdi
callq 0x9130
movq %rbx, %rax
addq $0x30, %rsp
popq %rbx
popq %r14
popq %r15
retq
pushq $0x10
popq %rdi
callq 0x9150
movq %rax, %r14
leaq 0xb3a6(%rip), %rsi      # 0x3cb83
movq %rax, %rdi
callq 0x93c0
movq 0x2a7e4(%rip), %rsi     # 0x5bfd0
movq 0x2a7a5(%rip), %rdx     # 0x5bf98
movq %r14, %rdi
callq 0x94b0
movq %rax, %rbx
movq %r14, %rdi
callq 0x9210
jmp 0x3183e
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
jmp 0x3181a
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x9130
jmp 0x3183e
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
jmp 0x3183b
movq %rax, %rbx
movq %rbx, %rdi
callq 0x94d0