// File: 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
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x7ce0
leaq -0x28(%rbp), %rdi
callq 0x89d0
leaq -0x40(%rbp), %rdi
callq 0x12de0
leaq -0x58(%rbp), %rdi
callq 0x12de0
movq -0xe0(%rbp), %rax
movl $0x0, -0x64(%rbp)
movl 0x34(%rax), %eax
movq %rsp, %rcx
movq %rcx, -0x70(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xd8(%rbp)
movq %rcx, %rsp
movq %rax, -0x78(%rbp)
movl $0x90, %edi
callq 0x32a0
movq %rax, -0xd0(%rbp)
jmp 0x11838
movq -0xe0(%rbp), %rsi
movq -0xd0(%rbp), %rdi
callq 0x83d0
jmp 0x1184d
movq -0xd0(%rbp), %rax
movq %rax, -0x10(%rbp)
movl $0x0, -0x5c(%rbp)
cmpl $0x2, -0x5c(%rbp)
jge 0x118b8
movq -0xd8(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movb $0x1, (%rax,%rcx)
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1185f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x11e20
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x90, %esi
callq 0x32b0
jmp 0x11e20
movl $0x2, -0x5c(%rbp)
movq -0xe0(%rbp), %rcx
movl -0x5c(%rbp), %eax
cmpl 0x34(%rcx), %eax
jge 0x11924
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movb $0x1, (%rax,%rcx)
movl -0x5c(%rbp), %esi
callq 0xda70
movl %eax, -0xe4(%rbp)
jmp 0x118f4
movl -0xe4(%rbp), %eax
cmpl $0x0, %eax
jne 0x11917
movq -0xd8(%rbp), %rax
movl -0x64(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x64(%rbp)
movslq -0x5c(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x11919
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x118bf
cmpl $0x0, -0x64(%rbp)
jle 0x11df0
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x8ab0
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8810
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x8860
movq %rax, -0xa0(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x8840
testb $0x1, %al
jne 0x1198e
jmp 0x11a05
leaq -0x20(%rbp), %rdi
callq 0x8890
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
cmpq $0x0, %rax
je 0x119c4
movq -0xf0(%rbp), %rdi
callq 0x89f0
movq -0xf0(%rbp), %rdi
movl $0x38, %esi
callq 0x32b0
leaq -0x28(%rbp), %rdi
callq 0x8b30
movq (%rax), %rax
movq %rax, -0xf8(%rbp)
cmpq $0x0, %rax
je 0x119ee
movq -0xf8(%rbp), %rdi
movl $0x8, %esi
callq 0x32b0
leaq -0x28(%rbp), %rdi
callq 0x8b60
leaq -0x20(%rbp), %rdi
callq 0x88b0
jmp 0x11968
movq -0x10(%rbp), %rdi
callq 0x8b80
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0x8bb0
movq -0xe0(%rbp), %rdi
movq -0x10(%rbp), %rax
movl $0x0, 0x34(%rax)
callq 0x8810
movq -0xe0(%rbp), %rdi
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0x20(%rbp)
addq $0x18, %rdi
callq 0x8ab0
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x12ff0
leaq -0x58(%rbp), %rdi
callq 0x12ff0
movl $0x0, -0x5c(%rbp)
movq -0xe0(%rbp), %rcx
movl -0x5c(%rbp), %eax
cmpl 0x34(%rcx), %eax
jge 0x11d0a
cmpl $0x2, -0x5c(%rbp)
jge 0x11bb2
movq -0x10(%rbp), %rax
movq %rax, -0x108(%rbp)
movl $0x38, %edi
callq 0x32a0
movq %rax, -0x100(%rbp)
jmp 0x11aba
leaq -0x20(%rbp), %rdi
callq 0x8890
movq -0x100(%rbp), %rdi
movq (%rax), %rsi
callq 0x90b0
jmp 0x11ad4
movq -0x108(%rbp), %rdi
movq -0x100(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0xb8(%rbp), %rsi
callq 0x13020
jmp 0x11af7
movq -0x10(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x118(%rbp)
movl $0x8, %edi
callq 0x32a0
movq %rax, -0x110(%rbp)
jmp 0x11b19
leaq -0x28(%rbp), %rdi
callq 0x8b30
movq -0x110(%rbp), %rdi
movq (%rax), %rsi
callq 0x92d0
jmp 0x11b33
movq -0x118(%rbp), %rdi
movq -0x110(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xc0(%rbp), %rsi
callq 0x9290
jmp 0x11b56
movq -0x10(%rbp), %rax
movl 0x34(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x34(%rax)
jmp 0x11cea
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x38, %esi
callq 0x32b0
jmp 0x11e20
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x8, %esi
callq 0x32b0
jmp 0x11e20
movq -0xd8(%rbp), %rax
movslq -0x5c(%rbp), %rcx
testb $0x1, (%rax,%rcx)
je 0x11ce8
movl $0x38, %edi
callq 0x32a0
movq %rax, -0x120(%rbp)
jmp 0x11bda
leaq -0x20(%rbp), %rdi
callq 0x8890
movq -0x120(%rbp), %rdi
movq (%rax), %rsi
callq 0x90b0
jmp 0x11bf4
movq -0x120(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x5c(%rbp), %rsi
callq 0x12df0
jmp 0x11c0e
movq -0x10(%rbp), %rsi
addq $0x34, %rsi
leaq -0x58(%rbp), %rdi
callq 0x12df0
jmp 0x11c21
movq -0x10(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x9250
jmp 0x11c30
movq -0x10(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x130(%rbp)
movl $0x8, %edi
callq 0x32a0
movq %rax, -0x128(%rbp)
jmp 0x11c52
leaq -0x28(%rbp), %rdi
callq 0x8b30
movq -0x128(%rbp), %rdi
movq (%rax), %rsi
callq 0x92d0
jmp 0x11c6c
movq -0x130(%rbp), %rdi
movq -0x128(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0xc8(%rbp), %rsi
callq 0x9290
jmp 0x11c8f
movq -0x10(%rbp), %rax
movl 0x34(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x34(%rax)
jmp 0x11ce8
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x38, %esi
callq 0x32b0
jmp 0x11e20
movq -0x128(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
movl $0x8, %esi
callq 0x32b0
jmp 0x11e20
jmp 0x11cea
leaq -0x20(%rbp), %rdi
callq 0x88b0
leaq -0x28(%rbp), %rdi
callq 0x8b60
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x11a7f
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x138(%rbp)
cmpq $0x0, %rax
je 0x11d2e
movq -0x138(%rbp), %rdi
callq 0x3340
movq -0x10(%rbp), %rax
movslq 0x34(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, -0x140(%rbp)
jmp 0x11d5a
movq -0x140(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x80(%rax)
movl $0x0, -0x60(%rbp)
movl $0x0, -0x5c(%rbp)
movq -0xe0(%rbp), %rcx
movl -0x5c(%rbp), %eax
cmpl 0x34(%rcx), %eax
jge 0x11ddb
movq -0xd8(%rbp), %rax
movslq -0x5c(%rbp), %rcx
testb $0x1, (%rax,%rcx)
je 0x11dce
movq -0xe0(%rbp), %rax
movq 0x80(%rax), %rax
movslq -0x5c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x10(%rbp), %rax
movq 0x80(%rax), %rax
movslq -0x60(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x11dd0
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x11d7a
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0xdde0
jmp 0x11dee
jmp 0x11df0
movq -0x10(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x70(%rbp), %rax
movq %rax, %rsp
leaq -0x58(%rbp), %rdi
callq 0x12eb0
leaq -0x40(%rbp), %rdi
callq 0x12eb0
movq -0x148(%rbp), %rax
movq %rbp, %rsp
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x12eb0
leaq -0x40(%rbp), %rdi
callq 0x12eb0
movq -0x80(%rbp), %rdi
callq 0x3430
nopl (%rax,%rax)