[Avida-SVN] r1799 - branches/uml/source/main

hjg at myxo.css.msu.edu hjg at myxo.css.msu.edu
Fri Jul 13 11:47:44 PDT 2007


Author: hjg
Date: 2007-07-13 14:47:44 -0400 (Fri, 13 Jul 2007)
New Revision: 1799

Added:
   branches/uml/source/main/cUMLModel.cc
   branches/uml/source/main/cUMLModel.h
   branches/uml/source/main/cUMLStateDiagram.cc
   branches/uml/source/main/cUMLStateDiagram.h
Log:


Added: branches/uml/source/main/cUMLModel.cc
===================================================================
--- branches/uml/source/main/cUMLModel.cc	                        (rev 0)
+++ branches/uml/source/main/cUMLModel.cc	2007-07-13 18:47:44 UTC (rev 1799)
@@ -0,0 +1,202 @@
+#include "cUMLModel.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <iomanip>
+#include <errno.h>
+
+
+using namespace std;
+
+std::string loadFile(const char* filename) {
+	std::string data, line; // or maybe stringstream? (strstream?)
+	std::ifstream infile;
+	infile.open(filename);
+	assert(infile.is_open());
+	
+	while (getline (infile, line))
+	{
+		data.append(line);
+		line.erase();
+	}
+	
+	//read from file; load into string/strstream, and return it.
+	infile.close();
+
+	return data;
+}
+
+std::string cUMLModel::xmi_begin = loadFile("xmi_begin");
+std::string cUMLModel::xmi_end = loadFile("xmi_end");
+std::string cUMLModel::xmi_class1 = loadFile("class1_xmi");
+std::string cUMLModel::xmi_class2 = loadFile("class2_xmi");
+
+
+cUMLModel::cUMLModel()
+{
+	// initialize / seed UML model here
+//	state_diagrams.clear();
+//	state_diagrams.resize(2);
+}
+
+cUMLModel::~cUMLModel()
+{}
+
+cUMLStateDiagram* cUMLModel::getStateDiagram (int x) 
+{
+	// check to see whether this state diagram exists
+	if (x < state_diagrams.size()) { 
+		return (&(state_diagrams.begin()[x]));
+	}
+
+}
+
+/* This is a crappy little function to read in from a file. 
+It is not robust. It will not understand things unless you 
+follow the *very* specific file format. */
+void cUMLModel::seedDiagrams()
+{
+	std::string data, line; // or maybe stringstream? (strstream?)
+	int num_states;
+	int num_sd = 0;
+	int cur_sd = -1;
+	char c;
+	std::string tr_l, tr_o, gu, act;
+	std::ifstream infile;
+	infile.open("seed-model.cfg");
+	assert(infile.is_open());
+	
+	while (getline (infile, line))
+	{
+		// Read in states
+		if (line == "=STATES====================") {
+//			std::cout << "Ooh, I found a state! " << std::endl;
+			line.erase();
+			infile >> num_states;
+//			std::cout << "Numer of states: "<< num_states << std::endl;
+		// Read in number of state diagrams	
+		} else if (line == "=STATE-DIAGRAM=============") { 
+//			std::cout << "Yippee! A state diagram for me! " << std::endl;
+			line.erase();
+			infile >> num_sd;
+//			std::cout << "Numer of sds: "<< num_sd << std::endl;
+			state_diagrams.resize(num_sd);
+		// Read in each state diagram	
+		} else if (line == "=SD========================") { 
+			line.erase();
+			cur_sd++;
+		} else if (line == "-TRIGGERS------------------") { 
+			line.erase();
+			infile >> tr_l;
+			while (tr_l != "-END---------------------------") { 
+				infile >> tr_o;
+				state_diagrams[cur_sd].addTrigger(tr_l, tr_o);
+//				std::cout << "Adding a trigger " << tr_l << " " << tr_o << std::endl;
+				infile >> tr_l;
+			}
+		}else if (line == "-GUARDS--------------------") { 
+			line.erase();
+			infile >> gu;
+			while (gu != "-END---------------------------") { 
+				state_diagrams[cur_sd].addGuard(gu);
+//				std::cout << "Adding a guard " << gu << std::endl;
+				infile >> gu;
+			}
+		} else if (line == "-ACTIONS--------------------") { 
+			line.erase();
+			infile >> act;
+			while (act != "-END---------------------------") { 
+				state_diagrams[cur_sd].addAction(act);
+//				std::cout << "Adding an action " << act << std::endl;
+				infile >> act;
+			}
+		}
+		
+		/* Missing code for reading in transition labels and transitions.... */
+		
+
+		
+		line.erase();
+	}
+	
+	//read from file; load into string/strstream, and return it.
+	infile.close();
+
+	return;
+  
+}
+
+
+void cUMLModel::printXMI()
+{
+	xmi = "";
+//	int v;
+	
+	xmi = xmi_begin; 
+	
+//	xmi += xmi_class1;
+//	xmi += state_diagrams[0].getXMI();
+//	xmi += xmi_class2;
+//	state_diagrams[1].printXMI();
+	xmi += state_diagrams[1].getXMI();
+
+	xmi += xmi_end;
+	
+}
+
+std::string cUMLModel::getXMI()
+{
+//	printXMI();
+	return xmi;
+}
+
+int cUMLModel::numStates() 
+{ 
+	int temp_states = 0;
+	for (int i=0; i<state_diagrams.size(); i++) { 
+		temp_states += getStateDiagram(i)->numStates();
+	}
+	return temp_states;
+}
+
+int cUMLModel::numTrans()
+{
+int temp_trans = 0;
+	for (int i=0; i<state_diagrams.size(); i++) { 
+		temp_trans += getStateDiagram(i)->numTrans();
+	}
+	return temp_trans;
+}
+
+int cUMLModel::numTriggers()
+{
+int temp_trigger = 0;
+	for (int i=0; i<state_diagrams.size(); i++) { 
+		temp_trigger += getStateDiagram(i)->numTriggers();
+	}
+	return temp_trigger;
+}
+
+int cUMLModel::numGuards() 
+{
+int temp = 0;
+	for (int i=0; i<state_diagrams.size(); i++) { 
+		temp += getStateDiagram(i)->numGuards();
+	}
+	return temp;
+}
+
+int cUMLModel::numActions()
+{
+int temp = 0;
+	for (int i=0; i<state_diagrams.size(); i++) { 
+		temp += getStateDiagram(i)->numActions();
+	}
+	return temp;
+}
+
+int cUMLModel::numSDs()
+{
+	return state_diagrams.size();
+}
+

