ErrorCode GcdRunner::generateResults()

in cli/gcd.cpp [12:105]


ErrorCode GcdRunner::generateResults( IN CModelData& modelData, IN bool justNegative )
{
    // translate all data to gcd-readable format, build exclusions etc.
    CGcdData gcdData( modelData );
    ErrorCode err = gcdData.TranslateToGCD();
    if( FAILED( err )) return( err );

    // check if we excluded all values of any parameter; generation will return nothing if that's the case
    if( gcdData.CheckEntireParameterExcluded() )
    {
        return( ErrorCode::ErrorCode_BadConstraints );
    }

    // save all one-element exclusions, they'll be used for warnings later
    _result.SolverWarnings       = gcdData.GetConstraintWarnings();
    _result.SingleItemExclusions = gcdData.GetSingleItemExclusions();

    if( modelData.Verbose )
    {
        modelData.PrintModelContents( L"*** AFTER MODEL IS PARSED ***" );
    }

    // run the generation from bottom up
    Model* model = gcdData.GetRootModel();
    model->SetRandomSeed( modelData.RandSeed );
    try
    {
        for( auto & submodel : model->GetSubmodels() )
        {
            // each submodel may assign different order to parameters
            if( !gcdData.FixParamOrder( submodel ))
            {
                return( ErrorCode::ErrorCode_BadModel );
            }

            if( modelData.Verbose )
            {
                modelData.PrintModelContents( L"*** AFTER ORDER IS FIXED ***" );
            }

            submodel->Generate();
        
            modelData.AddToTotalCombinationsCount( submodel->GetTotalCombinationsCount() );
            modelData.AddToRemainingCombinationsCount( submodel->GetRemainingCombinationsCount() );
        }

        if( !gcdData.FixParamOrder( model ))
        {
            return( ErrorCode::ErrorCode_BadModel );
        }

        if( modelData.Verbose )
        {
            modelData.PrintModelContents( L"*** AFTER ORDER IS FIXED ***" );
        }

        model->Generate();

        modelData.AddToTotalCombinationsCount( model->GetTotalCombinationsCount() );
        modelData.AddToRemainingCombinationsCount( model->GetRemainingCombinationsCount() );

        if( modelData.Verbose )
        {
            modelData.PrintModelContents( L"*** AFTER GENERATION ***" );
        }
    }
    catch( GenerationError e )
    {
        switch( e.GetErrorType() )
        {
        case ErrorType::OutOfMemory:
            PrintMessage( GcdError, L"Out of memory. Use smaller /o or simplify your model." );
            break;
        case ErrorType::GenerationCancelled: // not used in PICT.EXE
        case ErrorType::TooManyRows:         // not used in PICT.EXE
        case ErrorType::Unknown:
        case ErrorType::GenerationFailure:
            wstring msg = L"Internal error\n";
            msg += L"As a workaround run the tool with parameter /r a few times and see if any of the iterations produces a result.\n";
            msg += L"If the result is produced, it is guaranteed to be valid and it is safe to use.";
            PrintMessage( GcdError, msg.data() );
            break;
        }
#ifdef _DEBUG
        assert( false );
        throw;
#endif
        return( ErrorCode::ErrorCode_GenerationError );
    }

    translateResults( modelData, model->GetResults(), justNegative );

    return( ErrorCode::ErrorCode_Success );
}