Advertisement
froleyks

formula.hpp

Mar 20th, 2019
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.82 KB | None | 0 0
  1. #pragma once
  2.  
  3. extern "C" {
  4. #include "ipasir.h"
  5. }
  6.  
  7. #include "problem.hpp"
  8. #include "tools/Logger.h"
  9. #include <limits>
  10.  
  11. // lol
  12. #define inf_time std::numeric_limits<double>::max() * 0.5
  13.  
  14. #define UNSAT -3;
  15.  
  16. // this capsules the ipasir interface
  17. // clauses added will be added to all past and future steps
  18. class Formula {
  19. private:
  20.   void *solver;
  21.   int num_base_variables     = 0;
  22.   unsigned new_clauses_begin = 0;
  23.   int current_step           = -1;
  24.   // makestep x variable x value
  25.   unsigned initial_clauses_index = 0;
  26.  
  27.   std::vector<int> clauses;
  28.   std::vector<std::pair<unsigned, unsigned>> assumptions;
  29.  
  30.   void activate_assumptions() {
  31.     for (auto [index, value] : assumptions) {
  32.       ipasir_assume(solver, state.back()[index][value]);
  33.     }
  34.   }
  35.  
  36.   void add_clauses_for_new_step() {
  37.     for (size_t i = 0; i < clauses.size(); ++i) {
  38.       if (clauses[i] > 0) {
  39.         clauses[i] += num_base_variables;
  40.       } else if (clauses[i] < 0) {
  41.         clauses[i] -= num_base_variables;
  42.       }
  43.       // 0 -> 0
  44.       ipasir_add(solver, clauses[i]);
  45.     }
  46.   }
  47.  
  48.   // only new clauses
  49.   // known clauses are added in increase makespan
  50.   void add_clauses_for_all_steps() {
  51.     if (new_clauses_begin == clauses.size()) {
  52.       return;
  53.     }
  54.     std::vector<int> new_clauses(clauses.begin() + new_clauses_begin,
  55.                                  clauses.end());
  56.     new_clauses_begin = clauses.size();
  57.     assert(new_clauses.back() == 0);
  58.     for (int step = 0; step < current_step + 1; ++step) {
  59.       for (unsigned i = 0; i < new_clauses.size(); ++i) {
  60.         ipasir_add(solver, new_clauses[i]);
  61.         if (new_clauses[i] > 0) {
  62.           new_clauses[i] -= num_base_variables;
  63.         } else if (new_clauses[i] < 0) {
  64.           new_clauses[i] += num_base_variables;
  65.         }
  66.         // 0 -> 0
  67.       }
  68.     }
  69.   }
  70.  
  71. public:
  72.   std::vector<std::vector<std::vector<int>>> state;
  73.   std::vector<std::vector<unsigned>> action;
  74.  
  75.   Formula(const Problem &problem,
  76.           const std::vector<int> &additional_clauses = {}) {
  77.     solver = ipasir_init();
  78.  
  79.     // glucose fix
  80.     // ipasir_set_learn(solver, NULL, 0, NULL);
  81.  
  82.     std::cout << "Log: " << getTime() << " "
  83.               << "Using the incremental SAT solver" << ipasir_signature()
  84.               << std::endl;
  85.  
  86.     // set state variables
  87.     state.emplace_back(problem.vars.size());
  88.     for (size_t i = 0; i < state[0].size(); ++i) {
  89.       state[0][i].resize(problem.vars[i].values.size());
  90.       if (state[0][i].size() == 2) {
  91.         // no dual-rail encoding for binary values
  92.         ++num_base_variables;
  93.         state[0][i] = {num_base_variables, -num_base_variables};
  94.       } else {
  95.         for (size_t v = 0; v < problem.vars[i].values.size(); ++v) {
  96.           state[0][i][v] = ++num_base_variables;
  97.         }
  98.       }
  99.     }
  100.  
  101.     // set action variables
  102.     action.emplace_back(problem.actions.size());
  103.     for (size_t i = 0; i < action[0].size(); ++i) {
  104.       action[0][i] = ++num_base_variables;
  105.     }
  106.  
  107.     // TODO the last set of action vars is not needed
  108.     increase_makespan();
  109.  
  110.     // at least one value
  111.     // is not necessary for the fixed initial sate
  112.     for (size_t i = 0; i < state[0].size(); ++i) {
  113.       if (state[0][i].size() > 2) {
  114.         for (size_t v = 0; v < state[0][i].size(); ++v) {
  115.           add_s(i, v, true, true);
  116.         }
  117.         close();
  118.       }
  119.     }
  120.  
  121.     // mutex which are generated by sas transform of fastdownward
  122.     for (const auto &mutex : problem.mutexes) {
  123.       for (size_t i = 0; i < mutex.size() - 1; ++i) {
  124.         for (size_t j = i + 1; j < mutex.size(); ++j) {
  125.           add_s(mutex[i].first, mutex[i].second, false, true);
  126.           add_s(mutex[j].first, mutex[j].second, false, true);
  127.           close();
  128.         }
  129.       }
  130.     }
  131.     initial_clauses_index = clauses.size();
  132.     clauses.insert(clauses.begin(), additional_clauses.begin(),
  133.                    additional_clauses.end());
  134.   }
  135.  
  136.   ~Formula() { ipasir_release(solver); }
  137.  
  138.   unsigned increase_makespan(unsigned steps = 1) {
  139.     for (unsigned i = 0; i < steps; ++i) {
  140.       // set state variables
  141.       state.push_back(state.back());
  142.       for (size_t i = 0; i < state.back().size(); ++i) {
  143.         for (size_t v = 0; v < state.back()[i].size(); ++v) {
  144.           if (state.back()[i][v] > 0) {
  145.             state.back()[i][v] += num_base_variables;
  146.           } else {
  147.             state.back()[i][v] -= num_base_variables;
  148.           }
  149.         }
  150.       }
  151.  
  152.       // set action variables
  153.       action.push_back(action.back());
  154.       for (size_t i = 0; i < action.back().size(); ++i) {
  155.         action.back()[i] += num_base_variables;
  156.       }
  157.  
  158.       add_clauses_for_new_step();
  159.  
  160.       current_step++;
  161.     }
  162.  
  163.     return current_step + 1;
  164.   }
  165.  
  166.   // assuming the goal
  167.   inline void assume_at_last(int variable, unsigned value) {
  168.     assumptions.emplace_back(variable, value);
  169.   }
  170.  
  171.   inline void add_initial_s_atom(int variable, unsigned value,
  172.                                  bool polarity = true) {
  173.     ipasir_add(solver, (polarity ? 1 : -1) * state[0][variable][value]);
  174.     ipasir_add(solver, 0);
  175.   }
  176.  
  177.   // clauses added will be added to all past and future steps
  178.   inline void add_s(int variable, unsigned value, bool polarity = true,
  179.                     bool next = false) {
  180.     if (next) {
  181.       clauses.push_back((polarity ? 1 : -1) *
  182.                         state[current_step + 1][variable][value]);
  183.     } else {
  184.       clauses.push_back((polarity ? 1 : -1) *
  185.                         state[current_step][variable][value]);
  186.     }
  187.   }
  188.  
  189.   inline void add_a(int index, bool polarity = true, bool next = false) {
  190.     if (next) {
  191.       clauses.push_back((polarity ? 1 : -1) * action[current_step + 1][index]);
  192.     } else {
  193.       clauses.push_back((polarity ? 1 : -1) * action[current_step][index]);
  194.     }
  195.   }
  196.  
  197.   inline void close() { clauses.push_back(0); }
  198.  
  199.   // assume goal and try to solve
  200.   bool solve(double time_limit = inf_time) {
  201.     add_clauses_for_all_steps();
  202.     activate_assumptions();
  203.     double end_time = getTime() + time_limit;
  204.     ipasir_set_terminate(solver, &end_time, [](void *end_time) {
  205.       return (int)(getTime() > *(double *)(end_time));
  206.     });
  207.     int satRes = ipasir_solve(solver);
  208.     return satRes == 10;
  209.   }
  210.  
  211.   int get_state_value(unsigned variable, unsigned t) const {
  212.     for (unsigned i = 0; i < state[t][variable].size(); ++i) {
  213.       int lit = state[t][variable][i];
  214.       if (lit > 0) {
  215.         // TODO not important values
  216.         if (ipasir_val(solver, lit) >= 0) {
  217.           return i;
  218.         }
  219.       } else {
  220.         if (ipasir_val(solver, -lit) <= 0) {
  221.           return i;
  222.         }
  223.       }
  224.     }
  225.     assert(false);
  226.     return -1;
  227.   }
  228.  
  229.   bool get_action_value(unsigned index, unsigned t) const {
  230.     // not important variables should be false, a minimum of actions is
  231.     // preferred
  232.     return ipasir_val(solver, action[t][index]) > 0;
  233.   }
  234.  
  235.   void get_clauses(std::vector<int> &c) {
  236.     c = std::vector<int>(clauses.begin() + initial_clauses_index,
  237.                          clauses.end());
  238.   }
  239. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement