CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
26template <typename T>
27struct 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
42 {
43 return possible_states.count(state_label) != 0;
44 }
45 };
46
47 nfat() = default;
48
51 {
53 transitions[from].when[when].insert(to);
54 }
55
64
71
73 {
74 statet result{};
75 result.possible_states.insert(initial);
77 return result;
78 }
79
80 statet next_state(const statet &current, const T &input) const
81 {
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 }
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
131private:
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
142 {
143 std::vector<state_labelt> new_states{};
144 do
145 {
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
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
virtual void clear()
Reset the abstract state.
Definition ai.h:265
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
A state is a set of possibly active transitions.
Definition nfa.h:34
std::unordered_set< state_labelt > possible_states
Definition nfa.h:36
bool contains(state_labelt state_label) const
Definition nfa.h:41
std::unordered_map< T, std::unordered_set< state_labelt > > when
Definition nfa.h:168
std::unordered_set< state_labelt > arbitrary
Definition nfa.h:167
std::unordered_set< state_labelt > epsilon
Definition nfa.h:166
Very simple NFA implementation Not super performant, but should be good enough for our purposes.
Definition nfa.h:28
statet initial_state(state_labelt initial) const
Definition nfa.h:72
statet next_state(const statet &current, const T &input) const
Definition nfa.h:80
nfat()=default
std::size_t state_labelt
Definition nfa.h:29
void resize_if_necessary(state_labelt from, state_labelt to)
Definition nfa.h:132
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
std::vector< transitiont > transitions
Definition nfa.h:171
void dump_automaton_dot_to(std::ostream &out) const
Write the automaton structure to out in graphviz dot format.
Definition nfa.h:105
void follow_epsilon_transitions(statet &state) const
Definition nfa.h:141
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
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