void ExclusionDeriver::DeriveExclusions()

in api/deriver.cpp [284:369]


void ExclusionDeriver::DeriveExclusions()
{
    // For preview generation we don't invoke the core of the deriver at all
    if( m_task->GetGenerationMode() != GenerationMode::Regular ) return;

    DOUT( L"Exclusions:\n" );
    for( auto & exclusion : m_exclusions )
    {
        exclusion.Print();
    }
    DOUT( L"Derivation: Started\n" );

    // Add pointers to referencing exclusions to each parameter
    // for_each(m_exclusions.begin(), m_exclusions.end(), AddExclusionParamBackPtrs);
    for( ExclusionCollection::iterator ie = m_exclusions.begin(); ie != m_exclusions.end(); ++ie )
    {
        AddExclusionParamBackPtrs( ie );
    }

    // Initialize the worklist
    for( vector<Parameter*>::iterator i = m_parameters.begin(); i != m_parameters.end(); ++i )
    {
        if( ( *i )->GetExclusionCount() >= ( *i )->GetValueCount() )
        {
            m_worklist.push_back( &**i );
        }
    }

    while( !m_worklist.empty() )
    {
        DOUT( L"worklist size: " << static_cast<int>( m_worklist.size() ) << L"\n" );
        DOUT( L"excl col size: " << static_cast<int>( m_exclusions.size() ) << L"\n"; )

        m_currentParam = m_worklist[ 0 ];
        m_worklist.pop_front();

        DOUT( L"worklist item: [" << m_currentParam->GetName() << L"]" <<
              L", avg excl size: " << m_currentParam->GetAverageExclusionSize() <<
              L", num excls: " << m_currentParam->GetExclusionCount() <<
              L"\n"; )

        // We need buckets to hold the exclusions pertaining to each value
        vector<list<Exclusion *> > buckets( m_currentParam->GetValueCount() );

        for( ExclIterCollection::iterator ie =  m_currentParam->GetExclusions().begin();
                                          ie != m_currentParam->GetExclusions().end();
                                        ++ie )
        {
            // put ref to each exclusion in appropriate value-relative bucket
            // find this parameter in the exclusion
            Exclusion::iterator iExcl = find_if( ( *ie )->begin(), ( *ie )->end(),
                                                 [this](const ExclusionTerm et) {
                                                     return et.first == m_currentParam;
                                                 } );

            // put the exclusion in the right bucket
            assert( iExcl != ( *ie )->end() );
            Exclusion* pExcl = const_cast<Exclusion*>( &**ie );
            buckets.at( iExcl->second ).push_back( pExcl );
        }

        // if all the buckets have something in them
        int n;
        for( n = 0; n < m_currentParam->GetValueCount(); ++n )
        {
            if( buckets[ n ].empty() ) break;
        }

        // if there was an empty bucket, go to the next entry in the worklist
        if( n < m_currentParam->GetValueCount() ) continue;

        // recursively build all cover sets, building up exclusion on other params
        Exclusion exclImplied;
        m_end = buckets.end();
        buildExclusion( exclImplied, buckets.begin() );

        peformDelete();
    }

    DOUT( L"Derivation: Finished\n" );
    DOUT( L"Exclusions:\n" );
    for( auto & exclusion : m_exclusions )
    {
        exclusion.Print();
    }
}