// File: /workspace/github_cpp_makefile_star2_O2/pfnet-research[P]pml/src/mdp_expr.cpp
// Function: mdp::operator==(mdp::expr_t const&, mdp::expr_t const&)
bool operator==(expr_t const& lhs, expr_t const& rhs) {
    if (lhs.kind() != rhs.kind())
        return false;
    if (lhs.kind() == expr_kind_t::Int)
        return cast<int_expr_t>(lhs).n == cast<int_expr_t>(rhs).n;
    if (lhs.kind() == expr_kind_t::Real)
        return cast<real_expr_t>(lhs).d == cast<real_expr_t>(rhs).d;
    if (lhs.kind() == expr_kind_t::Bool)
        return cast<bool_expr_t>(lhs).b == cast<bool_expr_t>(rhs).b;
    if (lhs.kind() == expr_kind_t::Var)
        return cast<var_expr_t>(lhs).name == cast<var_expr_t>(rhs).name;
    if (lhs.kind() == expr_kind_t::Neg)
        return *cast<neg_expr_t>(lhs).inner == *cast<neg_expr_t>(rhs).inner;
    if (lhs.kind() == expr_kind_t::BinOp) {
        auto const& lhs_ = cast<binop_expr_t>(lhs);
        auto const& rhs_ = cast<binop_expr_t>(rhs);
        return
            *lhs_.lhs == *rhs_.lhs && *lhs_.rhs == *rhs_.rhs &&
            lhs_.binop_kind == rhs_.binop_kind;
    }
    if (lhs.kind() == expr_kind_t::If) {
        auto const& lhs_ = cast<if_expr_t>(lhs);
        auto const& rhs_ = cast<if_expr_t>(rhs);
        return
            *lhs_.cond == *rhs_.cond &&
            *lhs_.true_branch == *rhs_.true_branch &&
            *lhs_.false_branch == *rhs_.false_branch;
    }
    if (lhs.kind() == expr_kind_t::Min) {
        auto const& lhs_args = cast<min_expr_t>(lhs).elems;
        auto const& rhs_args = cast<min_expr_t>(rhs).elems;
        if (lhs_args.size() != rhs_args.size())
            return false;
        for (size_t i=0; i<lhs_args.size(); ++i) {
            if (*lhs_args[i] != *rhs_args[i])
                return false;
        }
        return true;
    }
    if (lhs.kind() == expr_kind_t::Max) {
        auto const& lhs_args = cast<max_expr_t>(lhs).elems;
        auto const& rhs_args = cast<max_expr_t>(rhs).elems;
        if (lhs_args.size() != rhs_args.size())
            return false;
        for (size_t i=0; i<lhs_args.size(); ++i) {
            if (*lhs_args[i] != *rhs_args[i])
                return false;
        }
        return true;
    }
    if (lhs.kind() == expr_kind_t::Floor)
        return *cast<floor_expr_t>(lhs).inner == *cast<floor_expr_t>(rhs).inner;
    if (lhs.kind() == expr_kind_t::Ceil)
        return *cast<ceil_expr_t>(lhs).inner == *cast<ceil_expr_t>(rhs).inner;
    if (lhs.kind() == expr_kind_t::Pow) {
        return
            *cast<pow_expr_t>(lhs).x == *cast<pow_expr_t>(rhs).x &&
            *cast<pow_expr_t>(lhs).y == *cast<pow_expr_t>(rhs).y;
    }
    if (lhs.kind() == expr_kind_t::Mod) {
        return
            *cast<mod_expr_t>(lhs).i == *cast<mod_expr_t>(rhs).i &&
            *cast<mod_expr_t>(lhs).n == *cast<mod_expr_t>(rhs).n;
    }
    if (lhs.kind() == expr_kind_t::Log) {
        return
            *cast<log_expr_t>(lhs).x == *cast<log_expr_t>(rhs).x &&
            *cast<log_expr_t>(lhs).b == *cast<log_expr_t>(rhs).b;
    }
    throw std::logic_error{"unreachable"};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
movl %eax, %ebp
movq (%rbx), %rax
movq %rbx, %rdi
callq *(%rax)
cmpl %eax, %ebp
jne 0x14db7
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
testl %eax, %eax
je 0x14bfc
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x1, %eax
je 0x14c14
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x2, %eax
je 0x14c46
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x3, %eax
je 0x14c66
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x4, %eax
jne 0x14a2e
movq %r14, %rdi
callq 0x14842
movq 0x8(%rax), %r14
movq %rbx, %rdi
callq 0x14842
movq %rax, %rbx
addq $0x8, %rbx
jmp 0x14a94
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x5, %eax
je 0x14c94
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x6, %eax
jne 0x14a9c
movq %r14, %rdi
callq 0x14886
movq %rax, %r14
movq %rbx, %rdi
callq 0x14886
movq %rax, %rbx
movq 0x8(%r14), %rdi
movq 0x8(%rax), %rsi
callq 0x14996
testb %al, %al
je 0x14db7
movq 0x18(%r14), %rdi
movq 0x18(%rbx), %rsi
callq 0x14996
testb %al, %al
je 0x14db7
movq 0x28(%r14), %r14
addq $0x28, %rbx
movq (%rbx), %rbx
jmp 0x149a7
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x7, %eax
je 0x14cdd
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x8, %eax
je 0x14d4e
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0x9, %eax
jne 0x14ae4
movq %r14, %rdi
callq 0x148ec
movq 0x8(%rax), %r14
movq %rbx, %rdi
callq 0x148ec
jmp 0x14a25
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0xa, %eax
jne 0x14b0a
movq %r14, %rdi
callq 0x1490e
movq 0x8(%rax), %r14
movq %rbx, %rdi
callq 0x1490e
jmp 0x14a25
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0xb, %eax
jne 0x14b58
movq %r14, %rdi
callq 0x14930
movq 0x8(%rax), %r15
movq %rbx, %rdi
callq 0x14930
movq 0x8(%rax), %rsi
movq %r15, %rdi
callq 0x14996
testb %al, %al
je 0x14db7
movq %r14, %rdi
callq 0x14930
movq 0x18(%rax), %r14
movq %rbx, %rdi
callq 0x14930
jmp 0x14bf0
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0xc, %eax
jne 0x14ba3
movq %r14, %rdi
callq 0x14952
movq 0x8(%rax), %r15
movq %rbx, %rdi
callq 0x14952
movq 0x8(%rax), %rsi
movq %r15, %rdi
callq 0x14996
testb %al, %al
je 0x14db7
movq %r14, %rdi
callq 0x14952
movq 0x18(%rax), %r14
movq %rbx, %rdi
callq 0x14952
jmp 0x14bf0
movq (%r14), %rax
movq %r14, %rdi
callq *(%rax)
cmpl $0xd, %eax
jne 0x14dca
movq %r14, %rdi
callq 0x14974
movq 0x8(%rax), %r15
movq %rbx, %rdi
callq 0x14974
movq 0x8(%rax), %rsi
movq %r15, %rdi
callq 0x14996
testb %al, %al
je 0x14db7
movq %r14, %rdi
callq 0x14974
movq 0x18(%rax), %r14
movq %rbx, %rdi
callq 0x14974
movq %rax, %rbx
addq $0x18, %rbx
jmp 0x14a94
movq %r14, %rdi
callq 0x147ba
movl 0x8(%rax), %ebp
movq %rbx, %rdi
callq 0x147ba
cmpl 0x8(%rax), %ebp
jmp 0x14c5e
movq %r14, %rdi
callq 0x147dc
movsd 0x8(%rax), %xmm0
movsd %xmm0, (%rsp)
movq %rbx, %rdi
callq 0x147dc
movsd (%rsp), %xmm0
cmpeqsd 0x8(%rax), %xmm0
movq %xmm0, %rbx
andl $0x1, %ebx
jmp 0x14db9
movq %r14, %rdi
callq 0x147fe
movb 0x8(%rax), %bpl
movq %rbx, %rdi
callq 0x147fe
cmpb 0x8(%rax), %bpl
sete %bl
jmp 0x14db9
movq %r14, %rdi
callq 0x14820
leaq 0x8(%rax), %r14
movq %rbx, %rdi
callq 0x14820
leaq 0x8(%rax), %rsi
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa5de
movq %r14, %rdi
callq 0x14864
movq %rax, %r14
movq %rbx, %rdi
callq 0x14864
movq %rax, %rbx
movq 0x8(%r14), %rdi
movq 0x8(%rax), %rsi
callq 0x14996
testb %al, %al
je 0x14db7
movq 0x18(%r14), %rdi
movq 0x18(%rbx), %rsi
callq 0x14996
testb %al, %al
je 0x14db7
movl 0x28(%r14), %eax
cmpl 0x28(%rbx), %eax
jmp 0x14c5e
movq %r14, %rdi
callq 0x148a8
movq %rax, %r14
movq %rbx, %rdi
callq 0x148a8
movq %rax, %r15
movq 0x10(%r14), %rax
subq 0x8(%r14), %rax
movq 0x10(%r15), %rcx
subq 0x8(%r15), %rcx
cmpq %rcx, %rax
jne 0x14db7
pushq $-0x1
popq %r12
xorl %ecx, %ecx
movq 0x8(%r14), %rax
movq 0x10(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
incq %r12
cmpq %rdx, %r12
setae %bl
jae 0x14db9
leaq 0x10(%rcx), %r13
movq (%rax,%rcx), %rdi
movq 0x8(%r15), %rax
movq (%rax,%rcx), %rsi
callq 0x14e0d
movq %r13, %rcx
testb %al, %al
je 0x14d12
jmp 0x14db9
movq %r14, %rdi
callq 0x148ca
movq %rax, %r14
movq %rbx, %rdi
callq 0x148ca
movq %rax, %r15
movq 0x10(%r14), %rax
subq 0x8(%r14), %rax
movq 0x10(%r15), %rcx
subq 0x8(%r15), %rcx
cmpq %rcx, %rax
jne 0x14db7
pushq $-0x1
popq %r12
xorl %ecx, %ecx
movq 0x8(%r14), %rax
movq 0x10(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
incq %r12
cmpq %rdx, %r12
setae %bl
jae 0x14db9
leaq 0x10(%rcx), %r13
movq (%rax,%rcx), %rdi
movq 0x8(%r15), %rax
movq (%rax,%rcx), %rsi
callq 0x14e0d
movq %r13, %rcx
testb %al, %al
je 0x14d7f
jmp 0x14db9
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x9150
movq %rax, %rbx
leaq 0x248a3(%rip), %rsi     # 0x3967f
movq %rax, %rdi
callq 0x93c0
movq 0x471e5(%rip), %rsi     # 0x5bfd0
movq 0x471a6(%rip), %rdx     # 0x5bf98
movq %rbx, %rdi
callq 0x94b0
movq %rax, %r14
movq %rbx, %rdi
callq 0x9210
movq %r14, %rdi
callq 0x94d0