Skip to content

Commit c732d56

Browse files
Some fixes in AbsoluteValueConstraint and the preprocessor (#329)
* unserialize an absolute value constraint * reduce the tolerance of abs and relu constraints * abs constraint dumping * preprocessor: declare UNSAT based on bounds from PLCs * indentation * higher precision * review comments Co-authored-by: Guy Katz <guykatz@cs.huji.ac.il>
1 parent adbe073 commit c732d56

File tree

10 files changed

+119
-22
lines changed

10 files changed

+119
-22
lines changed

src/configuration/GlobalConfiguration.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ const unsigned GlobalConfiguration::PSE_ITERATIONS_BEFORE_RESET = 1000;
6767
const double GlobalConfiguration::PSE_GAMMA_ERROR_THRESHOLD = 0.001;
6868
const double GlobalConfiguration::PSE_GAMMA_UPDATE_TOLERANCE = 0.000000001;
6969

70-
const double GlobalConfiguration::RELU_CONSTRAINT_COMPARISON_TOLERANCE = 0.001;
71-
const double GlobalConfiguration::ABS_CONSTRAINT_COMPARISON_TOLERANCE = 0.001;
70+
const double GlobalConfiguration::RELU_CONSTRAINT_COMPARISON_TOLERANCE = 0.00001;
71+
const double GlobalConfiguration::ABS_CONSTRAINT_COMPARISON_TOLERANCE = 0.00001;
7272

7373
const bool GlobalConfiguration::ONLY_AUX_INITIAL_BASIS = false;
7474

src/engine/AbsoluteValueConstraint.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ AbsoluteValueConstraint::AbsoluteValueConstraint( unsigned b, unsigned f )
3030
setPhaseStatus( PhaseStatus::PHASE_NOT_FIXED );
3131
}
3232

