| 1977 | } |
| 1978 | |
| 1979 | void Engine::applySplit( const PiecewiseLinearCaseSplit &split ) |
| 1980 | { |
| 1981 | ENGINE_LOG( "" ); |
| 1982 | ENGINE_LOG( "Applying a split. " ); |
| 1983 | |
| 1984 | DEBUG( _tableau->verifyInvariants() ); |
| 1985 | |
| 1986 | List<Tightening> bounds = split.getBoundTightenings(); |
| 1987 | List<Equation> equations = split.getEquations(); |
| 1988 | |
| 1989 | // We assume that case splits only apply new bounds but do not apply |
| 1990 | // new equations. This can always be made possible. |
| 1991 | if ( _lpSolverType != LPSolverType::NATIVE && equations.size() > 0 ) |
| 1992 | throw MarabouError( MarabouError::FEATURE_NOT_YET_SUPPORTED, |
| 1993 | "Can only update bounds when using non-native" |
| 1994 | "simplex engine!" ); |
| 1995 | |
| 1996 | for ( auto &equation : equations ) |
| 1997 | { |
| 1998 | /* |
| 1999 | First, adjust the equation if any variables have been merged. |
| 2000 | E.g., if the equation is x1 + x2 + x3 = 0, and x1 and x2 have been |
| 2001 | merged, the equation becomes 2x1 + x3 = 0 |
| 2002 | */ |
| 2003 | for ( auto &addend : equation._addends ) |
| 2004 | addend._variable = _tableau->getVariableAfterMerging( addend._variable ); |
| 2005 | |
| 2006 | List<Equation::Addend>::iterator addend; |
| 2007 | List<Equation::Addend>::iterator otherAddend; |
| 2008 | |
| 2009 | addend = equation._addends.begin(); |
| 2010 | while ( addend != equation._addends.end() ) |
| 2011 | { |
| 2012 | otherAddend = addend; |
| 2013 | ++otherAddend; |
| 2014 | |
| 2015 | while ( otherAddend != equation._addends.end() ) |
| 2016 | { |
| 2017 | if ( otherAddend->_variable == addend->_variable ) |
| 2018 | { |
| 2019 | addend->_coefficient += otherAddend->_coefficient; |
| 2020 | otherAddend = equation._addends.erase( otherAddend ); |
| 2021 | } |
| 2022 | else |
| 2023 | ++otherAddend; |
| 2024 | } |
| 2025 | |
| 2026 | if ( FloatUtils::isZero( addend->_coefficient ) ) |
| 2027 | addend = equation._addends.erase( addend ); |
| 2028 | else |
| 2029 | ++addend; |
| 2030 | } |
| 2031 | |
| 2032 | /* |
| 2033 | In the general case, we just add the new equation to the tableau. |
| 2034 | However, we also support a very common case: equations of the form |
| 2035 | x1 = x2, which are common, e.g., with ReLUs. For these equations we |
| 2036 | may be able to merge two columns of the tableau. |
no test coverage detected