|
From: <ba...@us...> - 2009-01-17 15:36:40
|
Revision: 172
http://scstudio.svn.sourceforge.net/scstudio/?rev=172&view=rev
Author: babicaj
Date: 2009-01-17 15:36:32 +0000 (Sat, 17 Jan 2009)
Log Message:
-----------
livelock_checker returns proper counter example
Modified Paths:
--------------
trunk/src/check/liveness/livelock_checker.cpp
trunk/src/data/msc.h
trunk/src/data/refnode_finder.cpp
trunk/src/data/refnode_finder.h
Modified: trunk/src/check/liveness/livelock_checker.cpp
===================================================================
--- trunk/src/check/liveness/livelock_checker.cpp 2009-01-16 22:29:45 UTC (rev 171)
+++ trunk/src/check/liveness/livelock_checker.cpp 2009-01-17 15:36:32 UTC (rev 172)
@@ -18,6 +18,7 @@
#include "check/liveness/livelock_checker.h"
#include "data/dfs_refnode_hmsc_traverser.h"
+#include "check/pseudocode/msc_duplicators.h"
const std::string ATTRIBUTE_REACHABLE = "LL_reachable";
@@ -110,8 +111,59 @@
HMscPtr LivelockChecker::create_counter_example(const MscElementPListList& path)
{
- HMscPtr e = HMscPtr(new HMsc("Erroneous path"));
- return e;
+ HMscPtr example;
+ MscElementPListList::const_iterator h;
+ MscElementPListList complete_path;
+ ReferenceNodeFinder finder;
+ //path doesn't contain connection nodes and relations -- find them
+ for(h=path.begin();h!=path.end();h++)
+ {
+ complete_path.push_back(MscElementPList());
+ MscElementPList::const_iterator e;
+ for(e=(*h).begin();e!=(*h).end();e++)
+ {
+ if(e==(*h).begin())
+ {
+ complete_path.back().push_back(*e);
+ }
+ else
+ {
+ finder.find_node(
+ dynamic_cast<HMscNode*>(complete_path.back().back()),
+ dynamic_cast<HMscNode*>(*e));
+ const MscElementPList& node_path = *(finder.get_reached_elements().begin());
+ if(node_path.size()>1)
+ {
+ complete_path.back().insert(
+ complete_path.back().end(),
+ ++node_path.begin(),
+ node_path.end()
+ );
+ }
+ finder.cleanup_traversing_attributes();
+ }
+ }
+ }
+ HMscPathDuplicator duplicator;
+ example = duplicator.duplicate_path(complete_path);
+ //mark last node in each hmsc if it is reference node
+ for(h=complete_path.begin();h!=complete_path.end();h++)
+ {
+ MscElement* last = (*h).back();
+ duplicator.get_copy(last)->set_marked(true);
+ }
+ //mark cycle in last hmsc
+ MscElementPList::const_iterator e=complete_path.back().begin();
+ while(*e!=complete_path.back().back())
+ {
+ e++;
+ }
+ while(e!=complete_path.back().end())
+ {
+ duplicator.get_copy(*e)->set_marked(true);
+ e++;
+ }
+ return example;
}
LivelockCheckerPtr LivelockChecker::instance()
Modified: trunk/src/data/msc.h
===================================================================
--- trunk/src/data/msc.h 2009-01-16 22:29:45 UTC (rev 171)
+++ trunk/src/data/msc.h 2009-01-17 15:36:32 UTC (rev 172)
@@ -314,7 +314,7 @@
* and the newly created one. Therefore algorithms keep this relation in this
* attribute.
*/
- T* m_original;
+ boost::intrusive_ptr<T> m_original;
/**
* \brief Creates MscElement referencing the original one.
@@ -333,7 +333,7 @@
*/
T* get_original() const
{
- return m_original;
+ return m_original.get();
}
/**
@@ -344,6 +344,14 @@
m_original = e;
}
+ /**
+ * Setter for m_original.
+ */
+ void set_original(boost::intrusive_ptr<T>& e)
+ {
+ m_original = e;
+ }
+
virtual ~MscElementTmpl()
{
Modified: trunk/src/data/refnode_finder.cpp
===================================================================
--- trunk/src/data/refnode_finder.cpp 2009-01-16 22:29:45 UTC (rev 171)
+++ trunk/src/data/refnode_finder.cpp 2009-01-17 15:36:32 UTC (rev 172)
@@ -72,4 +72,40 @@
return finder.find_successors(node);
}
+void ReferenceNodeFinder::find_node(HMscNode* start, HMscNode* desired)
+{
+ FindNodeListener l(desired);
+ add_white_node_found_listener(&l);
+ push_top_attributes();
+ set_color(start,GRAY); //set node to GRAY to avoid him to be traversed
+ m_reached_elements.back().push_back(start); //push him on top to simulate it was already traversed
+ PredecessorNode* pred = dynamic_cast<PredecessorNode*>(start);
+ if(pred)
+ {
+ try
+ {
+ traverse_successors(pred);
+ }
+ catch(...)
+ {
+
+ }
+ }
+ remove_white_node_found_listeners();
+}
+
+FindNodeListener::FindNodeListener(HMscNode* desired):
+m_desired(desired)
+{
+
+}
+
+void FindNodeListener::on_white_node_found(HMscNode* n)
+{
+ if(m_desired==n)
+ {
+ throw 1;
+ }
+}
+
// $Id$
Modified: trunk/src/data/refnode_finder.h
===================================================================
--- trunk/src/data/refnode_finder.h 2009-01-16 22:29:45 UTC (rev 171)
+++ trunk/src/data/refnode_finder.h 2009-01-17 15:36:32 UTC (rev 172)
@@ -62,6 +62,20 @@
};
+class FindNodeListener:public WhiteNodeFoundListener
+{
+private:
+
+ HMscNode* m_desired;
+
+public:
+
+ FindNodeListener(HMscNode* desired);
+
+ void on_white_node_found(HMscNode* n);
+
+};
+
/**
* \brief See method traverse(HMscNode* node) for purpose.
*/
@@ -84,6 +98,13 @@
* \brief Creates ReferenceNodeFinder and returns result of find_successors
*/
static HMscNodePListPtr successors(HMscNode* node, const std::string& color_attribute = "rnf_color");
+
+ /**
+ * \brief Finds path from start to desired node
+ *
+ * Found path can be retrieved by get_reached_elements()
+ */
+ void find_node(HMscNode* start, HMscNode* desired);
protected:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|