[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, '<' => '<'
+ 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