// File: canzarlab[P]Trajan/src/match.cpp
// Function: tree::tree(char const*, char const*)
tree(const char* filename, const char* mapname) : n(0), nb(0), r(-1)
    {
        ifstream file(filename), mapfile(mapname);
        if (!file || !mapfile)
            die();

        // map string indices to integers
        int node_idx; string node_name;
        while (mapfile >> node_idx >> node_name)
            m[node_name] = node_idx;
        n = m.size();

        // create reverse mapping
        rm.resize(n);
        for (auto [name, idx] : m)
            rm[idx] = name;

        // nroot[x] == 1 means x is not the root
        vector<int> nroot(MAXN);

        // read from file
        string sa, sb, type;
        while (file >> sa >> sb >> type)
        {
            if (type != "default")
                die();

            // directed edge sb->sa
            int x = m[sa], y = m[sb];
            adj[y].push_back(x);
            nroot[x] = 1;
        }

        // tree too big
        if (m.size() > MAXN)
            die();

        // find root
        for (uint i = 0; i < m.size(); ++i)
        {
            // found the root
            if (!nroot[i])
            {
                // multiple roots
                if (r != -1)
                    die();

                r = i;
            }
        }

        // tree has no root
        if (r == -1)
            die();

        // identify branching nodes
        function<void(int)> mark = [&] (int x)
        {
            for (int y : adj[x])
            {
                // fill the parent table
                par[y] = x;
                mark(y);
            }
            // x is a leaf/branching node - record finishing time
            if (adj[x].size() != 1)
                b[nb++] = x;
        };
        // root has no parent
        par[r] = -1;
        mark(r);

        // too many leaf/branching nodes
        if (nb > MAXLB)
            die();

        // obtain topological ordering
        reverse(b, b + nb);

        // create node->leaf/branching node index mapping
        memset(rb, -1, sizeof rb);
        for (int i = 0; i < nb; ++i)
            rb[b[i]] = i;

        // fill the table of immediate leaf/branching descendant masks
        function<mask(int)> child = [&] (int x)
        {
            mask msk = 0;
            for (int y : adj[x])
                msk |= child(y);

            // x is a leaf/branching node
            if (rb[x] != -1)
            {
                // record leaf/branching children mask
                ch[rb[x]] = msk;
                return in(rb[x]);
            }
            return msk;
        };
        child(r);

        // identify branching ancestors
        function<void(int, mask, int)> branch = [&] (int x, mask m, int p)
        {
            // x is a branching or leaf node
            if (rb[x] != -1)
            {
                // set branching ancestor mask
                ba[rb[x]] = m;
                m |= in(rb[x]);
                // set branching parent
                bp[rb[x]] = p;
                p = x;
            }
            for (int y : adj[x])
                branch(y, m, p);
        };
        branch(r, 0, -1);
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6b0, %rsp            # imm = 0x6B0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x5f8(%rbp)
callq 0xb640
movq -0x5f8(%rbp), %rdi
addq $0x30, %rdi
movq %rdi, -0x600(%rbp)
callq 0xb660
movq -0x5f8(%rbp), %rax
addq $0x48, %rax
movq %rax, -0x5f0(%rbp)
movq %rax, %rcx
addq $0x5dc0, %rcx           # imm = 0x5DC0
movq %rcx, -0x5e8(%rbp)
movq %rax, -0x5e0(%rbp)
movq -0x5e0(%rbp), %rdi
movq %rdi, -0x608(%rbp)
callq 0xac30
movq -0x608(%rbp), %rax
movq -0x5e8(%rbp), %rcx
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, -0x5e0(%rbp)
jne 0x8838
movq -0x5f8(%rbp), %rax
movl $0x0, 0x5e08(%rax)
movl $0x0, 0x5e0c(%rax)
movl $0xffffffff, 0x5e10(%rax) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rsi
leaq -0x220(%rbp), %rdi
movl $0x8, %edx
callq 0x4510
jmp 0x88a5
movq -0x18(%rbp), %rsi
leaq -0x438(%rbp), %rdi
movl $0x8, %edx
callq 0x4510
jmp 0x88bc
movq -0x220(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x220(%rbp,%rax), %rdi
callq 0x4150
movb %al, -0x609(%rbp)
jmp 0x88dc
movb -0x609(%rbp), %al
testb $0x1, %al
jne 0x8914
jmp 0x88e8
movq -0x438(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x438(%rbp,%rax), %rdi
callq 0x4150
movb %al, -0x60a(%rbp)
jmp 0x8908
movb -0x60a(%rbp), %al
testb $0x1, %al
jne 0x8914
jmp 0x8978
leaq 0x157d4(%rip), %rdi     # 0x1e0ef
leaq 0x15796(%rip), %rsi     # 0x1e0b8
movl $0x7e, %edx
leaq 0x157c7(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x916e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x9162
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x9156
leaq -0x460(%rbp), %rdi
callq 0x43f0
leaq -0x438(%rbp), %rdi
leaq -0x43c(%rbp), %rsi
callq 0x41d0
movq %rax, -0x618(%rbp)
jmp 0x89a0
movq -0x618(%rbp), %rdi
leaq -0x460(%rbp), %rsi
callq 0x43b0
movq %rax, -0x620(%rbp)
jmp 0x89bc
movq -0x620(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x43a0
movb %al, -0x621(%rbp)
jmp 0x89da
movb -0x621(%rbp), %al
testb $0x1, %al
jne 0x89e6
jmp 0x8a39
movq -0x5f8(%rbp), %rdi
movl -0x43c(%rbp), %eax
movl %eax, -0x634(%rbp)
leaq -0x460(%rbp), %rsi
callq 0xb680
movq %rax, -0x630(%rbp)
jmp 0x8a0e
movq -0x630(%rbp), %rax
movl -0x634(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x8984
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x914a
movq -0x5f8(%rbp), %rdi
callq 0xb760
movq %rax, %rcx
movq -0x5f8(%rbp), %rax
movl %ecx, 0x5e08(%rax)
movq %rax, %rdi
addq $0x30, %rdi
movslq 0x5e08(%rax), %rsi
callq 0xb780
jmp 0x8a6a
movq -0x5f8(%rbp), %rax
movq %rax, -0x468(%rbp)
movq -0x468(%rbp), %rdi
callq 0xb810
movq %rax, -0x470(%rbp)
movq -0x468(%rbp), %rdi
callq 0xb840
movq %rax, -0x478(%rbp)
leaq -0x470(%rbp), %rdi
leaq -0x478(%rbp), %rsi
callq 0xb870
testb $0x1, %al
jne 0x8aba
jmp 0x8b7d
leaq -0x470(%rbp), %rdi
callq 0xb8a0
movq %rax, %rsi
leaq -0x4a0(%rbp), %rdi
callq 0xb8c0
jmp 0x8ad7
leaq -0x4a0(%rbp), %rdi
movq %rdi, -0x648(%rbp)
callq 0xb900
movq -0x648(%rbp), %rdi
movq %rax, -0x4a8(%rbp)
callq 0xb920
movq -0x5f8(%rbp), %rdi
movq %rax, -0x4b0(%rbp)
movq -0x4a8(%rbp), %rax
movq %rax, -0x640(%rbp)
addq $0x30, %rdi
movq -0x4b0(%rbp), %rax
movslq (%rax), %rsi
callq 0x9460
movq -0x640(%rbp), %rsi
movq %rax, %rdi
callq 0x4050
jmp 0x8b3d
leaq -0x4a0(%rbp), %rdi
callq 0xb940
leaq -0x470(%rbp), %rdi
callq 0xb960
jmp 0x8a9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0xb940
jmp 0x914a
leaq -0x4c9(%rbp), %rdi
movq %rdi, -0x650(%rbp)
callq 0x7cd0
movq -0x650(%rbp), %rdx
leaq -0x4c8(%rbp), %rdi
movl $0x3e8, %esi            # imm = 0x3E8
callq 0xb990
jmp 0x8baa
leaq -0x4c9(%rbp), %rdi
callq 0x7d70
leaq -0x4f0(%rbp), %rdi
callq 0x43f0
leaq -0x510(%rbp), %rdi
callq 0x43f0
leaq -0x530(%rbp), %rdi
callq 0x43f0
leaq -0x220(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x43b0
movq %rax, -0x658(%rbp)
jmp 0x8bf6
movq -0x658(%rbp), %rdi
leaq -0x510(%rbp), %rsi
callq 0x43b0
movq %rax, -0x660(%rbp)
jmp 0x8c12
movq -0x660(%rbp), %rdi
leaq -0x530(%rbp), %rsi
callq 0x43b0
movq %rax, -0x668(%rbp)
jmp 0x8c2e
movq -0x668(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x43a0
movb %al, -0x669(%rbp)
jmp 0x8c4c
movb -0x669(%rbp), %al
testb $0x1, %al
jne 0x8c5b
jmp 0x8d74
leaq 0x154ba(%rip), %rsi     # 0x1e11c
leaq -0x530(%rbp), %rdi
callq 0xba00
movb %al, -0x66a(%rbp)
jmp 0x8c76
movb -0x66a(%rbp), %al
testb $0x1, %al
jne 0x8c82
jmp 0x8cdb
leaq 0x15466(%rip), %rdi     # 0x1e0ef
leaq 0x15428(%rip), %rsi     # 0x1e0b8
movl $0x93, %edx
leaq 0x15459(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x4c9(%rbp), %rdi
callq 0x7d70
jmp 0x914a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x911a
movq -0x5f8(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0xb680
movq %rax, -0x678(%rbp)
jmp 0x8cf7
movq -0x5f8(%rbp), %rdi
movq -0x678(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x534(%rbp)
leaq -0x510(%rbp), %rsi
callq 0xb680
movq %rax, -0x680(%rbp)
jmp 0x8d22
movq -0x5f8(%rbp), %rax
movq -0x680(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, -0x538(%rbp)
movslq -0x538(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq 0x48(%rax,%rcx,8), %rdi
leaq -0x534(%rbp), %rsi
callq 0x8180
jmp 0x8d56
movslq -0x534(%rbp), %rsi
leaq -0x4c8(%rbp), %rdi
callq 0x7cb0
movl $0x1, (%rax)
jmp 0x8bda
movq -0x5f8(%rbp), %rdi
callq 0xb760
cmpq $0x3e8, %rax            # imm = 0x3E8
jbe 0x8da7
leaq 0x15360(%rip), %rdi     # 0x1e0ef
leaq 0x15322(%rip), %rsi     # 0x1e0b8
movl $0x9d, %edx
leaq 0x15353(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movl $0x0, -0x53c(%rbp)
movq -0x5f8(%rbp), %rdi
movl -0x53c(%rbp), %eax
movq %rax, -0x688(%rbp)
callq 0xb760
movq %rax, %rcx
movq -0x688(%rbp), %rax
cmpq %rcx, %rax
jae 0x8e4a
movl -0x53c(%rbp), %eax
movl %eax, %esi
leaq -0x4c8(%rbp), %rdi
callq 0x7cb0
cmpl $0x0, (%rax)
jne 0x8e34
movq -0x5f8(%rbp), %rax
cmpl $-0x1, 0x5e10(%rax)
je 0x8e21
leaq 0x152e6(%rip), %rdi     # 0x1e0ef
leaq 0x152a8(%rip), %rsi     # 0x1e0b8
movl $0xa7, %edx
leaq 0x152d9(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movq -0x5f8(%rbp), %rax
movl -0x53c(%rbp), %ecx
movl %ecx, 0x5e10(%rax)
jmp 0x8e36
movl -0x53c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x53c(%rbp)
jmp 0x8db1
movq -0x5f8(%rbp), %rax
cmpl $-0x1, 0x5e10(%rax)
jne 0x8e79
leaq 0x1528e(%rip), %rdi     # 0x1e0ef
leaq 0x15250(%rip), %rsi     # 0x1e0b8
movl $0xaf, %edx
leaq 0x15281(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movq -0x5f8(%rbp), %rax
movq %rax, -0x570(%rbp)
leaq -0x560(%rbp), %rdi
movq %rdi, -0x690(%rbp)
movq %rdi, -0x568(%rbp)
leaq -0x570(%rbp), %rsi
callq 0xba30
movq -0x5f8(%rbp), %rax
movq -0x690(%rbp), %rdi
movslq 0x5e10(%rax), %rcx
movl $0xffffffff, 0x5f14(%rax,%rcx,4) # imm = 0xFFFFFFFF
movl 0x5e10(%rax), %esi
callq 0xbac0
jmp 0x8ed5
movq -0x5f8(%rbp), %rax
cmpl $0x40, 0x5e0c(%rax)
jle 0x8f1b
leaq 0x15203(%rip), %rdi     # 0x1e0ef
leaq 0x151c5(%rip), %rsi     # 0x1e0b8
movl $0xc4, %edx
leaq 0x151f6(%rip), %rcx     # 0x1e0f5
callq 0x41f0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x910e
movq -0x5f8(%rbp), %rax
movq %rax, %rdi
addq $0x5e14, %rdi           # imm = 0x5E14
movslq 0x5e0c(%rax), %rcx
leaq 0x5e14(%rax,%rcx,4), %rsi
callq 0xbb00
jmp 0x8f42
movq -0x5f8(%rbp), %rdi
addq $0x70b8, %rdi           # imm = 0x70B8
movl $0xff, %esi
movl $0xfa0, %edx            # imm = 0xFA0
callq 0x4190
movl $0x0, -0x574(%rbp)
movq -0x5f8(%rbp), %rcx
movl -0x574(%rbp), %eax
cmpl 0x5e0c(%rcx), %eax
jge 0x8fb2
movq -0x5f8(%rbp), %rax
movl -0x574(%rbp), %edx
movslq -0x574(%rbp), %rcx
movslq 0x5e14(%rax,%rcx,4), %rcx
movl %edx, 0x70b8(%rax,%rcx,4)
movl -0x574(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x574(%rbp)
jmp 0x8f69
movq -0x5f8(%rbp), %rax
movq %rax, -0x5a8(%rbp)
leaq -0x598(%rbp), %rdi
movq %rdi, -0x698(%rbp)
movq %rdi, -0x5a0(%rbp)
leaq -0x5a8(%rbp), %rsi
callq 0xbb40
movq -0x5f8(%rbp), %rax
movq -0x698(%rbp), %rdi
movl 0x5e10(%rax), %esi
callq 0xbbd0
jmp 0x8ffc
movq -0x5f8(%rbp), %rax
movq %rax, -0x5d8(%rbp)
leaq -0x5c8(%rbp), %rdi
movq %rdi, -0x6a0(%rbp)
movq %rdi, -0x5d0(%rbp)
leaq -0x5d8(%rbp), %rsi
callq 0xbc10
movq -0x5f8(%rbp), %rax
movq -0x6a0(%rbp), %rdi
movl 0x5e10(%rax), %esi
xorl %eax, %eax
movl %eax, %edx
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
callq 0xbca0
jmp 0x904f
leaq -0x5c8(%rbp), %rdi
callq 0xbcf0
leaq -0x598(%rbp), %rdi
callq 0xbd10
leaq -0x560(%rbp), %rdi
callq 0xbd30
leaq -0x530(%rbp), %rdi
callq 0x41e0
leaq -0x510(%rbp), %rdi
callq 0x41e0
leaq -0x4f0(%rbp), %rdi
callq 0x41e0
leaq -0x4c8(%rbp), %rdi
callq 0x7dc0
leaq -0x460(%rbp), %rdi
callq 0x41e0
leaq -0x438(%rbp), %rdi
callq 0x40b0
leaq -0x220(%rbp), %rdi
callq 0x40b0
addq $0x6b0, %rsp            # imm = 0x6B0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
jmp 0x9102
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x228(%rbp)
movl %eax, -0x22c(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0xbcf0
leaq -0x598(%rbp), %rdi
callq 0xbd10
leaq -0x560(%rbp), %rdi
callq 0xbd30
leaq -0x530(%rbp), %rdi
callq 0x41e0
leaq -0x510(%rbp), %rdi
callq 0x41e0
leaq -0x4f0(%rbp), %rdi
callq 0x41e0
leaq -0x4c8(%rbp), %rdi
callq 0x7dc0
leaq -0x460(%rbp), %rdi
callq 0x41e0
leaq -0x438(%rbp), %rdi
callq 0x40b0
leaq -0x220(%rbp), %rdi
callq 0x40b0
movq -0x5f0(%rbp), %rax
addq $0x5dc0, %rax           # imm = 0x5DC0
movq %rax, -0x6a8(%rbp)
movq -0x6a8(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x6b0(%rbp)
callq 0x7dc0
movq -0x5f0(%rbp), %rcx
movq -0x6b0(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x6a8(%rbp)
jne 0x9182
movq -0x600(%rbp), %rdi
callq 0xbd50
movq -0x5f8(%rbp), %rdi
callq 0xbdb0
movq -0x228(%rbp), %rdi
callq 0x44e0
nopw (%rax,%rax)