libgsjj  1
Deterministic finite automata learning library
UnaryCNFMethod.cpp
Go to the documentation of this file.
2 
3 #include <iostream>
4 
5 using namespace Minisat;
6 
7 namespace gsjj {
8  namespace passive {
9  namespace CNF {
10  UnaryCNFMethod::UnaryCNFMethod(const std::set<std::string> &SpSet, const std::set<std::string> &SmSet, const std::set<std::string> &SSet, const std::set<std::string> &prefixesSet, const std::set<char> &alphabetSet, unsigned int n) :
11  SATCNFMethod(SpSet, SmSet, SSet, prefixesSet, alphabetSet, n)
12  {
14  }
15 
17 
18  }
19 
21  return "unary";
22  }
23 
25  // For each prefix and each state in the DFA, we create a new variable
26  for (const auto &u : m_prefixes) {
27  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
28  auto pair = std::make_pair(u, q);
29  Var var = newVariable();
30  m_stateName.insert(state(pair, var));
31  }
32  }
33  }
34 
36  // Equation 4.3.1
37  // For some reason, Minisat defines its own vector type...
38  vec<Lit> clause(m_numberStates);
39  for (const auto &u : m_prefixes) {
40  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
41  // We know (u, q) is in the map thanks to createVariables
42  clause[q] = mkLit(m_stateName.find(std::make_pair(u, q))->second, false);
43  }
44  addClause(clause);
45  }
46 
47  // Equation 4.3.2
48  clause.clear();
49  clause.growTo(2);
50  for (const auto &u : m_prefixes) {
51  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
52  for (unsigned int p = 0 ; p < m_numberStates ; p++) {
53  if (p != q) {
54  Var qState = m_stateName.find(std::make_pair(u, q))->second;
55  Var pState = m_stateName.find(std::make_pair(u, p))->second;
56  clause[0] = mkLit(qState, true);
57  clause[1] = mkLit(pState, true);
58  addClause(clause);
59  }
60  }
61  }
62  }
63 
64  // Equation 4.3.3
65  clause.clear();
66  clause.growTo(4);
67  for (const auto &ua : m_prefixes) {
68  for (const auto &va : m_prefixes) {
69  // We must have that ua and va end with the same symbol
70  // We must have at least one symbol as well
71  if (ua.size() > 0 && va.size() > 0 && ua.at(ua.size() - 1) == va.at(va.size() - 1)) {
72  std::string u = ua.substr(0, ua.size() - 1);
73  std::string v = va.substr(0, va.size() - 1);
74  // Now, we can create every clause
75  for (unsigned int p = 0 ; p < m_numberStates ; p++) {
76  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
77  Var upState = m_stateName.find(std::make_pair(u, p))->second;
78  Var vpState = m_stateName.find(std::make_pair(v, p))->second;
79  Var uaqState = m_stateName.find(std::make_pair(ua, q))->second;
80  Var vaqState = m_stateName.find(std::make_pair(va, q))->second;
81 
82  clause[0] = mkLit(upState, true);
83  clause[1] = mkLit(vpState, true);
84  clause[2] = mkLit(uaqState, false);
85  clause[3] = mkLit(vaqState, true);
86  addClause(clause);
87 
88  clause[0] = mkLit(upState, true);
89  clause[1] = mkLit(vpState, true);
90  clause[2] = mkLit(uaqState, true);
91  clause[3] = mkLit(vaqState, false);
92  addClause(clause);
93  }
94  }
95  }
96  }
97  }
98 
99  // Equation 4.3.4
100  clause.clear();
101  clause.growTo(2);
102  for (const auto &u : m_Sp) {
103  for (const auto &v : m_Sm) {
104  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
105  Var uqState = m_stateName.find(std::make_pair(u, q))->second;
106  Var vqState = m_stateName.find(std::make_pair(v, q))->second;
107 
108  clause[0] = mkLit(uqState, true);
109  clause[1] = mkLit(vqState, true);
110 
111  addClause(clause);
112  }
113  }
114  }
115  }
116 
117  std::unique_ptr<DFA<char>> UnaryCNFMethod::toDFA(const Minisat::vec<Minisat::lbool> &model) const {
118  // First, we seek the initial state
119  unsigned int initial = 0;
120  for (unsigned int i = 0 ; i < m_numberStates ; i++) {
121  Var v = m_stateName.find(std::make_pair("", i))->second;
122  if (model[v] == l_True) {
123  initial = i;
124  }
125  }
126 
127  // The initial state is accepting if epsilon is in Sp
128  std::unique_ptr<DFA<char>> dfa = std::make_unique<DFA<char>>(initial, m_Sp.find("") != m_Sp.end());
129 
130  // We create every state (and we seek the accepting states)
131  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
132  if (q != initial) {
133  bool accepting = false;
134  for (const auto &u : m_Sp) {
135  Var var = m_stateName.find(std::make_pair(u, q))->second;
136  if (model[var] == l_True) {
137  accepting = true;
138  break;
139  }
140  }
141 
142  dfa->addState(q, accepting);
143  }
144  }
145 
146  // Now, we create delta (the transitions)
147  for (unsigned int i = 0 ; i < m_numberStates ; i++) {
148  for (const char &a : m_alphabet) {
149  bool found = false;
150  for (unsigned int j = 0 ; j < m_numberStates ; j++) {
151  for (const auto &ua : m_prefixes) {
152  if (ua.size() > 0 && ua.at(ua.size() - 1) == a){
153  std::string u = ua.substr(0, ua.size() - 1);
154 
155  Var uiState = m_stateName.find(std::make_pair(u, i))->second;
156  Var uajState = m_stateName.find(std::make_pair(ua, j))->second;
157 
158  if (model[uiState] == l_True && model[uajState] == l_True) {
159  found = true;
160  dfa->addTransition(i, a, j);
161  }
162  }
163  }
164  }
165 
166  if (!found) {
167  dfa->addTransition(i, a, i);
168  }
169  }
170  }
171 
172  return dfa;
173  }
174  }
175  }
176 }
const std::set< char > m_alphabet
Definition: Method.h:121
The namespace of the library.
Definition: binary.h:11
void addClause(const Minisat::vec< Minisat::Lit > &clause)
Adds a new clause to the SAT solver.
const std::set< std::string > m_Sm
The set of words to reject .
Definition: Method.h:105
const std::set< std::string > m_prefixes
Definition: Method.h:117
void createVariables() override
Creates all needed variables for the method.
static bool s_registered
Useful to make sure the template is correctly used by the compiler.
Definition: MethodFactory.h:97
const unsigned int m_numberStates
The number of states in the DFA to construct.
Definition: Method.h:109
Base class for every method that relies on a SAT solver.
Definition: SATCNFMethod.h:22
std::unique_ptr< DFA< char > > toDFA(const Minisat::vec< Minisat::lbool > &model) const override
Effectively creates the DFA from the values of the variables in the given model.
const std::set< std::string > m_Sp
The set of words to accept .
Definition: Method.h:101
void createClauses() override
Creates all needed clauses for the method.
Minisat::Var newVariable()
Creates a new variable in the SAT solver.