33+
AbsoluteValueConstraint::AbsoluteValueConstraint( const String &serializedAbs )
34+
: _haveEliminatedVariables( false )
35+
{
36+
String constraintType = serializedAbs.substring( 0, 13 );
37+
ASSERT( constraintType == String( "absoluteValue" ) );
38+
39+
// Remove the constraint type in serialized form
40+
String serializedValues = serializedAbs.substring( 14, serializedAbs.length() - 14 );
41+
List<String> values = serializedValues.tokenize( "," );
42+
43+
ASSERT( values.size() == 2 );
44+
45+
auto var = values.begin();
46+
_f = atoi( var->ascii() );
47+
++var;
48+
_b = atoi( var->ascii() );
49+
50+
setPhaseStatus( PhaseStatus::PHASE_NOT_FIXED );
51+
}
52+
3353
PiecewiseLinearFunctionType AbsoluteValueConstraint::getType() const
3454
{
3555
return PiecewiseLinearFunctionType::ABSOLUTE_VALUE;
@@ -274,6 +294,23 @@ void AbsoluteValueConstraint::eliminateVariable( unsigned variable, double /* fi
274294
_haveEliminatedVariables = true;
275295
}
276296

297+
void AbsoluteValueConstraint::dump( String &output ) const
298+
{
299+
output = Stringf( "AbsoluteValueCosntraint: x%u = Abs( x%u ). Active? %s. PhaseStatus = %u (%s).\n",
300+
_f, _b,
301+
_constraintActive ? "Yes" : "No",
302+
_phaseStatus, phaseToString( _phaseStatus ).ascii()
303+
);
304+
305+
output += Stringf( "b in [%s, %s], ",
306+
_lowerBounds.exists( _b ) ? Stringf( "%lf", _lowerBounds[_b] ).ascii() : "-inf",
307+
_upperBounds.exists( _b ) ? Stringf( "%lf", _upperBounds[_b] ).ascii() : "inf" );
308+
309+
output += Stringf( "f in [%s, %s]",
310+
_lowerBounds.exists( _f ) ? Stringf( "%lf", _lowerBounds[_f] ).ascii() : "-inf",
311+
_upperBounds.exists( _f ) ? Stringf( "%lf", _upperBounds[_f] ).ascii() : "inf" );
312+
}
313+
277314
void AbsoluteValueConstraint::updateVariableIndex( unsigned oldIndex, unsigned newIndex )
278315
{
279316
ASSERT( oldIndex == _b || oldIndex == _f );
@@ -429,6 +466,24 @@ void AbsoluteValueConstraint::fixPhaseIfNeeded()
429466
}
430467
}
431468

469+
String AbsoluteValueConstraint::phaseToString( PhaseStatus phase )
470+
{
471+
switch ( phase )
472+
{
473+
case PHASE_NOT_FIXED:
474+
return "PHASE_NOT_FIXED";
475+
476+
case PHASE_POSITIVE:
477+
return "PHASE_POSITIVE";
478+
479+
case PHASE_NEGATIVE:
480+
return "PHASE_NEGATIVE";
481+
482+
default:
483+
return "UNKNOWN";
484+
}
485+
};
486+
432487
void AbsoluteValueConstraint::setPhaseStatus( PhaseStatus phaseStatus )
433488
{
434489
_phaseStatus = phaseStatus;

src/engine/AbsoluteValueConstraint.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class AbsoluteValueConstraint : public PiecewiseLinearConstraint
3333
f = | b |
3434
*/
3535
AbsoluteValueConstraint( unsigned b, unsigned f );
36+
AbsoluteValueConstraint( const String &serializedAbs );
3637

3738
/*
3839
Get the type of this constraint.
@@ -126,6 +127,11 @@ class AbsoluteValueConstraint : public PiecewiseLinearConstraint
126127
*/
127128
void getEntailedTightenings( List<Tightening> &tightenings ) const;
128129

130+
/*
131+
Dump the current state of the constraint.
132+
*/
133+
void dump( String &output ) const;
134+
129135
/*
130136
For preprocessing: get any auxiliary equations that this
131137
constraint would like to add to the equation pool. In the ReLU
@@ -163,6 +169,8 @@ class AbsoluteValueConstraint : public PiecewiseLinearConstraint
163169
PhaseStatus _phaseStatus;
164170
void setPhaseStatus( PhaseStatus phaseStatus );
165171

172+
static String phaseToString( PhaseStatus phase );
173+
166174
/*
167175
The two case splits.
168176
*/

src/engine/Engine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ bool Engine::applyValidConstraintCaseSplit( PiecewiseLinearConstraint *constrain
15521552
String constraintString;
15531553
constraint->dump( constraintString );
15541554
ENGINE_LOG( Stringf( "A constraint has become valid. Dumping constraint: %s",
1555-
constraintString.ascii() ).ascii() );
1555+
constraintString.ascii() ).ascii() );
15561556

15571557
constraint->setActiveConstraint( false );
15581558
PiecewiseLinearCaseSplit validSplit = constraint->getValidCaseSplit();

src/engine/InputQuery.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,11 @@ void InputQuery::saveQuery( const String &fileName )
321321

322322
// Lower Bounds
323323
for ( const auto &lb : _lowerBounds )
324-
queryFile->write( Stringf( "\n%d,%f", lb.first, lb.second ) );
324+
queryFile->write( Stringf( "\n%d,%.10f", lb.first, lb.second ) );
325325

326326
// Upper Bounds
327327
for ( const auto &ub : _upperBounds )
328-
queryFile->write( Stringf( "\n%d,%f", ub.first, ub.second ) );
328+
queryFile->write( Stringf( "\n%d,%.10f", ub.first, ub.second ) );
329329

330330
// Equations
331331
i = 0;
@@ -338,9 +338,9 @@ void InputQuery::saveQuery( const String &fileName )
338338
queryFile->write( Stringf( "%01d,", e._type ) );
339339

340340
// Equation scalar
341-
queryFile->write( Stringf( "%f", e._scalar ) );
341+
queryFile->write( Stringf( "%.10f", e._scalar ) );
342342
for ( const auto &a : e._addends )
343-
queryFile->write( Stringf( ",%u,%f", a._variable, a._coefficient ) );
343+
queryFile->write( Stringf( ",%u,%.10f", a._variable, a._coefficient ) );
344344

345345
++i;
346346
}

src/engine/Marabou.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void Marabou::prepareInputQuery()
7272

