omg_5_rabindet.cpp
Go to the documentation of this file.
1/** @file omg_5_rabindet.cpp
2 *
3 * Example usage of pseudo-determinization algorithm for Rabin automata
4 *
5 * This example demonstrates how to use the PseudoDet function to convert
6 * nondeterministic Rabin automata to deterministic ones.
7 *
8 * @ingroup Tutorials
9 * @include omg_5_rabindet.cpp
10 */
11
12 #include "libfaudes.h"
13 #include <chrono>
14 #include <ctime>
15 #include <cstdlib>
16
17 using namespace faudes;
18
19/**
20 * Generate a random nondeterministic Rabin automaton
21 * @param numStates Number of states (3-100)
22 * @param numEvents Number of events (3-7)
23 * @return Generated NRA
24 */
25RabinAutomaton GenerateRandomNRA(int numStates, int numEvents) {
27
28 // Create states (1, 2, 3, ...)
29 for(int i = 1; i <= numStates; ++i) {
30 nra.InsState(i);
31 }
32
33 // Set initial state (always state 1)
34 nra.SetInitState(1);
35
36 // Set some marked states (randomly select 1-2 states)
37 unsigned int numMarked = 1 + (rand() % std::min(2, numStates));
38 std::set<int> markedStates;
39 while(markedStates.size() < numMarked) {
40 int state = 1 + (rand() % numStates);
41 markedStates.insert(state);
42 nra.SetMarkedState(state);
43 }
44
45 // Create events (a, b, c, ...)
46 std::vector<Idx> events;
47 for(int i = 0; i < numEvents; ++i) {
48 char eventName = 'a' + i;
49 Idx event = nra.InsEvent(std::string(1, eventName));
50 events.push_back(event);
51 }
52
53 // Generate exactly numStates * numEvents transitions
54 int targetTransitions = numStates * numEvents;
55 int transitionsAdded = 0;
56
57 // First ensure each state has at least one outgoing transition
58 for(int state = 1; state <= numStates; ++state) {
59 Idx event = events[rand() % events.size()];
60 Idx target = 1 + (rand() % numStates);
61
62 if(!nra.ExistsTransition(state, event, target)) {
63 nra.SetTransition(state, event, target);
64 transitionsAdded++;
65 }
66 }
67
68 // Add remaining transitions randomly
69 while(transitionsAdded < targetTransitions) {
70 Idx source = 1 + (rand() % numStates);
71 Idx event = events[rand() % events.size()];
72 Idx target = 1 + (rand() % numStates);
73
74 if(!nra.ExistsTransition(source, event, target)) {
75 nra.SetTransition(source, event, target);
76 transitionsAdded++;
77 }
78 }
79
80 // Create simple Rabin acceptance condition (1 pair)
81 RabinAcceptance rabinPairs;
82 RabinPair pair;
83
84 // R-set: select 1-2 random states
85 unsigned int rSize = 1 + (rand() % std::min(2, numStates));
86 std::set<int> rStates;
87 while(rStates.size() < rSize) {
88 int state = 1 + (rand() % numStates);
89 rStates.insert(state);
90 pair.RSet().Insert(state);
91 }
92
93 // I-set: select 2-4 random states (include all states by default)
94 for(int state = 1; state <= numStates; ++state) {
95 pair.ISet().Insert(state);
96 }
97
98 rabinPairs.Insert(pair);
99 nra.RabinAcceptance() = rabinPairs;
100
101 return nra;
102}
103
104/**
105 * Validation function to test PseudoDet algorithm with random NRAs
106 */
107void validate() {
108 std::cout << "======== PseudoDet Algorithm Validation ========" << std::endl;
109
110 // Initialize random seed
111 srand(time(nullptr));
112
113 // Test parameters
114 std::vector<int> stateCounts = {3, 5, 10, 15, 20, 30, 50, 75, 100};
115 std::vector<int> eventCounts = {3, 4, 5, 7};
116 int testsPerConfig = 3;
117
118 std::cout << "State_Count\tEvent_Count\tNRA_States\tNRA_Trans\tDRA_States\tDRA_Trans\tTime_ms\tStatus" << std::endl;
119 std::cout << "==========================================================================" << std::endl;
120
121 int totalTests = 0;
122 int successfulTests = 0;
123
124 for(int numStates : stateCounts) {
125 for(int numEvents : eventCounts) {
126 for(int test = 0; test < testsPerConfig; ++test) {
127 totalTests++;
128
129 try {
130 // Generate random NRA
131 RabinAutomaton nra = GenerateRandomNRA(numStates, numEvents);
132
133 // Record NRA statistics
134 int nraStates = nra.Size();
135 int nraTransitions = nra.TransRelSize();
136
137 // Apply PseudoDet algorithm
138 RabinAutomaton dra;
139 auto startTime = std::chrono::high_resolution_clock::now();
140
141 PseudoDet(nra, dra);
142
143 auto endTime = std::chrono::high_resolution_clock::now();
144 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
145
146 // Record DRA statistics
147 int draStates = dra.Size();
148 int draTransitions = dra.TransRelSize();
149
150 std::cout << numStates << "\t\t" << numEvents << "\t\t"
151 << nraStates << "\t\t" << nraTransitions << "\t\t"
152 << draStates << "\t\t" << draTransitions << "\t\t"
153 << duration.count() << "\t\tSUCCESS" << std::endl;
154
155 successfulTests++;
156
157 } catch(const std::exception& e) {
158 std::cout << numStates << "\t\t" << numEvents << "\t\t"
159 << "N/A\t\tN/A\t\tN/A\t\tN/A\t\tN/A\t\tFAILED: " << e.what() << std::endl;
160 } catch(...) {
161 std::cout << numStates << "\t\t" << numEvents << "\t\t"
162 << "N/A\t\tN/A\t\tN/A\t\tN/A\t\tN/A\t\tFAILED: Unknown error" << std::endl;
163 }
164 }
165 }
166 }
167
168}
169
170
171 int main(void) {
172
173 std::cout << "======== Pseudo-Determinization Example ========" << std::endl;
174
175 // Read nondeterministic Rabin automaton from file
176 RabinAutomaton NRA;
177 NRA.Read("pseudotest/test4.gen");
178
179 // Apply pseudo-determinization algorithm
180 RabinAutomaton DRA;
181 PseudoDet(NRA, DRA);
182
183 // record test case
184 FAUDES_TEST_DUMP("pseudo det result", DRA);
185
186 // compare with our records
188
189 //std::cout << "\n======== Running Validation Tests ========" << std::endl;
190 //validate();
191
192 return 0;
193 }
194
195
#define FAUDES_TEST_DIFF()
Definition cfl_utils.h:515
#define FAUDES_TEST_DUMP(mes, dat)
Definition cfl_utils.h:505
StateSet & RSet(void)
StateSet & ISet(void)
virtual void Insert(const T &rElem)
bool InsEvent(Idx index)
bool SetTransition(Idx x1, Idx ev, Idx x2)
void RabinAcceptance(const faudes::RabinAcceptance &rRabAcc)
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
bool ExistsTransition(const std::string &rX1, const std::string &rEv, const std::string &rX2) const
void SetInitState(Idx index)
void SetMarkedState(Idx index)
Idx TransRelSize(void) const
Idx Size(void) const
void PseudoDet(const RabinAutomaton &rGen, RabinAutomaton &rRes)
uint32_t Idx
void validate()
RabinAutomaton GenerateRandomNRA(int numStates, int numEvents)
int main(void)

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen