// File: WShabti-Team[P]WShabtiPict/wshabtilib/api/deriver.cpp
// Function: pictcore::ExclusionDeriver::buildExclusion(pictcore::Exclusion&, __gnu_cxx::__normal_iterator<std::__cxx11::list<pictcore::Exclusion*, std::allocator<pictcore::Exclusion*>>*, std::vector<std::__cxx11::list<pictcore::Exclusion*, std::allocator<pictcore::Exclusion*>>, std::allocator<std::__cxx11::list<pictcore::Exclusion*, std::allocator<pictcore::Exclusion*>>>>>)
inline void ExclusionDeriver::buildExclusion( Exclusion& exclImplied, vector<ExclPtrList>::iterator begin )
{
    // derivation can take a long time, use the call back to check if it should be aborted
    if( m_task->AbortGeneration() )
    {
        throw GenerationError( __FILE__, __LINE__, GenerationCancelled );
    }

    if( begin != m_end )
    {
        // for each exclusion in this bucket
        for( ExclPtrList::iterator i = begin->begin(); i != begin->end(); ++i )
        {
            // don't bother if the exclusion was already marked obsolete
            if( ( *i )->isDeleted() ) continue;

            // check for contradiction, continue if found
            if( !consistent( exclImplied, **i ) ) continue; 

            // merge the exclusion into the given one to make a new one
            Exclusion excl( exclImplied );
            for( Exclusion::iterator ie = ( *i )->begin(); ie != ( *i )->end(); ++ie )
            {
                if( ie->first != m_currentParam )
                {
                    excl.insert( *ie );
                }
            }

            // checking for being in the collection while still in progress of generation 
            // is just an optimization but it speeds things up considerably
            // The reasoning: if at this point the exclusion being built is already obsolete
            // we should stop building immediatelly and move on
            // however, it does not make sense to check if an exclusion is in the collection
            // before it reaches a size of 3; very rarely there will be an broader
            // exclusion for size <3

            if( alreadyInCollection( excl ) ) continue;

            // call buildExclusion on next bucket, passing our exclusion in progress
            buildExclusion( excl, begin + 1 );
        }
    }
    else
    {
        // add new exclusion to model
        //   first  = an iterator to the new exclusion,
        //   second = return whether item was added (true means it wasn't a duplicate)
        pair<ExclusionCollection::iterator, bool> addResult = AddExclusion( exclImplied, false );
        if( !addResult.second ) return;

        // now go through the collection and mark those that became obsolete
        markObsolete( addResult.first );

        DOUT( static_cast<int>( m_exclusions.size() ) << L" " );

        // add new references to existing structures
        AddExclusionParamBackPtrs( addResult.first );

        // if exclusion count >= value count for any params in new exclusion
        for( Exclusion::iterator i = exclImplied.begin(); i != exclImplied.end(); ++i )
        {
            if( i->first->GetExclusionCount() >= i->first->GetValueCount() &&
                m_worklist.end() == find( m_worklist.begin(), m_worklist.end(), i->first ) )
            {
                m_worklist.push_back( i->first );
                DOUT( L"worklist: 1 added\n" );
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1d0, %rsp            # imm = 0x1D0
movq %rdx, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1a0(%rbp)
movq 0x50(%rax), %rdi
callq 0xd6c0
testb $0x1, %al
jne 0xb764
jmp 0xb823
movb $0x1, -0x4d(%rbp)
movl $0x30, %edi
callq 0x7300
movq %rax, -0x1b0(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x79e0
movq -0x1a8(%rbp), %rdx
leaq 0x589f5(%rip), %rsi     # 0x6418c
leaq -0x38(%rbp), %rdi
callq 0xd700
jmp 0xb7a2
movq -0x1b0(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0xb4, %edx
xorl %ecx, %ecx
callq 0xd7b0
jmp 0xb7bb
movq -0x1b0(%rbp), %rdi
movb $0x0, -0x4d(%rbp)
leaq 0x86223(%rip), %rsi     # 0x919f0
leaq 0x201c(%rip), %rdx      # 0xd7f0
callq 0x7980
jmp 0xbc37
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0xb801
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x73e0
leaq -0x39(%rbp), %rdi
callq 0x7660
testb $0x1, -0x4d(%rbp)
jne 0xb812
jmp 0xb81e
movq -0x1b0(%rbp), %rdi
callq 0x74a0
jmp 0xbc2e
movq -0x1a0(%rbp), %rsi
addq $0x58, %rsi
leaq -0x8(%rbp), %rdi
callq 0xd810
testb $0x1, %al
jne 0xb840
jmp 0xba5a
leaq -0x8(%rbp), %rdi
callq 0xd850
movq %rax, %rdi
callq 0xd870
movq %rax, -0x58(%rbp)
leaq -0x8(%rbp), %rdi
callq 0xd850
movq %rax, %rdi
callq 0xd8d0
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xd8a0
testb $0x1, %al
jne 0xb880
jmp 0xba55
leaq -0x58(%rbp), %rdi
callq 0xd900
movq (%rax), %rdi
callq 0xaf80
testb $0x1, %al
jne 0xb897
jmp 0xb89c
jmp 0xba47
movq -0x18(%rbp), %rax
movq %rax, -0x1b8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xd900
movq -0x1a0(%rbp), %rdi
movq -0x1b8(%rbp), %rsi
movq (%rax), %rdx
callq 0x9d10
testb $0x1, %al
jne 0xb8cf
jmp 0xba47
movq -0x18(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xd930
leaq -0x58(%rbp), %rdi
callq 0xd900
movq (%rax), %rdi
callq 0x9090
movq %rax, -0xb8(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xd900
movq (%rax), %rdi
callq 0x90c0
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0xb92b
jmp 0xb9bd
leaq -0xb8(%rbp), %rdi
callq 0x9160
movq -0x1a0(%rbp), %rcx
movq (%rax), %rax
cmpq 0x48(%rcx), %rax
je 0xb9aa
leaq -0xb8(%rbp), %rdi
callq 0x9910
movq %rax, %rsi
leaq -0xb0(%rbp), %rdi
callq 0xd9b0
movb %dl, -0x1c1(%rbp)
movq %rax, -0x1c0(%rbp)
jmp 0xb971
movb -0x1c1(%rbp), %al
movq -0x1c0(%rbp), %rcx
movq %rcx, -0xd0(%rbp)
movb %al, -0xc8(%rbp)
jmp 0xb9aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xbc70
jmp 0xbc2e
jmp 0xb9ac
leaq -0xb8(%rbp), %rdi
callq 0x9210
jmp 0xb8f7
movq -0x1a0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0xaa80
movb %al, -0x1c2(%rbp)
jmp 0xb9d8
movb -0x1c2(%rbp), %al
testb $0x1, %al
jne 0xb9e4
jmp 0xb9f0
movl $0x4, -0xd4(%rbp)
jmp 0xba2b
leaq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0xda60
movq -0x1a0(%rbp), %rdi
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdx
leaq -0xb0(%rbp), %rsi
callq 0xb730
jmp 0xba21
movl $0x0, -0xd4(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xbc70
movl -0xd4(%rbp), %eax
testl %eax, %eax
je 0xba45
jmp 0xba43
jmp 0xba47
jmp 0xba47
leaq -0x58(%rbp), %rdi
callq 0xdaa0
jmp 0xb855
jmp 0xbc25
movq -0x1a0(%rbp), %rdi
movq -0x18(%rbp), %rsi
xorl %edx, %edx
callq 0x9ef0
movb %dl, -0xf8(%rbp)
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rax
movq %rax, -0xf0(%rbp)
movb -0xf8(%rbp), %al
movb %al, -0xe8(%rbp)
testb $0x1, -0xe8(%rbp)
jne 0xbaa1
jmp 0xbc25
movq -0x1a0(%rbp), %rdi
movq -0xf0(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rsi
callq 0x9ff0
leaq -0xf0(%rbp), %rdi
callq 0xa0e0
movq -0x18(%rbp), %rdi
callq 0x9090
movq %rax, -0x110(%rbp)
movq -0x18(%rbp), %rdi
callq 0x90c0
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0xbb0a
jmp 0xbc23
leaq -0x110(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0xb330
movl %eax, -0x1c8(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x8eb0
movl -0x1c8(%rbp), %ecx
movl %eax, %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x1c3(%rbp)
jl 0xbbd7
movq -0x1a0(%rbp), %rsi
addq $0x60, %rsi
leaq -0x138(%rbp), %rdi
callq 0xdaf0
movq -0x1a0(%rbp), %rsi
addq $0x60, %rsi
leaq -0x178(%rbp), %rdi
callq 0xdb90
movq -0x1a0(%rbp), %rsi
addq $0x60, %rsi
leaq -0x198(%rbp), %rdi
callq 0xdaf0
leaq -0x110(%rbp), %rdi
callq 0x9160
movq %rax, %rcx
leaq -0x158(%rbp), %rdi
leaq -0x178(%rbp), %rsi
leaq -0x198(%rbp), %rdx
callq 0xdb20
leaq -0x138(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0xdac0
movb %al, -0x1c3(%rbp)
movb -0x1c3(%rbp), %al
testb $0x1, %al
jne 0xbbe3
jmp 0xbc10
movq -0x1a0(%rbp), %rax
addq $0x60, %rax
movq %rax, -0x1d0(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x9160
movq -0x1d0(%rbp), %rdi
movq %rax, %rsi
callq 0xdbc0
jmp 0xbc12
leaq -0x110(%rbp), %rdi
callq 0x9210
jmp 0xbade
jmp 0xbc25
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x79d0
nopw (%rax,%rax)