7373
printf( "InputQuery: %s\n", inputQueryFilePath.ascii() );
7474
_inputQuery = QueryLoader::loadQuery( inputQueryFilePath );
75+
_inputQuery.constructNetworkLevelReasoner();
7576
}
7677
else
7778
{
@@ -104,21 +105,10 @@ void Marabou::prepareInputQuery()
104105
printf( "Property: None\n" );
105106

106107
printf( "\n" );
107-
108-
/*
109-
Step 3: extract options
110-
*/
111-
int splitThreshold = Options::get()->getInt( Options::SPLIT_THRESHOLD );
112-
if ( splitThreshold < 0 )
113-
{
114-
printf( "Invalid constraint violation threshold value %d,"
115-
" using default value %u.\n\n", splitThreshold,
116-
GlobalConfiguration::CONSTRAINT_VIOLATION_THRESHOLD );
117-
splitThreshold = GlobalConfiguration::CONSTRAINT_VIOLATION_THRESHOLD;
118-
}
119-
_engine.setConstraintViolationThreshold( splitThreshold );
120108
}
121109

110+
extractSplittingThreshold();
111+
122112
String queryDumpFilePath = Options::get()->getString( Options::QUERY_DUMP_FILE );
123113
if ( queryDumpFilePath.length() > 0 )
124114
{
@@ -203,6 +193,19 @@ void Marabou::displayResults( unsigned long long microSecondsElapsed ) const
203193
}
204194
}
205195

196+
void Marabou::extractSplittingThreshold()
197+
{
198+
int splitThreshold = Options::get()->getInt( Options::SPLIT_THRESHOLD );
199+
if ( splitThreshold < 0 )
200+
{
201+
printf( "Invalid constraint violation threshold value %d,"
202+
" using default value %u.\n\n", splitThreshold,
203+
GlobalConfiguration::CONSTRAINT_VIOLATION_THRESHOLD );
204+
splitThreshold = GlobalConfiguration::CONSTRAINT_VIOLATION_THRESHOLD;
205+
}
206+
_engine.setConstraintViolationThreshold( splitThreshold );
207+
}
208+
206209
//
207210
// Local Variables:
208211
// compile-command: "make -C ../.. "

src/engine/Marabou.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ class Marabou
3535
InputQuery _inputQuery;
3636

3737
/*
38-
Extract the input files: network and property, and use them
39-
to generate the input query
38+
Extract the options and input files (network and property), and
39+
use them to generate the input query
4040
*/
4141
void prepareInputQuery();
42+
void extractSplittingThreshold();
4243

4344
/*
4445
Invoke the engine to solve the input query

src/engine/Preprocessor.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,13 @@ bool Preprocessor::processConstraints()
439439
GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD ) )
440440
_preprocessed.setUpperBound( tightening._variable,
441441
_preprocessed.getLowerBound( tightening._variable ) );
442+
443+
if ( FloatUtils::gt( _preprocessed.getLowerBound( tightening._variable ),
444+
_preprocessed.getUpperBound( tightening._variable ),
445+
GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD ) )
446+
{
447+
throw InfeasibleQueryException();
448+
}
442449
}
443450
}
444451

src/engine/tests/Test_AbsoluteValueConstraint.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,25 @@ class AbsoluteValueConstraintTestSuite : public CxxTest::TestSuite
10481048
for ( const auto &it : a )
10491049
TS_ASSERT( b.exists( it ) );
10501050
}
1051+
1052+
void test_serialize_and_unserialize()
1053+
{
1054+
unsigned b = 42;
1055+
unsigned f = 7;
1056+
1057+
AbsoluteValueConstraint originalAbs( b, f );
1058+
originalAbs.notifyLowerBound( b, -10 );
1059+
originalAbs.notifyUpperBound( f, 5 );
1060+
originalAbs.notifyUpperBound( f, 5 );
1061+
1062+
String originalSerialized = originalAbs.serializeToString();
1063+
AbsoluteValueConstraint recoveredAbs( originalSerialized );
1064+
1065+
TS_ASSERT_EQUALS( originalAbs.serializeToString(),
1066+
recoveredAbs.serializeToString() );
1067+
1068+
TS_ASSERT_EQUALS( originalSerialized, "absoluteValue,7,42" );
1069+
}
10511070
};
10521071

10531072
//

src/query_loader/QueryLoader.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ InputQuery QueryLoader::loadQuery( const String &fileName )
209209
{
210210
constraint = new MaxConstraint( serializeConstraint );
211211
}
212+
else if ( coType == "absoluteValue" )
213+
{
214+
constraint = new AbsoluteValueConstraint( serializeConstraint );
215+
}
212216
else
213217
{
214218
throw MarabouError( MarabouError::UNSUPPORTED_PIECEWISE_CONSTRAINT, Stringf( "Unsupported piecewise constraint: %s\n", coType.ascii() ).ascii() );

0 commit comments

Comments
 (0)