SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
IntEqModule.tpp
Go to the documentation of this file.
1 /**
2  * @file IntEqModule.tpp
3  * @author Dustin Huetter <dustin.huetter@rwth-aachen.de>
4  *
5  * @version 2014-10-17
6  * Created on 2014-10-17.
7  */
8 
9 #include "IntEqModule.h"
10 
11 #include <carl-formula/model/Assignment.h>
12 
13 //#define DEBUG_IntEqModule
14 
15 namespace smtrat
16 {
17  /**
18  * Constructors.
19  */
20 
21  template<class Settings>
22  IntEqModule<Settings>::IntEqModule( const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager ):
23  Module( _formula, _conditionals, _manager ),
24  mProc_Constraints(),
25  mRecent_Constraints(),
26  mSubstitutions(),
27  mVariables(),
28  mAuxiliaries(),
29  mTemp_Model()
30  {
31  mNew_Substitution = false;
32  }
33 
34  template<class Settings>
35  bool IntEqModule<Settings>::addCore( ModuleInput::const_iterator _subformula )
36  {
37  #ifdef DEBUG_IntEqModule
38  std::cout << "Assert: " << _subformula->formula() << std::endl;
39  #endif
40  if( _subformula->formula().is_false() )
41  {
42  FormulaSetT infSubSet;
43  infSubSet.insert( _subformula->formula() );
44  mInfeasibleSubsets.push_back( std::move( infSubSet ) );
45  return false;
46  }
47  else if( _subformula->formula().is_true() )
48  {
49  return true;
50  }
51  if( _subformula->formula().constraint().relation() == carl::Relation::EQ )
52  {
53  // Do substitutions that have already been determined and update origins accordingly
54  std::shared_ptr<std::vector<FormulaT>> origins( new std::vector<FormulaT>() );
55  origins->push_back( _subformula->formula() );
56  const ConstraintT& constr = _subformula->formula().constraint();
57  Poly new_poly( constr.lhs() );
58  if( mRecent_Constraints.empty() )
59  {
60  mRecent_Constraints.push_back( Formula_Origins() );
61  }
62  auto iter_recent = mRecent_Constraints.begin();
63  iter_recent->insert( std::make_pair( _subformula->formula(), origins ) );
64  ++iter_recent;
65  auto iter_subs = mSubstitutions.begin();
66  while( iter_subs != mSubstitutions.end() )
67  {
68  Poly tmp_poly = new_poly;
69  new_poly = carl::substitute(new_poly, (iter_subs)->first, (iter_subs)->second );
70  if( tmp_poly != new_poly )
71  {
72  auto iter_var = mVariables.find( iter_subs->first );
73  assert( iter_var != mVariables.end() );
74  *origins = std::move( merge( *origins, *( iter_var->second ) ) );
75  }
76  #ifdef DEBUG_IntEqModule
77  std::cout << "After temporary substitution: " << new_poly << std::endl;
78  #endif
79  FormulaT temp_eq( ( ConstraintT( new_poly, carl::Relation::EQ ) ) );
80  if( !temp_eq.is_true() && !temp_eq.is_false() )
81  {
82  if( *iter_subs != mSubstitutions.back() )
83  {
84  if( iter_recent != mRecent_Constraints.end() )
85  {
86  iter_recent->insert( std::make_pair( temp_eq, origins ) );
87  }
88  }
89  else
90  {
91  // Check whether a new substitution has been found since the last addCore call
92  if( mNew_Substitution )
93  {
94  Formula_Origins temp;
95  temp.emplace( temp_eq, origins );
96  mRecent_Constraints.push_back( temp );
97  mNew_Substitution = false;
98  }
99  else
100  {
101  auto iter_help = mRecent_Constraints.back().find( temp_eq );
102  if( iter_help == mRecent_Constraints.back().end() )
103  {
104  mRecent_Constraints.back().insert( std::make_pair( temp_eq, origins ) );
105  }
106  else
107  {
108  iter_help->second->insert( iter_help->second->end(), origins->begin(), origins->end() );
109  }
110  }
111  }
112  }
113  if( iter_recent != mRecent_Constraints.end() )
114  {
115  ++iter_recent;
116  }
117  else
118  {
119  break;
120  }
121  ++iter_subs;
122  }
123  #ifdef DEBUG_IntEqModule
124  std::cout << "After substitution: " << new_poly << std::endl;
125  #endif
126  FormulaT newEq( ConstraintT( new_poly, carl::Relation::EQ ) );
127  // Return UNSAT if the newly obtained constraint is unsatisfiable
128  if( newEq.is_false() )
129  {
130  #ifdef DEBUG_IntEqModule
131  std::cout << "NewEq is invalid" << std::endl;
132  #endif
133  size_t i = determine_smallest_origin( *origins );
134  FormulaSetT infSubSet;
135  collectOrigins( origins->at(i), infSubSet );
136  mInfeasibleSubsets.push_back( infSubSet );
137  return false;
138  }
139  if( newEq.is_true() )
140  {
141  return true;
142  }
143  #ifdef DEBUG_IntEqModule
144  std::cout << mRecent_Constraints << std::endl;
145  #endif
146  mProc_Constraints = mRecent_Constraints.back();
147  }
148  return true;
149  }
150 
151  template<class Settings>
152  void IntEqModule<Settings>::removeCore( ModuleInput::const_iterator _subformula )
153  {
154  #ifdef DEBUG_IntEqModule
155  std::cout << "Remove: " << _subformula->formula() << std::endl;
156  #endif
157  if( _subformula->formula().constraint().relation() == carl::Relation::EQ )
158  {
159  // Check whether _subformula was used to derive a substitution
160  auto iter_temp = mSubstitutions.begin();
161  auto iter_temp_two = mRecent_Constraints.begin();
162  bool derived_sub = false;
163  Poly maybe_sub = _subformula->formula().constraint().lhs();
164  while( iter_temp != mSubstitutions.end() )
165  {
166  if( carl::substitute(maybe_sub, iter_temp->first, iter_temp->second ) == Poly() )
167  {
168  derived_sub = true;
169  #ifdef DEBUG_IntEqModule
170  std::cout << "Is a substitution" << std::endl;
171  #endif
172  break;
173  }
174  ++iter_temp;
175  if( iter_temp_two != mRecent_Constraints.end() )
176  {
177  ++iter_temp_two;
178  }
179  }
180  if( derived_sub )
181  {
182  while( iter_temp != mSubstitutions.end() )
183  {
184  auto iter_help = mVariables.find( iter_temp->first );
185  assert( iter_help != mVariables.end() );
186  mVariables.erase( iter_help );
187  iter_temp = mSubstitutions.erase( iter_temp );
188  }
189  if( iter_temp_two != mRecent_Constraints.end() )
190  {
191  mRecent_Constraints.erase( iter_temp_two, mRecent_Constraints.end() );
192  if( mRecent_Constraints.empty() )
193  {
194  mRecent_Constraints.push_back( Formula_Origins() );
195  }
196  }
197  }
198  /* Iterate through all the processed constraints and delete all corresponding sets
199  * in the latter containing the element that has to be deleted. Delete a processed
200  * constraint if the corresponding vector is empty
201  */
202  #ifdef DEBUG_IntEqModule
203  std::cout << "Size of mRecent_Constraints: " << mRecent_Constraints.size() << std::endl;
204  std::cout << mRecent_Constraints << std::endl;
205  #endif
206  auto iter_steps = mRecent_Constraints.begin();
207  while( iter_steps != mRecent_Constraints.end() )
208  {
209  auto iter_formula = iter_steps->begin();
210  while( iter_formula != iter_steps->end() )
211  {
212  auto iter_origins = iter_formula->second->begin();
213  while( iter_origins != iter_formula->second->end() )
214  {
215  bool contains = iter_origins->contains( _subformula->formula() );
216  if( contains || *iter_origins == _subformula->formula() )
217  {
218  iter_origins = iter_formula->second->erase( iter_origins );
219  }
220  else
221  {
222  ++iter_origins;
223  }
224  }
225  if( iter_formula->second->empty() )
226  {
227  auto to_delete = iter_formula;
228  ++iter_formula;
229  iter_steps->erase( to_delete );
230  }
231  else
232  {
233  ++iter_formula;
234  }
235  }
236  if( iter_steps->empty() )
237  {
238  #ifdef DEBUG_IntEqModule
239  std::cout << "Delete all iteration steps from here on!" << std::endl;
240  #endif
241  mRecent_Constraints.erase( iter_steps, mRecent_Constraints.end() );
242  if( mRecent_Constraints.empty() )
243  {
244  mRecent_Constraints.push_back( Formula_Origins() );
245  }
246  break;
247  }
248  else
249  {
250  ++iter_steps;
251  }
252  }
253  // Now possibly delete iteration steps in the case that two
254  // adjacent steps are equal due to the fact that a deleted substitution
255  // is followed by another one. In this case two adjacent steps can be equal.
256  auto iter_recent = mRecent_Constraints.begin();
257  while( iter_recent != mRecent_Constraints.end() )
258  {
259  auto iter_next = iter_recent;
260  ++iter_next;
261  if( iter_next == mRecent_Constraints.end() )
262  {
263  break;
264  }
265  if( *iter_next == *iter_recent )
266  {
267  iter_recent = mRecent_Constraints.erase( iter_recent );
268  }
269  else
270  {
271  ++iter_recent;
272  }
273  }
274  // Do the same for the substitution data structure(s)
275  #ifdef DEBUG_IntEqModule
276  std::cout << "Size of mVariables: " << mVariables.size() << std::endl;
277  std::cout << "Size of mSubstitutions: " << mSubstitutions.size() << std::endl;
278  #endif
279  auto iter_substitutions = mVariables.begin();
280  while( iter_substitutions != mVariables.end() )
281  {
282  auto iter_origins = iter_substitutions->second->begin();
283  while( iter_origins != iter_substitutions->second->end() )
284  {
285  bool contains = iter_origins->contains( _subformula->formula() );
286  if( contains || *iter_origins == _subformula->formula() )
287  {
288  iter_origins = iter_substitutions->second->erase( iter_origins );
289  }
290  else
291  {
292  ++iter_origins;
293  }
294  }
295  if( iter_substitutions->second->empty() )
296  {
297  auto var_to_be_deleted = iter_substitutions->first;
298  auto to_delete = iter_substitutions;
299  ++iter_substitutions;
300  mVariables.erase( to_delete );
301  auto iter_help = mSubstitutions.begin();
302  while( iter_help != mSubstitutions.end() )
303  {
304  if( iter_help->first == var_to_be_deleted )
305  {
306  mSubstitutions.erase( iter_help );
307  break;
308  }
309  ++iter_help;
310  }
311  //assert( mSubstitutions.size() == mVariables.size() );
312  }
313  else
314  {
315  ++iter_substitutions;
316  }
317  }
318  if( mRecent_Constraints.back().size() == 1 )
319  {
320  // Check whether the one constraint in mRecent_Constraints.back() corresponds to a substitution
321  #ifdef DEBUG_IntEqModule
322  std::cout << "Check whether: " << mRecent_Constraints.back().begin()->first.constraint() << " corresponds to a substitution" << std::endl;
323  #endif
324  auto iter_temp = mSubstitutions.begin();
325  bool is_sub = false;
326  Poly maybe_sub = mRecent_Constraints.back().begin()->first.constraint().lhs();
327  while( iter_temp != mSubstitutions.end() )
328  {
329  #ifdef DEBUG_IntEqModule
330  std::cout << "Substitute: " << iter_temp->first << " by: " << iter_temp->second << std::endl;
331  #endif
332  if( carl::substitute(maybe_sub, iter_temp->first, iter_temp->second ) == Poly() )
333  {
334  is_sub = true;
335  break;
336  }
337  ++iter_temp;
338  }
339  #ifdef DEBUG_IntEqModule
340  std::cout << "Is a substitution: " << is_sub << std::endl;
341  #endif
342  if( is_sub )
343  {
344  mNew_Substitution = true;
345  #ifdef DEBUG_IntEqModule
346  std::cout << "mRecent_Constraints: " << mRecent_Constraints << std::endl;
347  #endif
348  }
349  }
350  #ifdef DEBUG_IntEqModule
351  std::cout << "Size of mVariables: " << mVariables.size() << std::endl;
352  std::cout << "Size of mSubstitutions: " << mSubstitutions.size() << std::endl;
353  std::cout << "Size of mRecent_Constraints: " << mRecent_Constraints.size() << std::endl;
354  #endif
355  //assert( mSubstitutions.empty() || mSubstitutions.size() == mRecent_Constraints.size() );
356  mProc_Constraints = mRecent_Constraints.back();
357  }
358  }
359 
360  template<class Settings>
361  void IntEqModule<Settings>::updateModel() const
362  {
363  mModel.clear();
364  if( solverState() == SAT )
365  {
366  mModel = mTemp_Model;
367  }
368  }
369 
370  template<class Settings>
371  Answer IntEqModule<Settings>::checkCore()
372  {
373  if( !rReceivedFormula().is_constraint_conjunction() )
374  {
375  return UNKNOWN;
376  }
377  // Check whether a module which has been called on the same instance in parallel, has found an answer
378  if( anAnswerFound() )
379  {
380  return ABORTED;
381  }
382  // Execute the algorithm until unsatisfiability or a parametric solution
383  // is detected
384  #ifdef DEBUG_IntEqModule
385  std::cout << "Determine unsatisfiability or a parametric solution:" << std::endl;
386  #endif
387  auto constr_iter = mProc_Constraints.begin();
388  while( !mProc_Constraints.empty() )
389  {
390  /* Pick the first equation for the following step
391  * and determine the coefficient of the latter with
392  * the smallest absolute value
393  */
394  const ConstraintT& curr_constr = mProc_Constraints.begin()->first.constraint();
395  if( mProc_Constraints.begin()->first.is_false() )
396  {
397  size_t i = determine_smallest_origin( *( mProc_Constraints.begin()->second ) );
398  FormulaSetT infSubSet;
399  collectOrigins( mProc_Constraints.begin()->second->at(i), infSubSet );
400  mInfeasibleSubsets.push_back( std::move( infSubSet ) );
401  return UNSAT;
402  }
403  #ifdef DEBUG_IntEqModule
404  std::cout << mProc_Constraints.begin()->first.constraint() << " was chosen." << std::endl;
405  #endif
406  std::shared_ptr<std::vector<FormulaT>> origins = mProc_Constraints.begin()->second;
407  typename Poly::PolyType ccExpanded = (typename Poly::PolyType)curr_constr.lhs();
408  auto iter_coeff = ccExpanded.begin();
409  Rational smallest_abs_value = (Rational)(*iter_coeff).coeff();
410  carl::Variable corr_var;
411  bool value_negative = false;
412  if( (*iter_coeff).is_constant() )
413  {
414  corr_var = (*(++iter_coeff)).single_variable();
415  Rational coeff = (Rational)(*iter_coeff).coeff();
416  if( coeff < 0 )
417  {
418  value_negative = true;
419  }
420  smallest_abs_value = carl::abs( coeff );
421  }
422  else
423  {
424  corr_var = (*(iter_coeff)).single_variable();
425  if( smallest_abs_value < 0 )
426  {
427  value_negative = true;
428  }
429  smallest_abs_value = carl::abs( smallest_abs_value );
430  }
431  while( iter_coeff != ccExpanded.end())
432  {
433  if( !(*iter_coeff).is_constant() )
434  {
435  Rational coeff = (Rational)(*iter_coeff).coeff();
436  carl::Variable var = (*iter_coeff).single_variable();
437  if( carl::abs(coeff) < smallest_abs_value )
438  {
439  if( coeff < 0 )
440  {
441  value_negative = true;
442  }
443  else
444  {
445  value_negative = false;
446  }
447  smallest_abs_value = carl::abs(coeff);
448  corr_var = var;
449  }
450  }
451  ++iter_coeff;
452  }
453  // Proceed with the execution of the equation elimination
454  // depending on the value of the smallest absolute value of curr_constr
455  Poly* temp = new Poly();
456  *temp = Poly();
457  Rational sign = (Rational)1;
458  if( value_negative )
459  {
460  sign = (Rational)-1;
461  }
462  iter_coeff = ccExpanded.begin();
463  if( smallest_abs_value == 1 )
464  {
465  while( iter_coeff != ccExpanded.end() )
466  {
467  if( !(*iter_coeff).is_constant() )
468  {
469  if( (*iter_coeff).single_variable() != corr_var )
470  {
471  carl::Variable var = (*iter_coeff).single_variable();
472  *temp += Poly(var)*Poly(Rational(-1)*sign*(Rational)(*iter_coeff).coeff());
473  }
474  }
475  else
476  {
477  *temp += (Rational)(-1)*sign*(Rational)(*iter_coeff).coeff();
478  }
479  ++iter_coeff;
480  }
481  #ifdef DEBUG_IntEqModule
482  std::cout << "Delete the constraint: " << mProc_Constraints.begin()->first.constraint() << std::endl;
483  #endif
484  mProc_Constraints.erase( mProc_Constraints.begin() );
485  }
486  else
487  {
488  assert( smallest_abs_value > 1 );
489  while( iter_coeff != ccExpanded.end() )
490  {
491  Rational coeff = (Rational)(*iter_coeff).coeff();
492  bool positive = (Rational)(*iter_coeff).coeff() > 0;
493  if( !(*iter_coeff).is_constant() )
494  {
495  if( (*iter_coeff).single_variable() != corr_var )
496  {
497  carl::Variable var = (*iter_coeff).single_variable();
498  if( positive )
499  {
500  *temp -= sign*Poly( Rational( carl::floor( carl::div( coeff, smallest_abs_value ) ) ) )*Poly(var);
501  }
502  else
503  {
504  *temp -= sign*Poly( (Rational)(-1)*Rational( carl::floor( carl::div( (Rational)(-1)*coeff, smallest_abs_value ) ) ) )*Poly(var);
505  }
506  }
507  }
508  else
509  {
510  if( positive )
511  {
512  *temp -= sign*Rational( carl::floor( carl::div( coeff, smallest_abs_value ) ) );
513  }
514  else
515  {
516  *temp -= sign*Rational( (-1)*carl::floor( carl::div( (Rational)(-1)*coeff, smallest_abs_value ) ) );
517  }
518  }
519  ++iter_coeff;
520  }
521  carl::Variable fresh_var = carl::fresh_variable( carl::VariableType::VT_INT );
522  mAuxiliaries.insert( fresh_var );
523  *temp += Poly(fresh_var);
524  }
525  // Substitute the reformulation of the found variable for all occurences
526  // of this variable in equations of mProc_Constraints
527  #ifdef DEBUG_IntEqModule
528  std::cout << "Substitute " << corr_var << " by: " << *temp << std::endl;
529  #endif
530  std::pair<carl::Variable, Poly>* new_pair = new std::pair<carl::Variable, Poly>(corr_var, *temp );
531  auto iter_help = mVariables.find( new_pair->first );
532  mNew_Substitution = true;
533  if( iter_help == mVariables.end() )
534  {
535  mSubstitutions.push_back( *new_pair );
536  mVariables[ new_pair->first ] = origins;
537  }
538  Formula_Origins temp_proc_constraints;
539  constr_iter = mProc_Constraints.begin();
540  while( constr_iter != mProc_Constraints.end() )
541  {
542  Poly new_poly = constr_iter->first.constraint().lhs();
543  Poly tmp_poly = new_poly;
544  new_poly = carl::substitute(new_poly, new_pair->first, new_pair->second );
545  std::shared_ptr<std::vector<FormulaT>> origins_new = constr_iter->second;
546  if( new_poly != tmp_poly )
547  {
548  auto iter_help = mVariables.find( new_pair->first );
549  assert( iter_help != mVariables.end() );
550  *origins_new = ( std::move( merge( *( iter_help->second ), *( constr_iter->second ) ) ) );
551  }
552  FormulaT newEq( ConstraintT( new_poly, carl::Relation::EQ ) );
553  // Check whether newEq is unsatisfiable
554  if( newEq.is_false() )
555  {
556  #ifdef DEBUG_IntEqModule
557  std::cout << "Constraint is invalid!" << std::endl;
558  #endif
559  size_t i = determine_smallest_origin( *origins_new );
560  FormulaSetT infSubSet;
561  collectOrigins( origins_new->at(i), infSubSet );
562  mInfeasibleSubsets.push_back( infSubSet );
563  return UNSAT;
564  }
565  auto iter_help = temp_proc_constraints.find( newEq );
566  if( iter_help == temp_proc_constraints.end() )
567  {
568  temp_proc_constraints.emplace( newEq, origins_new );
569  }
570  else
571  {
572  iter_help->second->insert( iter_help->second->end(), origins_new->begin(), origins_new->end() );
573  }
574  ++constr_iter;
575  }
576  mProc_Constraints = temp_proc_constraints;
577  if( !mProc_Constraints.empty() )
578  {
579  mRecent_Constraints.push_back( mProc_Constraints );
580  }
581  #ifdef DEBUG_IntEqModule
582  std::cout << mRecent_Constraints << std::endl;
583  #endif
584  }
585  #ifdef DEBUG_IntEqModule
586  std::cout << "Substitute in the received inequalities:" << std::endl;
587  #endif
588  auto iter_formula = rReceivedFormula().begin();
589  // Iterate through the received constraints and remove the equations
590  // by substituting the expressions according to mSubstitutions in the inequalities
591  // and ignoring the equations
592  while( iter_formula != rReceivedFormula().end() )
593  {
594  #ifdef DEBUG_IntEqModule
595  //cout << "Substitute in: " << (*iter_formula).formula().constraint() << std::endl;
596  #endif
597  if( (*iter_formula).formula().constraint().relation() == carl::Relation::LEQ || (*iter_formula).formula().constraint().relation() == carl::Relation::NEQ )
598  {
599  const smtrat::ConstraintT constr = (*iter_formula).formula().constraint();
600  Poly new_poly = constr.lhs();
601  std::shared_ptr<std::vector<FormulaT>> origins( new std::vector<FormulaT>() );
602  origins->push_back( (*iter_formula).formula() );
603  auto iter_subs = mSubstitutions.begin();
604  while( iter_subs != mSubstitutions.end() )
605  {
606  Poly tmp_poly = new_poly;
607  new_poly = carl::substitute(new_poly, (iter_subs)->first, (iter_subs)->second );
608  if( tmp_poly != new_poly )
609  {
610  auto iter_help = mVariables.find( iter_subs->first );
611  assert( iter_help != mVariables.end() );
612  *origins = std::move( merge( *origins, *( iter_help->second ) ) );
613  }
614  ++iter_subs;
615  }
616  #ifdef DEBUG_IntEqModule
617  //cout << "After substitution: " << new_poly << std::endl;
618  #endif
619  FormulaT formula_passed( ConstraintT( new_poly, (*iter_formula).formula().constraint().relation() ) );
620  if( formula_passed.is_false() )
621  {
622  #ifdef DEBUG_IntEqModule
623  std::cout << "The obtained formula is unsatisfiable" << std::endl;
624  std::cout << "Origins: " << *origins << std::endl;
625  #endif
626  size_t i = determine_smallest_origin( *origins );
627  FormulaSetT infSubSet;
628  collectOrigins( origins->at(i), infSubSet );
629  mInfeasibleSubsets.push_back( std::move( infSubSet ) );
630  return UNSAT;
631  }
632  addConstraintToInform( formula_passed );
633  addSubformulaToPassedFormula( formula_passed, origins );
634  }
635  else if( mSubstitutions.empty() )
636  {
637  addReceivedSubformulaToPassedFormula( iter_formula );
638  }
639  ++iter_formula;
640  }
641  #ifdef DEBUG_IntEqModule
642  std::cout << "Run LRAModule" << std::endl;
643  #endif
644  Answer ans = runBackends();
645  if( ans == UNSAT )
646  {
647  getInfeasibleSubsets();
648  }
649  else if( ans == SAT )
650  {
651  if( !constructSolution() )
652  {
653  ans = UNKNOWN;
654  }
655  }
656  return ans;
657  }
658 
659  template<class Settings>
660  bool IntEqModule<Settings>::constructSolution()
661  {
662  mTemp_Model.clear();
663  Module::getBackendsModel();
664  auto iter_model = mModel.begin();
665  while( iter_model != mModel.end() )
666  {
667  mTemp_Model.emplace(iter_model->first, iter_model->second);
668  ++iter_model;
669  }
670  std::map<carl::Variable, Rational> temp_map;
671  bool all_rational;
672  all_rational = getRationalAssignmentsFromModel( mTemp_Model, temp_map );
673  assert( all_rational );
674  #ifdef DEBUG_IntEqModule
675  std::cout << "Model: " << mModel << std::endl;
676  std::cout << "Temp Model: " << mTemp_Model << std::endl;
677  std::cout << "Auxiliaries: " << mAuxiliaries << std::endl;
678  #endif
679  // Determine the assignments of the variables that haven't been passed
680  // to the backends i.e. all variables for which substitutions exist
681  auto iter_vars = mSubstitutions.end();
682  if( mSubstitutions.empty() )
683  {
684  return true;
685  }
686  else
687  {
688  --iter_vars;
689  }
690  while( true )
691  {
692  #ifdef DEBUG_IntEqModule
693  std::cout << "Substitution: " << iter_vars->first << " by " << iter_vars->second << std::endl;
694  #endif
695  Poly value = iter_vars->second;
696  value = carl::substitute(value, temp_map);
697  assert( value.is_constant() );
698  temp_map[ iter_vars->first ] = (Rational)value.constant_part();
699  ModelValue assignment = carl::createSubstitution<Rational,Poly,ModelPolynomialSubstitution>( value );
700  mTemp_Model.emplace(iter_vars->first, assignment);
701  if( iter_vars != mSubstitutions.begin() )
702  {
703  --iter_vars;
704  }
705  else
706  {
707  break;
708  }
709  }
710  // Delete the assignments of the auxiliary variables
711  auto iter_ass = mTemp_Model.begin();
712  while( iter_ass != mTemp_Model.end() )
713  {
714  auto iter_help = mAuxiliaries.find( iter_ass->first.asVariable() );
715  if( iter_help == mAuxiliaries.end() )
716  {
717  ++iter_ass;
718  }
719  else
720  {
721  auto to_delete = iter_ass;
722  ++iter_ass;
723  mTemp_Model.erase( to_delete );
724  }
725  }
726  #ifdef DEBUG_IntEqModule
727  std::cout << "Temp Model: " << mTemp_Model << std::endl;
728  #endif
729  temp_map = std::map<carl::Variable, Rational>();
730  all_rational = getRationalAssignmentsFromModel( mTemp_Model, temp_map );
731  #ifdef DEBUG_IntEqModule
732  std::cout << "temp_map: " << temp_map << std::endl;
733  #endif
734  auto iter = rReceivedFormula().begin();
735  while( iter != rReceivedFormula().end() )
736  {
737  if( carl::satisfied_by( iter->formula().constraint(),temp_map ) != 1 )
738  {
739  return false;
740  #ifdef DEBUG_IntEqModule
741  std::cout << iter->formula() << std::endl;
742  #endif
743  }
744  ++iter;
745  }
746  return true;
747  }
748 }
749 
750