getters for the used actions, automata supporting actions, transitions for actions, etc.

This commit is contained in:
Artur Meski
2017-01-01 00:34:27 +01:00
parent ebee3aa03e
commit 1594659509
7 changed files with 219 additions and 48 deletions

View File

@@ -9,6 +9,7 @@ class ContextAutomaton(object):
self._init_state = None self._init_state = None
self._reaction_system = reaction_system self._reaction_system = reaction_system
self._name = "" self._name = ""
self._prod_entities = set()
@property @property
def states(self): def states(self):
@@ -18,6 +19,14 @@ class ContextAutomaton(object):
def transitions(self): def transitions(self):
return self._transitions return self._transitions
@property
def prod_entities(self):
return self._prod_entities
@property
def reaction_system(self):
return self._reaction_system
@property @property
def name(self): def name(self):
return self._name return self._name
@@ -102,6 +111,8 @@ class ContextAutomaton(object):
for e in set(context_set): for e in set(context_set):
new_context_set.add(self._reaction_system.get_entity_id(e)) 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))) self._transitions.append((self.get_state_id(src),new_context_set,self.get_state_id(dst)))
def rsset2str(self, elements): def rsset2str(self, elements):
@@ -140,8 +151,14 @@ class ContextAutomaton(object):
name_string = ": " + colour_str(C_BOLD, self.name) name_string = ": " + colour_str(C_BOLD, self.name)
print(C_MARK_INFO + " Context automaton" + name_string) 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): def show(self):
self.show_header() self.show_header()
self.show_states() self.show_states()
self.show_transitions() self.show_transitions()
self.show_prod_entities()

View File

