SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
SplitSOSModule.tpp
Go to the documentation of this file.
1 /**
2  * @file SplitSOSModule.tpp
3  * @author Florian Corzilius <corzilius@cs.rwth-aachen.de>
4  *
5  * @version 2015-09-10
6  * Created on 2015-09-10.
7  */
8 
9 #include "SplitSOSModule.h"
10 
11 #include <carl-arith/poly/umvpoly/functions/SoSDecomposition.h>
12 
13 namespace smtrat
14 {
15  template<class Settings>
16  SplitSOSModule<Settings>::SplitSOSModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
17  PModule( _formula, _conditionals, _manager )
18  {
19  splitSOSFunction = std::bind(&SplitSOSModule<Settings>::splitSOS, this, std::placeholders::_1);
20  }
21 
22  template<class Settings>
23  SplitSOSModule<Settings>::~SplitSOSModule()
24  {}
25 
26  template<class Settings>
27  Answer SplitSOSModule<Settings>::checkCore()
28  {
29  if (is_minimizing()) { // TODO optimization possible?
30  SMTRAT_LOG_ERROR("smtrat.splitsos", "Optimization not supported");
31  assert(false);
32  }
33 
34  auto receivedFormula = firstUncheckedReceivedSubformula();
35  while( receivedFormula != rReceivedFormula().end() )
36  {
37  FormulaT formula = receivedFormula->formula();
38  if( receivedFormula->formula().property_holds(carl::PROP_CONTAINS_NONLINEAR_POLYNOMIAL) )
39  {
40  formula = carl::visit_result( receivedFormula->formula(), splitSOSFunction );
41  }
42  if( formula.is_false() )
43  {
44  mInfeasibleSubsets.clear();
45  FormulaSetT infeasibleSubset;
46  infeasibleSubset.insert( receivedFormula->formula() );
47  mInfeasibleSubsets.push_back( std::move(infeasibleSubset) );
48  return UNSAT;
49  }
50  if( !formula.is_true() )
51  {
52  addSubformulaToPassedFormula( formula, receivedFormula->formula() );
53  }
54  ++receivedFormula;
55  }
56  Answer ans = runBackends();
57  if( ans == UNSAT )
58  {
59  mInfeasibleSubsets.clear();
60  FormulaSetT infeasibleSubset;
61  // TODO: compute a better infeasible subset
62  for( auto subformula = rReceivedFormula().begin(); subformula != rReceivedFormula().end(); ++subformula )
63  {
64  infeasibleSubset.insert( subformula->formula() );
65  }
66  mInfeasibleSubsets.push_back( std::move(infeasibleSubset) );
67  }
68  return ans;
69  }
70 
71  template<typename Settings>
72  FormulaT SplitSOSModule<Settings>::splitSOS( const FormulaT& formula )
73  {
74  if( formula.type() == carl::FormulaType::CONSTRAINT )
75  {
76  std::vector<std::pair<Rational,Poly>> sosDec;
77  bool lcoeffNeg = carl::is_negative( formula.constraint().lhs().lcoeff() );
78  if( lcoeffNeg ) {
79  sosDec = carl::sos_decomposition(-formula.constraint().lhs());
80  }
81  else
82  {
83  sosDec = carl::sos_decomposition(formula.constraint().lhs());
84  }
85  if( sosDec.size() <= 1 )
86  {
87  return formula;
88  }
89  carl::Relation rel = carl::Relation::EQ;
90  carl::FormulaType boolOp = carl::FormulaType::AND;
91  switch( formula.constraint().relation() )
92  {
93  case carl::Relation::EQ:
94  if( formula.constraint().lhs().has_constant_term() )
95  return FormulaT( carl::FormulaType::FALSE );
96  break;
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;
102  break;
103  case carl::Relation::LEQ:
104  if( lcoeffNeg )
105  return FormulaT( carl::FormulaType::TRUE );
106  else if( formula.constraint().lhs().has_constant_term() )
107  return FormulaT( carl::FormulaType::FALSE );
108  break;
109  case carl::Relation::LESS:
110  if( lcoeffNeg )
111  {
112  if( formula.constraint().lhs().has_constant_term() )
113  return FormulaT( carl::FormulaType::TRUE );
114  rel = carl::Relation::NEQ;
115  boolOp = carl::FormulaType::OR;
116  }
117  else
118  return FormulaT(carl::FormulaType::FALSE);
119  break;
120  case carl::Relation::GEQ:
121  if( !lcoeffNeg )
122  return FormulaT( carl::FormulaType::TRUE );
123  else if( formula.constraint().lhs().has_constant_term() )
124  return FormulaT( carl::FormulaType::FALSE );
125  break;
126  default:
127  assert( formula.constraint().relation() == carl::Relation::GREATER );
128  if( lcoeffNeg )
129  return FormulaT( carl::FormulaType::FALSE );
130  else
131  {
132  if( formula.constraint().lhs().has_constant_term() )
133  return FormulaT( carl::FormulaType::TRUE );
134  rel = carl::Relation::NEQ;
135  boolOp = carl::FormulaType::OR;
136  }
137  }
138  FormulasT subformulas;
139  for( auto it = sosDec.begin(); it != sosDec.end(); ++it )
140  {
141  subformulas.emplace_back( it->second, rel );
142  }
143  return FormulaT( boolOp, subformulas );
144  }
145  return formula;
146  }
147 }
148 
149