getters for the used actions, automata supporting actions, transitions for actions, etc.
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
4
rssmt.py
4
rssmt.py
@@ -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>
|
||||
"""
|
||||
|
||||
##################################################################
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user