libgsjj  1
Deterministic finite automata learning library
BiermannMethod.cpp
Go to the documentation of this file.
3 
4 using namespace CVC4;
5 
6 namespace gsjj {
7  namespace passive {
8  namespace SMT {
9  BiermannMethod::BiermannMethod(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) :
10  SMTMethod(SpSet, SmSet, SSet, prefixesSet, alphabetSet, n)
11  {
13  }
14 
16 
17  }
18 
20  return "biermann";
21  }
22 
24  Type integer = m_exprManager.integerType();
25 
26  for (const auto &u : m_prefixes) {
27  Expr x = m_exprManager.mkVar(u, integer);
28  m_stateName[u] = x;
29  }
30  }
31 
33  Expr formula;
34 
35  // Values in [0, numberStates-1]
36  Expr zero = m_exprManager.mkConst(Rational(0));
37  Expr n = m_exprManager.mkConst(Rational(m_numberStates - 1));
38  for (const auto &u : m_prefixes) {
39  Expr positive = m_exprManager.mkExpr(kind::GEQ, m_stateName[u], zero);
40  Expr lowerN = m_exprManager.mkExpr(kind::LEQ, m_stateName[u], n);
41  Expr between = positive.andExpr(lowerN);
42  if (formula.isNull()) {
43  formula = between;
44  }
45  else {
46  formula = formula.andExpr(between);
47  }
48  }
49 
50  // Equation 4.2.1
51  for (const auto &ua : m_prefixes) {
52  if (ua.size() > 0) {
53  const char &a = ua.at(ua.size() - 1);
54  const std::string &u = ua.substr(0, ua.size() - 1);
55  for (const auto &va : m_prefixes) {
56  if(va.size() > 0 && va.at(va.size() - 1) == a) {
57  const std::string &v = va.substr(0, va.size() - 1);
58 
59  Expr premise = m_exprManager.mkExpr(kind::EQUAL, m_stateName[u], m_stateName[v]);
60  Expr conclusion = m_exprManager.mkExpr(kind::EQUAL, m_stateName[ua], m_stateName[va]);
61 
62  Expr implication = m_exprManager.mkExpr(kind::IMPLIES, premise, conclusion);
63 
64  formula = formula.andExpr(implication);
65  }
66  }
67  }
68  }
69 
70  // Equation 4.2.2
71  for (const auto &u : m_Sp) {
72  for (const auto &v : m_Sm) {
73  Expr diff = m_exprManager.mkExpr(kind::EQUAL, m_stateName[u], m_stateName[v]).notExpr();
74 
75  formula = formula.andExpr(diff);
76  }
77  }
78 
79  return formula;
80  }
81 
82  std::unique_ptr<DFA<char>> BiermannMethod::toDFA() {
83  // First, we must seek the initial state
84  unsigned int initial = m_SMTEngine.getValue(m_stateName.find("")->second).getConst<Rational>().getNumerator().toUnsignedInt();
85 
86  std::unique_ptr<DFA<char>> dfa = std::make_unique<DFA<char>>(initial, m_Sp.find("") != m_Sp.end());
87 
88  // Now, we create every needed state (and we set it accepting if needed)
89  for (unsigned int q = 0 ; q < m_numberStates ; q++) {
90  if (q != initial) {
91  bool accepting = false;
92  for (const auto &u : m_Sp) {
93  Expr expr = m_stateName.find(u)->second;
94  if (m_SMTEngine.getValue(expr).getConst<Rational>().getNumerator().toUnsignedInt() == q) {
95  accepting = true;
96  break;
97  }
98  }
99 
100  dfa->addState(q, accepting);
101  }
102  }
103 
104  // Finally, we create delta
105  for (unsigned int i = 0 ; i < m_numberStates ; i++) {
106  for (const char &a : m_alphabet) {
107  bool found = false;
108  for (unsigned int j = 0 ; j < m_numberStates ; j++) {
109  for (const auto &ua : m_prefixes) {
110  if (ua.size() > 0 && ua.at(ua.size() - 1) == a){
111  std::string u = ua.substr(0, ua.size() - 1);
112 
113  Expr uState = m_stateName.find(u)->second;
114  Expr uaState = m_stateName.find(ua)->second;
115 
116  if (m_SMTEngine.getValue(uState).getConst<Rational>().getNumerator().toUnsignedInt() == i && m_SMTEngine.getValue(uaState).getConst<Rational>().getNumerator().toUnsignedInt() == j) {
117  found = true;
118  dfa->addTransition(i, a, j);
119  }
120  }
121  }
122  }
123 
124  if (!found) {
125  dfa->addTransition(i, a, i);
126  }
127  }
128  }
129 
130  return dfa;
131  }
132  }
133  }
134 }
const std::set< char > m_alphabet
Definition: Method.h:121
The namespace of the library.
Definition: binary.h:11
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
static bool s_registered
Useful to make sure the template is correctly used by the compiler.
Definition: MethodFactory.h:97
The base class for every SMT-based method.
Definition: SMTMethod.h:20
const unsigned int m_numberStates
The number of states in the DFA to construct.
Definition: Method.h:109
void createVariables() override
Creates all needed variables for the method.
CVC4::ExprManager m_exprManager
This must be used to create new variables, constants and expressions.
Definition: SMTMethod.h:35
const std::set< std::string > m_Sp
The set of words to accept .
Definition: Method.h:101
std::unique_ptr< DFA< char > > toDFA()
Effectively creates the DFA from the values of the variables in the SMT solver (see SMTMethod::m_SMTE...
CVC4::Expr createConstraints() override
Creates an unique expression describing the constraints of this method.
CVC4::SmtEngine m_SMTEngine
This computes acceptable values for the variables and allows to retrieve them.
Definition: SMTMethod.h:39