// File: pfnet-research[P]pml/src/logic.cpp
// Function: logic::subst(std::shared_ptr<logic::term_t> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::shared_ptr<logic::term_t> const&)
ptr<term_t> subst(
        ptr<term_t> const& t1,
        std::string const& var, ptr<term_t> const& t2) {
    switch (t1->kind()) {
    case term_kind_t::Add:
        return make<add_term_t>(
                subst(logic::cast<add_term_t>(*t1).lhs, var, t2),
                subst(logic::cast<add_term_t>(*t1).rhs, var, t2));
    case term_kind_t::Sub:
        return make<sub_term_t>(
                subst(logic::cast<sub_term_t>(*t1).lhs, var, t2),
                subst(logic::cast<sub_term_t>(*t1).rhs, var, t2));
    case term_kind_t::Mul:
        return make<mul_term_t>(
                subst(logic::cast<mul_term_t>(*t1).lhs, var, t2),
                subst(logic::cast<mul_term_t>(*t1).rhs, var, t2));
    case term_kind_t::Div:
        return make<div_term_t>(
                subst(logic::cast<div_term_t>(*t1).lhs, var, t2),
                subst(logic::cast<div_term_t>(*t1).rhs, var, t2));
    case term_kind_t::Prob:
        return make<prob_term_t>(subst(cast<prob_term_t>(*t1).inner, var ,t2));
    case term_kind_t::Var:
        if (var == cast<var_term_t>(*t1).name)
            return t2;
        else
            return t1;
    case term_kind_t::Int:
        return t1;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rdi, -0x128(%rbp)
movq %rdi, %rax
movq %rax, -0x120(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x24f60
movq %rax, %rdi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
movl %eax, %ecx
movq %rcx, -0x118(%rbp)
subl $0x6, %eax
ja 0x1eb18
movq -0x118(%rbp), %rax
leaq 0x7d3dc(%rip), %rcx     # 0x9ba4c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1eb80
movq %rax, %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x40(%rbp), %rdi
callq 0x1e610
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1eb80
movq %rax, -0x130(%rbp)
jmp 0x1e6bc
movq -0x130(%rbp), %rsi
addq $0x18, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x50(%rbp), %rdi
callq 0x1e610
jmp 0x1e6da
leaq -0x30(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x50(%rbp), %rdx
callq 0x1eb40
jmp 0x1e6ed
movq -0x128(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x24fb0
leaq -0x30(%rbp), %rdi
callq 0x24fe0
leaq -0x50(%rbp), %rdi
callq 0x25000
leaq -0x40(%rbp), %rdi
callq 0x25000
jmp 0x1eb1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x1e740
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x25000
leaq -0x40(%rbp), %rdi
callq 0x25000
jmp 0x1eb2a
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ec00
movq %rax, %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x80(%rbp), %rdi
callq 0x1e610
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ec00
movq %rax, -0x138(%rbp)
jmp 0x1e791
movq -0x138(%rbp), %rsi
addq $0x18, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x90(%rbp), %rdi
callq 0x1e610
jmp 0x1e7b2
leaq -0x70(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x90(%rbp), %rdx
callq 0x1ebc0
jmp 0x1e7c8
movq -0x128(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x25020
leaq -0x70(%rbp), %rdi
callq 0x25050
leaq -0x90(%rbp), %rdi
callq 0x25000
leaq -0x80(%rbp), %rdi
callq 0x25000
jmp 0x1eb1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x1e821
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x25000
leaq -0x80(%rbp), %rdi
callq 0x25000
jmp 0x1eb2a
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ec80
movq %rax, %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
callq 0x1e610
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ec80
movq %rax, -0x140(%rbp)
jmp 0x1e875
movq -0x140(%rbp), %rsi
addq $0x18, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0xc0(%rbp), %rdi
callq 0x1e610
jmp 0x1e896
leaq -0xa0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
callq 0x1ec40
jmp 0x1e8b2
movq -0x128(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x25070
leaq -0xa0(%rbp), %rdi
callq 0x250a0
leaq -0xc0(%rbp), %rdi
callq 0x25000
leaq -0xb0(%rbp), %rdi
callq 0x25000
jmp 0x1eb1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x1e914
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x25000
leaq -0xb0(%rbp), %rdi
callq 0x25000
jmp 0x1eb2a
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ed00
movq %rax, %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0xe0(%rbp), %rdi
callq 0x1e610
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1ed00
movq %rax, -0x148(%rbp)
jmp 0x1e96b
movq -0x148(%rbp), %rsi
addq $0x18, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0xf0(%rbp), %rdi
callq 0x1e610
jmp 0x1e98c
leaq -0xd0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
leaq -0xf0(%rbp), %rdx
callq 0x1ecc0
jmp 0x1e9a8
movq -0x128(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x250c0
leaq -0xd0(%rbp), %rdi
callq 0x250f0
leaq -0xf0(%rbp), %rdi
callq 0x25000
leaq -0xe0(%rbp), %rdi
callq 0x25000
jmp 0x1eb1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x1ea0a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x25000
leaq -0xe0(%rbp), %rdi
callq 0x25000
jmp 0x1eb2a
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1f620
movq %rax, %rsi
addq $0x8, %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq -0x110(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0x1ed70
movq -0x150(%rbp), %rsi
leaq -0x100(%rbp), %rdi
callq 0x1ed40
jmp 0x1ea63
movq -0x128(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x25110
leaq -0x100(%rbp), %rdi
callq 0x25140
leaq -0x110(%rbp), %rdi
callq 0x16150
jmp 0x1eb1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x16150
jmp 0x1eb2a
movq -0x18(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x10(%rbp), %rdi
callq 0x24f80
movq %rax, %rdi
callq 0x1f660
movq -0x158(%rbp), %rdi
movq %rax, %rsi
addq $0x8, %rsi
callq 0xf040
testb $0x1, %al
jne 0x1eae2
jmp 0x1eaf4
movq -0x128(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x25160
jmp 0x1eb1a
movq -0x128(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x25160
jmp 0x1eb1a
movq -0x128(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x25160
jmp 0x1eb1a
ud2
movq -0x120(%rbp), %rax
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0xa650
nopw %cs:(%rax,%rax)