@@ -4,15 +4,52 @@ from colour import *
from rs.context_automaton import ContextAutomaton from rs.context_automaton import ContextAutomaton
class ExtendedContextAutomaton(ContextAutomaton): class ExtendedContextAutomaton(ContextAutomaton):
"""Extended Context Automaton""" """Extended Context Automaton
Supports transitions with actions.
Each transitions is additionally guarded with
reactants and inhibitors.
The provided context entities are the products
of the reactions labelling the transition taken.
"""
def __init__(self, reaction_system): def __init__(self, reaction_system):
self._actions = []
super(ExtendedContextAutomaton, self).__init__(reaction_system) super(ExtendedContextAutomaton, self).__init__(reaction_system)
self._actions = []
self._transitions_for_products = dict()
self._actions_for_products = dict()
@property @property
def number_of_actions(self): def number_of_actions(self):
return len(self._actions) return len(self._actions)
@property
def actions(self):
return self._actions
def has_action(self, action):
"""Checks if the automaton supports a given action"""
return action in self._actions
def get_transitions_producing_entity(self, entity):
"""Returns the transitions that produce a given entity"""
if entity in self._transitions_for_products:
return self._transitions_for_products[entity]
else:
return []
def get_actions_producing_entity(self, entity):
"""Returns the actions that produce a given entity"""
if entity in self._actions_for_products:
return self._actions_for_products[entity]
else:
return set()
def add_transition(self, src, actions, ctx_reaction, dst): def add_transition(self, src, actions, ctx_reaction, dst):
"""Adds a transition """Adds a transition
@@ -49,10 +86,21 @@ class ExtendedContextAutomaton(ContextAutomaton):
i_ids = self.get_set_of_ids(ctx_inhibitors) i_ids = self.get_set_of_ids(ctx_inhibitors)
p_ids = self.get_set_of_ids(ctx_products) p_ids = self.get_set_of_ids(ctx_products)
self._transitions.append((src_id, act_ids, (r_ids, i_ids, p_ids), dst_id)) new_transition = (src_id, act_ids, (r_ids, i_ids, p_ids), dst_id)
for product_id in p_ids:
self._transitions_for_products.setdefault(product_id, [])
self._transitions_for_products[product_id].append(new_transition)
self._actions_for_products.setdefault(product_id, set())
self._actions_for_products[product_id] |= set(actions)
self._prod_entities |= p_ids
self._transitions.append(new_transition)
def show_transitions(self): def show_transitions(self):
"""Prints the set of registered transitions""" """Prints the set of registered transitions"""
print(C_MARK_INFO + " Context automaton transitions:") print(C_MARK_INFO + " Context automaton transitions:")
for src_id, act_id, reaction, dst_id in self._transitions: for src_id, act_id, reaction, dst_id in self._transitions:
str_transition = self.get_state_name(src_id) + " --( " str_transition = self.get_state_name(src_id) + " --( "
@@ -63,6 +111,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def add_action(self, action_name): def add_action(self, action_name):
"""Registers an action""" """Registers an action"""
if action_name not in self._actions: if action_name not in self._actions:
self._actions.append(action_name) self._actions.append(action_name)
else: else:
@@ -70,6 +119,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_action_id(self, action_name): def get_action_id(self, action_name):
"""For an action name returns its id""" """For an action name returns its id"""
try: try:
return self._actions.index(action_name) return self._actions.index(action_name)
except ValueError: except ValueError:
@@ -81,6 +131,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_set_of_action_ids(self, actions): def get_set_of_action_ids(self, actions):
"""Converts a set of actions into the set of their ids""" """Converts a set of actions into the set of their ids"""
act_ids = set() act_ids = set()
for act in actions: for act in actions:
act_ids.add(self.get_action_id(act)) act_ids.add(self.get_action_id(act))
@@ -88,6 +139,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_actions_str(self, actions): def get_actions_str(self, actions):
"""Returns the string for the set of action ids given by actions""" """Returns the string for the set of action ids given by actions"""
s = "" s = ""
for act in actions: for act in actions:
s += self.get_action_name(act) + ", " s += self.get_action_name(act) + ", "
@@ -96,6 +148,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def show_actions(self): def show_actions(self):
"""Prints all the actions""" """Prints all the actions"""
print(C_MARK_INFO + " Context automaton actions:") print(C_MARK_INFO + " Context automaton actions:")
for act in self._actions: for act in self._actions:
print(" - " + act + " (id=" + str(self.get_action_id(act)) + ")") print(" - " + act + " (id=" + str(self.get_action_id(act)) + ")")
@@ -103,3 +156,4 @@ class ExtendedContextAutomaton(ContextAutomaton):
def show(self): def show(self):
super(ExtendedContextAutomaton, self).show() super(ExtendedContextAutomaton, self).show()
self.show_actions() self.show_actions()

View File

@@ -1,18 +1,100 @@
from sys import exit from sys import exit
from colour import *
class NetworkOfContextAutomata(object): class NetworkOfContextAutomata(object):
def __init__(self, context_automata): def __init__(self, reaction_system, context_automata):
self.automata = list(context_automata) self.automata = []
self._reaction_system = reaction_system
self._actions = set()
self._prod_entities = set()
self._automata_for_actions = dict()
self._actions_for_products = dict()
if len(context_automata) < 1:
print("Context automata network must contain at least one automaton!")
exit(1)
for automaton in context_automata:
self.add(automaton)
self.sanity_check()
@property @property
def number_of_automata(self): def number_of_automata(self):
return len(self.automata) return len(self.automata)
@property
def reaction_system(self):
return self._reaction_system
@property
def prod_entities(self):
"""Returns the set of entities that can potentially be produced by the automata in the network"""
return self._prod_entities
def sanity_check(self):
"""Performs a sanity check of the network of automata"""
for automaton in self.automata:
if automaton.reaction_system != self._reaction_system:
print_error("Mismatching reaction system used in \"" + str(automaton.name) + "\"!!!")
exit(1)
def show_prod_entities(self):
print(C_MARK_INFO + " Possible context-products for the network of automata:")
for entity in self.prod_entities:
print(" - " + self._reaction_system.get_entity_name(entity))
def show_actions(self):
print(C_MARK_INFO + " Actions of the network:")
for action in self._actions:
print(" - " + action)
def register_action(self, action, aut):
"""Associates an action with an automaton"""
self._automata_for_actions.setdefault(action, set())
aut_index = self.automata.index(aut)
self._automata_for_actions[action].add(aut_index)
def get_actions_producing_entity(self, entity):
"""Returns the set of actions producing an entity"""
if entity in self._actions_for_products:
return self._actions_for_products[entity]
else:
return set()
def get_automata_with_action(self, action):
"""Returns the set of automata that support an action"""
if action in self._automata_for_actions:
return self._automata_for_actions[action]
else:
return set()
def add(self, aut):
"""Adds an automaton to the network"""
self.automata.append(aut)
self._prod_entities |= aut.prod_entities
self._actions |= set(aut.actions)
for action in aut.actions:
self.register_action(action, aut)
for entity in aut.prod_entities:
self._actions_for_products.setdefault(entity, set())
self._actions_for_products[entity] |= aut.get_actions_producing_entity(entity)
def show(self): def show(self):
print()
print(C_MARK_INFO + " NETWORK OF CONTEXT AUTOMATA")
for ca in self.automata: for ca in self.automata:
print() print()
ca.show() ca.show()
print()
self.show_prod_entities()
self.show_actions()
def add(self, aut):
self.automata.append(aut)

View File

@@ -15,6 +15,14 @@ class ReactionSystem(object):
self.init_contexts = [] self.init_contexts = []
self.context_entities = [] self.context_entities = []
@property
def background_set_size(self):
return len(self.background_set)
@property
def set_of_bgset_ids(self):
return set(range(self.background_set_size))
def assume_not_in_bgset(self, name): def assume_not_in_bgset(self, name):
if self.is_in_background_set(name): if self.is_in_background_set(name):
raise RuntimeError("The entity " + name + " is already on the list") raise RuntimeError("The entity " + name + " is already on the list")

View File

@@ -12,6 +12,8 @@ def test_extended_automaton():
r = ReactionSystem() r = ReactionSystem()
r.add_bg_set_entity("inc") r.add_bg_set_entity("inc")
r.add_bg_set_entity("dec") r.add_bg_set_entity("dec")
r.add_bg_set_entity("decx")
c1 = ExtendedContextAutomaton(r) c1 = ExtendedContextAutomaton(r)
c1.add_init_state("init") c1.add_init_state("init")
@@ -19,19 +21,44 @@ def test_extended_automaton():
c1.add_state("working") c1.add_state("working")
c1.add_action("act1") c1.add_action("act1")
c1.add_action("act2") c1.add_action("act2")
c1.add_transition("init", ["act1", "act2"], ([],[],["inc"]), "working") c1.add_transition("init", ["act1", "act2"], ([],[],["inc","dec"]), "working")
c1.add_transition("working", ["act2"], ([],[],["inc"]), "working") c1.add_transition("working", ["act2"], ([],[],["inc"]), "working")
c2 = ExtendedContextAutomaton(r) c2 = ExtendedContextAutomaton(r)
c2.add_init_state("init") c2.add_init_state("init")
c2.name = "cxxxx" c2.name = "c2"
c2.add_state("working") c2.add_state("working")
c2.add_action("act1") c2.add_action("act1")
c2.add_action("act2") c2.add_action("act2")
c2.add_transition("init", ["act1", "act2"], ([],[],["inc"]), "working") c2.add_transition("init", ["act1", "act2"], ([],[],["inc"]), "working")
c2.add_transition("working", ["act2"], ([],[],["inc"]), "working") c2.add_transition("working", ["act2"], ([],[],["inc"]), "working")
na = NetworkOfContextAutomata([c1,c2]) c3 = ExtendedContextAutomaton(r)
c3.add_init_state("init")
c3.name = "c3"
c3.add_state("working")
c3.add_action("act1")
c3.add_transition("init", ["act1"], ([],[],["inc"]), "working")
#
# c4 = ExtendedContextAutomaton(r)
# c4.add_init_state("init")
# c4.name = "c4"
# c4.add_state("working")
# c4.add_action("act1")
# c4.add_action("act42")
# c4.add_transition("init", ["act1", "act42"], ([],[],["inc"]), "working")
# c4.add_transition("working", ["act42"], ([],[],["inc"]), "working")
#
# c5 = ExtendedContextAutomaton(r)
# c5.add_init_state("init")
# c5.name = "c5"
# c5.add_state("working")
# c5.add_action("act1")
# c5.add_action("act2")
# c5.add_transition("init", ["act1", "act2"], ([],[],["inc"]), "working")
# c5.add_transition("working", ["act2"], ([],[],["inc"]), "working")
na = NetworkOfContextAutomata(r, [c1,c2,c3])
rna = ReactionSystemWithNetworkOfAutomata(r,na) rna = ReactionSystemWithNetworkOfAutomata(r,na)

