165 lines
4.7 KiB
Python
165 lines
4.7 KiB
Python
from sys import exit
|
|
from colour import *
|
|
|
|
|
|
class ContextAutomaton(object):
|
|
def __init__(self, reaction_system):
|
|
self._states = []
|
|
self._transitions = []
|
|
self._init_state = None
|
|
self._reaction_system = reaction_system
|
|
self._name = ""
|
|
self._prod_entities = set()
|
|
|
|
@property
|
|
def states(self):
|
|
return self._states
|
|
|
|
@property
|
|
def transitions(self):
|
|
return self._transitions
|
|
|
|
@property
|
|
def prod_entities(self):
|
|
return self._prod_entities
|
|
|
|
@property
|
|
def reaction_system(self):
|
|
return self._reaction_system
|
|
|
|
@property
|
|
def name(self):
|
|
return self._name
|
|
|
|
@name.setter
|
|
def name(self, automaton_name):
|
|
self._name = automaton_name
|
|
|
|
def add_state(self, name):
|
|
if name not in self._states:
|
|
self._states.append(name)
|
|
else:
|
|
print("'%s' already added. skipping..." % (name,))
|
|
|
|
def add_states(self, states_set):
|
|
for st in states_set:
|
|
self.add_state(st)
|
|
|
|
def add_init_state(self, name):
|
|
self.add_state(name)
|
|
self._init_state = self._states.index(name)
|
|
|
|
def get_init_state_name(self):
|
|
if self._init_state == None:
|
|
return None
|
|
return self._states[self._init_state]
|
|
|
|
def is_state(self, name):
|
|
return name in self._states
|
|
|
|
def get_state_id(self, name):
|
|
try:
|
|
return self._states.index(name)
|
|
except ValueError:
|
|
print_error("Undefined context automaton state: " + repr(name))
|
|
exit(1)
|
|
|
|
def get_state_name(self, state_id):
|
|
return self._states[state_id]
|
|
|
|
def get_init_state_id(self):
|
|
return self._init_state
|
|
|
|
def print_states(self):
|
|
for state in self._states:
|
|
print(state)
|
|
|
|
def is_valid_rs_set(self, elements):
|
|
return set(elements).issubset(self._reaction_system.background_set)
|
|
|
|
def is_valid_context(self, context):
|
|
return self.is_valid_rs_set(context)
|
|
|
|
def get_set_of_ids(self, elements):
|
|
"""Converts a set/list/tuple of entities into a set of their ids"""
|
|
|
|
new_set = set()
|
|
for e in set(elements):
|
|
new_set.add(self._reaction_system.get_entity_id(e))
|
|
return new_set
|
|
|
|
def add_transition(self, src, context_set, dst):
|
|
if not isinstance(context_set, (set, list)):
|
|
print("Contexts set must be of type set or list")
|
|
|
|
if not self.is_valid_context(context_set):
|
|
raise RuntimeError(
|
|
"one of the entities in the context set is unknown (undefined)!"
|
|
)
|
|
|
|
if not self.is_state(src):
|
|
raise RuntimeError('"' + src + '" is an unknown (undefined) state')
|
|
|
|
if not self.is_state(dst):
|
|
raise RuntimeError('"' + dst + '" is an unknown (undefined) state')
|
|
|
|
new_context_set = set()
|
|
for e in set(context_set):
|
|
new_context_set.add(self._reaction_system.get_entity_id(e))
|
|
|
|
self._prod_entities |= new_context_set
|
|
|
|
self._transitions.append(
|
|
(self.get_state_id(src), new_context_set, self.get_state_id(dst))
|
|
)
|
|
|
|
def rsset2str(self, elements):
|
|
"""Converts the set of entities ids into the string with their names"""
|
|
if len(elements) == 0:
|
|
return "0"
|
|
s = "{"
|
|
for c in elements:
|
|
s += " " + self._reaction_system.get_entity_name(c)
|
|
s += " }"
|
|
return s
|
|
|
|
def context2str(self, ctx):
|
|
return self.rsset2str(ctx)
|
|
|
|
def show_transitions(self):
|
|
print(C_MARK_INFO + " Context automaton transitions:")
|
|
for transition in self._transitions:
|
|
str_transition = str(transition[0]) + " --( "
|
|
str_transition += self.context2str(transition[1])
|
|
str_transition += " )--> " + str(transition[2])
|
|
print(" - " + str_transition)
|
|
|
|
def show_states(self):
|
|
init_state_name = self.get_init_state_name()
|
|
print(C_MARK_INFO + " Context automaton states:")
|
|
for state in self._states:
|
|
print(" - " + state, end="")
|
|
if state == init_state_name:
|
|
print(" [init]")
|
|
else:
|
|
print()
|
|
|
|
def show_header(self):
|
|
if self.name:
|
|
name_string = ": " + colour_str(C_BOLD, self.name)
|
|
print(C_MARK_INFO + " Context automaton" + name_string)
|
|
|
|
def show_prod_entities(self):
|
|
print(C_MARK_INFO + " Context automaton possible products:")
|
|
for entity in self._prod_entities:
|
|
print(" - " + self._reaction_system.get_entity_name(entity))
|
|
|
|
def show(self):
|
|
self.show_header()
|
|
self.show_states()
|
|
self.show_transitions()
|
|
self.show_prod_entities()
|
|
|
|
|
|
# EOF
|