Added: branches/uml/source/main/cUMLModel.h
===================================================================
--- branches/uml/source/main/cUMLModel.h	                        (rev 0)
+++ branches/uml/source/main/cUMLModel.h	2007-07-13 18:47:44 UTC (rev 1799)
@@ -0,0 +1,55 @@
+#ifndef _C_UMLMODEL_H_
+#define _C_UMLMODEL_H_
+
+#include "cUMLStateDiagram.h"
+
+#include <string>
+#include <iostream>
+#include <map>
+#include <utility>
+#include <set>
+#include <vector>
+#include <fstream>
+
+
+class cUMLModel { 
+public:
+	cUMLModel();
+	~cUMLModel();
+
+	// Read in from file seed-model.cfg and add the building blocks for the diagrams.
+	void seedDiagrams(); 
+	
+	// Used to generate and access the XMI version of the model.
+	std::string getXMI(); // get the XMI version of the model.
+	void printXMI(); // create the XMI version of the model.	
+	
+	// Access the size of the state diagrams and also a specific state diagram
+	int getStateDiagramSize() { return state_diagrams.size(); } 
+	cUMLStateDiagram* getStateDiagram (int); 
+	
+	// Set and access the bonus info for a model. Should be used by the tasks
+	bool setBonusInfo (std::string s, float f) { bonus_info[s] = f; } 
+	float getBonusInfo (std::string s) { return bonus_info[s]; }
+	
+	// Get the number of, well, everything
+	int numStates();
+	int numTrans();
+	int numTriggers();
+	int numGuards();
+	int numActions();
+	int numSDs();
+	
+
+protected: 
+	static std::string xmi_begin;
+	std::string	xmi; 
+	static std::string xmi_end;
+	static std::string xmi_class1;
+	static std::string xmi_class2;
+	std::vector<cUMLStateDiagram> state_diagrams;
+	std::map<std::string, float> bonus_info;
+										
+};
+
+#endif

