2 * @file SplitSOSModule.tpp
3 * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
6 * Created on 2015-09-10.
9 #include "SplitSOSModule.h"
11 #include <carl-arith/poly/umvpoly/functions/SoSDecomposition.h>
15 template<class Settings>
16 SplitSOSModule<Settings>::SplitSOSModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
17 PModule( _formula, _conditionals, _manager )
19 splitSOSFunction = std::bind(&SplitSOSModule<Settings>::splitSOS, this, std::placeholders::_1);
22 template<class Settings>
23 SplitSOSModule<Settings>::~SplitSOSModule()
26 template<class Settings>
27 Answer SplitSOSModule<Settings>::checkCore()
29 if (is_minimizing()) { // TODO optimization possible?
30 SMTRAT_LOG_ERROR("smtrat.splitsos", "Optimization not supported");
34 auto receivedFormula = firstUncheckedReceivedSubformula();
35 while( receivedFormula != rReceivedFormula().end() )
37 FormulaT formula = receivedFormula->formula();
38 if( receivedFormula->formula().property_holds(carl::PROP_CONTAINS_NONLINEAR_POLYNOMIAL) )
40 formula = carl::visit_result( receivedFormula->formula(), splitSOSFunction );
42 if( formula.is_false() )
44 mInfeasibleSubsets.clear();
45 FormulaSetT infeasibleSubset;
46 infeasibleSubset.insert( receivedFormula->formula() );
47 mInfeasibleSubsets.push_back( std::move(infeasibleSubset) );
50 if( !formula.is_true() )
52 addSubformulaToPassedFormula( formula, receivedFormula->formula() );
56 Answer ans = runBackends();
59 mInfeasibleSubsets.clear();
60 FormulaSetT infeasibleSubset;
61 // TODO: compute a better infeasible subset
62 for( auto subformula = rReceivedFormula().begin(); subformula != rReceivedFormula().end(); ++subformula )
64 infeasibleSubset.insert( subformula->formula() );
66 mInfeasibleSubsets.push_back( std::move(infeasibleSubset) );
71 template<typename Settings>
72 FormulaT SplitSOSModule<Settings>::splitSOS( const FormulaT& formula )
74 if( formula.type() == carl::FormulaType::CONSTRAINT )
76 std::vector<std::pair<Rational,Poly>> sosDec;
77 bool lcoeffNeg = carl::is_negative( formula.constraint().lhs().lcoeff() );
79 sosDec = carl::sos_decomposition(-formula.constraint().lhs());
83 sosDec = carl::sos_decomposition(formula.constraint().lhs());
85 if( sosDec.size() <= 1 )
89 carl::Relation rel = carl::Relation::EQ;
90 carl::FormulaType boolOp = carl::FormulaType::AND;
91 switch( formula.constraint().relation() )
93 case carl::Relation::EQ:
94 if( formula.constraint().lhs().has_constant_term() )
95 return FormulaT( carl::FormulaType::FALSE );
97 case carl::Relation::NEQ:
98 if( formula.constraint().lhs().has_constant_term() )
99 return FormulaT( carl::FormulaType::TRUE );
100 rel = carl::Relation::NEQ;
101 boolOp = carl::FormulaType::OR;
103 case carl::Relation::LEQ:
105 return FormulaT( carl::FormulaType::TRUE );
106 else if( formula.constraint().lhs().has_constant_term() )
107 return FormulaT( carl::FormulaType::FALSE );
109 case carl::Relation::LESS:
112 if( formula.constraint().lhs().has_constant_term() )
113 return FormulaT( carl::FormulaType::TRUE );
114 rel = carl::Relation::NEQ;
115 boolOp = carl::FormulaType::OR;
118 return FormulaT(carl::FormulaType::FALSE);
120 case carl::Relation::GEQ:
122 return FormulaT( carl::FormulaType::TRUE );
123 else if( formula.constraint().lhs().has_constant_term() )
124 return FormulaT( carl::FormulaType::FALSE );
127 assert( formula.constraint().relation() == carl::Relation::GREATER );
129 return FormulaT( carl::FormulaType::FALSE );
132 if( formula.constraint().lhs().has_constant_term() )
133 return FormulaT( carl::FormulaType::TRUE );
134 rel = carl::Relation::NEQ;
135 boolOp = carl::FormulaType::OR;
138 FormulasT subformulas;
139 for( auto it = sosDec.begin(); it != sosDec.end(); ++it )
141 subformulas.emplace_back( it->second, rel );
143 return FormulaT( boolOp, subformulas );