cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
nfa.h
Go to the documentation of this file.
1
11
12
#ifndef CPROVER_UTIL_NFA_H
13
#define CPROVER_UTIL_NFA_H
14
15
#include <algorithm>
16
#include <cstddef>
17
#include <fstream>
18
#include <iosfwd>
19
#include <iterator>
20
#include <unordered_map>
21
#include <unordered_set>
22
#include <vector>
23
26
template
<
typename
T>
27
struct
nfat
28
{
29
using
state_labelt
= std::size_t;
33
struct
statet
34
{
35
private
:
36
std::unordered_set<state_labelt>
possible_states
;
37
38
public
:
39
friend
struct
nfat
;
40
41
bool
contains
(
state_labelt
state_label)
const
42
{
43
return
possible_states
.count(state_label) != 0;
44
}
45
};
46
47
nfat
() =
default
;
48
50
void
add_transition
(
state_labelt
from, T when,
state_labelt
to)
51
{
52
resize_if_necessary
(from, to);
53
transitions
[from].when[when].insert(to);
54
}
55
59
void
add_arbitrary_transition
(
state_labelt
from,
state_labelt
to)
60
{
61
resize_if_necessary
(from, to);
62
transitions
[from].arbitrary.insert(to);
63
}
64
66
void
add_epsilon_transition
(
state_labelt
from,
state_labelt
to)
67
{
68
resize_if_necessary
(from, to);
69
transitions
[from].epsilon.insert(to);
70
}
71
72
statet
initial_state
(
state_labelt
initial)
const
73
{
74
statet result{};
75
result.possible_states.insert(initial);
76
follow_epsilon_transitions
(result);
77
return
result;
78
}
79
80
statet
next_state
(
const
statet ¤t,
const
T &input)
const
81
{
82
statet new_state{};
83
for
(
const
auto
label : current.possible_states)
84
{
85
const
auto
&transition =
transitions
[label];
86
const
auto
it = transition.when.find(input);
87
if
(it != transition.when.end())
88
{
89
for
(
const
auto
result_state : it->second)
90
{
91
new_state.possible_states.insert(result_state);
92
}
93
}
94
for
(
const
auto
result_state : transition.arbitrary)
95
{
96
new_state.possible_states.insert(result_state);
97
}
98
}
99
follow_epsilon_transitions
(new_state);
100
return
new_state;
101
}
102
105
void
dump_automaton_dot_to
(std::ostream &out)
const
106
{
107
out <<
"digraph {\n"
;
108
for
(
state_labelt
from = 0; from <
transitions
.size(); ++from)
109
{
110
for
(
const
auto
to :
transitions
[from].arbitrary)
111
{
112
out <<
'S'
<< from <<
" -> S"
<< to <<
"[label=\"*\"]\n"
;
113
}
114
for
(
const
auto
to :
transitions
[from].epsilon)
115
{
116
out <<
'S'
<< from <<
" -> S"
<< to <<
u8
"[label=\"ε\"]\n"
;
117
}
118
for
(
const
auto
&pair :
transitions
[from].when)
119
{
120
const
auto
&in = pair.first;
121
const
auto
&tos = pair.second;
122
for
(
const
auto
to : tos)
123
{
124
out <<
'S'
<< from <<
" -> S"
<< to <<
"[label=\"("
<< in <<
")\"]\n"
;
125
}
126
}
127
}
128
out <<
"}\n"
;
129
}
130
131
private
:
132
void
resize_if_necessary
(
state_labelt
from,
state_labelt
to)
133
{
134
const
auto
min_size = std::max(from, to) + 1;
135
if
(
transitions
.size() < min_size)
136
{
137
transitions
.resize(min_size);
138
}
139
}
140
141
void
follow_epsilon_transitions
(statet &state)
const
142
{
143
std::vector<state_labelt> new_states{};
144
do
145
{
146
new_states.clear();
147
for
(
const
auto
from : state.possible_states)
148
{
149
for
(
const
auto
to :
transitions
[from].epsilon)
150
{
151
if
(!state.contains(to))
152
{
153
new_states.push_back(to);
154
}
155
}
156
}
157
std::copy(
158
new_states.begin(),
159
new_states.end(),
160
std::inserter(state.possible_states, state.possible_states.end()));
161
}
while
(!new_states.empty());
162
}
163
164
struct
transitiont
165
{
166
std::unordered_set<state_labelt>
epsilon
;
167
std::unordered_set<state_labelt>
arbitrary
;
168
std::unordered_map<T, std::unordered_set<state_labelt>>
when
;
169
};
170
171
std::vector<transitiont>
transitions
;
172
};
173
174
#endif
// CPROVER_UTIL_NFA_H
u8
uint64_t u8
Definition
bytecode_info.h:58
nfat::statet
A state is a set of possibly active transitions.
Definition
nfa.h:34
nfat::statet::possible_states
std::unordered_set< state_labelt > possible_states
Definition
nfa.h:36
nfat::statet::nfat
friend struct nfat
Definition
nfa.h:39
nfat::statet::contains
bool contains(state_labelt state_label) const
Definition
nfa.h:41
nfat::transitiont
Definition
nfa.h:165
nfat::transitiont::when
std::unordered_map< T, std::unordered_set< state_labelt > > when
Definition
nfa.h:168
nfat::transitiont::arbitrary
std::unordered_set< state_labelt > arbitrary
Definition
nfa.h:167
nfat::transitiont::epsilon
std::unordered_set< state_labelt > epsilon
Definition
nfa.h:166
nfat::initial_state
statet initial_state(state_labelt initial) const
Definition
nfa.h:72
nfat::next_state
statet next_state(const statet ¤t, const T &input) const
Definition
nfa.h:80
nfat::nfat
nfat()=default
state_labelt::state_labelt
std::size_t state_labelt
Definition
nfa.h:29
nfat::resize_if_necessary
void resize_if_necessary(state_labelt from, state_labelt to)
Definition
nfa.h:132
nfat::add_arbitrary_transition
void add_arbitrary_transition(state_labelt from, state_labelt to)
Add a transition from "from" to "to" when any input is consumed This is handled a special case so not...
Definition
nfa.h:59
state_labelt::transitions
std::vector< transitiont > transitions
Definition
nfa.h:171
nfat::dump_automaton_dot_to
void dump_automaton_dot_to(std::ostream &out) const
Write the automaton structure to out in graphviz dot format.
Definition
nfa.h:105
nfat::follow_epsilon_transitions
void follow_epsilon_transitions(statet &state) const
Definition
nfa.h:141
nfat::add_transition
void add_transition(state_labelt from, T when, state_labelt to)
Add a transition from "from" to "to" exactly when "when" is consumed.
Definition
nfa.h:50
nfat::add_epsilon_transition
void add_epsilon_transition(state_labelt from, state_labelt to)
Add a transition from "from" to "to" that doesn’t consume input.
Definition
nfa.h:66
util
nfa.h
Generated by
1.17.0