SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
Node.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 #include <set>
5 
6 #include "Matrix.h"
7 
8 namespace smtrat::fmplex {
9 
10 struct Node {
13 
14  enum class Type { UNDETERMINED, CONFLICT, LEAF, LBS, UBS, NBS, FM };
15 
19  std::vector<ColIndex> cols_to_elim;
20  std::vector<RowIndex> eliminators;
21  std::set<RowIndex> ignored;
22 
23  Node(bool is_sat) {
25  eliminators.clear();
26  }
27 
28  Node() {}
29 
30  Node(const Matrix& m, const std::vector<ColIndex>& cols)
31  : matrix(m)
32  , cols_to_elim(cols) {}
33 
34  Node(const Matrix& m, const std::vector<ColIndex>& cols, const std::set<RowIndex>& ign)
35  : matrix(m)
36  , cols_to_elim(cols)
37  , ignored(ign) {}
38 
39  Node(Matrix&& m, const std::vector<ColIndex>& cols)
40  : matrix(std::move(m))
41  , cols_to_elim(cols) {}
42 
43 
44  inline bool is_conflict() const { return type == Node::Type::CONFLICT; }
45  inline bool is_finished() const { return eliminators.empty(); }
46 
47  static Node conflict() { return Node(false); }
48  static Node leaf() { return Node(true); }
49 
51  if (matrix.n_rows() == 0 || cols_to_elim.empty()) {
53  return;
54  }
55 
56  if (cols_to_elim.size() == 1) {
58  chosen_col = cols_to_elim.front();
59  return;
60  }
61 
62  // find best column
63  std::size_t min_branches = matrix.n_rows();
64  for (const auto j : cols_to_elim) {
65  std::size_t lbs = 0, ubs = 0;
66  for (const auto& entry : matrix.col_entries(j)) {
67  if (entry.value < 0) ++lbs;
68  else ++ubs;
69  }
70  std::size_t min_j = std::min(lbs, ubs);
71  if (min_j == 0) {
72  chosen_col = j;
74  break;
75  } else if (min_j < min_branches) {
76  min_branches = min_j;
77  chosen_col = j;
78  type = (lbs == min_j) ? Node::Type::LBS : Node::Type::UBS;
79  }
80  }
81 
82  // gather eliminators
83  auto col_it = matrix.col_begin(chosen_col);
84  auto col_end = matrix.col_end(chosen_col);
85 
86  auto ign_it = ignored.begin();
87  switch (type) {
88  case Node::Type::LBS:
89  for (; col_it != col_end; ++col_it) {
90  if (ign_it != ignored.end() && *ign_it == col_it.row()) ++ign_it;
91  else if (col_it->value < 0) eliminators.push_back(col_it.row());
92  }
93  break;
94  case Node::Type::UBS:
95  for (; col_it != col_end; ++col_it){
96  if (ign_it != ignored.end() && *ign_it == col_it.row()) ++ign_it;
97  else if (col_it->value > 0) eliminators.push_back(col_it.row());
98  }
99  break;
100  case Node::Type::NBS:
101  for (; col_it != col_end; ++col_it){
102  eliminators.push_back(col_it.row());
103  }
104  break;
105  default:
106  break;
107  }
108  }
109 };
110 
111 
112 
113 }
col_iterator col_begin(ColIndex c) const
Definition: Matrix.h:194
col_view col_entries(const ColIndex ci) const
Definition: Matrix.h:208
col_iterator col_end(ColIndex c) const
Definition: Matrix.h:195
std::size_t RowIndex
Definition: Matrix.h:13
std::size_t n_rows() const
Definition: Matrix.h:69
std::size_t ColIndex
Definition: Matrix.h:14
bool is_sat(Answer a)
Definition: types.h:58
std::vector< ColIndex > cols_to_elim
Definition: Node.h:19
void choose_elimination()
Definition: Node.h:50
Matrix::RowIndex RowIndex
Definition: Node.h:11
Node(bool is_sat)
Definition: Node.h:23
ColIndex chosen_col
Definition: Node.h:18
std::vector< RowIndex > eliminators
Definition: Node.h:20
std::set< RowIndex > ignored
Definition: Node.h:21
static Node leaf()
Definition: Node.h:48
static Node conflict()
Definition: Node.h:47
Node(const Matrix &m, const std::vector< ColIndex > &cols)
Definition: Node.h:30
bool is_finished() const
Definition: Node.h:45
Node(Matrix &&m, const std::vector< ColIndex > &cols)
Definition: Node.h:39
bool is_conflict() const
Definition: Node.h:44
Matrix::ColIndex ColIndex
Definition: Node.h:12
Node(const Matrix &m, const std::vector< ColIndex > &cols, const std::set< RowIndex > &ign)
Definition: Node.h:34
Matrix matrix
Definition: Node.h:16