// File: Bartor[P]kompilator/middle/ast_optimizer/ASTOptimizer.cpp
// Function: checkTautology(Condition&)
ConditionState checkTautology(Condition &condition) {
    try {
        NumberValue &lVal = dynamic_cast<NumberValue &>(condition.lhs);
        NumberValue &rVal = dynamic_cast<NumberValue &>(condition.rhs);

        switch (condition.type) {
            case EQUAL:
                return lVal.value == rVal.value ? ALWAYS : NEVER;
            case NOT_EQUAL:
                return lVal.value != rVal.value ? ALWAYS : NEVER;
            case LESS:
                return lVal.value < rVal.value ? ALWAYS : NEVER;
            case GREATER:
                return lVal.value > rVal.value ? ALWAYS : NEVER;
            case LESS_OR_EQUAL:
                return lVal.value <= rVal.value ? ALWAYS : NEVER;
            case GREATER_OR_EQUAL:
                return lVal.value >= rVal.value ? ALWAYS : NEVER;
        }
    } catch (std::bad_cast _) {
        try {
            IdentifierValue &lVal = dynamic_cast<IdentifierValue &>(condition.lhs);
            IdentifierValue &rVal = dynamic_cast<IdentifierValue &>(condition.rhs);

            try {
                VariableIdentifier &lValId = dynamic_cast<VariableIdentifier &>(lVal.identifier);
                VariableIdentifier &rValId = dynamic_cast<VariableIdentifier &>(rVal.identifier);

                if (lValId.name == rValId.name) {
                    switch (condition.type) {
                        case EQUAL:
                        case LESS_OR_EQUAL:
                        case GREATER_OR_EQUAL:
                            return ALWAYS;
                        case NOT_EQUAL:
                        case LESS:
                        case GREATER:
                            return NEVER;
                    }
                } else return SOMETIMES;
            } catch (std::bad_cast _) {
                try {
                    AccessIdentifier &lValAcc = dynamic_cast<AccessIdentifier &>(lVal.identifier);
                    AccessIdentifier &rValAcc = dynamic_cast<AccessIdentifier &>(rVal.identifier);

                    if (lValAcc.name == rValAcc.name && lValAcc.index == rValAcc.index) {
                        switch (condition.type) {
                            case EQUAL:
                            case LESS_OR_EQUAL:
                            case GREATER_OR_EQUAL:
                                return ALWAYS;
                            case NOT_EQUAL:
                            case LESS:
                            case GREATER:
                                return NEVER;
                        }
                    } else return SOMETIMES;
                } catch (std::bad_cast) {
                    try {
                        VariableAccessIdentifier &lValVarAcc = dynamic_cast<VariableAccessIdentifier &>(lVal.identifier);
                        VariableAccessIdentifier &rValVarAcc = dynamic_cast<VariableAccessIdentifier &>(rVal.identifier);

                        if (lValVarAcc.name == rValVarAcc.name && lValVarAcc.accessName == rValVarAcc.accessName) {
                            switch (condition.type) {
                                case EQUAL:
                                case LESS_OR_EQUAL:
                                case GREATER_OR_EQUAL:
                                    return ALWAYS;
                                case NOT_EQUAL:
                                case LESS:
                                case GREATER:
                                    return NEVER;
                            }
                        } else return SOMETIMES;
                    } catch (std::bad_cast _) {}
                }
            }
        } catch (std::bad_cast _) {}
    }
    return SOMETIMES;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a94a(%rip), %rsi     # 0x40078
leaq 0x1aaab(%rip), %rdx     # 0x401e0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
jne 0x25752
callq 0x6530
jmp 0x25752
movq -0xa8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x1a90c(%rip), %rsi     # 0x40078
leaq 0x1aa6d(%rip), %rdx     # 0x401e0
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xb0(%rbp)
cmpq $0x0, %rax
jne 0x25790
callq 0x6530
jmp 0x25790
movq -0xb0(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
movq %rax, -0xb8(%rbp)
subq $0x5, %rax
ja 0x25a43
movq -0xb8(%rbp), %rax
leaq 0xcfff(%rip), %rcx      # 0x327c0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x25f2a
movq -0x20(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0x38(%rbp), %rdi
callq 0x203d0
movq -0xc8(%rbp), %rdi
callq 0x60f0
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a85b(%rip), %rsi     # 0x40078
leaq 0x1aa04(%rip), %rdx     # 0x40228
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xc0(%rbp)
cmpq $0x0, %rax
jne 0x25841
callq 0x6530
jmp 0x25841
movq -0xc0(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x1a81d(%rip), %rsi     # 0x40078
leaq 0x1a9c6(%rip), %rdx     # 0x40228
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xd0(%rbp)
cmpq $0x0, %rax
jne 0x2587f
callq 0x6530
jmp 0x2587f
movq -0xd0(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a827(%rip), %rsi     # 0x400c0
leaq 0x1a868(%rip), %rdx     # 0x40108
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xd8(%rbp)
cmpq $0x0, %rax
jne 0x258bd
callq 0x6530
jmp 0x258bd
movq -0xd8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a7e9(%rip), %rsi     # 0x400c0
leaq 0x1a82a(%rip), %rdx     # 0x40108
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xe0(%rbp)
cmpq $0x0, %rax
jne 0x258fb
callq 0x6530
jmp 0x258fb
movq -0xe0(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x24890
testb $0x1, %al
jne 0x25924
jmp 0x25bb6
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0xe4(%rbp)
testl %eax, %eax
je 0x25b8e
jmp 0x2593b
movl -0xe4(%rbp), %eax
decl %eax
subl $0x3, %eax
jb 0x25ba1
jmp 0x2594e
movl -0xe4(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x25b8e
jmp 0x25bb4
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovll %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovgl %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovlel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
xorl %eax, %eax
movl $0x2, %ecx
cmpq %rsi, %rdx
cmovgel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x25f1e
jmp 0x25ef7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x25e82
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x25e82
movq -0x20(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0x68(%rbp), %rdi
callq 0x203d0
movq -0xf8(%rbp), %rdi
callq 0x60f0
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a614(%rip), %rsi     # 0x400c0
leaq 0x1a69d(%rip), %rdx     # 0x40150
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0xf0(%rbp)
cmpq $0x0, %rax
jne 0x25ad0
callq 0x6530
jmp 0x25ad0
movq -0xf0(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a5d6(%rip), %rsi     # 0x400c0
leaq 0x1a65f(%rip), %rdx     # 0x40150
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x100(%rbp)
cmpq $0x0, %rax
jne 0x25b0e
callq 0x6530
jmp 0x25b0e
movq -0x100(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x70(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x24890
testb $0x1, %al
jne 0x25b37
jmp 0x25d45
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x78(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x25d45
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x104(%rbp)
testl %eax, %eax
je 0x25d1d
jmp 0x25b64
movl -0x104(%rbp), %eax
decl %eax
subl $0x3, %eax
jb 0x25d30
jmp 0x25b77
movl -0x104(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x25d1d
jmp 0x25d43
movl $0x2, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25edc
movl $0x0, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25edc
jmp 0x25bc9
movl $0x1, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25edc
jmp 0x25e08
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x25e70
movq -0x20(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0x80(%rbp), %rdi
callq 0x203d0
movq -0x118(%rbp), %rdi
callq 0x60f0
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a49f(%rip), %rsi     # 0x400c0
leaq 0x1a570(%rip), %rdx     # 0x40198
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x110(%rbp)
cmpq $0x0, %rax
jne 0x25c45
callq 0x6530
jmp 0x25c45
movq -0x110(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1a45e(%rip), %rsi     # 0x400c0
leaq 0x1a52f(%rip), %rdx     # 0x40198
xorl %eax, %eax
movl %eax, %ecx
callq 0x62f0
movq %rax, -0x120(%rbp)
cmpq $0x0, %rax
jne 0x25c86
callq 0x6530
jmp 0x25c86
movq -0x120(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x24890
testb $0x1, %al
jne 0x25cb8
jmp 0x25e2f
movq -0x88(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x24890
testb $0x1, %al
jne 0x25cdc
jmp 0x25e2f
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x124(%rbp)
testl %eax, %eax
je 0x25e0d
jmp 0x25cf3
movl -0x124(%rbp), %eax
decl %eax
subl $0x3, %eax
jb 0x25e1d
jmp 0x25d06
movl -0x124(%rbp), %eax
addl $-0x4, %eax
subl $0x2, %eax
jb 0x25e0d
jmp 0x25e2d
movl $0x2, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25de9
movl $0x0, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25de9
jmp 0x25d58
movl $0x1, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25de9
jmp 0x25de2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x25e50
movq -0x20(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
movq %rdi, -0x130(%rbp)
callq 0x203d0
movq -0x138(%rbp), %rdi
callq 0x60f0
movq -0x130(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25dbe
jmp 0x25dc0
movl $0x0, -0x5c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25dd7
movl -0x5c(%rbp), %eax
testl %eax, %eax
jne 0x25de9
jmp 0x25de0
jmp 0x25de2
movl $0x0, -0x5c(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25df9
movl -0x5c(%rbp), %eax
testl %eax, %eax
jne 0x25edc
jmp 0x25e06
jmp 0x25e08
jmp 0x25ed5
movl $0x2, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25dc7
movl $0x0, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25dc7
jmp 0x25e3f
movl $0x1, -0x4(%rbp)
movl $0x1, -0x5c(%rbp)
jmp 0x25dc7
jmp 0x25dc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25e6e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x25e70
jmp 0x25e70
leaq -0x68(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25e80
jmp 0x25e82
movl -0x24(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x25f0c
movq -0x20(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x6360
movq %rax, %rsi
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x203d0
movq -0x148(%rbp), %rdi
callq 0x60f0
movq -0x140(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25ed3
jmp 0x25ed5
movl $0x0, -0x5c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x6500
callq 0x6450
movl -0x5c(%rbp), %eax
testl %eax, %eax
je 0x25ef5
jmp 0x25ef3
jmp 0x25f1e
jmp 0x25ef7
movl $0x1, -0x4(%rbp)
jmp 0x25f1e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x6500
callq 0x6450
jmp 0x25f1c
jmp 0x25f2a
movl -0x4(%rbp), %eax
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x64d0
movq %rax, %rdi
callq 0x9470
nopl (%rax,%rax)