in cli/gcdexcl.cpp [112:267]
void ConstraintsInterpreter::interpretTerm( IN CTerm* term, OUT CGcdExclusions& gcdExclusions )
{
// a useful simplification: gcdData.Parameters, constrModel.Parameters, and modelData.Parameters
// have elements in the same order thus indexes correspond to the same parameters
// find the param in modelData
vector< CModelParameter >::iterator found = _modelData.FindParameterByName( term->Parameter->Name );
assert( found != _modelData.Parameters.end() );
CModelParameter& modelParam = *found;
// find the parameter in gcdParam
unsigned int paramIdx = (unsigned int) distance( _modelData.Parameters.begin(), found );
CParameter parameter = _constrModel.Parameters[ paramIdx ];
// set up the structure: a vector of as many elements as there are values, initially set all
// to false; then for every value that satisfies the relation set corresponding element to true
vector< bool > satisfyingValues;
satisfyingValues.resize( modelParam.Values.size(), false );
// do the solving depending on how the term looks like
switch( term->DataType )
{
// everything except INs
case TermDataType::Value:
{
for( size_t valueIdx = 0; valueIdx < modelParam.Values.size(); ++valueIdx )
{
CModelValue& value = modelParam.Values[ valueIdx ];
if( valueSatisfiesRelation( parameter, value, term->RelationType, (CValue*) term->Data ) )
{
satisfyingValues[ valueIdx ] = true;
}
}
break;
}
// INs
case TermDataType::ValueSet:
{
assert( term->RelationType == RelationType::In
|| term->RelationType == RelationType::NotIn );
for( size_t valueIdx = 0; valueIdx < modelParam.Values.size(); ++valueIdx )
{
CModelValue& value = modelParam.Values[ valueIdx ];
// any name must satisfy any value
bool satisfied = false;
CValueSet* valueSet = (CValueSet*) term->Data;
for( auto & vset : *valueSet )
{
if ( valueSatisfiesRelation( parameter, value, RelationType::Eq, &vset ))
{
satisfied = true;
break;
}
}
if (( RelationType::In == term->RelationType && satisfied )
|| ( RelationType::NotIn == term->RelationType && ! satisfied ))
{
satisfyingValues[ valueIdx ] = true;
}
}
break;
}
case TermDataType::ParameterName:
{
// find the param in modelData
vector< CModelParameter >::iterator found1 = _modelData.FindParameterByName( term->Parameter->Name );
assert( found1 != _modelData.Parameters.end() );
CModelParameter& modelParam1 = *found1;
unsigned int param1Idx = (unsigned int) distance( _modelData.Parameters.begin(), found1 );
CParameter parameter1 = _constrModel.Parameters[ param1Idx ];
vector< CModelParameter >::iterator found2 = _modelData.FindParameterByName( ((CParameter*) term->Data)->Name );
assert( found2 != _modelData.Parameters.end() );
CModelParameter& modelParam2 = *found2;
unsigned int param2Idx = (unsigned int) distance( _modelData.Parameters.begin(), found2 );
CParameter parameter2 = _constrModel.Parameters[ param2Idx ];
for( unsigned int value1Idx = 0; value1Idx < modelParam1.Values.size(); ++value1Idx )
{
CModelValue value1 = modelParam1.Values[ value1Idx ];
// if any name of value1 satifies the relation with any of the names of value2, values match
for( unsigned int value2Idx = 0; value2Idx < modelParam2.Values.size(); ++value2Idx )
{
CModelValue value2 = modelParam2.Values[ value2Idx ];
for( auto & name2 : value2.GetNamesForComparisons() )
{
// create temp CValue to use compare function
CValue* v2;
if ( DataType::Number == parameter2.Type )
{
v2 = new CValue( stringToNumber( name2 ));
}
else
{
v2 = new CValue( name2 );
}
if( valueSatisfiesRelation( parameter1, value1, term->RelationType, v2 ))
{
Exclusion newExcl;
newExcl.insert( make_pair( _gcdParameters[ param1Idx ], value1Idx ));
newExcl.insert( make_pair( _gcdParameters[ param2Idx ], value2Idx ));
gcdExclusions.insert( newExcl );
}
delete( v2 );
}
}
}
}
}
// satisfying values for Value and ValueSet must be now converted into exclusions
// for ParameterName terms this has been done already
if ( term->DataType != TermDataType::ParameterName )
{
// warn if no value or all values satisfy the relation
bool oneSatifies = false;
bool allSatisfy = true;
for( auto value : satisfyingValues )
{
if ( value )
{
oneSatifies = true;
}
else
{
allSatisfy = false;
}
}
if ( ! oneSatifies || allSatisfy )
{
wstring s = L"All or no values satisfy relation ";
s += (term->RawText).c_str();
_warnings.push_back( s );
}
// create exclusions
for( unsigned int idx = 0; idx < satisfyingValues.size(); ++idx )
{
if( satisfyingValues[ idx ] )
{
Exclusion newExcl;
newExcl.insert( make_pair( _gcdParameters[ paramIdx ], idx ));
gcdExclusions.insert( newExcl );
}
}
}
}