// File: /workspace/github_cpp_makefile_star2_O3/pgrouchy[P]NoiseWorld/mathNet.cpp
// Function: Genome::removeUnusedEquations()
Genome* Genome::removeUnusedEquations() {
    Genome *tempParent;
    Tree *tempTree;
    list<Tree*>::iterator curTree1;
    list<TreeID*>::iterator curTreeID;
    list<int> oldIDs, newIDs;
    int i, j, numNotConnected = 0;
    bool isConnected[this->num_trees];

    tempParent = new Genome(this);

    for (i = 0; i < NUM_OUTPUTS; i++) { // we will never remove the original output equations
        isConnected[i] = true;
    }
    for (i = NUM_OUTPUTS; i < this->num_trees; i++) {
        isConnected[i] = true;
            
        if (this->numRefsToTree(i) == 0) { // this tree is not directly or indirectly referenced by an original output equation
            numNotConnected++;
            isConnected[i] = false;
        }
    }
    if (numNotConnected > 0) { // remove unconnected trees

        // delete all tree ids, will need to reorder
        curTreeID = tempParent->tree_id_lookup.begin();
        for (curTree1 = tempParent->trees.begin(); curTree1 != tempParent->trees.end(); ++curTree1) {
            delete (*curTree1);
            delete (*curTreeID);
            ++curTreeID;
        }

        // delete all trees, will need to reorder
        tempParent->trees.clear();
        tempParent->tree_id_lookup.clear();
        tempParent->num_trees = 0;
        curTree1 = this->trees.begin();
        curTreeID = this->tree_id_lookup.begin();
        oldIDs.clear();
        newIDs.clear();
        for (i = 0; i < this->num_trees; i++) {
            if (i < NUM_OUTPUTS) { // put original equations back
                tempParent->trees.push_back(new Tree((*curTree1)));
                tempParent->tree_id_lookup.push_back(new TreeID((*curTreeID)));
                tempParent->num_trees++;
            } else if (isConnected[i]) { // put connected equations back (leaving out unconnected equation tree)
                tempTree = new Tree((*curTree1));
                oldIDs.push_back(i); // keep track of order changes
                newIDs.push_back(tempParent->num_trees); // keep track of order changes
                tempParent->trees.push_back(tempTree);
                tempParent->tree_id_lookup.push_back(new TreeID((*curTreeID)));
                tempParent->num_trees++;

            }
            ++curTree1;
            ++curTreeID;
        }

        // resize initial value array as the number of trees has changed
        delete [] tempParent->initialVal;
        tempParent->initialVal = new double[tempParent->num_trees];
        j = 0;
        for (i = 0; i < this->num_trees; i++) {
            if (isConnected[i]) {
                tempParent->initialVal[j] = this->initialVal[i];
                j++;
            }
        }

        // reorder references to internal variables as trees have been reordered
        tempParent->updateIDrefs(oldIDs, newIDs);
    }
    return tempParent;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %r14
movq %rsp, -0x78(%rbp)
leaq -0x70(%rbp), %r13
movq %r13, 0x8(%r13)
movq %r13, (%r13)
xorl %eax, %eax
movq %rax, 0x10(%r13)
leaq -0x50(%rbp), %rcx
movq %rcx, 0x8(%rcx)
movq %rcx, (%rcx)
movq %rax, 0x10(%rcx)
movl 0x34(%rdi), %eax
movq %rsp, %rcx
addq $0xf, %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x38(%rbp)
movq %rcx, %rsp
movl $0x90, %edi
callq 0x21e0
movq %rax, -0x30(%rbp)
movq %rax, %rdi
movq %r14, %rsi
callq 0x58fa
movq -0x38(%rbp), %rax
movw $0x101, (%rax)          # imm = 0x101
cmpl $0x3, 0x34(%r14)
jl 0xa324
xorl %ebx, %ebx
movl $0x2, %r15d
movq -0x38(%rbp), %rax
movb $0x1, (%rax,%r15)
movq %r14, %rdi
movl %r15d, %esi
callq 0x7e36
testl %eax, %eax
jne 0xa049
incl %ebx
movq -0x38(%rbp), %rax
movb $0x0, (%rax,%r15)
incq %r15
movslq 0x34(%r14), %rax
cmpq %rax, %r15
jl 0xa026
testl %ebx, %ebx
movq -0x30(%rbp), %rax
jle 0xa324
leaq 0x18(%rax), %rcx
movq %rcx, -0x58(%rbp)
movq (%rax), %rbx
cmpq %rax, %rbx
je 0xa0ad
movq -0x58(%rbp), %r15
movq (%r15), %r15
movq 0x10(%rbx), %r12
testq %r12, %r12
je 0xa089
movq %r12, %rdi
callq 0x5b2a
movl $0x38, %esi
movq %r12, %rdi
callq 0x21f0
movq 0x10(%r15), %rdi
movl $0x8, %esi
callq 0x21f0
movq (%rbx), %rbx
cmpq -0x30(%rbp), %rbx
jne 0xa075
movq -0x30(%rbp), %rbx
movq %rbx, %rdi
callq 0x5b90
movq -0x58(%rbp), %rdi
callq 0x5bcc
movl $0x0, 0x34(%rbx)
movq (%r14), %r15
movq 0x18(%r14), %rbx
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
je 0xa0ee
movq (%rdi), %r12
movl $0x18, %esi
callq 0x21f0
movq %r12, %rdi
cmpq %r13, %r12
jne 0xa0d9
movq %r13, -0x68(%rbp)
movq %r13, -0x70(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x50(%rbp), %rdi
leaq -0x50(%rbp), %r13
cmpq %r13, %rdi
je 0xa120
movq (%rdi), %r12
movl $0x18, %esi
callq 0x21f0
movq %r12, %rdi
cmpq %r13, %r12
jne 0xa10b
movq %r13, -0x48(%rbp)
movq %r13, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
cmpl $0x0, 0x34(%r14)
jle 0xa285
xorl %r13d, %r13d
cmpq $0x1, %r13
ja 0xa1a6
movl $0x38, %edi
callq 0x21e0
movq %rax, %r12
movq 0x10(%r15), %rsi
movq %rax, %rdi
callq 0x5c08
movl $0x18, %edi
callq 0x21e0
movq %r12, 0x10(%rax)
movq %rax, %rdi
movq -0x30(%rbp), %r12
movq %r12, %rsi
callq 0x2060
incq 0x10(%r12)
movl $0x8, %edi
callq 0x21e0
movq %rax, %r12
movq 0x10(%rbx), %rax
movq (%rax), %rax
movq %rax, (%r12)
movl $0x18, %edi
callq 0x21e0
jmp 0xa254
movq -0x38(%rbp), %rax
cmpb $0x1, (%rax,%r13)
jne 0xa26f
movl $0x38, %edi
callq 0x21e0
movq %rax, %r12
movq 0x10(%r15), %rsi
movq %rax, %rdi
callq 0x5c08
movl $0x18, %edi
callq 0x21e0
movl %r13d, 0x10(%rax)
movq %rax, %rdi
leaq -0x70(%rbp), %rsi
callq 0x2060
incq -0x60(%rbp)
movl $0x18, %edi
callq 0x21e0
movq -0x30(%rbp), %rcx
movl 0x34(%rcx), %ecx
movl %ecx, 0x10(%rax)
movq %rax, %rdi
leaq -0x50(%rbp), %rsi
callq 0x2060
incq -0x40(%rbp)
movl $0x18, %edi
callq 0x21e0
movq %r12, 0x10(%rax)
movq %rax, %rdi
movq -0x30(%rbp), %r12
movq %r12, %rsi
callq 0x2060
incq 0x10(%r12)
movl $0x8, %edi
callq 0x21e0
movq %rax, %r12
movq 0x10(%rbx), %rax
movq (%rax), %rax
movq %rax, (%r12)
movl $0x18, %edi
callq 0x21e0
movq %r12, 0x10(%rax)
movq %rax, %rdi
movq -0x58(%rbp), %rsi
callq 0x2060
movq -0x30(%rbp), %rax
incq 0x28(%rax)
incl 0x34(%rax)
movq (%r15), %r15
movq (%rbx), %rbx
incq %r13
movslq 0x34(%r14), %rax
cmpq %rax, %r13
jl 0xa13e
movq -0x30(%rbp), %r15
movq 0x80(%r15), %rdi
testq %rdi, %rdi
je 0xa29a
callq 0x2240
movslq 0x34(%r15), %rax
leaq (,%rax,8), %rcx
testq %rax, %rax
movq $-0x1, %rdi
cmovnsq %rcx, %rdi
leaq -0x70(%rbp), %r13
callq 0x2030
movq %rax, 0x80(%r15)
movslq 0x34(%r14), %rcx
testq %rcx, %rcx
jle 0xa2fa
movq 0x80(%r14), %rdx
xorl %esi, %esi
xorl %edi, %edi
movq -0x38(%rbp), %r8
cmpb $0x1, (%r8,%rsi)
jne 0xa2f2
movsd (%rdx,%rsi,8), %xmm0
movslq %edi, %rdi
movsd %xmm0, (%rax,%rdi,8)
incl %edi
incq %rsi
cmpq %rsi, %rcx
jne 0xa2dc
movq (%r15), %rbx
cmpq %r15, %rbx
je 0xa324
movq %r15, %r12
leaq -0x70(%rbp), %r14
leaq -0x50(%rbp), %r15
movq 0x10(%rbx), %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x80ce
movq (%rbx), %rbx
cmpq %r12, %rbx
jne 0xa30d
movq -0x78(%rbp), %rsp
movq -0x50(%rbp), %rdi
leaq -0x50(%rbp), %r14
cmpq %r14, %rdi
je 0xa34a
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r14, %rbx
jne 0xa335
movq -0x70(%rbp), %rdi
cmpq %r13, %rdi
movq -0x30(%rbp), %r14
je 0xa36c
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r13, %rbx
jne 0xa357
movq %r14, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
movl $0x90, %esi
movq -0x30(%rbp), %rdi
jmp 0xa39d
jmp 0xa3aa
jmp 0xa392
jmp 0xa3aa
movq %rax, %r14
movl $0x38, %esi
movq %r12, %rdi
callq 0x21f0
jmp 0xa3ad
jmp 0xa3aa
jmp 0xa3aa
jmp 0xa3aa
movq %rax, %r14
movq -0x50(%rbp), %rdi
leaq -0x50(%rbp), %r15
cmpq %r15, %rdi
je 0xa3cf
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r15, %rbx
jne 0xa3ba
movq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %r15
cmpq %r15, %rdi
je 0xa3f1
movq (%rdi), %rbx
movl $0x18, %esi
callq 0x21f0
movq %rbx, %rdi
cmpq %r15, %rbx
jne 0xa3dc
movq %r14, %rdi
callq 0x2300
nop