Added: branches/uml/source/main/cUMLStateDiagram.cc
===================================================================
--- branches/uml/source/main/cUMLStateDiagram.cc	                        (rev 0)
+++ branches/uml/source/main/cUMLStateDiagram.cc	2007-07-13 18:47:44 UTC (rev 1799)
@@ -0,0 +1,567 @@
+#include "cUMLStateDiagram.h"
+
+cUMLStateDiagram::cUMLStateDiagram()
+{
+
+  // initialize the state diagram with 10 states.
+  sd0 = state_diagram(10); 
+
+  // initialize / seed UML state diagram here
+//  orig_state_index = 0;
+//  dest_state_index = 0;
+	orig = vertex(0, sd0);
+	dest = vertex(0, sd0);
+  
+  trans_label_index = 0;
+  trigger_index = 0;
+  guard_index = 0;
+  action_index = 0;
+
+  xmi = "";
+    
+}
+
+cUMLStateDiagram::~cUMLStateDiagram()
+{
+}
+
+
+// This function accepts a path throught the state diagram as a deque and returns the length 
+// of the longest path segment that the diagram satisfies. 
+// The function is complicated by the fact that the longest path segment could start at the 
+// beginning, middle, or end of the path itself AND the path could begin at any reachable vertex. 
+int cUMLStateDiagram::findPath(std::deque<std::string> p) { 
+	int path_dist = 0; // the current path distance satisfied is 0. 
+//	int path_total_length = p.size();
+	int path_longest_length = 0; 
+	int len = 0;
+	int num_vert = num_vertices(sd0);
+	std::deque<std::string> p_temp = p;
+
+
+
+	// Must start at state 0. 
+	// Must check each state. 
+	while (!p.empty()) {
+
+	for (int i = 0; i<num_vert; i++) { 
+			len = checkForPathStep(p, vertex(i, sd0), 0);
+			// check to see if this path is longer than other paths....
+			if (len > path_dist) { 
+				path_dist = len;
+			}	
+		}
+		p.pop_front(); 
+		
+		if (len > p.size()) break;
+	}
+	return path_dist;
+	
+	
+}
+
+int cUMLStateDiagram::checkForPathStep(std::deque<std::string> path, 
+				boost::graph_traits<state_diagram>::vertex_descriptor v, 
+				int curr_dist) { 
+	
+	boost::graph_traits<state_diagram>::out_edge_iterator out_edge_start, out_edge_end;
+	boost::graph_traits<state_diagram>::edge_descriptor ed;
+	std::string tt, tg, ta, ts;
+	int longest_dist = curr_dist;
+	int temp;
+
+	if (path.empty()) return curr_dist;
+
+	// Get the outgoing edges of v
+	for(tie(out_edge_start, out_edge_end) = out_edges(v, sd0);
+			 out_edge_start != out_edge_end; ++out_edge_start) { 
+			ed = *out_edge_start;
+			
+			// Get the label of the edge
+			tt = triggers[(sd0[ed]._tr)].operation_id;
+			tg = guards[(sd0[ed]._gu)];
+			ta = actions[(sd0[ed]._act)];
+			
+			// eliminate nulls
+			if (tt == "<null>") tt = "";
+			if (tg == "<null>") tg = "";
+			if (ta == "<null>") ta = "";
+			
+			ts = tt + tg + ta;
+			
+			
+			if (ts == path.front()) { 
+				//std::cout << "Looking for and found a path named: " << ts << std::endl;
+				//std::cout << "Searching vertex " << target(ed, sd0) << "with distance " << curr_dist+1 << std::endl; 
+
+				temp = checkForPathStep(std::deque<std::string>(++path.begin(), path.end()), target(ed,sd0), curr_dist+1);
+				if (temp > longest_dist) longest_dist = temp;
+			}
+	}
+	
+	//std::cout << "Returning longest_dist " << longest_dist << std::endl;
+	return longest_dist;
+
+} 
+
+
+
+
+bool cUMLStateDiagram::findTrans(int origin, int destination, int trig, int gu, int act) 
+{
+
+	bool result = false;
+	
+	if (num_edges(sd0) == 0) { 
+		return false;
+	}
+	
+	boost::graph_traits<state_diagram>::vertex_descriptor o_temp, d_temp;
+	boost::graph_traits<state_diagram>::edge_iterator edge_start, edge_end;
+	boost::graph_traits<state_diagram>::out_edge_iterator out_edge_start, out_edge_end;
+	boost::graph_traits<state_diagram>::in_edge_iterator in_edge_start, in_edge_end;
+	boost::graph_traits<state_diagram>::edge_descriptor ed;
+
+	// Get the set of transitions.
+	if ((origin == -1) && (destination == -1)) { 
+		for (tie(edge_start, edge_end) = edges(sd0);
+			 edge_start != edge_end; ++edge_start) { 
+			ed = *edge_start;
+			if (((trig == -1)	|| (sd0[ed]._tr == trig))		&& 
+				((gu == -1)		|| (sd0[ed]._gu == gu))			&& 
+				((act == -1)	|| (sd0[ed]._act == act)))  { 
+				result = true; 
+				break;
+			}	
+		}
+	} else if (origin == -1 && destination != -1) { 
+		if (destination > num_vertices(sd0)) return result;
+		d_temp = vertex(destination, sd0);
+		for (tie(in_edge_start, in_edge_end) = in_edges(d_temp, sd0);
+			 in_edge_start != in_edge_end; ++in_edge_start) { 
+			ed = *in_edge_start;
+			if (((trig == -1)	|| (sd0[ed]._tr == trig))		&& 
+				((gu == -1)		|| (sd0[ed]._gu == gu))			&& 
+				((act == -1)	|| (sd0[ed]._act == act)))  { 
+				result = true; 
+				break;
+			}	
+		}
+	} else if (origin != -1 && destination == -1) { 
+		if (origin > num_vertices(sd0)) return result;
+		o_temp = vertex(origin, sd0);
+
+		for(tie(out_edge_start, out_edge_end) = out_edges(o_temp, sd0);
+			 out_edge_start != out_edge_end; ++out_edge_start) { 
+			ed = *out_edge_start;
+			if (((trig == -1)	|| (sd0[ed]._tr == trig))		&& 
+				((gu == -1)		|| (sd0[ed]._gu == gu))			&& 
+				((act == -1)	|| (sd0[ed]._act == act)))  { 
+				result = true; 
+				break;
+			}	
+		}
+	} else if (origin != -1 && destination != -1) { 
+		if ((destination > num_vertices(sd0)) || 
+			(origin > num_vertices(sd0))) return result;
+		o_temp = vertex(origin, sd0);
+		d_temp = vertex(destination, sd0);
+		for(tie(out_edge_start, out_edge_end) = edge_range (o_temp, d_temp, sd0);
+			 out_edge_start != out_edge_end; ++out_edge_start) { 
+			ed = *out_edge_start;
+			if (((trig == -1)	|| (sd0[ed]._tr == trig))		&& 
+				((gu == -1)		|| (sd0[ed]._gu == gu))			&& 
+				((act == -1)	|| (sd0[ed]._act == act)))  { 
+				result = true; 
+				break;
+			}	
+		}
+	}
+	
+	return result;
+
+}
+
+
+
+template <typename T>
+bool cUMLStateDiagram::absoluteMoveIndex (T x, int &index, int amount )
+{
+
+	if (x.size() == 0 || amount > x.size()) {
+		return false;
+	}
+	
+	index = 0;
+	return relativeMoveIndex(x, index, amount);
+}
+
+template <typename T>
+bool cUMLStateDiagram::relativeMoveIndex (T x, int &index, int amount )
+{
+	if (x.size() == 0) {
+		return false;
+	}
+	
+	if (amount > 0) { 
+		index += (amount % x.size());
+
+		// index is greater than vector
+		if (index >= x.size()) { 
+			index -= x.size();
+		} else if(index < 0) { 
+			index += x.size();
+		}
+	}	
+		
+	return true;
+}
+
+
+
+bool cUMLStateDiagram::absoluteJumpTrigger(int jump_amount)
+{
+	return absoluteMoveIndex(triggers, trigger_index, jump_amount);
+}
+
+bool cUMLStateDiagram::absoluteJumpGuard(int jump_amount)
+{
+	return absoluteMoveIndex(guards, guard_index, jump_amount);	
+}
+
+bool cUMLStateDiagram::absoluteJumpAction(int jump_amount)
+{
+	return absoluteMoveIndex(actions, action_index, jump_amount);
+}
+
+bool cUMLStateDiagram::absoluteJumpTransitionLabel(int jump_amount)
+{
+	return absoluteMoveIndex(transition_labels, trans_label_index, jump_amount);
+}
+
+bool cUMLStateDiagram::absoluteJumpOriginState(int jump_amount) 
+{	
+	bool result = false;
+	int x = num_vertices(sd0);
+	
+	if (num_vertices(sd0) > jump_amount) {  	
+		orig = vertex(jump_amount, sd0);
+		result = true;
+	}
+	return result;
+}
+
+bool cUMLStateDiagram::absoluteJumpDestinationState(int jump_amount) 
+{	
+	bool result = false;
+	if (num_vertices(sd0) > jump_amount) {  	
+		dest = vertex(jump_amount, sd0);
+		result = true;
+	}
+	return result;
+}
+
+
+int cUMLStateDiagram::getTriggerIndex()
+{
+	return trigger_index;
+}
+
+int cUMLStateDiagram::getGuardIndex()
+{
+		return guard_index;
+}
+
+int cUMLStateDiagram::getActionIndex()
+{
+		return action_index;
+	
+}
+
+
+transition_label cUMLStateDiagram::getTransLabel()
+{
+	return transition_labels[trans_label_index];
+}
+
+bool cUMLStateDiagram::addTrigger(std::string op_id, std::string lab) 
+{
+	trigger_info t;
+	t.operation_id = op_id;
+	t.label = lab;
+	
+	triggers.push_back(t);
+	
+	return true;
+}
+
+bool cUMLStateDiagram::addGuard(std::string gu) 
+{
+	guards.push_back(gu);
+	return true;
+}
+
+bool cUMLStateDiagram::addAction(std::string act)
+{
+	actions.push_back(act);
+	return true;
+}
+
+/*
+bool cUMLStateDiagram::addTransition()
+{
+	
+	if ((states.size() == 0) || (transition_labels.size() == 0)) {
+
+		return false;
+	} 
+
+	transition t;
+	t.orig_state = getOrigStateIndex();
+	t.dest_state = getDestStateIndex();
+	// increment number of edges for a state
+	states[getOrigStateIndex()].num_outgoing += 1;
+	states[getDestStateIndex()].num_incoming += 1;
+	
+	t.trans = getTransLabel();
+	
+	if ((t.orig_state != 0) && (states[t.orig_state].num_incoming == 0)) {
+		return false;
+	}
+	
+	// no dupes
+    if (findTrans(t.orig_state, t.dest_state, t.trans.trigger, t.trans.guard, t.trans.action)) {
+		return false;
+	}
+
+	transitions.push_back(t);
+//	boost::add_edge(transition_properties());
+
+	orig_state_index = 0;
+	dest_state_index = 0;
+	trans_label_index = 0;
+	trigger_index = 0;
+	guard_index = 0 ;
+	action_index = 0;
+	
+	return true;
+
+}
+*/
+
+bool cUMLStateDiagram::addTransitionLabel(int tr, int gu, int act)
+{
+	transition_label t;
+	t.trigger = tr;
+	t.guard = gu;
+	t.action = act;
+
+	// currently, not checking for dupes, since we are seeding the labels.
+	
+	transition_labels.push_back(t);
+}
+
+
+bool cUMLStateDiagram::addTransitionTotal()
+{
+	// Check that there are two vertices
+	if (num_vertices(sd0) == 0) {
+		return false;
+	} 
+		
+	// Check that the origin state of the transition is reachable.
+	boost::graph_traits<state_diagram>::in_edge_iterator in_start, in_end;
+	tie (in_start, in_end) = in_edges(orig, sd0);
+	if ((in_start == in_end) && (orig != vertex(0, sd0))) { 
+		return false;
+	}
+
+	// Check that there is not a duplicate transition
+	if (findTrans(orig, dest, trigger_index, guard_index, action_index)) { 
+		return false;
+	}
+	
+	// Create the transition properties
+	transition_properties tp = transition_properties(trigger_index, guard_index, action_index); 
+	
+	// Create the transition
+	add_edge(orig, dest, tp, sd0);
+		
+	// Reset all the indices
+	trigger_index = 0;
+	action_index = 0;
+	guard_index = 0;
+	orig = vertex(0, sd0);
+	dest = vertex(0, sd0);
+		
+	return true;
+
+}
+
+
+
+
+int cUMLStateDiagram::numStates()
+{
+	return num_vertices(sd0);
+}
+
+int cUMLStateDiagram::numTrans()
+{
+	return num_edges(sd0);
+} 
+
+// print the label. Change - signs to _
+std::string cUMLStateDiagram::StringifyAnInt(int x) { 
+
+	std::ostringstream o;
+
+	if (x < 0) {
+		x = abs(x);
+		o << "_";
+	} 
+	
+	o << x;
+	return o.str();
+}
+
+void cUMLStateDiagram::executeVisitor() {
+
+	PathVisitor visitor; 
+	boost::graph_traits<state_diagram>::vertex_descriptor o_temp;
+	o_temp = vertex(0, sd0);
+	
+	boost::breadth_first_search(sd0, o_temp, boost::visitor(visitor));
+
+}
+
+
+struct transition_writer {
+	transition_writer(cUMLStateDiagram::state_diagram& sd) : _sd(sd) { }
+	
+	template<typename Edge>
+	void operator()(std::ostream& out) {
+		out << "working?";
+	}
+  
+	cUMLStateDiagram::state_diagram& _sd;
+}; 
+
+void cUMLStateDiagram::printGraphViz() { 
+	std::ofstream outfile("gv");
+    boost::write_graphviz(outfile, sd0); //, transition_writer(sd0)); //, topo_vertex_writer(_topo_last_network));
+    outfile.close();
+
+}
+
+std::string cUMLStateDiagram::getXMI()
+{
+	printXMI();
+	return (xmi);
+}
+
+void cUMLStateDiagram::printXMI()
+{
+	std::string temp, temp1, temp2, temp3;
+	std::string trig_label, trig_op_name;
+	
+	boost::graph_traits<state_diagram>::edge_iterator edge_start, edge_end;
+	boost::graph_traits<state_diagram>::edge_descriptor ed;
+
+	int s_count = 0;
+	int t_count = 0;
+	xmi = "";
+
+	// This state is the initial state; thus it should be printed regardless of whether it has an incoming
+	// edge or not.
+	if (numStates() > 0) {
+		temp = "_1";
+		xmi += "<UML:Pseudostate xmi.id=\"s" + temp + "\" kind=\"initial\" outgoing=\"\" name=\"s";
+		xmi += temp + "\" isSpecification=\"false\"/>\n";
+	}
+	
+	for (; s_count < numStates(); ++s_count) {
+				temp = "s" + StringifyAnInt(s_count);
+			xmi+="<UML:CompositeState xmi.id=\"";
+			xmi+=temp;
+			xmi+= "\" isConcurrent=\"false\" name=\""; 
+			xmi+= temp; 
+			xmi+= "\" isSpecification=\"false\"/>\n";
+	}
+		
+		// end the set of states....
+		xmi+= "</UML:CompositeState.subvertex>\n";
+		xmi+= "</UML:CompositeState>\n";
+		xmi+= "</UML:StateMachine.top>\n";
+		
+		// start the set of transitions...
+		xmi+="<UML:StateMachine.transitions>\n";
+
+
+	// Get the set of transitions.
+	for (tie(edge_start, edge_end) = edges(sd0);
+			 edge_start != edge_end; ++edge_start) {
+		
+		ed = *edge_start;
+	 	 
+		// info determined from the trans itself....
+		temp = "t" + StringifyAnInt(t_count);
+		temp1 = "s" + StringifyAnInt(source(ed, sd0));
+		temp2 = "s" + StringifyAnInt(target(ed, sd0));
+		temp3 = temp + temp1 + temp2;
+		
+		xmi+= "<UML:Transition xmi.id=\"" + temp3 + "\"";
+		xmi+= " source=\"" + temp1 + "\"";
+		xmi += " target=\"" + temp2 + "\" name=\"\" isSpecification=\"false\">\n";
+
+		// Get guard, trigger, and action
+		temp1 = guards[(sd0[ed]._gu)];
+		temp2 = actions[(sd0[ed]._act)];
+		trig_label = triggers[(sd0[ed]._tr)].label;
+		trig_op_name = triggers[(sd0[ed]._tr)].operation_id;
+
+		// print trigger, if any
+		if (trig_label != "<null>") {
+			xmi+= "<UML:Transition.trigger> <UML:Event> <UML:ModelElement.namespace> <UML:Namespace> ";
+			xmi+= "<UML:Namespace.ownedElement> <UML:CallEvent xmi.id=\"" + temp3;
+			xmi+= "tt\"  operation=\""+ trig_label + "\" ";
+			xmi+= "name=\"" + trig_op_name + "\" isSpecification=\"false\"/> "; 
+			xmi+= "</UML:Namespace.ownedElement> </UML:Namespace> </UML:ModelElement.namespace> ";
+			xmi+= "</UML:Event>  </UML:Transition.trigger> ";
+		}
+		
+		// print guard, if any
+		// Note: for guard to work, '<' => '&lt'
+		if (temp1 != "<null>"){
+			xmi+= "<UML:Transition.guard> <UML:Guard> <UML:Guard.expression> ";
+			xmi+= "<UML:BooleanExpression body=\"" + temp1 + "\" language=\"\"/> ";
+			xmi+= "</UML:Guard.expression> </UML:Guard> </UML:Transition.guard> ";
+		}
+		
+		// print action, if any
+		if (temp2 != "<null>") { 
+			xmi+= "<UML:Transition.effect> <UML:UninterpretedAction xmi.id=\"" + temp3 + "ui\" ";
+			xmi+= "isAsynchronous=\"false\" name=\"\" isSpecification=\"false\"> ";
+			xmi+= "<UML:Action.script> <UML:ActionExpression language=\"\" body=\""; 
+			xmi+= temp2 + "\"/> </UML:Action.script> </UML:UninterpretedAction> </UML:Transition.effect> ";		
+		}
+		
+		xmi += "</UML:Transition>\n";
+		t_count++;
+	}
+	
+	// Add one transition to connect the init state to state 0
+	temp = "t" + StringifyAnInt(t_count);
+	temp1 = "s" + StringifyAnInt(-1);
+	temp2 = "s" + StringifyAnInt(0);
+	temp3 = temp + temp1 + temp2;
+
+	xmi+= "<UML:Transition xmi.id=\"" + temp3 + "\"";
+	xmi+= " source=\"" + temp1 + "\"";
+	xmi += " target=\"" + temp2 + "\" name=\"\" isSpecification=\"false\">\n";
+	xmi += "</UML:Transition>\n";
+		
+	return;
+}
+
+

