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 );
}