Initial encoding of reactions

This commit is contained in:
Artur Meski
2017-08-13 20:11:25 +01:00
parent dd4ea5d939
commit 9ca4d3954f

View File

@@ -103,10 +103,15 @@ class SmtCheckerRSCParam(object):
level = self.next_level_to_encode level = self.next_level_to_encode
if level < 1: if level < 1:
self.v_improd.append([]) #
# If we are at level==0, we add a dummy "level"
# to match the indices of of the successors
# which are always at level+1.
#
self.v_improd.append(None)
else: else:
variables = [] reactions_dict = dict()
number_of_reactions = len(self.rs.reactions) number_of_reactions = len(self.rs.reactions)
for reaction in self.rs.reactions: for reaction in self.rs.reactions:
@@ -120,13 +125,15 @@ class SmtCheckerRSCParam(object):
str(reaction_id) + "_e" + str(entity)) str(reaction_id) + "_e" + str(entity))
entities_dict[entity] = varname entities_dict[entity] = varname
variables.append(entities_dict) reactions_dict[reaction_id] = entities_dict
self.v_improd.append(variables) self.v_improd.append(reactions_dict)
print(self.v_improd)
def enc_concentration_levels_assertion(self, level): def enc_concentration_levels_assertion(self, level):
"""Encodes assertions that (some) variables need to be >0 """
Encodes assertions that (some) variables need to be >0
We do not need to actually control all the variables, We do not need to actually control all the variables,
only those that can possibly go below 0. only those that can possibly go below 0.
@@ -158,143 +165,6 @@ class SmtCheckerRSCParam(object):
return init_state_enc return init_state_enc
def enc_produced_concentration(self, level, prod_entity):
"""Encodes the produced concentrations for the given level and entity"""
rcts_for_prod_entity = []
if prod_entity in self.rs.get_reactions_by_product():
rcts_for_prod_entity = self.rs.get_reactions_by_product()[prod_entity]
meta_reactions = []
if prod_entity in self.rs.meta_reactions:
meta_reactions = self.rs.meta_reactions[prod_entity]
permanency_inhibition = None
if prod_entity in self.rs.permanent_entities:
permanency_inhibition = self.rs.permanent_entities[prod_entity]
if rcts_for_prod_entity == [] and meta_reactions == []:
return simplify(self.v[level+1][prod_entity] == 0) # this should never happen
enc_enabledness = False
# ----------- ordinary reactions --------------------------------------------
enc_rct_prod = False
enc_ordinary_reactions_enabledness = False
for reactants,inhibitors,products in rcts_for_prod_entity:
enc_reactants = True
for reactant,concentration in reactants:
enc_reactants = simplify(And(enc_reactants,
Or(self.v[level][reactant] >= concentration, self.v_ctx[level][reactant] >= concentration)))
enc_inhibitors = True
for inhibitor,concentration in inhibitors:
enc_inhibitors = simplify(And(enc_inhibitors,
And(self.v[level][inhibitor] < concentration, self.v_ctx[level][inhibitor] < concentration)))
enc_rct_enabled = And(enc_reactants, enc_inhibitors)
enc_products = self.v[level+1][products[0][0]] == products[0][1]
enc_rct_prod = simplify(If(enc_rct_enabled, enc_products, enc_rct_prod))
enc_enabledness = simplify(Or(enc_enabledness, enc_rct_enabled))
enc_ordinary_reactions_enabledness = simplify(Or(enc_ordinary_reactions_enabledness,enc_rct_enabled))
# for reactants,inhibitors,products in rcts_for_prod_entity:
# enc_reactants = True
# enc_inhibitors = True
# # enc_products -- below
#
# for reactant,concentration in reactants:
# enc_reactants = simplify(And(enc_reactants,
# Or(self.v[level][reactant] >= concentration, self.v_ctx[level][reactant] >= concentration)))
# for inhibitor,concentration in inhibitors:
# enc_inhibitors = simplify(And(enc_inhibitors,
# And(self.v[level][inhibitor] < concentration, self.v_ctx[level][inhibitor] < concentration)))
#
# enc_products = self.v[level+1][products[0][0]] == products[0][1]
#
# enc_enabledness = simplify(Or(enc_enabledness, And(enc_reactants, enc_inhibitors)))
# enc_rct_prod = simplify(Or(enc_rct_prod, And(enc_reactants, enc_inhibitors, enc_products)))
# -------- meta reactions ---------------------------------------------------
for r_type,command_entity,reactants,inhibitors in meta_reactions:
# command entity is e.g. 'inc' for incrementation operation
# (inc,W) gives us the value W by which the given entity's value should be incremented
enc_reactants = True
enc_inhibitors = True
for reactant,concentration in reactants:
enc_reactants = simplify(And(enc_reactants,
Or(self.v[level][reactant] >= concentration, self.v_ctx[level][reactant] >= concentration)))
# command entity needs to be present (with concentration level > 0) in order to perform the operation
enc_reactants = simplify(And(enc_reactants,
Or(self.v[level][command_entity] > 0, self.v_ctx[level][command_entity] > 0)))
for inhibitor,concentration in inhibitors:
enc_inhibitors = simplify(And(enc_inhibitors,
And(self.v[level][inhibitor] < concentration, self.v_ctx[level][inhibitor] < concentration)))
if r_type == "inc":
value_after_inc = If(self.v[level][prod_entity]>self.v_ctx[level][prod_entity],self.v[level][prod_entity],self.v_ctx[level][prod_entity]) + \
If(self.v[level][command_entity]>self.v_ctx[level][command_entity],self.v[level][command_entity],self.v_ctx[level][command_entity])
enc_products = self.v[level+1][prod_entity] == value_after_inc
elif r_type == "dec":
value_after_dec = simplify(If(self.v[level][prod_entity]>self.v_ctx[level][prod_entity],self.v[level][prod_entity],self.v_ctx[level][prod_entity]) - \
If(self.v[level][command_entity]>self.v_ctx[level][command_entity],self.v[level][command_entity],self.v_ctx[level][command_entity]))
enc_products = self.v[level+1][prod_entity] == If(value_after_dec < 0, 0, value_after_dec)
else:
raise RuntimeError("Unknown meta-reaction type: " + repr(r_type))
enc_meta_reaction_enabledness = And(enc_reactants, enc_inhibitors, Not(enc_ordinary_reactions_enabledness))
enc_enabledness = simplify(Or(enc_enabledness, enc_meta_reaction_enabledness))
enc_rct_prod = simplify(Or(enc_rct_prod, And(enc_meta_reaction_enabledness, enc_products)))
# -----------------------------------------------------------------------------
if not permanency_inhibition == None:
enc_reactants = Or(self.v[level][prod_entity] >= concentration, self.v_ctx[level][prod_entity] >= concentration)
enc_inhibitors = True
for inhibitor,concentration in permanency_inhibition:
enc_inhibitors = simplify(And(enc_inhibitors,
And(self.v[level][inhibitor] < concentration, self.v_ctx[level][inhibitor] < concentration)))
enc_products = simplify(self.v[level+1][prod_entity] == \
If(self.v[level][prod_entity] > self.v_ctx[level][prod_entity],self.v[level][prod_entity],self.v_ctx[level][prod_entity]))
enc_permanency_enabledness = And(enc_reactants, enc_inhibitors, Not(enc_ordinary_reactions_enabledness))
enc_enabledness = simplify(Or(enc_enabledness, enc_permanency_enabledness))
enc_permanency = And(enc_permanency_enabledness, enc_products)
enc_rct_prod = simplify(Or(enc_rct_prod, enc_permanency))
# -----------------------------------------------------------------------------
enc_when_to_produce_zero_conc = simplify(And(Not(enc_enabledness), self.v[level+1][prod_entity] == 0))
enc_rct_prod = Or(enc_rct_prod, enc_when_to_produce_zero_conc)
return enc_rct_prod
# def enc_entity_production(self, level, prod_entity):
# """Encodes the production of a given entity from a given level at level+1"""
#
# enc_enab_cond = self.enc_enabledness(level, prod_entity)
#
# enc_ent_prod = Or(And(enc_enab_cond, self.v[level+1][prod_entity]),
# And(Not(enc_enab_cond), Not(self.v[level+1][prod_entity])))
#
# return simplify(enc_ent_prod)
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)))
@@ -302,19 +172,54 @@ class SmtCheckerRSCParam(object):
def enc_rs_trans(self, level): def enc_rs_trans(self, level):
"""Encodes the transition relation""" """Encodes the transition relation"""
unused_entities = set(range(len(self.rs.background_set))) #
# IMPORTANT NOTE
#
# We need to make sure we do something about the UNUSED ENTITIES
# that is, those that are never produced.
#
# They should have concentration levels set to 0.
#
enc_trans = True enc_trans = True
reactions = self.rs.get_reactions_by_product() for reaction in self.rs.reactions:
meta_reactions = self.rs.meta_reactions
for prod_entity in chain(reactions, meta_reactions): reactants, inhibitors, products = reaction
unused_entities.discard(prod_entity) reaction_id = self.rs.reactions.index(reaction)
enc_trans = simplify(And(enc_trans, self.enc_produced_concentration(level, prod_entity)))
enc_reactants = True
for entity, conc in reactants:
enc_reactants = And(enc_reactants,
Or(self.v[level][entity] >= conc, self.v_ctx[level][entity] >= conc))
enc_inhibitors = True
for entity, conc in inhibitors:
enc_inhibitors = And(enc_inhibitors,
And(self.v[level][entity] < conc, self.v_ctx[level][entity] < conc))
enc_products = True
#
#
#
for entity, conc in products:
enc_products = And(enc_products,
self.v_improd[level+1][reaction_id][entity] == conc)
#
# (R and I) iff P
#
enc_reaction = simplify(And(enc_reactants, enc_inhibitors) == enc_products)
enc_trans = simplify(And(enc_trans, enc_reaction))
print(enc_trans)
#
# TODO:
#
# Max of all the produced concentrations for each entity/product...
for prod_entity in unused_entities:
enc_trans = simplify(And(enc_trans, self.v[level+1][prod_entity] == 0))
return enc_trans return enc_trans