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,7 +9,8 @@ class ContextAutomaton(object):
self._init_state = None
self._reaction_system = reaction_system
self._name = ""
self._prod_entities = set()
@property
def states(self):
return self._states
@@ -18,6 +19,14 @@ class ContextAutomaton(object):
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
@@ -101,6 +110,8 @@ class ContextAutomaton(object):
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)))
@@ -140,8 +151,14 @@ class ContextAutomaton(object):
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()

View File

@@ -4,15 +4,52 @@ from colour import *
from rs.context_automaton import 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):
self._actions = []
super(ExtendedContextAutomaton, self).__init__(reaction_system)
self._actions = []
self._transitions_for_products = dict()
self._actions_for_products = dict()
@property
def number_of_actions(self):
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):
"""Adds a transition
@@ -49,10 +86,21 @@ class ExtendedContextAutomaton(ContextAutomaton):
i_ids = self.get_set_of_ids(ctx_inhibitors)
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):
"""Prints the set of registered transitions"""
print(C_MARK_INFO + " Context automaton transitions:")
for src_id, act_id, reaction, dst_id in self._transitions:
str_transition = self.get_state_name(src_id) + " --( "
@@ -63,6 +111,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def add_action(self, action_name):
"""Registers an action"""
if action_name not in self._actions:
self._actions.append(action_name)
else:
@@ -70,6 +119,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_action_id(self, action_name):
"""For an action name returns its id"""
try:
return self._actions.index(action_name)
except ValueError:
@@ -81,6 +131,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_set_of_action_ids(self, actions):
"""Converts a set of actions into the set of their ids"""
act_ids = set()
for act in actions:
act_ids.add(self.get_action_id(act))
@@ -88,6 +139,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def get_actions_str(self, actions):
"""Returns the string for the set of action ids given by actions"""
s = ""
for act in actions:
s += self.get_action_name(act) + ", "
@@ -96,6 +148,7 @@ class ExtendedContextAutomaton(ContextAutomaton):
def show_actions(self):
"""Prints all the actions"""
print(C_MARK_INFO + " Context automaton actions:")
for act in self._actions:
print(" - " + act + " (id=" + str(self.get_action_id(act)) + ")")
@@ -103,3 +156,4 @@ class ExtendedContextAutomaton(ContextAutomaton):
def show(self):
super(ExtendedContextAutomaton, self).show()
self.show_actions()

View File

@@ -1,18 +1,100 @@
from sys import exit
from colour import *
class NetworkOfContextAutomata(object):
def __init__(self, context_automata):
self.automata = list(context_automata)
def __init__(self, reaction_system, 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
def number_of_automata(self):
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):
print()
print(C_MARK_INFO + " NETWORK OF CONTEXT AUTOMATA")
for ca in self.automata:
print()
ca.show()
def add(self, aut):
self.automata.append(aut)
print()
self.show_prod_entities()
self.show_actions()

View File

@@ -15,6 +15,14 @@ class ReactionSystem(object):
self.init_contexts = []
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):
if self.is_in_background_set(name):
raise RuntimeError("The entity " + name + " is already on the list")

View File

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

View File

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

View File

@@ -59,45 +59,26 @@ class SmtCheckerRSNA(SmtCheckerRS):
def enc_transition_relation(self, 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):
"""Encodes the transition relation for the context automaton"""
enc_canet = True
for aut in self.canet:
enc_canet = simplify(And(enc_canet, self.enc_single_automaton_trans(level, aut)))
enc_trans = True
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]
return enc_canet
# entities that are never produced:
return enc_trans
def check_reachability(self, state, print_witness=True, print_time=True, print_mem=True):
@@ -108,4 +89,6 @@ class SmtCheckerRSNA(SmtCheckerRS):
self.prepare_all_variables()
self.prepare_all_variables()
self.prepare_all_variables()
print(self.enc_automaton_trans(0))