Added: branches/uml/source/main/cUMLStateDiagram.h
===================================================================
--- branches/uml/source/main/cUMLStateDiagram.h	                        (rev 0)
+++ branches/uml/source/main/cUMLStateDiagram.h	2007-07-13 18:47:44 UTC (rev 1799)
@@ -0,0 +1,164 @@
+#ifndef _C_UMLSTATEDIAGRAM_H_
+#define _C_UMLSTATEDIAGRAM_H_
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <utility>                   
+#include <algorithm>              
+#include <boost/config.hpp>   
+#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/breadth_first_search.hpp>
+#include <boost/graph/visitors.hpp>
+#include <boost/graph/graphviz.hpp>
+
+
+struct transition_properties { 
+	transition_properties() {}
+	transition_properties(int trigger, int guard, int action) 
+		: _tr(trigger), _gu(guard), _act(action) {}
+	int _tr, _gu, _act; 
+}; 
+
+struct transition_label { 
+	int trigger;
+	int guard;
+	int action;
+};
+
+
+struct state {
+	int identifier;
+	int num_incoming;
+	int num_outgoing;
+};
+
+struct trigger_info {
+	std::string operation_id;
+	std::string label;
+};
+
+
+class cUMLStateDiagram { 
+protected: 
+  std::vector<trigger_info> triggers;
+  std::vector<std::string> guards;
+  std::vector<std::string> actions;
+//  std::vector<transition> transitions;
+  std::vector<transition_label> transition_labels;
+
+//  int orig_state_index;
+//  int dest_state_index;
+  int trans_label_index;
+  int trigger_index;
+  int guard_index;
+  int action_index;
+
+  
+  std::string xmi;
+  	
+public:
+
+  cUMLStateDiagram();
+  ~cUMLStateDiagram();
+
+  void printXMI();	 // print the XMI version of the model
+  std::string getXMI (); // get the xmi string (including beginning & end read from file.)
+  std::string StringifyAnInt(int);
+  int numStates();
+  int numTrans();
+  int numTriggers() { return triggers.size(); } 
+  int numGuards() { return guards.size(); } 
+  int numActions() { return actions.size(); }
+
+
+  bool findTrans(int, int, int, int, int);
+//  bool findTransLabel(transition_label); // find a specific transition label
+
+// Boost graph type for a state diagram.
+  typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, 
+	int, transition_properties> state_diagram;
+
+  template <typename T>
+  bool absoluteMoveIndex (T x, int &y, int z);
+
+ 
+  template <typename T>
+  bool relativeMoveIndex (T x, int &y, int z);  
+ 
+ 
+ // pass in the path; state to know path step; examine_edge
+ // Issue: the need to revisit the same node.
+ //! A BGL breadth-first visitor used to see if a path is included in a state diagram.
+class PathVisitor : public boost::bfs_visitor< > {
+public:
+  PathVisitor() {}
+  template <class state_diagram>
+  void tree_edge(typename boost::graph_traits<state_diagram>::edge_descriptor e, state_diagram& g) {
+    typename boost::graph_traits<state_diagram>::vertex_descriptor u, v;
+    u = boost::source(e, g);
+    v = boost::target(e, g);
+//    distance[v] = distance[u] + 1;
+	std::cout << "origin: " << u << std::endl;
+	std::cout << "destination: " << v << std::endl;
+	std::cout << "tga: " << g[e]._tr << g[e]._gu << g[e]._act << std::endl;
+	}
+  };
+  
+struct transition_writer {
+	transition_writer(state_diagram& sd) : _sd(sd) { }
+	
+	template<typename Edge>
+	void operator()(std::ostream& out) {
+		out << "working?";
+	}
+  
+	state_diagram& _sd;
+}; 
+ 
+ 
+// The jump functions jump the index of the various vectors either forward (+ int) or backwards (- int)
+  bool absoluteJumpGuard(int);
+  bool absoluteJumpAction(int);
+  bool absoluteJumpTrigger(int);
+  bool absoluteJumpTransitionLabel(int);
+  bool absoluteJumpOriginState(int);
+  bool absoluteJumpDestinationState(int);
+  
+  
+// Implement a scenario check.  
+//  void checkForPath(std::deque<std::string>, boost::graph_traits<state_diagram>::vertex_descriptor, bool&, int&);
+  int findPath(std::deque<std::string> p); 
+  int checkForPathStep(std::deque<std::string>, boost::graph_traits<state_diagram>::vertex_descriptor, int); 
+  
+// The get functions get the value of the index of various vectors  
+  int getTriggerIndex();
+  int getGuardIndex();
+  int getActionIndex();
+  transition_label getTransLabel();
+  
+// Visit graph
+  void executeVisitor();
+  void printGraphViz();
+
+
+// Add functions
+
+//  bool addTransition();
+  bool addTransitionTotal();
+  bool addTrigger(std::string, std::string);
+  bool addGuard(std::string);
+  bool addAction(std::string);
+  bool addTransitionLabel(int, int, int);
+  // END UML functions
+protected:
+    state_diagram sd0;
+	boost::graph_traits<state_diagram>::vertex_descriptor orig;
+	boost::graph_traits<state_diagram>::vertex_descriptor dest;
+	
+
+};
+
+#endif




More information about the Avida-cvs mailing list