void Model::markUndefinedValuesInResultParams()

in api/model.cpp [423:529]


void Model::markUndefinedValuesInResultParams()
{
    // don't bother if no result parameters were defined
    if( GetResultParameterCount() <= 0 ) return;

    
    // set up an auxiliary structure that for each result parameter holds
    // an array of as many elements as there are rows in the output; each
    // element is a set of integers

    // for each result param
    // initilize a vector of N lists, where N = number of rows

    map< Parameter*, vector< set< int > > > excludedResultValues;

    vector< set< int > > emptyVector;
    emptyVector.resize( m_results.size() );
    for( ParamCollection::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
    {
        if( ( *ip )->IsExpectedResultParam() )
        {
            excludedResultValues.insert( make_pair( *ip, emptyVector ) );
        }
    }

    // remove excluded elements
    // for each result row (i_row)
    //   for each exclusion (i_excl)
    //     if non-result items of i_excl consistent with i_row
    //     for each result param of i_excl (i_param)
    //       remove value of i_param from corresponding set in structure

    int row_idx = 0;
    for( ResultCollection::iterator i_row = m_results.begin();
                                    i_row != m_results.end(); ++i_row, ++row_idx )
    {
        for( ExclusionCollection::iterator i_excl = m_exclusions.begin();
                                           i_excl != m_exclusions.end(); ++i_excl )
        {
            // only look at exclusions that have only one result param in them
            // if there are two or more, they will skew the true picture
            if( i_excl->ResultParamCount() > 1 ) continue;

            bool matches = true;
            for( Exclusion::iterator i_term = i_excl->begin();
                                     i_term != i_excl->end(); ++i_term )
            {
                // TODO: when result params are suported check modl/modl021.txt doesn't break here
                if( !i_term->first->IsExpectedResultParam()
                &&  i_row->at( i_term->first->GetSequence() ) != i_term->second )
                {
                    matches = false;
                    break;
                }
            }

            if( matches )
            {
                for( Exclusion::iterator i_term = i_excl->begin();
                                         i_term != i_excl->end(); ++i_term )
                {
                    if( i_term->first->IsExpectedResultParam() )
                    {
                        excludedResultValues[ i_term->first ][ row_idx ].insert( i_term->second );
                    }
                }
            }
        }
    }

    DOUT( L"-- result param map --\n" );
    for( auto ip = excludedResultValues.begin(); ip != excludedResultValues.end(); ++ip )
    {
        DOUT( ip->first->GetName() << ":\n" );
        for( auto iv = ip->second.begin(); iv != ip->second.end(); ++iv )
        {
            for( auto il = iv->begin(); il != iv->end(); ++il )
            {
                DOUT( *il << L" " );
            }
            DOUT( "\n" );
        }
    }

    //mark output rows as unknown

    //for each i_row in S
    //for each result param (i_param) in i_row
    //if i_param's set is empty
    //mark corresponding result value in the output as unknown

    for( map< Parameter*, vector< set< int > > >::iterator ip = excludedResultValues.begin();
                                                           ip != excludedResultValues.end();
                                                           ++ip )
    {
        int col = ( ip->first )->GetSequence();

        for( size_t row = 0; row < ip->second.size(); ++row )
        {
            // all values have to be excluded except for 1
            if( ip->second[ row ].size() != ip->first->GetValueCount() - 1 )
            {
                m_results[ row ][ col ] = Parameter::UndefinedValue;
            }
        }
    }
}