// File: /workspace/github_cpp_makefile_star2_O1/pfnet-research[P]pml/src/expr_ast.cpp
// Function: ast::operator==(ast::expr_t const&, ast::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::Let) {
        auto const& l = cast<let_expr_t>(lhs);
        auto const& r = cast<let_expr_t>(rhs);
        return l.name == r.name && *l.init == *r.init && *l.body == *r.body;
    }
    if (lhs.kind() == expr_kind_t::LetFun) {
        auto const& l = cast<letfun_expr_t>(lhs);
        auto const& r = cast<letfun_expr_t>(rhs);
        return
            l.name == r.name && l.type == r.type &&
            *l.init == *r.init && *l.body == *r.body;
    }
    if (lhs.kind() == expr_kind_t::If) {
        auto const& l = cast<if_expr_t>(lhs);
        auto const& r = cast<if_expr_t>(rhs);
        return
            *l.cond_expr == *r.cond_expr &&
            *l.true_expr == *r.true_expr && *l.false_expr == *r.false_expr;
    }
    if (lhs.kind() == expr_kind_t::App) {
        auto const& l = cast<app_expr_t>(lhs);
        auto const& r = cast<app_expr_t>(rhs);
        if (*l.f != *r.f || l.args.size() != r.args.size())
            return false;
        for (size_t i=0; i<l.args.size(); ++i) {
            if (*l.args[i] != *r.args[i])
                return false;
        }
        return true;
    }
    if (lhs.kind() == expr_kind_t::Rand) {
        auto const& l = cast<rand_expr_t>(lhs);
        auto const& r = cast<rand_expr_t>(rhs);
        return l.start == r.start && l.end == r.end;
    }
    if (lhs.kind() == expr_kind_t::Eq ||
            lhs.kind() == expr_kind_t::Neq ||
            lhs.kind() == expr_kind_t::Leq ||
            lhs.kind() == expr_kind_t::Geq ||
            lhs.kind() == expr_kind_t::Add ||
            lhs.kind() == expr_kind_t::Sub ||
            lhs.kind() == expr_kind_t::Mul ||
            lhs.kind() == expr_kind_t::Div ||
            lhs.kind() == expr_kind_t::And ||
            lhs.kind() == expr_kind_t::Or) {
        auto const& l = cast<binop_expr_t>(lhs);
        auto const& r = cast<binop_expr_t>(rhs);
        return *l.lhs == *r.lhs && *l.rhs == *r.rhs;
    }
    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::Typed) {
        auto const& l = cast<typed_expr_t>(lhs);
        auto const& r = cast<typed_expr_t>(rhs);
        return *l.expr == *r.expr && l.type == r.type;
    }
    if (lhs.kind() == expr_kind_t::Int) {
        return cast<int_expr_t>(lhs) == cast<int_expr_t>(rhs);
    }
    if (lhs.kind() == expr_kind_t::Bool)
        return cast<bool_expr_t>(lhs) == cast<bool_expr_t>(rhs);
    throw std::logic_error{"unreachable!!"};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r13
