// File: ALSchwalm[P]cppEvolve/examples/primes.cpp
// Function: main
int main() {

    //Construct a Tree generator which will return trees with a max-depth of 5
    tree::TreeFactory<int> factory(5);

    //Register the previous functions
    factory.addNode(sum, "sum");
    factory.addNode(product, "product");
    factory.addNode(difference, "difference");
    factory.addNode(negative, "negative");
    factory.addTerminator([]{return 5;}, "5");
    factory.addTerminator(getX, "X");

    //Construct the algorithm
    TreeGA<int, 100> gaTree(
        //Generator: The previously build TreeFactory
        factory,

        //Fitness: number of distince primes yielded by consecutive input
        treeFitness,

        //Crossover: Choose a single node in one parent tree and crossover with
        // a node from the other parent (hight will not increase)
        tree::crossover::singlePoint<int>,

        //Mutation: Replace a random node with a new random subtree
        tree::mutator::randomNode<int>,

        //Selector: Select the 10 most fit members of the population each generation
        selector::top<tree::Tree<int>*, 10>);

    //Set mutation rate to 2%
    gaTree.setMutationRate(0.02f);

    //Run and log statistics every 20 generations, should reach around 7 primes
    gaTree.run(500, 20);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3d0, %rsp            # imm = 0x3D0
leaq -0x68(%rbp), %rdi
movl $0x5, %esi
callq 0x2fb0
leaq -0x89(%rbp), %rdi
movq %rdi, -0x378(%rbp)
callq 0x2220
movq -0x378(%rbp), %rdx
leaq 0xea7f(%rip), %rsi      # 0x11129
leaq -0x88(%rbp), %rdi
callq 0x21c0
jmp 0x26b8
leaq -0x27f(%rip), %rsi      # 0x2440
leaq -0x68(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0x2ff0
jmp 0x26d1
leaq -0x88(%rbp), %rdi
callq 0x20c0
leaq -0x89(%rbp), %rdi
callq 0x2190
leaq -0xc1(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x2220
movq -0x380(%rbp), %rdx
leaq 0xea23(%rip), %rsi      # 0x1112d
leaq -0xc0(%rbp), %rdi
callq 0x21c0
jmp 0x2718
leaq -0x2bf(%rip), %rsi      # 0x2460
leaq -0x68(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
callq 0x2ff0
jmp 0x2731
leaq -0xc0(%rbp), %rdi
callq 0x20c0
leaq -0xc1(%rbp), %rdi
callq 0x2190
leaq -0xe9(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x2220
movq -0x388(%rbp), %rdx
leaq 0xe9cb(%rip), %rsi      # 0x11135
leaq -0xe8(%rbp), %rdi
callq 0x21c0
jmp 0x2778
leaq -0x2ff(%rip), %rsi      # 0x2480
leaq -0x68(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
callq 0x2ff0
jmp 0x2791
leaq -0xe8(%rbp), %rdi
callq 0x20c0
leaq -0xe9(%rbp), %rdi
callq 0x2190
leaq -0x111(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x2220
movq -0x390(%rbp), %rdx
leaq 0xe976(%rip), %rsi      # 0x11140
leaq -0x110(%rbp), %rdi
callq 0x21c0
jmp 0x27d8
leaq -0x33f(%rip), %rsi      # 0x24a0
leaq -0x68(%rbp), %rdi
leaq -0x110(%rbp), %rdx
callq 0x30e0
jmp 0x27f1
leaq -0x110(%rbp), %rdi
callq 0x20c0
leaq -0x111(%rbp), %rdi
callq 0x2190
leaq -0x112(%rbp), %rdi
callq 0x2c40
movq %rax, -0x3a0(%rbp)
leaq -0x139(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0x2220
movq -0x398(%rbp), %rdx
leaq 0xe90c(%rip), %rsi      # 0x11149
leaq -0x138(%rbp), %rdi
callq 0x21c0
jmp 0x284b
movq -0x3a0(%rbp), %rsi
leaq -0x68(%rbp), %rdi
leaq -0x138(%rbp), %rdx
callq 0x31d0
jmp 0x2864
leaq -0x138(%rbp), %rdi
callq 0x20c0
leaq -0x139(%rbp), %rdi
callq 0x2190
leaq -0x161(%rbp), %rdi
movq %rdi, -0x3a8(%rbp)
callq 0x2220
movq -0x3a8(%rbp), %rdx
leaq 0xe8ae(%rip), %rsi      # 0x1114b
leaq -0x160(%rbp), %rdi
callq 0x21c0
jmp 0x28ab
leaq -0x402(%rip), %rsi      # 0x24b0
leaq -0x68(%rbp), %rdi
leaq -0x160(%rbp), %rdx
callq 0x31d0
jmp 0x28c4
leaq -0x160(%rbp), %rdi
callq 0x20c0
leaq -0x161(%rbp), %rdi
callq 0x2190
leaq -0x2f0(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x32c0
jmp 0x28ee
leaq -0x435(%rip), %rsi      # 0x24c0
leaq -0x310(%rbp), %rdi
movq %rdi, -0x3c8(%rbp)
callq 0x3340
leaq 0xac1(%rip), %rsi       # 0x33d0
leaq -0x330(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
callq 0x35b0
leaq 0xd17(%rip), %rsi       # 0x3640
leaq -0x350(%rbp), %rdi
movq %rdi, -0x3b8(%rbp)
callq 0x37f0
leaq 0xf3d(%rip), %rsi       # 0x3880
leaq -0x370(%rbp), %rdi
movq %rdi, -0x3b0(%rbp)
callq 0x38e0
movq -0x3c8(%rbp), %rdx
movq -0x3c0(%rbp), %rcx
movq -0x3b8(%rbp), %r8
movq -0x3b0(%rbp), %r9
leaq -0x288(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x3970
jmp 0x2987
leaq -0x370(%rbp), %rdi
callq 0x3b10
leaq -0x350(%rbp), %rdi
callq 0x3b30
leaq -0x330(%rbp), %rdi
callq 0x3b50
leaq -0x310(%rbp), %rdi
callq 0x3b70
leaq -0x2f0(%rbp), %rdi
callq 0x3b90
leaq -0x288(%rbp), %rdi
movss 0xe63e(%rip), %xmm0     # 0x11010
callq 0x3bc0
jmp 0x29d9
leaq -0x288(%rbp), %rdi
movl $0x1f4, %esi            # imm = 0x1F4
movl $0x14, %edx
callq 0x3be0
jmp 0x29f1
leaq -0x288(%rbp), %rdi
callq 0x4040
leaq -0x68(%rbp), %rdi
callq 0x3b90
xorl %eax, %eax
addq $0x3d0, %rsp            # imm = 0x3D0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2a43
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x20c0
leaq -0x89(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2a86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x20c0
leaq -0xc1(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2ac9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x20c0
leaq -0xe9(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2b0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x20c0
leaq -0x111(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2b4f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x20c0
leaq -0x139(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2b92
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x20c0
leaq -0x161(%rbp), %rdi
callq 0x2190
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x3b10
leaq -0x350(%rbp), %rdi
callq 0x3b30
leaq -0x330(%rbp), %rdi
callq 0x3b50
leaq -0x310(%rbp), %rdi
callq 0x3b70
leaq -0x2f0(%rbp), %rdi
callq 0x3b90
jmp 0x2c25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x98(%rbp)
movl %eax, -0x9c(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x4040
leaq -0x68(%rbp), %rdi
callq 0x3b90
movq -0x98(%rbp), %rdi
callq 0x2210
nopw (%rax,%rax)