|
From: <ba...@us...> - 2008-11-23 20:43:34
|
Revision: 120
http://scstudio.svn.sourceforge.net/scstudio/?rev=120&view=rev
Author: babicaj
Date: 2008-11-23 20:43:27 +0000 (Sun, 23 Nov 2008)
Log Message:
-----------
msc_presser replaced by msc_duplicator, new acyclic_checker_test added (not included in build yet), bug in dfs_bmsc_graph_traverser fixed
Modified Paths:
--------------
trunk/src/check/dfs_area_traverser.cpp
trunk/src/check/dfs_area_traverser.h
trunk/src/check/dfs_bmsc_graph_traverser.cpp
trunk/src/check/dfs_events_traverser.cpp
trunk/src/check/dfs_events_traverser.h
trunk/src/check/dfs_instance_events_traverser.cpp
trunk/src/check/dfs_instance_events_traverser.h
trunk/src/data/msc.cpp
trunk/src/data/msc.h
Added Paths:
-----------
trunk/src/check/msc_duplicators.cpp
trunk/src/check/msc_duplicators.h
trunk/tests/acyclic_checker_test.cpp
Removed Paths:
-------------
trunk/src/check/msc_presser.cpp
trunk/src/check/msc_presser.h
Modified: trunk/src/check/dfs_area_traverser.cpp
===================================================================
--- trunk/src/check/dfs_area_traverser.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_area_traverser.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -16,56 +16,74 @@
* $Id$
*/
-#include <stack>
+#include "check/dfs_area_traverser.h"
+DFSAreaTraverser::DFSAreaTraverser(const std::string& color):
+DFSEventsTraverser(color)
+{
-#include "check/dfs_area_traverser.h"
+}
-void DFSAreaTraverser::traverse_area(EventAreaPtr area)
+void DFSAreaTraverser::traverse_area(EventArea* area)
{
- if(area.get())
+ if(!area) return;
+ StrictOrderArea* strict = dynamic_cast<StrictOrderArea*>(area);
+ if(strict)
{
- try
+ if(!strict->is_empty())
+ traverse_strict_event(strict->get_first().get());
+ }
+ else
+ {
+ CoregionArea* coregion = dynamic_cast<CoregionArea*>(area);
+ const CoregionEventPSet& minimals = coregion->get_minimal_events();
+ CoregionEventPSet::const_iterator min;
+ for(min=minimals.begin(); min!=minimals.end(); min++)
+ traverse_coregion_event(*min);
+ }
+}
+
+void DFSAreaTraverser::traverse(BMscPtr bmsc)
+{
+ InstancePtrList::const_iterator instance;
+ const InstancePtrList& instances = bmsc->get_instances();
+ for(instance=instances.begin(); instance!=instances.end(); instance++)
+ {
+ EventArea* area = (*instance)->get_first().get();
+ while(area)
{
- EventPStack stack;
- StrictOrderAreaPtr strict = area;
- StrictEvent* e = strict->get_first().get();
- while(e)
- {
- stack.push(e);
- white_event_found(e);
- e = e->get_successor().get();
- }
- //neccessary to keep semantic of DFS
- while(!stack.empty())
- {
- event_finished(stack.top());
- stack.pop();
- }
-
+ traverse_area(area);
+ area = area->get_next().get();
}
- catch(std::bad_cast& bd)
- {
- CoregionAreaPtr coregion = area;
- const CoregionEventPSet& minimals = coregion->get_minimal_events();
- CoregionEventPSet::const_iterator min;
- for(min=minimals.begin(); min!=minimals.end(); min++)
- traverse_coregion_event(*min);
- }
- traverse_area(area->get_next());
}
+ cleanup_traversing_attributes();
}
void DFSAreaTraverser::traverse_coregion_event(CoregionEvent* event)
{
+ m_reached_elements.push_back(event);
if(!is_processed(event))
{
- const CoregionEventPSet& successors = event->get_successors();
- CoregionEventPSet::const_iterator successor;
+ const CoregEventRelPtrSet& successors = event->get_successors();
+ CoregEventRelPtrSet::const_iterator successor;
for(successor=successors.begin(); successor!=successors.end(); successor++)
- traverse_coregion_event(*successor);
- set_color(event,BLACK);
+ {
+ m_reached_elements.push_back((*successor).get());
+ traverse_coregion_event((*successor)->get_successor());
+ m_reached_elements.pop_back();
+ }
event_finished(event);
}
}
+void DFSAreaTraverser::traverse_strict_event(StrictEvent* event)
+{
+ m_reached_elements.push_back(event);
+ if(!is_processed(event))
+ {
+ if(event->get_successor().get())
+ traverse_strict_event(event->get_successor().get());
+ event_finished(event);
+ }
+}
+
Modified: trunk/src/check/dfs_area_traverser.h
===================================================================
--- trunk/src/check/dfs_area_traverser.h 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_area_traverser.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -21,35 +21,32 @@
#include "check/dfs_instance_events_traverser.h"
-typedef std::stack<Event*> EventPStack;
-
/**
* Processes EventAreas' events in sequence and do not follow matching events
* during traversing.
*
* Single EventAreas are traversed in depth first search manner.
*/
-class DFSAreaTraverser:public DFSInstanceEventsTraverser
+class DFSAreaTraverser:public DFSEventsTraverser
{
public:
- DFSAreaTraverser()
- {
- }
+ DFSAreaTraverser(const std::string& color="color");
+
+ void traverse(BMscPtr bmsc);
protected:
- /**
- * More effective traversing of StrictOrderArea
- */
- void traverse_area(EventAreaPtr area);
+ void traverse_area(EventArea* area);
/**
* Doesn't continue in traversing next EventArea in case of event hasn't got
* any successors.
*/
void traverse_coregion_event(CoregionEvent* event);
+
+ void traverse_strict_event(StrictEvent* event);
};
Modified: trunk/src/check/dfs_bmsc_graph_traverser.cpp
===================================================================
--- trunk/src/check/dfs_bmsc_graph_traverser.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_bmsc_graph_traverser.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -81,13 +81,13 @@
}
white_node_found(node);
ReferenceNode* ref_node = dynamic_cast<ReferenceNode*>(node);
+ bool ending_successors;
if(ref_node!=NULL)
{
- return traverse_reference_node(ref_node);
+ ending_successors = traverse_reference_node(ref_node);
}
else
{
- bool ending_successors;
ConnectionNode* conn_node = dynamic_cast<ConnectionNode*>(node);
if(conn_node)
{
@@ -106,9 +106,9 @@
ending_successors = true;
}
}
- node_finished(node);
- return ending_successors;
}
+ node_finished(node);
+ return ending_successors;
}
bool DFSBMscGraphTraverser::traverse_reference_node(ReferenceNode* ref_node)
Modified: trunk/src/check/dfs_events_traverser.cpp
===================================================================
--- trunk/src/check/dfs_events_traverser.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_events_traverser.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -19,7 +19,10 @@
#include "check/dfs_events_traverser.h"
#include "check/utils.h"
-const std::string DFSEventsTraverser::color_attribute = "events_traverse_color";
+DFSEventsTraverser::DFSEventsTraverser(const std::string& color)
+{
+ m_color = color;
+}
DFSEventsTraverser::~DFSEventsTraverser()
{
@@ -141,7 +144,7 @@
{
EventPList::iterator event;
for(event=m_colored_events.begin();event!=m_colored_events.end();event++)
- (*event)->remove_attribute<Color>(color_attribute);
+ (*event)->remove_attribute<Color>(m_color);
m_colored_events.erase(m_colored_events.begin(),m_colored_events.end());
}
@@ -189,3 +192,37 @@
return topology;
}
+Color DFSEventsTraverser::get_color(Event* e)
+{
+ return e->get_attribute<Color>(m_color,WHITE);
+}
+
+void DFSEventsTraverser::remove_white_event_found_listeners()
+{
+ white_event_found_listeners.clear();
+}
+
+void DFSEventsTraverser::remove_gray_event_found_listeners()
+{
+ gray_event_found_listeners.clear();
+}
+
+void DFSEventsTraverser::remove_black_event_found_listeners()
+{
+ black_event_found_listeners.clear();
+}
+
+void DFSEventsTraverser::remove_event_finished_listeners()
+{
+ event_finished_listeners.clear();
+}
+
+void DFSEventsTraverser::remove_all_listeners()
+{
+ remove_white_event_found_listeners();
+ remove_gray_event_found_listeners();
+ remove_black_event_found_listeners();
+ remove_event_finished_listeners();
+}
+
+
Modified: trunk/src/check/dfs_events_traverser.h
===================================================================
--- trunk/src/check/dfs_events_traverser.h 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_events_traverser.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -107,9 +107,7 @@
public:
- DFSEventsTraverser()
- {
- }
+ DFSEventsTraverser(const std::string& color="color");
virtual ~DFSEventsTraverser();
@@ -118,7 +116,7 @@
*
* Events are traversed in depth first search manner.
*/
- void traverse(BMscPtr bmsc);
+ virtual void traverse(BMscPtr bmsc);
/**
* Adds EventFinishedListener
@@ -163,6 +161,12 @@
}
static EventPList* topology_order(BMscPtr b);
+
+ void remove_white_event_found_listeners();
+ void remove_gray_event_found_listeners();
+ void remove_black_event_found_listeners();
+ void remove_event_finished_listeners();
+ void remove_all_listeners();
protected:
@@ -175,6 +179,8 @@
* List of colored events during traversing.
*/
EventPList m_colored_events;
+
+ std::string m_color;
/**
* Holds listeners
@@ -200,11 +206,6 @@
* Holds listeners
*/
GrayEventFoundListenerPList grey_event_found_listeners;
-
- /**
- * Color attribute's name
- */
- static const std::string color_attribute;
virtual void traverse_area(EventArea* area);
@@ -241,7 +242,7 @@
*/
void set_color(Event* e, Color c)
{
- e->set_attribute<Color>(color_attribute,c);
+ e->set_attribute<Color>(m_color,c);
}
/**
@@ -249,10 +250,7 @@
*
* If attribute isn't set it is set to default value WHITE.
*/
- Color get_color(Event* e)
- {
- return e->get_attribute<Color>(color_attribute,WHITE);
- }
+ Color get_color(Event* e);
};
Modified: trunk/src/check/dfs_instance_events_traverser.cpp
===================================================================
--- trunk/src/check/dfs_instance_events_traverser.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_instance_events_traverser.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -19,6 +19,13 @@
#include "check/dfs_instance_events_traverser.h"
#include "check/utils.h"
+#include <string>
+
+DFSInstanceEventsTraverser::DFSInstanceEventsTraverser(const std::string& color):DFSEventsTraverser(color)
+{
+
+}
+
void DFSInstanceEventsTraverser::traverse_strict_event(StrictEvent* event)
{
m_reached_elements.push_back(event);
Modified: trunk/src/check/dfs_instance_events_traverser.h
===================================================================
--- trunk/src/check/dfs_instance_events_traverser.h 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/dfs_instance_events_traverser.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -31,11 +31,11 @@
public:
- DFSInstanceEventsTraverser()
- {
- }
+ DFSInstanceEventsTraverser(const std::string& color="color");
void traverse(Instance* instance);
+
+ using DFSEventsTraverser::traverse;
static EventPList* topology_order(Instance* i);
Added: trunk/src/check/msc_duplicators.cpp
===================================================================
--- trunk/src/check/msc_duplicators.cpp (rev 0)
+++ trunk/src/check/msc_duplicators.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -0,0 +1,469 @@
+/*
+ * scstudio - Sequence Chart Studio
+ * http://scstudio.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (c) 2008 Jindra Babica <ba...@ma...>
+ *
+ * $Id$
+ */
+
+#include "check/msc_duplicators.h"
+#include "check/dfs_instance_events_traverser.h"
+
+const std::string BMSC_DUPLICATOR_TRAVERSING_ATTR = "BDcolor";
+const std::string BMSC_DUPLICATOR_COPY_ATTR = "BDcopy";
+const std::string BMSC_GRAPH_DUPLICATOR_COPY_ATTR = "BGDcopy";
+const std::string BMSC_GRAPH_DUPLICATOR_REF_ATTR = "BGDreferencing";
+const std::string BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR = "BGDendlist";
+
+BMscDuplicator::BMscDuplicator()
+{
+}
+
+BMscPtr BMscDuplicator::duplicate_bmsc(BMscPtr &bmsc)
+{
+ BMscPtr new_bmsc;
+ if(bmsc.get())
+ {
+ new_bmsc = new BMsc(bmsc.get());
+ DFSAreaTraverser traverser(BMSC_DUPLICATOR_TRAVERSING_ATTR);
+ EventsCreatorListener events_creator(this,&traverser,new_bmsc.get());
+ traverser.add_white_event_found_listener(&events_creator);
+ traverser.add_black_event_found_listener(&events_creator);
+ traverser.add_gray_event_found_listener(&events_creator);
+ traverser.traverse(bmsc);
+ traverser.remove_all_listeners();
+ MessagesCreatorListener messages_creator(this);
+ traverser.add_white_event_found_listener(&messages_creator);
+ traverser.traverse(bmsc);
+ }
+ return new_bmsc;
+}
+
+Event*& BMscDuplicator::get_copy(Event* e)
+{
+ bool just_set;
+ Event*& copy = e->get_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_elements.push_back(e);
+ }
+ return copy;
+}
+
+BMscDuplicator::~BMscDuplicator()
+{
+ EventPList::const_iterator i;
+ for(i=m_modified_elements.begin();i!=m_modified_elements.end();i++)
+ {
+ (*i)->remove_attribute<Event*>(BMSC_DUPLICATOR_COPY_ATTR);
+ }
+}
+
+BMscPtr BMscDuplicator::duplicate(BMscPtr& bmsc)
+{
+ BMscDuplicator duplicator;
+ return duplicator.duplicate_bmsc(bmsc);
+}
+
+EventsCreatorListener::EventsCreatorListener(BMscDuplicator* duplicator, DFSAreaTraverser* traverser, BMsc* bmsc):
+ m_duplicator(duplicator),
+ m_traverser(traverser),
+ m_bmsc(bmsc),
+ m_last_instance(NULL),
+ m_last_area(NULL),
+ m_last_new_instance(NULL),
+ m_last_new_area(NULL)
+{
+
+}
+
+void EventsCreatorListener::on_white_event_found(Event* e)
+{
+ if(m_last_instance!=e->get_instance())
+ {
+ InstancePtr new_instance = new Instance(e->get_instance());
+ m_bmsc->add_instance(new_instance);
+ m_last_instance = e->get_instance();
+ m_last_new_instance = new_instance.get();
+ }
+ if(m_last_area!=e->get_general_area())
+ {
+ StrictOrderArea* strict = dynamic_cast<StrictOrderArea*>(e->get_general_area());
+ EventAreaPtr area;
+ if(strict)
+ {
+ area = new StrictOrderArea(strict);
+ }
+ else
+ {
+ area = new CoregionArea(dynamic_cast<CoregionArea*>(e->get_general_area()));
+ }
+ m_last_new_area = area.get();
+ m_last_new_instance->add_area(area);
+ m_last_area = e->get_general_area();
+ }
+ EventPtr new_event = m_last_new_area->add_event();
+ new_event->set_original(e);
+ Event*& copy = m_duplicator->get_copy(e);
+ copy = new_event.get();
+ create_successor(e);
+}
+
+CoregionEvent* EventsCreatorListener::get_preceding_event()
+{
+ const MscElementPList& elements = m_traverser->get_reached_elements();
+ if(elements.size()>1)
+ {
+ //in this case currently traversed event isn't alone in elements
+ MscElementPList::const_iterator i = elements.end();
+ i--; i--;
+ return dynamic_cast<CoregionEvent*>(*i);
+ }
+ return NULL;
+}
+
+void EventsCreatorListener::on_gray_event_found(Event* e)
+{
+ create_successor(e);
+}
+
+void EventsCreatorListener::on_black_event_found(Event* e)
+{
+ create_successor(e);
+}
+
+void EventsCreatorListener::create_successor(Event* e)
+{
+ CoregionEvent* coreg_new_event = dynamic_cast<CoregionEvent*>(e);
+ if(coreg_new_event)
+ {
+ CoregionEvent* preceding = get_preceding_event();
+ if(preceding)
+ {
+ preceding->add_successor(coreg_new_event);
+ }
+ }
+}
+
+MessagesCreatorListener::MessagesCreatorListener(BMscDuplicator* duplicator):
+m_duplicator(duplicator)
+{
+
+}
+
+void MessagesCreatorListener::on_white_event_found(Event* e)
+{
+ Event* event_copy = m_duplicator->get_copy(e);
+ if(e->is_matched())
+ {
+ if(e->is_send())
+ {
+ MscMessagePtr complete = new CompleteMessage(e,NULL,e->get_complete_message().get());
+ event_copy->set_message(complete);
+ Event* matching_copy = m_duplicator->get_copy(e->get_matching_event());
+ matching_copy->set_message(complete);
+ }
+ }
+ else
+ {
+ MscMessagePtr incomplete = new IncompleteMessage(e->get_incomplete_message().get());
+ event_copy->set_message(incomplete);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+GraphCreatorListener::GraphCreatorListener(HMsc* hmsc):
+m_hmsc(hmsc)
+{
+}
+
+void GraphCreatorListener::on_white_node_found(HMscNode *n)
+{
+ HMscNodePtr node;
+ ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
+ if(reference)
+ {
+ on_white_node_found(reference);
+ }
+ else
+ {
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
+ if(connection)
+ {
+ on_white_node_found(connection);
+ }
+ else
+ {
+ EndNode* end = dynamic_cast<EndNode*>(n);
+ if(end)
+ {
+ on_white_node_found(end);
+ }
+ else
+ {
+ StartNode* start = dynamic_cast<StartNode*>(n);
+ on_white_node_found(start);
+ }
+ }
+ }
+}
+
+
+void GraphCreatorListener::on_white_node_found(ReferenceNode* n)
+{
+ BMscPtr bmsc = n->get_bmsc();
+ HMscNodePtr new_node;
+ if(bmsc.get())
+ {
+ BMscPtr new_bmsc = BMscDuplicator::duplicate(bmsc);
+ ReferenceNode* reference = new ReferenceNode(n);
+ reference->set_msc(new_bmsc);
+ new_node = reference;
+ }
+ else
+ {
+ ConnectionNode* connection = new ConnectionNode(n);
+ new_node = connection;
+ ReferenceNode*& attribute = get_referencing_node(n->get_hmsc().get());
+ attribute = n;
+ }
+ process_new_node(n,new_node);
+}
+
+void GraphCreatorListener::on_white_node_found(StartNode* n)
+{
+ if(is_root_element(n))
+ {
+ //in this case duplicated Startnode was already created
+ m_new_nodes.push_back(m_hmsc->get_start().get());
+ set_copy(n,m_hmsc->get_start().get());
+ }
+}
+
+void GraphCreatorListener::on_white_node_found(EndNode* n)
+{
+ HMscNodePtr new_node;
+ if(is_root_element(n))
+ {
+ EndNode* end = new EndNode(n);
+ new_node = end;
+ }
+ else
+ {
+ ConnectionNode* connection = new ConnectionNode(n);
+ new_node = connection;
+ add_to_end_list(connection);
+ }
+ process_new_node(n,new_node);
+}
+
+ConnectionNodePList& GraphCreatorListener::get_end_list(ReferenceNode* reference)
+{
+ static ConnectionNodePList empty;
+ //attribute is removed when reference is finished in traversing
+ return reference->get_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR,empty);
+}
+
+void GraphCreatorListener::add_to_end_list(ConnectionNode* new_end)
+{
+ HMsc* original_hmsc = new_end->get_original()->get_owner();
+ ReferenceNode* original_reference = get_referencing_node(original_hmsc);
+ ConnectionNodePList& end_list = get_end_list(original_reference);
+ end_list.push_back(new_end);
+}
+
+void GraphCreatorListener::on_white_node_found(ConnectionNode* n)
+{
+ PredecessorNode* predecessor = get_predecessor();
+ HMscNodePtr new_node = new ConnectionNode(n);
+ process_new_node(n,new_node);
+}
+
+void GraphCreatorListener::process_new_node(HMscNode* old_node, HMscNodePtr& new_node)
+{
+ m_hmsc->add_node(new_node);
+ add_new_successor(new_node.get());
+ m_new_nodes.push_back(new_node.get());
+ set_copy(old_node,new_node.get());
+}
+
+bool GraphCreatorListener::is_root_element(HMscNode* n)
+{
+ return n->get_owner()==m_hmsc->get_original();
+}
+
+void GraphCreatorListener::set_copy(HMscNode* n, HMscNode* copy)
+{
+ HMscNode*& attribute = get_copy(n);
+ attribute = copy;
+}
+
+HMscNode*& GraphCreatorListener::get_copy(HMscNode* n)
+{
+ bool just_set;
+ HMscNode*& copy = n->get_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_elements.push_back(n);
+ }
+ return copy;
+}
+
+PredecessorNode* GraphCreatorListener::get_predecessor()
+{
+ return dynamic_cast<PredecessorNode*>(m_new_nodes.back());
+}
+
+void GraphCreatorListener::process_nonwhite_node(HMscNode* n)
+{
+ HMscNode* copy = get_copy(n);
+ add_new_successor(copy);
+}
+
+void GraphCreatorListener::on_gray_node_found(HMscNode* n)
+{
+ process_nonwhite_node(n);
+}
+
+void GraphCreatorListener::on_black_node_found(HMscNode* n)
+{
+ process_nonwhite_node(n);
+}
+
+void GraphCreatorListener::on_node_finished(HMscNode* n)
+{
+ HMscNodePtr node;
+ ReferenceNode* reference = dynamic_cast<ReferenceNode*>(n);
+ if(reference)
+ {
+ on_node_finished(reference);
+ }
+ else
+ {
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(n);
+ if(connection)
+ {
+ on_node_finished(connection);
+ }
+ else
+ {
+ EndNode* end = dynamic_cast<EndNode*>(n);
+ if(end)
+ {
+ on_node_finished(end);
+ }
+ else
+ {
+ StartNode* start = dynamic_cast<StartNode*>(n);
+ on_node_finished(start);
+ }
+ }
+ }
+}
+
+void GraphCreatorListener::on_node_finished(ReferenceNode* n)
+{
+ n->remove_attribute<ConnectionNodePList>(BMSC_GRAPH_DUPLICATOR_ENDLIST_ATTR);
+ m_new_nodes.pop_back();
+}
+
+void GraphCreatorListener::on_node_finished(StartNode* n)
+{
+ if(is_root_element(n))
+ {
+ m_new_nodes.pop_back();
+ }
+}
+
+void GraphCreatorListener::on_node_finished(EndNode* n)
+{
+ m_new_nodes.pop_back();
+}
+
+void GraphCreatorListener::on_node_finished(ConnectionNode* n)
+{
+ m_new_nodes.pop_back();
+}
+
+ReferenceNode*& GraphCreatorListener::get_referencing_node(HMsc* hmsc)
+{
+ bool just_set;
+ ReferenceNode*& reference = hmsc->get_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR,NULL,just_set);
+ if(just_set)
+ {
+ m_modified_hmscs.push_back(hmsc);
+ }
+ return reference;
+}
+
+void GraphCreatorListener::add_new_successor(HMscNode* new_successor)
+{
+ SuccessorNode* new_succ = dynamic_cast<SuccessorNode*>(new_successor);
+ PredecessorNode* predecessor = get_predecessor();
+ ConnectionNode* connection = dynamic_cast<ConnectionNode*>(predecessor);
+ if(connection)
+ {
+ ReferenceNode* original_reference = dynamic_cast<ReferenceNode*>(connection->get_original());
+ if(original_reference &&
+ new_successor->get_original()->get_owner()==original_reference->get_owner())
+ {
+ //connection was transformed from ReferenceNode and probably contains end_list,
+ //elements of the end_list must become predecessors of new_successor which
+ //must be from same HMsc as original_reference
+ ConnectionNodePList& end_list = get_end_list(original_reference);
+ ConnectionNodePList::const_iterator i;
+ for(i=end_list.begin();i!=end_list.end();i++)
+ {
+ (*i)->add_successor(new_succ);
+ }
+ return;
+ }
+ }
+ predecessor->add_successor(new_succ);
+}
+
+GraphCreatorListener::~GraphCreatorListener()
+{
+ while(!m_modified_elements.empty())
+ {
+ MscElement* e = m_modified_elements.back();
+ e->remove_attribute<HMscNode*>(BMSC_DUPLICATOR_COPY_ATTR);
+ m_modified_elements.pop_back();
+ }
+ while(!m_modified_hmscs.empty())
+ {
+ HMsc* h = m_modified_hmscs.back();
+ h->remove_attribute<ReferenceNode*>(BMSC_GRAPH_DUPLICATOR_REF_ATTR);
+ m_modified_hmscs.pop_back();
+ }
+}
+
+HMscPtr BMscGraphDuplicator::duplicate(HMscPtr& hmsc)
+{
+ HMscPtr new_hmsc;
+ if(hmsc.get())
+ {
+ new_hmsc = new HMsc(hmsc.get());
+ GraphCreatorListener listener(new_hmsc.get());
+ DFSBMscGraphTraverser traverser;
+ traverser.add_black_node_found_listener(&listener);
+ traverser.add_gray_node_found_listener(&listener);
+ traverser.add_node_finished_listener(&listener);
+ traverser.add_white_node_found_listener(&listener);
+ traverser.traverse(hmsc);
+ }
+ return new_hmsc;
+}
+
+
Property changes on: trunk/src/check/msc_duplicators.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: trunk/src/check/msc_duplicators.h
===================================================================
--- trunk/src/check/msc_duplicators.h (rev 0)
+++ trunk/src/check/msc_duplicators.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -0,0 +1,186 @@
+/*
+ * scstudio - Sequence Chart Studio
+ * http://scstudio.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (c) 2008 Jindra Babica <ba...@ma...>
+ *
+ * $Id$
+ */
+
+#include "data/msc.h"
+#include "check/dfs_area_traverser.h"
+#include "check/dfs_bmsc_graph_traverser.h"
+
+typedef std::list<Event*> EventPList;
+typedef std::list<ReferenceNode*> ReferenceNodePList;
+typedef std::list<HMsc*> HMscPList;
+typedef std::list<ConnectionNode*> ConnectionNodePList;
+
+class BMscDuplicator;
+
+class EventsCreatorListener:
+ public WhiteEventFoundListener,public GrayEventFoundListener,
+ public BlackEventFoundListener
+{
+protected:
+
+ BMscDuplicator* m_duplicator;
+
+ Instance* m_last_instance;
+
+ Instance* m_last_new_instance;
+
+ EventArea* m_last_area;
+
+ EventArea* m_last_new_area;
+
+ BMsc* m_bmsc;
+
+ DFSAreaTraverser* m_traverser;
+
+ void create_successor(Event* e);
+
+ CoregionEvent* get_preceding_event();
+
+public:
+
+ EventsCreatorListener(BMscDuplicator* duplicator, DFSAreaTraverser* traverser, BMsc* bmsc);
+
+ void on_white_event_found(Event* e);
+ void on_gray_event_found(Event* e);
+ void on_black_event_found(Event* e);
+
+};
+
+class MessagesCreatorListener:public WhiteEventFoundListener
+{
+protected:
+
+ BMscDuplicator* m_duplicator;
+
+public:
+
+ MessagesCreatorListener(BMscDuplicator* duplicator);
+
+ void on_white_event_found(Event* e);
+
+};
+
+
+/**
+ * \brief Duplicates BMsc
+ *
+ * Duplicated BMsc's elemenents have set attribute original to the original
+ * BMsc's elements.
+ */
+class BMscDuplicator
+{
+protected:
+
+ EventPList m_modified_elements;
+
+ BMscPtr duplicate_bmsc(BMscPtr& bmsc);
+
+ BMscDuplicator();
+
+public:
+
+ static BMscPtr duplicate(BMscPtr& bmsc);
+
+ ~BMscDuplicator();
+
+ Event*& get_copy(Event* e);
+};
+
+///////////////////////////////////////////////////////////
+
+class GraphCreatorListener: public WhiteNodeFoundListener,public GrayNodeFoundListener,
+ public BlackNodeFoundListener,public NodeFinishedListener
+{
+protected:
+
+ MscElementPList m_modified_elements;
+ HMscPList m_modified_hmscs;
+
+ MscElementPList m_new_nodes;
+
+ HMsc* m_hmsc;
+
+ bool is_root_element(HMscNode* n);
+
+ HMscNode*& get_copy(HMscNode* n);
+
+ void set_copy(HMscNode* n, HMscNode* copy);
+
+ void process_new_node(HMscNode* old_node, HMscNodePtr& new_node);
+
+ void process_nonwhite_node(HMscNode* n);
+
+ PredecessorNode* get_predecessor();
+
+ ReferenceNode*& get_referencing_node(HMsc* hmsc);
+
+ ConnectionNodePList& get_end_list(ReferenceNode* reference);
+
+ void add_to_end_list(ConnectionNode* new_end);
+
+ void add_new_successor(HMscNode* new_successor);
+
+public:
+
+ GraphCreatorListener(HMsc* hmsc);
+
+ ~GraphCreatorListener();
+
+ void on_white_node_found(HMscNode* n);
+ void on_white_node_found(ReferenceNode* n);
+ void on_white_node_found(StartNode* n);
+ void on_white_node_found(EndNode* n);
+ void on_white_node_found(ConnectionNode* n);
+
+ void on_gray_node_found(HMscNode* n);
+
+ void on_black_node_found(HMscNode* n);
+
+ void on_node_finished(HMscNode* n);
+ void on_node_finished(ReferenceNode* n);
+ void on_node_finished(StartNode* n);
+ void on_node_finished(EndNode* n);
+ void on_node_finished(ConnectionNode* n);
+
+};
+
+/**
+ * \brief Duplicates HMsc like it would be BMsc graph.
+ *
+ * Result of this duplicator is flattened version of HMsc (BMsc graph)
+ * without unreachable HMscNodes and nodes which
+ * man isn't able to get to EndNode from.
+ *
+ * All ReferenceNodes reference only BMsc, moreover each BMsc is
+ * referenced only one time -- each BMsc is duplicated too. Kept elements
+ * references to its original element via attribute m_original.
+ *
+ * Original ReferenceNodes which references HMsc are transformed into
+ * ConnectionNodes referencing the ReferenceNode by m_original. StartNodes
+ * which don't occure in HMsc to be duplicated are removed. EndNodes
+ * of the same kind are transformed into ConnectionNodes referencing original
+ * EndNodes.
+ */
+class BMscGraphDuplicator
+{
+
+public:
+
+ static HMscPtr duplicate(HMscPtr& hmsc);
+
+};
\ No newline at end of file
Property changes on: trunk/src/check/msc_duplicators.h
___________________________________________________________________
Added: svn:keywords
+ Id
Added: svn:eol-style
+ native
Deleted: trunk/src/check/msc_presser.cpp
===================================================================
--- trunk/src/check/msc_presser.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/msc_presser.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -1,93 +0,0 @@
-/*
- * scstudio - Sequence Chart Studio
- * http://scstudio.sourceforge.net
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * Copyright (c) 2008 Ondrej Kocian <koc...@ma...>
- *
- * $Id:
- */
-
-#include "check/msc_presser.h"
-
-
-MscPresserListener::MscPresserListener(HMscPtr hmsc)
-{
- m_hmsc = new HMsc(hmsc);
- InnerNodePSet::const_iterator successor
- InnerNodePSet successors = hmsc->get_start()->get_successors();
- for(successor=successors.begin();successor!=successors.end();successor++)
- {
- m_hmcs->get_start()->add_successors(return_innernode(*successor));
- }
- if(hmsc->is_end_node())
- m_hmsc->get_start()->set_end(return_endnode(hmsc->get_start()->get_end().get()))
-}
-
-
-void MscPresserListener::deal_end_problem(InnerNode* node){
- ReferenceNode* refNode = m_stack.top();
- m_stack.pop()
- InnerNodePSet::const_iterator successor;
- successors = refNode->get_successors();
- for(successor=successors.begin();successor!=successors.end();successor++)
- {
- node->add_successors(return_innernode(*successor));
- }
- if(refNode->is_end_node()){
- if(!m_stack.empty())
- deal_end_problem(node);
- else node->set_end(return_endnode(refNode->get_end_node()));
- }
- m_stack.push(refNode);
-}
-
-void MscPresserListener::on_white_node_found(InnerNode* node)
-{
- /**
- * Get name of copy and check if there is hmsc in there if so
- * let the successors and
- */
- InnerNode* copy;
- copy = return_innernode(node);
- InnerNodePSet successors;
- InnerNodePSet::const_iterator successor;
-
- ReferenceNode* ref = dynamic_cast<ReferenceNode*>(node);
- if(ref!=NULL){
- HMscPtr hmsc = ref->get_hmsc();
- if(hmsc.get()!=NULL){
- if(hmsc->get_start()->is_end_node())
- {
- successors = node->get_successors();
- for(successor=successors.begin();successor!=successors.end();successor++)
- {
- copy->add_successors(return_innernode(*successor));
- }
- }
- successors = hmsc->get_start()->get_successors();
- }
- } else successors = node->get_successors();
-
- for(successor=successors.begin();successor!=successors.end();successor++)
- {
- copy->add_successors(return_innernode(*successor));
- }
- if(node->is_end_node()){
- if(m_stack.empty())
- {
- EndNodePtr new_end = return_endnode(node->get_end().get());
- node->set_end(new_end);
- } else deal_end_problem(copy);
- }
-}
-
-
Deleted: trunk/src/check/msc_presser.h
===================================================================
--- trunk/src/check/msc_presser.h 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/check/msc_presser.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -1,150 +0,0 @@
-/*
- * scstudio - Sequence Chart Studio
- * http://scstudio.sourceforge.net
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * Copyright (c) 2008 Ondrej Kocian <koc...@ma...>
- *
- * $Id:
- */
-
-#include <string>
-
-#include "data/msc.h"
-#include "data/counted_ptr.h"
-#include "check/dfs_inner_hmsc_traverser.h"
-
-class MscPresserListener;
-class MscPresser;
-
-class MscPresserListener: public WhiteRefNodeFoundListener, public InnerHMscListener
-{
-private:
- std::stack<ReferenceNode*> m_stack;
- std::stack<HMscNode*> image_attribute;
- HMscPtr hmsc;
-
- HMscNode* get_image(HMscNode* node)
- {
- return node->get_attribute<HMscNode*>(m_image,NULL);
- }
-
- void set_image(HMscNode* node, HMscNode* image)
- {
- node->set_attribute<HMscNode*>(m_image,image);
- image_attibute.push(node);
- }
-
- ReferenceNode* create_refnode(ReferenceNode* refNode)
- {
- ReferenceNode* new_refNode = new ReferenceNode(refNode);
- set_image(refNode,new_refNode);
- return new_refNode;
- }
-
- ConnectionNode* create_connode(ConnectionNode* conNode)
- {
- ConnectionNode* new_conNode = new ConnectionNode* conNode;
- set_image(conNode,new_conNode);
- return new_ConNode;
- }
-
- HMsc* create_hmsc(HMsc* hmsc)
- {
- HMsc* new_hmsc = new HMsc(hmsc);
- new_hmsc->set_label(hmsc->get_label);
-
- }
-
- EndNode* create_endnode(EndNode* node)
- {
- EndNode* new_end = new EndNode(node);
- set_image(node,new_end);
- return new_end;
- }
-
- InnerNode* return_innernode(InnerNode* node)
- {
- InnerNode* new_node;
- new_node = get_image(node);
- if(new_node==NULL){
- ReferenceNode* ref = dynamic_cast<ReferenceNode*>(node);
- if(ref!=NULL)
- new_node = create_refnode(ref);
- else
- new_node = create_connode(node);
- }
-
- return new_node;
- }
-
- EndNode* return_endnode(EndNode* node)
- {
- EndNode* new_end;
- new_end = get_image(node);
- if(new_end == NULL)
- new_end = create_endnode(node);
- return new_end;
- }
- // problem with node connected to end node
- void deal_end_problem(InnerNode* node);
-
- void clean_up(){
- while(!image_attribute.empty()){
- HMscNode* node = image_attribute.top();
- image_attribute.pop();
- node->remove_attribute<HMscNode*>(m_image);
-
- }
- }
-
-protected:
- static const std::string m_image;
-
-public:
-
- MscPresserListener(HMscPtr hmsc);
-
- ~MscPresserListener()
- {
- clean_up();
- }
-
- void on_white_node_found(InnerNode* node);
-
- void on_inner_hmsc_found(ReferenceNode* refNode)
- {
- m_stack.push(refnode);
- }
-
- void on_inner_hmsc_finished(ReferenceNode* refNode){
- m_stack.pop();
- }
-
- HMscPtr get_hmsc(){
- return m_hmsc;
- }
-};
-
-class MscPresser
-{
-public:
- HMscPtr press(HMscPtr hmsc)
- {
- DFSInnerHMscTraverser traverser;
- MscPresserListener listener = new MscPresserLister(hmsc);
- traverser->add_inner_hmsc_listener(listener);
- traverser->add_white_node_found_listener(listener);
-
- traverser.traverse(hmsc);
- return hmsc;
- }
-};
Modified: trunk/src/data/msc.cpp
===================================================================
--- trunk/src/data/msc.cpp 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/data/msc.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -49,6 +49,13 @@
n->get_successor()->m_predecessors.erase(n);
}
+/////////////////////////////////////////////////////////////////
+
+HMscNode::HMscNode(HMscNode* original):MscElementTmpl<HMscNode>(original),
+m_owner(NULL)
+{
+}
+
HMscNodePtr HMscNode::my_ptr()
{
if(m_owner==NULL){
@@ -58,6 +65,16 @@
return m_owner->find_ptr(this);
}
+/////////////////////////////////////
+
+void HMsc::add_node(HMscNodePtr node)
+{
+ m_nodes.insert(node);
+ node->set_owner(this);
+}
+
+////////////////////////////////////
+
/*inline StrictOrderArea* StrictEvent::get_strict_order_area()
{
return dynamic_cast<StrictOrderArea*>(m_area);
@@ -97,6 +114,13 @@
return dynamic_cast<CoregionArea*>(m_area);
}
+CoregEventRelPtr CoregionEvent::add_successor(CoregionEvent* e)
+{
+ CoregEventRelPtr rel = new CoregionEventRelation(this,e);
+ add_successor(rel);
+ return rel;
+}
+
Instance* CompleteMessage::get_sender() const
{
return m_send_event->get_instance();
@@ -107,13 +131,18 @@
return m_receive_event->get_instance();
}
+CompleteMessage::CompleteMessage(Event* sender, Event* receiver, MscMessage* original):
+MscMessage(original),m_send_event(sender),m_receive_event(receiver)
+{
+}
+
void BMsc::add_instance(InstancePtr& i)
{
m_instances.push_back(i);
i->set_bmsc(this);
}
-void Instance::add_area(EventAreaPtr& area)
+void Instance::add_area(EventAreaPtr area)
{
if(!is_empty())
{
@@ -126,3 +155,18 @@
m_last = area;
area->set_instance(this);
}
+
+Instance::Instance(const std::string& label, const std::string& kind):
+MscElementTmpl<Instance>(NULL),m_label(label),m_kind(kind)
+{
+}
+
+Instance::Instance(Instance* original):MscElementTmpl<Instance>(original)
+{
+
+}
+
+IncompleteMessage::IncompleteMessage(IncompleteMessage* original):MscMessage(original)
+{
+ m_type = original->get_type();
+}
Modified: trunk/src/data/msc.h
===================================================================
--- trunk/src/data/msc.h 2008-11-17 19:46:26 UTC (rev 119)
+++ trunk/src/data/msc.h 2008-11-23 20:43:27 UTC (rev 120)
@@ -421,11 +421,7 @@
HMsc* m_owner;
- /**
- * This is an abstract class
- */
- HMscNode(HMscNode* original=NULL):MscElementTmpl<HMscNode>(original)
- {}
+ HMscNode(HMscNode* original=NULL);
public:
@@ -694,10 +690,7 @@
return m_nodes;
}
- void add_node(HMscNodePtr node)
- {
- m_nodes.insert(node);
- }
+ void add_node(HMscNodePtr node);
void remove_node(HMscNodePtr node)
{
@@ -806,7 +799,11 @@
{
public:
- ConnectionNode(ConnectionNode* original=NULL):HMscNode(original),PredecessorNode(),SuccessorNode()
+ /**
+ * ConnectionNode is allowed to reference via m_original different types of
+ * HMscNode.
+ */
+ ConnectionNode(HMscNode* original=NULL):HMscNode(original),PredecessorNode(),SuccessorNode()
{
}
@@ -870,11 +867,10 @@
/**
* @param label - label of instance
*/
- Instance(const std::string& label, const std::string& kind="", Instance* original=NULL):
- MscElementTmpl<Instance>(original),m_label(label),m_kind(kind)
- {
- }
+ Instance(const std::string& label, const std::string& kind="");
+ Instance(Instance* original);
+
virtual ~Instance()
{
@@ -936,7 +932,7 @@
m_height = height;
}
- void add_area(EventAreaPtr& area);
+ void add_area(EventAreaPtr area);
bool is_empty()
{
@@ -963,11 +959,16 @@
* @param receiver - receiving instance
* @param label - label of message
*/
- MscMessage(const std::string& label="",MscMessage* original=NULL):
- MscElementTmpl<MscMessage>(original),m_label(label)
+ MscMessage(const std::string& label=""):
+ MscElementTmpl<MscMessage>(NULL),m_label(label)
{
}
+ MscMessage(MscMessage* original):
+ MscElementTmpl<MscMessage>(original)
+ {
+ }
+
virtual ~MscMessage()
{
@@ -1017,6 +1018,8 @@
{
}
+ CompleteMessage(Event* sender, Event* receiver, MscMessage* original);
+
/**
* Retrieves instance of m_send_event
*/
@@ -1082,12 +1085,13 @@
public:
IncompleteMessage(const IncompleteMsgType& type=LOST, const std::string& label="",
- const std::string& instance_label="", IncompleteMessage* original= NULL,
- const Point& dot_position=Point()):
- MscMessage(label,original),m_instance_label(instance_label),m_type(type),
+ const std::string& instance_label="", const Point& dot_position=Point()):
+ MscMessage(label),m_instance_label(instance_label),m_type(type),
m_dot_position(dot_position)
{
}
+
+ IncompleteMessage(IncompleteMessage* original);
Point& get_dot_position()
{
@@ -1270,9 +1274,14 @@
}
/**
- * Returns instance which this event occures at
+ * Returns Instance which this event occures at
*/
virtual Instance* get_instance() const=0;
+
+ /**
+ * Returns EventArea which this event occures at
+ */
+ virtual EventArea* get_general_area() const=0;
const std::string& get_receiver_label() const
{
@@ -1387,7 +1396,7 @@
return m_area->get_instance();
}
- EventArea* get_general_area()
+ EventArea* get_general_area() const
{
return m_area;
}
@@ -1469,6 +1478,8 @@
{
return m_successor==NULL;
}
+
+
};
class CoregionEventRelation:public MscElementTmpl<CoregionEventRelation>
@@ -1598,6 +1609,8 @@
return m_successors.size()==0;
}
+ CoregEventRelPtr add_successor(CoregionEvent* e);
+
};
/**
Added: trunk/tests/acyclic_checker_test.cpp
===================================================================
--- trunk/tests/acyclic_checker_test.cpp (rev 0)
+++ trunk/tests/acyclic_checker_test.cpp 2008-11-23 20:43:27 UTC (rev 120)
@@ -0,0 +1,138 @@
+/*
+ * scstudio - Sequence Chart Studio
+ * http://scstudio.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (c) 2008 Jindra Babica <ba...@ma...>
+ *
+ * $Id$
+ */
+
+#include "data/msc.h"
+#include "check/acyclic_checker.h"
+
+#include <iostream>
+
+#define RETURN_IF_FAILED(res) if(!(res)) return 1;
+
+bool print_result(const BMscPtr bmsc,const bool is_fifo,const std::string& mapper_name)
+{
+ bool result;
+ if(is_fifo)
+ if(bmsc.get())
+ {
+ result =false;
+ std::cout << "ERROR: BMsc is supposed to be acyclic for " << mapper_name
+ << " channels but it isn't" << std::endl;
+ }
+ else
+ {
+ result = true;
+ std::cout << "OK: BMsc is supposed to be acyclic for " << mapper_name
+ << " channels and it is" << std::endl;
+ }
+ else
+ if(bmsc.get())
+ {
+ result = true;
+ std::cout << "OK: BMsc is supposed not to be acyclic for " << mapper_name
+ << " channels and it isnt't" << std::endl;
+ }
+ else
+ {
+ result =false;
+ std::cout << "ERROR: BMsc is supposed not to be acyclic for " << mapper_name
+ << " channels but it is" << std::endl;
+ }
+ std::cout << std::endl;
+ return result;
+}
+
+bool check(BMscPtr bmsc,const bool is_sr_fifo,const bool is_srl_fifo)
+{
+ AcyclicCheckerPtr checker = AcyclicChecker::instance();
+ SRChannelMapperPtr srm = SRChannelMapper::instance();
+ SRLChannelMapperPtr srlm = SRLChannelMapper::instance();
+ return (print_result(checker->check(bmsc,srm),is_sr_fifo,"sender-receiver") &&
+ print_result(checker->check(bmsc,srlm),is_srl_fifo,"sender-receiver-label"));
+}
+
+bool BMscA() {
+ std::cout << "Checking:" << std::endl;
+ std::cout << " p1 p2 " << std::endl;
+ std::cout << " | | " << std::endl;
+ std::cout << "e1 O-----a----->O e3" << std::endl;
+ std::cout << " | | " << std::endl;
+ std::cout << "e2 O<----a------O e4" << std::endl;
+ std::cout << " | | " << std::endl;
+
+ BMscPtr myBmsc(new BMsc());
+
+ InstancePtr i1(new Instance("p1"));
+ myBmsc->add_instance(i1);
+ InstancePtr i2(new Instance("p2"));
+ myBmsc->add_instance(i2);
+
+ EventAreaPtr a1(new StrictOrderArea());
+ i1->add_area(a1);
+ EventAreaPtr a2(new StrictOrderArea());
+ i2->add_area(a2);
+
+ EventPtr e1 = a1->add_event();
+ EventPtr e2 = a1->add_event();
+ EventPtr e3 = a2->add_event();
+ EventPtr e4 = a2->add_event();
+
+ e1->send_message(e3.get(),"a");
+ e4->send_message(e2.get(),"a");
+
+ return check(myBmsc,true,true);
+}
+
+bool BMscB() {
+ std::cout << "Checking:" << std::endl;
+ std::cout << " p1 p2 " << std::endl;
+ std::cout << " | | " << std::endl;
+ std::cout << "e1 O<--a--- | " << std::endl;
+ std::cout << " | \\ | " << std::endl;
+ std::cout << "e2 O-----a----->O e3" << std::endl;
+ std::cout << " | \\ | " << std::endl;
+ std::cout << " | -O e4" << std::endl;
+ std::cout << " | | " << std::endl;
+
+ BMscPtr myBmsc(new BMsc());
+
+ InstancePtr i1(new Instance("p1"));
+ myBmsc->add_instance(i1);
+ InstancePtr i2(new Instance("p2"));
+ myBmsc->add_instance(i2);
+
+ EventAreaPtr a1(new StrictOrderArea());
+ i1->add_area(a1);
+ EventAreaPtr a2(new StrictOrderArea());
+ i2->add_area(a2);
+
+ EventPtr e1 = a1->add_event();
+ EventPtr e2 = a1->add_event();
+ EventPtr e3 = a2->add_event();
+ EventPtr e4 = a2->add_event();
+
+ e4->send_message(e1.get(),"a");
+ e2->send_message(e3.get(),"a");
+
+ return check(myBmsc,false,false);
+}
+
+int main(int argc, char** argv) {
+ RETURN_IF_FAILED(BMscA());
+ RETURN_IF_FAILED(BMscB());
+ return 0;
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|