Commit 0ac0fe65 authored by VIGNET Pierre's avatar VIGNET Pierre

Rewrite & add code for Strongly Connected Components detection

parent 5b4fc682
......@@ -9,7 +9,7 @@
<property name="orientation">vertical</property>
<child>
<widget class="GtkButton" id="frontierbutton">
<property name="label" translatable="yes">Frontier SCC</property>
<property name="label" translatable="yes">Frontier Strongly Connected Components</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
......
......@@ -374,7 +374,8 @@ class SCCWindow(object):
self.window = self.wtree.get_widget("window1")
self.window.set_resizable(True)
self.window.set_title("Isolated SCC - "+self.emvc.model.name)
self.window.set_title("Isolated Strongly Connected Components (SCC) - "\
+ self.emvc.model.name)
height = gtk.gdk.screen_height()
height = int(height * 0.30)
color = gtk.gdk.color_parse(BG_COLOR)
......@@ -429,9 +430,18 @@ class SCCWindow(object):
"""
Display info on isolated SCC
"""
SCC_found = (len(self.l_solutions[0]) != 0)
# info label
info = self.wtree.get_widget("label_nbsol")
info.set_text(str(len(self.l_solutions))+" isolated SCC found")
if not SCC_found:
info.set_text("No isolated Strongly Connected Components found.")
return
else:
info.set_text(str(len(self.l_solutions)) + \
" isolated Strongly Connected Components found.\n"
"(Only 1 node of each of them requires an input "
"transition with a StartNode)")
self.frame_sol = self.wtree.get_widget("frame_sol")
# button frame
......
......@@ -59,6 +59,9 @@ from cadbiom.models.guard_transitions.translators.chart_xml_pid import \
from cadbiom.models.guard_transitions.chart_model import ChartModel
from cadbiom.models.guard_transitions.analyser.ana_visitors import EstimExpVisitor, \
TableVisitor, FrontierVisitor, SigExpIdCollectVisitor
import cadbiom.commons as cm
LOGGER = cm.logger()
class StaticAnalyzer(object):
"""
......@@ -206,36 +209,73 @@ class StaticAnalyzer(object):
Find initial strongly connected components in the transition graph
@return: list<list<string>> - list of list of node names in frontier
strongly connected components
.. warning:: If the model is modified but not reloaded, KeyError is
raised (see below); we inform the user of that...
"""
dgraph = self.make_transition_dg()
scc_list = nx.strongly_connected_components(dgraph)
frontier_list = []
# Get directed graph
directed_graph = self.make_transition_dg()
# generator on the strongly connectec components
scc_list = nx.strongly_connected_components(directed_graph)
frontier_list = []
tvi = TableVisitor(self.reporter)
self.model.accept(tvi)
for scc in scc_list :
if len(scc) > 1: # eliminate isolated frontier nodes
for scc in scc_list:
# eliminate isolated frontier nodes
if len(scc) > 1:
frontier = True
# generate symbol table for partial evaluation
pest = dict()
# all places in scc are inactivated (-1)
symbol_table = dict.fromkeys(scc, -1)
pe_visitor = EstimExpVisitor(symbol_table)
# find all incoming transitions for each node in scc
LOGGER.debug("scc: " + str(scc))
for node_name in scc:
pest[node_name] = -1 # all places in scc inactivated
pe_visitor = EstimExpVisitor(pest)
for node_name in scc : # find incoming transitions in scc
chart_node = self.model.node_dict[node_name]
for in_trans in chart_node.incoming_trans :
ori_trans = in_trans.ori.name
# the transition comes from outside scc
if ori_trans not in scc :
try:
# raises keyerror if the model isn't reloaded manually..
chart_node = self.model.node_dict[node_name]
except KeyError:
return list([[
"Error: Please try by \
saving & reloading the model manually"]])
for in_trans in chart_node.incoming_trans:
LOGGER.debug(
"Node {}, trans: {}".format(
node_name,
(in_trans.ori.name, in_trans.ext.name)
)
)
# if the transition comes from outside scc,
# we try to detect if scc may be reached with this trans
if in_trans.ori.name not in scc :
cond = self.__tr_estim(in_trans, pe_visitor,
tvi.tab_symb)
# scc may be reached from other part of the model
if cond >= 0:
LOGGER.debug(
"scc validated as a cyle ?: " + str(cond)
)
# Guard of the transition is True
# (not False or indeterminate),
# so scc may be reached from other part of the model
# => switch to next scc
if cond >= 0:
frontier = False
break
if frontier:
LOGGER.debug("frontier found")
frontier_list.append(scc)
LOGGER.debug("SCC found: " + str(frontier_list))
# Nothing found => return empty result
if len(frontier_list) == 0:
return [[]]
return frontier_list
def get_basal_activated_genes(self):
......@@ -473,13 +513,13 @@ class StaticAnalyzer(object):
@return: a Networkx digraph
"""
graph = nx.DiGraph()
for trans in self.model.transition_list :
ori_name = trans.ori.name
ext_name = trans.ext.name
graph.add_edges_from([(ori_name, ext_name)])
for node in self.model.node_dict.keys():
if node not in graph.nodes():
graph.add_node(node)
edges = [(trans.ori.name, trans.ext.name)
for trans in self.model.transition_list]
graph.add_edges_from(edges)
graph.add_nodes_from(self.model.node_dict.keys())
return graph
def make_dependence_dg(self, weight = False):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment