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  */
25 RabinAutomaton GenerateRandomNRA(int numStates, int numEvents) {
26  RabinAutomaton nra;
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  */
107 void 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)
Definition: omg_rabinacc.h:68
StateSet & ISet(void)
Definition: omg_rabinacc.h:84
virtual void Insert(const T &rElem)
bool InsEvent(Idx index)
bool SetTransition(Idx x1, Idx ev, Idx x2)
void RabinAcceptance(const faudes::RabinAcceptance &rRabAcc)
Definition: omg_rabinaut.h:326
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_types.cpp:267
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.33l --- 2025.09.16 --- c++ api documentaion by doxygen