View File

@@ -24,8 +24,8 @@ version = "2016/12/28/00"
rsmc_banner = """ rsmc_banner = """
Reaction Systems SMT-Based Model Checking Reaction Systems SMT-Based Model Checking
Version: """ + version + """ Version: """ + version + """
Author: Artur Męski <meski@ipipan.waw.pl> / <artur.meski@ncl.ac.uk> Author: Artur Męski <meski@ipipan.waw.pl> / <artur.meski@ncl.ac.uk>
""" """
################################################################## ##################################################################

View File

@@ -60,44 +60,25 @@ class SmtCheckerRSNA(SmtCheckerRS):
def enc_transition_relation(self, level): def enc_transition_relation(self, level):
return simplify(And(self.enc_rs_trans(level), self.enc_automaton_trans(level))) return simplify(And(self.enc_rs_trans(level), self.enc_automaton_trans(level)))
def enc_automaton_single_trans(self, level, transition):
src,actions,ctx_reaction,dst = transition
src_enc = self.ca_state[level] == src
dst_enc = self.ca_state[level+1] == dst
all_ent = set(range(len(self.rs.background_set)))
incl_ctx = ctx
excl_ctx = all_ent - incl_ctx
ctx_enc = True
for c in incl_ctx:
ctx_enc = simplify(And(ctx_enc, self.v_ctx[level][c]))
for c in excl_ctx:
ctx_enc = simplify(And(ctx_enc, Not(self.v_ctx[level][c])))
enc_single_trans = simplify(And(src_enc, ctx_enc, dst_enc))
return enc_single_trans
def enc_single_automaton_trans(self, level, automaton):
enc_aut_trans = False
for transition in automaton.transitions:
enc_aut_trans = simplify(Or(enc_aut_trans, self.enc_automaton_single_trans(level, transition)))
return enc_aut_trans
def enc_automaton_trans(self, level): def enc_automaton_trans(self, level):
"""Encodes the transition relation for the context automaton""" """Encodes the transition relation for the context automaton"""
enc_canet = True enc_trans = True
for aut in self.canet:
enc_canet = simplify(And(enc_canet, self.enc_single_automaton_trans(level, aut)))
return enc_canet prod_context = self.canet.prod_entities
never_produced_context = self.rs.set_of_bgset_ids - prod_context
# producible entities:
for ent in prod_context:
actions_producing_ent = self.canet.get_actions_producing_entity(ent)
for act in actions_producing_ent:
automata_with_act = self.canet.get_automata_with_action(act)
for aut_id in automata_with_act:
aut = self.canet.automata[aut_id]
# entities that are never produced:
return enc_trans
def check_reachability(self, state, print_witness=True, print_time=True, print_mem=True): def check_reachability(self, state, print_witness=True, print_time=True, print_mem=True):
@@ -109,3 +90,5 @@ class SmtCheckerRSNA(SmtCheckerRS):
self.prepare_all_variables() self.prepare_all_variables()
self.prepare_all_variables() self.prepare_all_variables()
print(self.enc_automaton_trans(0))