SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
NRAILModule.tpp
Go to the documentation of this file.
1 /**
2  * @file Abstract.cpp
3  * @author YOUR NAME <YOUR EMAIL ADDRESS>
4  *
5  * @version 2018-07-12
6  * Created on 2018-07-12.
7  */
8 
9 #include "NRAILModule.h"
10 #include "MonomialMappingByVariablePool.h"
11 #include "stdlib.h"
12 #include "factory/AxiomFactory.h"
13 #include "LOG.h"
14 #include <algorithm>
15 #include <iostream>
16 #include <random>
17 #include <vector>
18 #include "boost/random.hpp"
19 #include "boost/generator_iterator.hpp"
20 
21 
22 namespace smtrat
23 {
24  template<class Settings>
25  NRAILModule<Settings>::NRAILModule(const ModuleInput* _formula, Conditionals& _conditionals, Manager* _manager):
26  Module( _formula, _conditionals, _manager )
27  {
28  linearizeSubformulaFunction = std::bind(&NRAILModule<Settings>::linearizeSubformula, this, std::placeholders::_1);
29  }
30  //mLRAFormula( new ModuleInput())
31 
32  template<class Settings>
33  NRAILModule<Settings>::~NRAILModule()
34  {}
35 
36  template<class Settings>
37  bool NRAILModule<Settings>::informCore( const FormulaT& )
38  {
39  // Your code.
40  return true; // This should be adapted according to your implementation.
41  }
42 
43  template<class Settings>
44  void NRAILModule<Settings>::init()
45  {}
46 
47  int zVariableCounter = 0;
48  std::string VariableName = "z_";
49  ModuleInput* originalFormula( new ModuleInput());
50 
51  /**
52  * create variables and each time increment the suffix e.g., z_0, z_1, etc.
53  * @return a carl Variable object
54  */
55  carl::Variable createZVariable(){
56  std::string GeneratedVariableName = VariableName + std::to_string(zVariableCounter++);
57  return carl::fresh_real_variable(GeneratedVariableName);
58  }
59 
60  /**
61  * create a square of the variable
62  * @param Variable a carl Variable object e.g., x_0
63  * @return a monomial object e.g., x_0^2
64  */
65  carl::Monomial::Arg createSquareOfVariable(carl::Variable Variable){
66  return carl::createMonomial((Variable), (carl::exponent)2);
67  }
68 
69  /**
70  * Insert the variable as key with monomial as value into the map
71  * The map is singeltone
72  * @param GeneratedVariable
73  * @param monomial
74  */
75  void insertIntoMap(carl::Variable GeneratedVariable, carl::Monomial::Arg monomial) {
76  if (smtrat::LOG::getInstance().isDebugEnabled()) {
77  std::cout << "inserting the monomial into the map:";
78  std::cout << "\n";
79  std::cout << "GeneratedVariable: " << GeneratedVariable << ", monomial: " << monomial;
80  std::cout << "\n";
81  }
82  smtrat::MonomialMappingByVariablePool::getInstance().insertMonomialMapping(GeneratedVariable, monomial);
83  }
84 
85  int divisionOfExponentByTwo(int exponent){
86  return (int)(exponent / 2);
87  }
88 
89  /**
90  * Check if the monomial is alreday inserted imto the map,
91  * If yes, returned the key which is a variable otherwise create new variable
92  * and insert the monomial into the map against this new variable
93  * @param monomial a monomoal object
94  * @return a carl::Variable object
95  */
96  carl::Variable insertIntoMapOrRetrieveExistingVariable(carl::Monomial::Arg monomial){
97 
98  carl::Variable retrievedVariable = smtrat::MonomialMappingByVariablePool::getInstance().variable(monomial);
99 
100  if(smtrat::MonomialMappingByVariablePool::getInstance().isNull(retrievedVariable)){
101  //create new variable as it doesn't exist in the map
102  carl::Variable GeneratedVariable = createZVariable();
103  //insert into the map
104  insertIntoMap(GeneratedVariable, monomial);
105 
106  return GeneratedVariable;
107  }
108 
109  if (smtrat::LOG::getInstance().isDebugEnabled()) {
110  std::cout << "the monomial, " << monomial << " alreday exists in the map!\nkey for this monomial in the map is, "
111  << retrievedVariable;
112  std::cout << "\n";
113  }
114 
115  return retrievedVariable;
116 
117  }
118 
119  /**
120  * Replace square of variable (x_0^2) of a monomial (x_0^6) by a variable (z_0),
121  * create a new monomial (z_0^3)
122  * and insert this variable as key with monomial (x_0^2) as value in the map
123  * @param Variable a carl::Variable object
124  * @param exponent an even exponent
125  * @return new monomial
126  */
127  carl::Monomial::Arg abstractUnivariateMonomialForEvenExponent(carl::Variable Variable, int exponent){
128 
129  int exponentToBe = divisionOfExponentByTwo(exponent);
130 
131  //carl::Variable GeneratedVariable = createZVariable();
132  carl::Monomial::Arg monomialAsSquareOfVariable = createSquareOfVariable(Variable);
133 
134  //insertIntoMap(GeneratedVariable, monomialAsSquareOfVariable);
135  carl::Variable newlyGeneratedOrOldVariable = insertIntoMapOrRetrieveExistingVariable(monomialAsSquareOfVariable);
136 
137  if (smtrat::LOG::getInstance().isDebugEnabled()) {
138  std::cout << "abstractUnivariateMonomialForEvenExponent: Exponent of newly generated or old variable: " << exponentToBe;
139  std::cout << "\n";
140  }
141 
142  carl::Monomial::Arg newMonomial = carl::createMonomial(newlyGeneratedOrOldVariable, (carl::exponent)exponentToBe);
143 
144  if (smtrat::LOG::getInstance().isDebugEnabled()) {
145  std::cout << "abstractUnivariateMonomialForEvenExponent: new Monomial: " << newMonomial;
146  std::cout << "\n";
147  std::cout << "\n";
148  }
149 
150  return newMonomial;
151  }
152 
153  /**
154  * It creates monomial by taking and popping first two items from the list,
155  * Insert this new monomial as value into the map against a newly generated variable,
156  * Each time the newly generated variable is insterted at the front of the list
157  * @param variables List of carl variables
158  * @return created new linear variable
159  */
160  carl::Variable abstractProductRecursively(std::list<carl::Variable> variables){
161 
162  while (variables.size() > 1) {
163  carl::Variable first = variables.front();
164  variables.pop_front();
165 
166  carl::Variable second = variables.front();
167  variables.pop_front();
168 
169  if (smtrat::LOG::getInstance().isDebugEnabled()) {
170  std::cout << "first: " << first << "\n";
171  std::cout << "second: " << second << "\n";
172  }
173 
174  // variables must be sorted to create monomial.
175  carl::Monomial::Content mExponents(std::initializer_list<std::pair<carl::Variable, carl::exponent>>
176  (
177  {std::make_pair(first,(carl::exponent)1), std::make_pair(second, (carl::exponent)1)}
178  ));
179 
180  std::sort(mExponents.begin(), mExponents.end(), [](const std::pair<carl::Variable, carl::uint>& p1, const std::pair<carl::Variable, carl::uint>& p2){ return p1.first < p2.first; });
181 
182  carl::Monomial::Arg createdMonomial = carl::createMonomial(std::initializer_list<std::pair<carl::Variable, carl::exponent>>
183  (
184  {mExponents[0], mExponents[1]}
185  ),
186  (carl::exponent)(2));
187 
188  if (smtrat::LOG::getInstance().isDebugEnabled()) {
189  std::cout << "createdMonomial: " << createdMonomial << "\n";
190  }
191 
192  //carl::Variable GeneratedVariable = createZVariable();
193  carl::Variable newlyGeneratedOrOldVariable = insertIntoMapOrRetrieveExistingVariable(createdMonomial);
194  //insertIntoMap(GeneratedVariable, createdMonomial);
195 
196  variables.push_front(newlyGeneratedOrOldVariable);
197 
198  }
199 
200  return variables.front();
201  }
202 
203 
204  /**
205  * Replace square of variable (x_0^2) of a monomial (x_0^7) by a variable (z_0),
206  * create a linear monomial (z_1)
207  * and insert the variable as key with monomial as value in the map
208  * @param Variable a carl::Variable object
209  * @param exponent an odd exponent
210  * @return new linear monomial
211  */
212  carl::Monomial::Arg abstractUnivariateMonomialForOddExponent(carl::Variable Variable, int exponent){
213 
214  std::list<carl::Variable> extraVariablesForOddExponenet;
215 
216  int exponentToBe = divisionOfExponentByTwo(exponent);
217  //carl::Variable GeneratedVariable = createZVariable();
218  carl::Monomial::Arg monomialAsSquareOfVariable = createSquareOfVariable(Variable);
219 
220  //insertIntoMap(GeneratedVariable, monomialAsSquareOfVariable);
221  carl::Variable newlyGeneratedOrOldVariable = insertIntoMapOrRetrieveExistingVariable(monomialAsSquareOfVariable);
222 
223  if (smtrat::LOG::getInstance().isDebugEnabled()) {
224  std::cout << "abstractUnivariateMonomialForOddExponent: Exponent of newly generated or old variable: " << exponentToBe;
225  std::cout << "\n";
226  }
227 
228  carl::Monomial::Arg newMonomial = carl::createMonomial(newlyGeneratedOrOldVariable, (carl::exponent)exponentToBe);
229 
230  extraVariablesForOddExponenet.push_front(Variable);
231 
232  // get linear monomial
233  while (!newMonomial->is_linear()) {
234  if (smtrat::LOG::getInstance().isDebugEnabled()) {
235  std::cout << "entering while" << "\n";
236  }
237 
238  if(newMonomial->begin()->second % 2 == 0){
239 
240  newMonomial = abstractUnivariateMonomialForEvenExponent(newMonomial->begin()->first,
241  newMonomial->begin()->second);
242 
243  } else {
244  newMonomial = abstractUnivariateMonomialForOddExponent(newMonomial->begin()->first,
245  newMonomial->begin()->second);
246  }
247  }
248 
249  // create newMonomial by multiplying newMonomial with the list extraVariablesForOddExponenet
250  if(newMonomial->is_linear()) {
251  carl::Variable variableOfNewMonomial = newMonomial->begin()->first;
252  if (smtrat::LOG::getInstance().isDebugEnabled()) {
253  std::cout << "new monomial is linear" << "\n";
254  std::cout << "variableOfNewMonomial: " << variableOfNewMonomial << "\n";
255  }
256  extraVariablesForOddExponenet.push_front(variableOfNewMonomial);
257  if (smtrat::LOG::getInstance().isDebugEnabled()) {
258  std::cout << "extraVariablesForOddExponenet: " << extraVariablesForOddExponenet << "\n";
259  }
260  newMonomial = carl::createMonomial((abstractProductRecursively(extraVariablesForOddExponenet)), (carl::exponent)1);
261  }
262 
263  if (smtrat::LOG::getInstance().isDebugEnabled()) {
264  std::cout << "abstractUnivariateMonomialForOddExponent: new Monomial: " << newMonomial;
265  std::cout << "\n";
266  std::cout << "\n";
267  }
268 
269  return newMonomial;
270  }
271 
272  /**
273  * create monomial which is linear
274  * @param Variable a carl Variable object
275  * @param exponent even or odd exponent of the variable
276  * @return a linear monomial
277  */
278  carl::Monomial::Arg abstractUnivariateMonomial (carl::Variable Variable, int exponent)
279  {
280  carl::Monomial::Arg monomial;
281 
282 
283  if(exponent == 1) {
284 
285  monomial = carl::createMonomial((Variable), (carl::exponent)1);
286 
287  } else if(exponent % 2 == 0){
288 
289  monomial = abstractUnivariateMonomialForEvenExponent(Variable, exponent);
290 
291  } else {
292  monomial = abstractUnivariateMonomialForOddExponent(Variable, exponent);
293  }
294 
295 
296  if (monomial->num_variables() == 1 && monomial->is_linear()) {
297 
298  if (smtrat::LOG::getInstance().isDebugEnabled()) {
299  std::cout << "final Linear Monomial: " << monomial << " tDeg: " << monomial->tdeg();
300  std::cout << "\n";
301  }
302 
303  return monomial;
304  }
305 
306 
307  return abstractUnivariateMonomial(monomial->begin()->first, monomial->begin()->second);
308  }
309 
310  /**
311  * It linearizes a non-linear monomial
312  * @param monomial a monomoal object
313  * @return a linear variable
314  */
315  carl::Variable abstractMonomial(carl::Monomial::Arg monomial){
316 
317  std::list<carl::Variable> variables;
318 
319  carl::Variable finalVariable;
320 
321  for (auto it = monomial->begin(); it != monomial->end(); ++it) {
322 
323  carl::Monomial::Arg monomial = abstractUnivariateMonomial(it->first, it->second);
324 
325  if (smtrat::LOG::getInstance().isDebugEnabled()) {
326  std::cout << "Received final Monomial is: " << monomial;
327  std::cout << "\n";
328  std::cout << "\n";
329  }
330 
331  variables.push_back(monomial->begin()->first);
332  }
333 
334  finalVariable = abstractProductRecursively(variables);
335 
336  return finalVariable;
337  }
338 
339  FormulaT linearization(FormulaT formula) {
340  originalFormula->add(formula, true);
341 
342  //get constraint
343  const ConstraintT& constraint = formula.constraint();
344 
345  if (smtrat::LOG::getInstance().isDebugEnabled()) {
346  std::cout << "\n";
347  std::cout << "Constraint is: " << constraint;
348  std::cout << "\n";
349  std::cout << "\n";
350  }
351 
352  //get polynomial(lhs) of constraint
353  Poly poly = constraint.lhs();
354  //counter of op[]
355  std::size_t indexCount = 0;
356 
357  //size of array
358  std::vector<Poly> op(poly.terms().size());
359 
360  // loops over each term and create linear polynomials
361  for( auto& term : poly.terms() ) {
362 
363  if (!term.is_constant() && term.is_linear()) { //if the term is already linear and not a constant
364 
365  Poly p(term);
366  op[indexCount] = p;
367 
368  if (smtrat::LOG::getInstance().isDebugEnabled()) {
369  std::cout << "Monomial is: " << term.monomial() << " (alreday linear)";
370  std::cout << "\n";
371  std::cout << "\n";
372  }
373 
374  } else if (!term.is_constant()) { //if the term is a product of two or more variables
375 
376  //get monomial
377  carl::Monomial::Arg monomial = term.monomial();
378 
379  if (smtrat::LOG::getInstance().isDebugEnabled()) {
380  std::cout << "Monomial is: " << monomial;
381  std::cout << "\n";
382  }
383 
384  //get the linearized variable of the monomial
385  carl::Variable finalVariable = abstractMonomial(monomial);
386 
387  //create new polynomial
388  Poly p(term.coeff()*finalVariable);
389  if (smtrat::LOG::getInstance().isDebugEnabled()) {
390  std::cout << "Generated MultiVariantPolynomial: " << p;
391  std::cout << "\n";
392  std::cout << "\n";
393  }
394  op[indexCount] = p;
395 
396  } else { //if the term is a constants
397 
398  //create new polynomial
399  Poly p(term);
400  op[indexCount] = p;
401 
402  }
403 
404  indexCount++;
405  }
406 
407  if (smtrat::LOG::getInstance().isDebugEnabled()) {
408  std::cout << "Vector: " << op;
409  std::cout << "\n";
410  }
411 
412  //construction lhs of the constraint
413  Poly finalPoly(Poly::ConstructorOperation::ADD,op);
414 
415  //create new formula
416  FormulaT finalFormula = FormulaT(finalPoly, constraint.relation());
417  if (smtrat::LOG::getInstance().isDebugEnabled()) {
418  std::cout << "Generated final Formula: " << finalFormula;
419  std::cout << "\n";
420  std::cout << "Generated New constraint: " << finalFormula.constraint();
421  std::cout << "\n";
422  std::cout << "\n";
423  }
424 
425  return finalFormula;
426  }
427 
428 
429  template<typename Settings>
430  FormulaT NRAILModule<Settings>::linearizeSubformula(const FormulaT &formula)
431  {
432  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Formula from linearizeSubformula: " << formula << " Formula Type: " << formula.type() << std::endl; }
433 
434  if (formula.type() == carl::FormulaType::CONSTRAINT) {
435  FormulaT linearizedFormula = linearization(formula);
436  return linearizedFormula;
437  }
438 
439  return formula;
440  }
441 
442 
443  template<class Settings>
444  bool NRAILModule<Settings>::addCore( ModuleInput::const_iterator _subformula )
445  {
446  const FormulaT& formula{_subformula->formula()};
447 
448  if (formula.type() == carl::FormulaType::FALSE){
449 
450  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Formula type is false and UNSAT! "; }
451 
452  mInfeasibleSubsets.push_back({formula});
453 
454  return false;
455  }
456 
457  if (formula.type() == carl::FormulaType::TRUE){
458  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Formula type is true! "; }
459  return true;
460  }
461 
462  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Sub Formula: " << formula << " Sub Formula type: " << formula.type() << std::endl; }
463 
464  FormulaT formulaFromVisitor = carl::visit_result( formula, linearizeSubformulaFunction );
465 
466  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Generated linearized Formula FromVisitor: " << formulaFromVisitor << std::endl; }
467  ////////////////////////////////////////////////
468  //
469  // Adding the Linearized Formula to the global
470  // ModuleInput type variable. This global
471  // variable will be used to add all of the
472  // Linearized formulas to the passed formula
473  //
474  ////////////////////////////////////////////////
475  addSubformulaToPassedFormula(formulaFromVisitor);
476 
477  return true; // This should be adapted according to your implementation.
478  }
479 
480  template<class Settings>
481  void NRAILModule<Settings>::removeCore( ModuleInput::const_iterator )
482  {
483  // Your code.
484  }
485 
486  template<class Settings>
487  void NRAILModule<Settings>::updateModel() const
488  {
489  mModel.clear();
490  if( solverState() == Answer::SAT )
491  {
492  // Your code.
493  }
494  }
495 
496  Answer toAnswer(int value){
497  if(value == 0){
498  return Answer::UNSAT;
499  } else if(value == 1) {
500  return Answer::SAT;
501  } else {
502  return Answer::UNKNOWN;
503  }
504  }
505 
506  /**
507  * Chekcs if the estimated Assignment satisfies the input NRA formula.
508  * @param estimatedModel The estimated model.
509  */
510  Answer isNRASatisfied(Model estimatedModel)
511  {
512  unsigned result = originalFormula->satisfiedBy(estimatedModel);
513  if (smtrat::LOG::getInstance().isDebugEnabled()) {
514  std::cout << "Result " << result;
515  std::cout << "\n";
516  }
517  return toAnswer(result);
518  }
519 
520  /**
521  * Creates the estimated model.
522  * estimated model takes the solution from mModel or randomly chosen.
523  * @param linearizedModel Model of linearized formula.
524  */
525  Model createEstimatedAssignment(Model linearizedModel){
526  Model estimatedModel;
527 
528  //collect the variables into the container "allVarsOfOriginalFormula"
529  carl::carlVariables allVarsOfOriginalFormula;
530  originalFormula->gatherVariables(allVarsOfOriginalFormula);
531  if (smtrat::LOG::getInstance().isDebugEnabled()) {
532  std::cout << "all variables of original formula: ";
533  for (auto it = allVarsOfOriginalFormula.begin(); it != allVarsOfOriginalFormula.end(); ++it) {
534  std::cout << it->name();
535  std::cout << " ";
536  }
537  std::cout << "\n";
538 
539  std::cout << "linearized variable | value: " << "\n";
540  for (auto it = linearizedModel.begin(); it != linearizedModel.end(); ++it) {
541  std::cout << it->first << " | " << it->second;
542  std::cout << "\n";
543  }
544  }
545  for (auto it1 = allVarsOfOriginalFormula.begin(); it1 != allVarsOfOriginalFormula.end(); ++it1) {
546  int counter = 0;
547  for (auto it2 = linearizedModel.begin(); it2 != linearizedModel.end(); ++it2) {
548  if(it1->name() == it2->first.asVariable().name()){
549  estimatedModel.emplace(*it1, it2->second.asRational());
550  counter++;
551  break;
552  }
553  }
554  if(counter == 0){
555  estimatedModel.emplace(*it1, Rational(0));
556  }
557  }
558  if (smtrat::LOG::getInstance().isDebugEnabled()) {
559  std::cout << "estimated model for original formula: " << "\n";
560  for (auto it = estimatedModel.begin(); it != estimatedModel.end(); ++it) {
561  std::cout << it->first << " | " << it->second;
562  std::cout << "\n";
563  }
564  }
565  return estimatedModel;
566  }
567 
568  /**
569  * create a model combining mModel, estimatedModel and rest of the variables are guessed.
570  * This model checks the satifiability of the axioms.
571  * @param mModel Model of linearized formula.
572  * @param estimatedModel the estimated model for original formula.
573  * @return the Abstract Model
574  */
575  Model extendLinearizedModel(Model mModel, Model estimatedModel){
576  Model linearizedModel;
577  std::ostream stream(nullptr);
578  stream.rdbuf(std::cout.rdbuf());
579 
580  for (auto mModelItarator = mModel.begin(); mModelItarator != mModel.end(); ++mModelItarator) {
581  if (mModelItarator->second.isRational())
582  linearizedModel.emplace(mModelItarator->first, mModelItarator->second.asRational());
583  }
584 
585  for (auto estimatedModelItarator = estimatedModel.begin(); estimatedModelItarator != estimatedModel.end(); ++estimatedModelItarator) {
586  linearizedModel.emplace(estimatedModelItarator->first, estimatedModelItarator->second.asRational());
587  }
588 
589  MonomialMap monomialMap = smtrat::MonomialMappingByVariablePool::getInstance().getMMonomialMapping();
590  for (MonomialMapIterator it = monomialMap.begin(); it != monomialMap.end(); ++it) {
591  linearizedModel.emplace(it->first, Rational(0));
592  }
593  if (smtrat::LOG::getInstance().isDebugEnabled()) {
594  std::cout << "Abstract model for checking axioms: " << "\n";
595  linearizedModel.printOneline(stream, true);
596  std::cout << "\n";
597  }
598  return linearizedModel;
599  }
600 
601  int rand(int min, int max) {
602  std::time_t now = std::time(0);
603  boost::random::mt19937 gen{static_cast<std::uint32_t>(now)};
604  boost::random::uniform_int_distribution<> dist{min, max};
605  return dist(gen);
606  }
607 
608  FormulasT unsatisfiedFormulas(AxiomFactory::AxiomType axiomType, FormulasT formulas, Model model, UNSATFormulaSelectionStrategy formulaSelectionStrategy){
609 
610  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "unsatisfiedFormulas to be check: " << formulas << std::endl; }
611 
612  FormulasT unsatisfiedFormulas;
613 
614  if (axiomType == AxiomFactory::AxiomType::TANGENT_PLANE || axiomType == AxiomFactory::AxiomType::MONOTONICITY) {
615  for(FormulaT formula:formulas) {
616  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "unsatisfiedFormula: " << formula << std::endl; }
617  unsatisfiedFormulas.push_back(formula);
618  if (formulaSelectionStrategy == UNSATFormulaSelectionStrategy::FIRST){
619  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "returning first formula" << std::endl; }
620  return unsatisfiedFormulas;
621  }
622  }
623  } else {
624  for(FormulaT formula:formulas) {
625  if (carl::satisfied_by(formula, model) == 0){
626  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "unsatisfiedFormula: " << formula << std::endl; }
627  unsatisfiedFormulas.push_back(formula);
628  if (formulaSelectionStrategy == UNSATFormulaSelectionStrategy::FIRST){
629  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "returning first formula" << std::endl; }
630  return unsatisfiedFormulas;
631  }
632  }
633  }
634  }
635  if (unsatisfiedFormulas.empty()) {
636  return unsatisfiedFormulas;
637  }
638 
639  int unsatisfiedFormulasSize = (int)unsatisfiedFormulas.size();
640 
641  if (formulaSelectionStrategy == UNSATFormulaSelectionStrategy::RANDOM) {
642  std::vector<FormulaT> randomlySelectedFormulas;
643 
644  int min = unsatisfiedFormulasSize / 2;
645  int max = (unsatisfiedFormulasSize * 80) / 100;
646 
647  size_t nelems = rand(min, max);
648 
649  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Selecting elements: " << nelems << " from the elemnts of: " << unsatisfiedFormulasSize << std::endl; }
650  std::sample(unsatisfiedFormulas.begin(), unsatisfiedFormulas.end(), std::back_inserter(randomlySelectedFormulas),
651  nelems, std::mt19937{std::random_device{}()});
652  return randomlySelectedFormulas;
653  }
654 
655  return unsatisfiedFormulas;
656  }
657 
658  FormulasT refinement(AxiomFactory::AxiomType axiomType, Model linearizedModel, UNSATFormulaSelectionStrategy formulaSelectionStrategy){
659 
660  FormulasT axiomFormulasToBeChecked = AxiomFactory::createFormula(axiomType, linearizedModel, smtrat::MonomialMappingByVariablePool::getInstance().getMMonomialMapping());
661 
662  FormulasT unsatFormulas = unsatisfiedFormulas(axiomType, axiomFormulasToBeChecked, linearizedModel, formulaSelectionStrategy);
663 
664  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "pushing to unsatisfiedFormulas " << unsatFormulas << std::endl; }
665 
666  return unsatFormulas;
667  }
668 
669 
670  template<class Settings>
671  Answer NRAILModule<Settings>::checkCore()
672  {
673  std::ostream stream(nullptr);
674  stream.rdbuf(std::cout.rdbuf());
675 
676  int loopCounter = 0;
677  std::vector<AxiomFactory::AxiomType> axiomType(std::begin(Settings::axiomType), std::end(Settings::axiomType));
678 
679  assert(axiomType.size() > 0);
680  std::size_t axiom_type_size = axiomType.size() - 1;
681 
682  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "axiom_type_size: " << axiom_type_size << std::endl; }
683 
684  std::size_t axiomCounter = 0;
685 
686  bool isUnsatFormulasNotEmpty = true;
687 
688  Model linearizedModel;
689 
690  while (true) {
691 
692  if (smtrat::LOG::getInstance().isDebugEnabled()) {
693  std::cout << "Loop" << loopCounter << "\n";
694  std::cout << "axiomCounter" << axiomCounter << "\n";
695  }
696 
697  if(isUnsatFormulasNotEmpty) {
698 
699  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Calling backend for axiom counter = " << axiomCounter << std::endl; }
700 
701  auto AnswerOfLRA = runBackends();
702  updateModel();
703 
704  if (smtrat::LOG::getInstance().isDebugEnabled()) {
705  std::cout << "Linearized Formula is AnswerOfLRA!" << AnswerOfLRA << "\n";
706  }
707 
708  if (AnswerOfLRA != SAT) {
709 
710  if (smtrat::LOG::getInstance().isDebugEnabled()) {std::cout << "Linearized Formula is Unsatisfied/Unknown!" << std::endl;}
711 
712  if (AnswerOfLRA == UNSAT) {
713  generateTrivialInfeasibleSubset();
714  }
715  return AnswerOfLRA;
716  }
717  // NOTE: This mModel is the actual linearized model.
718  mModel = backendsModel();
719 
720  if (smtrat::LOG::getInstance().isDebugEnabled()) {
721  std::cout << "Solution/model of linearized formula: ";
722  mModel.printOneline(stream, true);
723  std::cout << "\n";
724  std::cout << "\n";
725  }
726  Model estimatedModel = createEstimatedAssignment(mModel);
727  auto answerOfNRA = isNRASatisfied(estimatedModel);
728 
729  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "answerOfNRA: " << answerOfNRA << std::endl; }
730 
731  if (answerOfNRA != UNSAT) {
732 
733  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Input Formula is Satisfied!" << std::endl; }
734 
735  if (smtrat::LOG::getInstance().isDebugEnabled()) { estimatedModel.printOneline(stream, true); }
736  return answerOfNRA;
737  }
738  // NOTE: mModel is the actual linearized model, linearizedModel contains linearized model with estimatedAssignments
739  linearizedModel = extendLinearizedModel(mModel, estimatedModel);
740 
741  }
742 
743  FormulasT unsatFormulas = refinement(axiomType[axiomCounter], linearizedModel, Settings::formulaSelectionStrategy);
744 
745  isUnsatFormulasNotEmpty = !unsatFormulas.empty();
746 
747  if (unsatFormulas.empty()) {
748  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "empty" << std::endl; }
749  }
750 
751  for (FormulaT formulaT : unsatFormulas) {
752  addSubformulaToPassedFormula(formulaT);
753  }
754 
755 
756  if (axiomCounter == axiom_type_size) {
757  axiomCounter = 0;
758  } else {
759  axiomCounter++;
760  }
761 
762  loopCounter++;
763  }
764 
765  if (smtrat::LOG::getInstance().isDebugEnabled()) { std::cout << "Result is:" << std::endl; }
766 
767  return UNKNOWN; // This should be adapted according to your implementation.
768  }
769 
770 }
771 
772