movq %rdi, %rbp
leaq 0x525ac(%rip), %rbx     # 0x60a70
leaq 0x5265d(%rip), %r14     # 0x60b28
leaq 0x52716(%rip), %r15     # 0x60be8
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
movl %eax, %r12d
movq (%r13), %rax
movq %r13, %rdi
callq *(%rax)
cmpl %eax, %r12d
jne 0xe934
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
testl %eax, %eax
je 0xe5bd
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x1, %eax
jne 0xe63f
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x52620(%rip), %r12     # 0x60b40
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %rbp
movq %r13, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %r13
movq 0x10(%rbp), %rdx
cmpq 0x10(%rax), %rdx
jne 0xe934
testq %rdx, %rdx
je 0xe57a
movq 0x8(%r13), %rsi
movq 0x8(%rbp), %rdi
callq 0x9300
testl %eax, %eax
jne 0xe934
movq %rbp, %rdi
addq $0x28, %rdi
movq %r13, %rsi
addq $0x28, %rsi
callq 0x43918
testb %al, %al
je 0xe934
movq 0x78(%rbp), %rdi
movq 0x78(%r13), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x88(%rbp), %rbp
movq 0x88(%r13), %r13
jmp 0xe4d2
movq %rbp, %rdi
movq %rbx, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %rbp
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %r13
movq 0x10(%rbp), %rdx
cmpq 0x10(%rax), %rdx
jne 0xe934
testq %rdx, %rdx
je 0xe61d
movq 0x8(%r13), %rsi
movq 0x8(%rbp), %rdi
callq 0x9300
testl %eax, %eax
jne 0xe934
movq 0x28(%rbp), %rdi
movq 0x28(%r13), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x38(%rbp), %rbp
movq 0x38(%r13), %r13
jmp 0xe4d2
movq %r15, %r12
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x2, %eax
jne 0xe6bf
movq %rbp, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %rbp
movq %r13, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %r13
movq 0x8(%rbp), %rdi
movq 0x8(%rax), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x18(%rbp), %rdi
movq 0x18(%r13), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x28(%rbp), %rbp
movq 0x28(%r13), %r13
jmp 0xe4d2
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x3, %eax
je 0xe7d6
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x4, %eax
je 0xe8b8
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xb, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xc, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xd, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xe, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x6, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x7, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x8, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x9, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xf, %eax
je 0xe76f
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x10, %eax
jne 0xe7a7
movq %rbp, %rdi
callq 0xea0b
movq %rax, %rbp
movq %r13, %rdi
callq 0xea0b
movq %rax, %r13
movq 0x8(%rbp), %rdi
movq 0x8(%rax), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x18(%rbp), %rbp
movq 0x18(%r13), %r13
jmp 0xe4d2
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0xa, %eax
jne 0xe8de
movq %rbp, %rdi
callq 0xea2d
movq 0x8(%rax), %rbp
movq %r13, %rdi
callq 0xea2d
movq 0x8(%rax), %r13
jmp 0xe4d2
leaq 0x52293(%rip), %rsi     # 0x60a70
leaq 0x52464(%rip), %rdx     # 0x60c48
movq %rbp, %rdi
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %r14
leaq 0x5226f(%rip), %rsi     # 0x60a70
leaq 0x52440(%rip), %rdx     # 0x60c48
movq %r13, %rdi
xorl %ecx, %ecx
callq 0x9340
testq %rax, %rax
je 0xe973
movq %rax, %r15
movq 0x8(%r14), %rdi
movq 0x8(%rax), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
movq 0x20(%r14), %rax
subq 0x18(%r14), %rax
movq 0x20(%r15), %rcx
subq 0x18(%r15), %rcx
cmpq %rcx, %rax
jne 0xe934
movq 0x18(%r14), %rax
cmpq %rax, 0x20(%r14)
sete %bl
je 0xe936
movq (%rax), %rdi
movq 0x18(%r15), %rax
movq (%rax), %rsi
callq 0xe4ac
testb %al, %al
je 0xe936
movl $0x10, %ecx
xorl %r12d, %r12d
incq %r12
movq 0x18(%r14), %rax
movq 0x20(%r14), %rdx
subq %rax, %rdx
sarq $0x4, %rdx
cmpq %rdx, %r12
setae %bl
jae 0xe936
leaq 0x10(%rcx), %r13
movq (%rax,%rcx), %rdi
movq 0x18(%r15), %rax
movq (%rax,%rcx), %rsi
callq 0xe4ac
movq %r13, %rcx
testb %al, %al
jne 0xe87c
jmp 0xe936
movq %rbp, %rdi
callq 0xe9e9
movq %rax, %rbx
movq %r13, %rdi
callq 0xe9e9
movl 0x8(%rbx), %ecx
xorl 0x8(%rax), %ecx
movl 0xc(%rax), %eax
xorl 0xc(%rbx), %eax
orl %ecx, %eax
sete %bl
jmp 0xe936
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x5, %eax
jne 0xe947
movq %rbp, %rdi
callq 0xea4f
movq %rax, %rbx
movq %r13, %rdi
callq 0xea4f
movq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x8(%rax), %rsi
callq 0xe4ac
testb %al, %al
je 0xe934
addq $0x18, %rbx
addq $0x18, %r14
movq %rbx, %rdi
movq %r14, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x433d8
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x11, %eax
jne 0xe978
movq %rbp, %rdi
callq 0xea71
movq %rax, %rbx
movq %r13, %rdi
callq 0xea71
movl 0x8(%rbx), %ecx
cmpl 0x8(%rax), %ecx
jmp 0xe8d9
callq 0x9530
movq (%rbp), %rax
movq %rbp, %rdi
callq *(%rax)
cmpl $0x12, %eax
jne 0xe9a4
movq %rbp, %rdi
callq 0xea93
movq %rax, %rbx
movq %r13, %rdi
callq 0xea93
movb 0x8(%rbx), %cl
cmpb 0x8(%rax), %cl
jmp 0xe8d9
movl $0x10, %edi
callq 0x9150
movq %rax, %rbx
leaq 0x387d4(%rip), %rsi     # 0x4718c
movq %rax, %rdi
callq 0x93c0
movq 0x54609(%rip), %rsi     # 0x62fd0
movq 0x545da(%rip), %rdx     # 0x62fa8
movq %rbx, %rdi
callq 0x94b0
movq %rax, %r14
movq %rbx, %rdi
callq 0x9200
movq %r14, %rdi
callq 0x94e0