libgsjj  1
Deterministic finite automata learning library
BinaryNonCNFMethod.cpp
Go to the documentation of this file.
2 
3 #include <iostream>
4 #include <cmath>
5 #include <vector>
6 #include <fstream>
7 #include <math.h>
8 #include <boost/algorithm/string.hpp>
9 
10 #include "MapleCOMSPS_LRB/utils/System.h"
11 using namespace Minisat;
12 
13 #include "gsjj/binary.h"
14 
15 namespace gsjj {
16  namespace passive {
17  namespace NonCNF {
18  BinaryNonCNFMethod::BinaryNonCNFMethod(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) :
19  SATNonCNFMethod(SpSet, SmSet, SSet, prefixesSet, alphabetSet, n) {
21  }
22 
24  }
25 
27  return "binaryNonCNF";
28  }
29 
30  std::string BinaryNonCNFMethod::phi_different(std::string pref1, std::string pref2){
31  unsigned int m = ceil(log2(m_numberStates));
32  std::string toWrite = "(";
33  for (unsigned int i = 0; i < m; i++){
34  toWrite = toWrite +
35  "(" +
36  "(" +
37  "x_" + pref1 + "_" + std::to_string(i) +
38  " & !" +
39  "x_" + pref2 + "_" + std::to_string(i) +
40  ")" +
41  "|" +
42  "(" +
43  "!x_" + pref1 + "_" + std::to_string(i) +
44  " & " +
45  "x_" + pref2 + "_" + std::to_string(i) +
46  ")" +
47  ")";
48  if(i != m - 1){
49  toWrite += " | ";
50  }
51  }
52  return toWrite + ")";
53  }
54 
55  std::string BinaryNonCNFMethod::phi_not_q_i(std::string pref, unsigned int i){
56  unsigned int m = ceil(log2(m_numberStates));
57  std::vector<bool> bin_i = decimal_to_binary(i, m);
58  std::string toWrite = "(";
59  for (unsigned int j = 0; j < m; j++){
60  if(bin_i.at(j) == 0){
61  toWrite = toWrite + "x_" + pref + "_" + std::to_string(j);
62  }
63  else{
64  toWrite = toWrite + "!" + "x_" + pref + "_" + std::to_string(j);
65  }
66  if(j != m - 1){
67  toWrite += " | ";
68  }
69  }
70  return toWrite + ")";
71  }
72 
73  bool BinaryNonCNFMethod::createFormula(std::ostream &stream) {
74  unsigned int m = ceil(log2(m_numberStates));
75 
76  if (m == 0) {
77  return false;
78  }
79 
80  //Traduction of the first equation of Biermann and Feldman
81  std::string formula = "";
82  for (const auto &pref : m_prefixes){
83  if (mustStop && *mustStop) {
84  return false;
85  }
86  if (pref.size() > 0) {
87  const std::string &u = pref.substr(0, pref.length() - 1);
88  const char &a = pref.at(pref.length() - 1);
89 
90  for (const auto &pref2 : m_prefixes){
91  if(pref2.size() > 0 && a == pref2.at(pref2.length() - 1)){
92  const std::string &v = pref2.substr(0, pref2.length() - 1);
93  //Phi different for u and u'
94  std::string phi_dif_u = phi_different(u, v);
95  //Phi different for ua and u'a
96  std::string phi_dif_ua = phi_different(pref, pref2);
97  //Aggregation of the two formulas to respect the Biermann and Feldman formula
98  formula = formula + "(" + phi_dif_u + " | !" + phi_dif_ua + ")\n";
99  formula += " &\n";
100  }
101  }
102  }
103  }
104  formula = formula.substr(0, formula.length() - 3) + "\n\n";
105  stream << formula;
106 
107  //Traduction of the second equation of Biermann and Feldman
108  formula = " &\n";
109  for (const auto &pos : m_Sp){
110  for (const auto &neg : m_Sm){
111  formula += phi_different(pos, neg) + " &";
112  formula += "\n";
113  }
114  }
115  formula = formula.substr(0, formula.length() - 3) + "\n\n";
116  stream << formula;
117 
118  formula = " &\n";
119  for (const auto &pref : m_prefixes){
120  for (unsigned int i = m_numberStates; i < pow(2, m); i++){
121  std::string phi_q = phi_not_q_i(pref, i);
122  formula += "(" + phi_q + ")";
123  formula += " &\n";
124  }
125  }
126  formula = formula.substr(0, formula.length() - 3);
127  stream << formula;
128 
129  return true;
130  }
131 
132  std::unique_ptr<DFA<char>> BinaryNonCNFMethod::toDFA(std::istream &stream) const {
133  //1 : Building of the arrays for each prefix
134 
135  std::string line;
136  unsigned int m = ceil(log2(m_numberStates));
137  std::map<std::pair<std::string, unsigned int>, unsigned int> m_state_bit;
138 
139  while(std::getline(stream, line)){
140  //If there is a variable on this line
141  if (line.at(0) == 'x'){
142  std::vector<std::string> results;
143  std::vector<std::string> results_2;
144  //We split the line to get var - = - assignationOfTheVar
145  boost::split(results, line, [](char c){return c == ' ';});
146  //We split the var to get x - pref - posOfTheBit
147  boost::split(results_2, results[0], [](char c){return c == '_';});
148  auto pair = std::make_pair(results_2[1], std::stoi(results_2[2]));
149  m_state_bit.emplace(state(pair, std::stoi(results[2])));
150  }
151  }
152 
153  //A map to remain the state associated to a word from S
154  std::map<std::string, unsigned int> words_states;
155 
156  //Adding the words from Sp
157  // for(const auto &u : m_Sp){
158  // std::vector<unsigned int> binary_number;
159  // for (unsigned int i = 0; i < m; i++){
160  // binary_number.push_back(m_state_bit.find(std::make_pair(u, i))->second);
161  // }
162  // unsigned int bin = binary_to_decimal(binary_number);
163  // words_states.emplace(u, bin);
164  // }
165 
166  //Adding the words from S
167  for(const auto &u : m_prefixes){
168  std::vector<bool> binary_number;
169  for (unsigned int i = 0; i < m; i++){
170  binary_number.push_back(m_state_bit.at(std::make_pair(u, i)));
171  }
172  unsigned int bin = binary_to_decimal(binary_number);
173  words_states.emplace(u, bin);
174  }
175 
176  std::unique_ptr<DFA<char>> dfa = std::make_unique<DFA<char>>(words_states.find("") -> second, m_Sp.find("") != m_Sp.end());
177 
178  for(const auto &u : m_prefixes){
179  unsigned int state = words_states.find(u) -> second;
180  //If the state is final
181  if(std::find(m_Sp.begin(), m_Sp.end(), u) != m_Sp.end()){
182  dfa->addState(state, true);
183  }
184  else{
185  dfa->addState(state, false);
186  }
187  }
188  for (unsigned int i = 0 ; i < m_numberStates ; i++) {
189  for (const char &a : m_alphabet) {
190  bool found = false;
191  for (unsigned int j = 0 ; j < m_numberStates ; j++) {
192  for (const auto &ua : m_prefixes) {
193  if (ua.size() > 0 && ua.at(ua.size() - 1) == a){
194  std::string u = ua.substr(0, ua.size() - 1);
195 
196  if (words_states.at(u) == i && words_states.at(ua) == j) {
197  found = true;
198  dfa->addTransition(i, a, j);
199  }
200  }
201  }
202  }
203 
204  if (!found) {
205  dfa->addTransition(i, a, i);
206  }
207  }
208  }
209 
210  return dfa;
211  }
212 
213  std::string BinaryNonCNFMethod::getFileName() const {
214  return "binary";
215  }
216  }
217  }
218 }
const std::set< char > m_alphabet
Definition: Method.h:121
The namespace of the library.
Definition: binary.h:11
virtual std::string getFileName() const override
Gives the name of the file in which the boolean formula must be written.
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
This file declares the function to convert a number in its decimal form to its binary form and vice-v...
static bool s_registered
Useful to make sure the template is correctly used by the compiler.
Definition: MethodFactory.h:97
virtual bool createFormula(std::ostream &stream) override
Creates the boolean formula (must not be in CNF) and writes it in the stream.
std::vector< bool > decimal_to_binary(unsigned int dec_number, unsigned int size)
Converts a number in decimal form to binary form.
Definition: binary.cpp:12
virtual std::unique_ptr< DFA< char > > toDFA(std::istream &stream) const override
Effectively creates the DFA.
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 non-CNF SAT solver.
unsigned int binary_to_decimal(const std::vector< bool > &binary_number)
Converts a number in binary form to decimal form.
Definition: binary.cpp:37
const std::set< std::string > m_Sp
The set of words to accept .
Definition: Method.h:101