llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
sat.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <list>
8 #include <set>
9 
10 #include <llvm/ADT/ArrayRef.h>
11 #include <llvm/Support/raw_ostream.h>
12 
13 #include "core/adt/bitset.h"
14 
15 
16 
20 class SATProblem final {
21 public:
22  struct Lit;
23 
24  SATProblem() : is2SAT_(true) {}
25 
26  void Add(llvm::ArrayRef<ID<Lit>> pos, llvm::ArrayRef<ID<Lit>> neg);
27 
31  bool IsSatisfiable();
32 
36  bool IsSatisfiableWith(ID<Lit> id);
37 
41  void dump(llvm::raw_ostream &os = llvm::errs());
42 
43 private:
45  using Clause = llvm::SmallVector<unsigned, 4>;
47  using ClauseList = std::vector<llvm::SmallVector<unsigned, 4>>;
48 
50  class SAT2Solver {
51  public:
52  SAT2Solver(const ClauseList &list);
53 
54  bool IsSatisfiable();
55 
56  bool IsSatisfiableWith(ID<Lit> id);
57 
58  private:
60  bool unsat_;
62  std::vector<std::set<unsigned>> sccGraph_;
64  std::unordered_map<unsigned, unsigned> sccOfNode_;
65  };
66 
68  class SATNSolver {
69  public:
70  SATNSolver(const ClauseList &list);
71 
72  bool IsSatisfiable();
73 
74  bool IsSatisfiableWith(ID<Lit> id);
75 
76  private:
77  struct Clause {
79  llvm::SmallVector<unsigned, 4> Lits;
80  };
81 
83  class Literal {
84  public:
86  enum class State {
87  FALSE,
88  TRUE,
89  UNDEF,
90  };
91 
93  Literal(unsigned id)
94  : id_(id)
95  , state_(State::UNDEF)
96  {
97  }
98 
100  unsigned GetId() const { return id_; }
102  State GetState() const { return state_; }
104  bool IsAssigned() const { return state_ != State::UNDEF; }
106  bool IsTrue() const { return state_ != State::TRUE; }
108  bool IsFalse() const { return state_ != State::FALSE; }
110  void Assign(bool v)
111  {
112  state_ = v ? State::TRUE : State::FALSE;
113  }
115  void Unassign() { state_ = State::UNDEF; }
116 
117  private:
119  unsigned id_;
121  State state_;
122  };
123 
124  private:
125  Literal *PickBranchingVariable();
126 
127  bool FindConflict();
128 
129  void Backtrack();
130 
131  private:
133  std::vector<Clause> clauses_;
135  std::vector<Literal> lits_;
137  std::vector<Literal *> trail_;
139  unsigned decisionLevel_;
141  unsigned satisfied_;
142  };
143 
144 private:
146  ClauseList clauses_;
148  bool is2SAT_;
150  std::unique_ptr<SAT2Solver> solver2SAT_;
152  std::unique_ptr<SATNSolver> solverNSAT_;
153 };
SATProblem::IsSatisfiableWith
bool IsSatisfiableWith(ID< Lit > id)
Definition: sat.cpp:45
ID
Definition: id.h:19
SATProblem::dump
void dump(llvm::raw_ostream &os=llvm::errs())
Definition: sat.cpp:61
SATProblem
Definition: sat.h:20
SATProblem::IsSatisfiable
bool IsSatisfiable()
Definition: sat.cpp:29