parameter variables; some cleanup
This commit is contained in:
@@ -15,3 +15,5 @@ def colour_str(col, s):
|
|||||||
|
|
||||||
def print_error(s):
|
def print_error(s):
|
||||||
print(C_MARK_ERROR + " " + C_RED + s + C_ENDC)
|
print(C_MARK_ERROR + " " + C_RED + s + C_ENDC)
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|||||||
1
rs_examples.py
Normal file → Executable file
1
rs_examples.py
Normal file → Executable file
@@ -187,3 +187,4 @@ def heat_shock_response(print_system=True,verify_rsc=True):
|
|||||||
def state_translate_rsc2rs(p):
|
def state_translate_rsc2rs(p):
|
||||||
return [e[0] + "#" + str(e[1]) for e in p]
|
return [e[0] + "#" + str(e[1]) for e in p]
|
||||||
|
|
||||||
|
# EOF
|
||||||
@@ -48,7 +48,7 @@ def trivial_param():
|
|||||||
#
|
#
|
||||||
# WARNING: depth limit is set
|
# WARNING: depth limit is set
|
||||||
#
|
#
|
||||||
smt_rsc.check_rsltl(formula=f1, max_level=5)
|
smt_rsc.check_rsltl(formula=f1, max_level=10, print_witness=True)
|
||||||
|
|
||||||
|
|
||||||
def example44_param():
|
def example44_param():
|
||||||
|
|||||||
@@ -42,10 +42,18 @@ class SmtCheckerRSCParam(object):
|
|||||||
self.v_improd = []
|
self.v_improd = []
|
||||||
self.v_improd_for_entities = []
|
self.v_improd_for_entities = []
|
||||||
|
|
||||||
|
self.v_param = []
|
||||||
|
|
||||||
self.next_level_to_encode = 0
|
self.next_level_to_encode = 0
|
||||||
|
|
||||||
|
# this is probably not needed anymore
|
||||||
self.producible_entities = self.rs.get_producible_entities()
|
self.producible_entities = self.rs.get_producible_entities()
|
||||||
self.improducible_entities = set(self.rs.get_state_ids(self.rs.background_set)) - self.producible_entities
|
# self.improducible_entities = set(self.rs.get_state_ids(self.rs.background_set)) - self.producible_entities
|
||||||
|
|
||||||
|
# WARNING: improd vs. improducible
|
||||||
|
# there is some confusion related to the variables naming:
|
||||||
|
# improd - intermediate products
|
||||||
|
# improducible - entities that are never produces (there is no reaction that produces that entity)
|
||||||
|
|
||||||
self.loop_position = Int("loop_position")
|
self.loop_position = Int("loop_position")
|
||||||
|
|
||||||
@@ -64,6 +72,7 @@ class SmtCheckerRSCParam(object):
|
|||||||
self.prepare_state_variables()
|
self.prepare_state_variables()
|
||||||
self.prepare_context_variables()
|
self.prepare_context_variables()
|
||||||
self.prepare_intermediate_product_variables()
|
self.prepare_intermediate_product_variables()
|
||||||
|
self.prepare_param_variables()
|
||||||
self.next_level_to_encode += 1
|
self.next_level_to_encode += 1
|
||||||
|
|
||||||
def prepare_context_variables(self):
|
def prepare_context_variables(self):
|
||||||
@@ -93,7 +102,7 @@ class SmtCheckerRSCParam(object):
|
|||||||
"""
|
"""
|
||||||
Prepares the intermediate product variables
|
Prepares the intermediate product variables
|
||||||
carrying the individual concentration levels produced
|
carrying the individual concentration levels produced
|
||||||
the reactions.
|
by the reactions.
|
||||||
|
|
||||||
These variables are used later on to encode the final
|
These variables are used later on to encode the final
|
||||||
concentration levels for all the entities
|
concentration levels for all the entities
|
||||||
@@ -123,12 +132,12 @@ class SmtCheckerRSCParam(object):
|
|||||||
|
|
||||||
entities_dict = dict()
|
entities_dict = dict()
|
||||||
for entity, conc in products:
|
for entity, conc in products:
|
||||||
varname = Int("IP" + str(level) + "_R" +
|
new_var = Int("IP" + str(level) + "_R" +
|
||||||
str(reaction_id) + "_e" + str(entity))
|
str(reaction_id) + "_e" + str(entity))
|
||||||
entities_dict[entity] = varname
|
entities_dict[entity] = new_var
|
||||||
|
|
||||||
all_entities_dict.setdefault(entity, [])
|
all_entities_dict.setdefault(entity, [])
|
||||||
all_entities_dict[entity].append(varname)
|
all_entities_dict[entity].append(new_var)
|
||||||
|
|
||||||
reactions_dict[reaction_id] = entities_dict
|
reactions_dict[reaction_id] = entities_dict
|
||||||
|
|
||||||
@@ -139,6 +148,25 @@ class SmtCheckerRSCParam(object):
|
|||||||
|
|
||||||
# print(self.v_improd_for_entities)
|
# print(self.v_improd_for_entities)
|
||||||
|
|
||||||
|
def prepare_param_variables(self):
|
||||||
|
"""
|
||||||
|
Prepares variables for parameters
|
||||||
|
|
||||||
|
A parameter (it's valuation) is a subset of the background set,
|
||||||
|
therefore we need separate variables for each element of the
|
||||||
|
background set.
|
||||||
|
"""
|
||||||
|
|
||||||
|
level = self.next_level_to_encode
|
||||||
|
|
||||||
|
params = []
|
||||||
|
for entity in self.rs.background_set:
|
||||||
|
new_var = Int("L{:d}_Pm_{:s}".format(level, entity))
|
||||||
|
params.append(new_var)
|
||||||
|
self.v_param.append(params)
|
||||||
|
|
||||||
|
print(self.v_param)
|
||||||
|
|
||||||
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
|
||||||
@@ -177,23 +205,21 @@ class SmtCheckerRSCParam(object):
|
|||||||
And(self.enc_rs_trans(level),
|
And(self.enc_rs_trans(level),
|
||||||
self.enc_automaton_trans(level)))
|
self.enc_automaton_trans(level)))
|
||||||
|
|
||||||
def enc_rs_trans(self, level):
|
def enc_single_reaction(self, level, reaction):
|
||||||
"""Encodes the transition relation"""
|
"""
|
||||||
|
Encodes a single reaction
|
||||||
|
|
||||||
#
|
For encoding the products we use intermediate variables:
|
||||||
# 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
|
* each reaction has its own product variables,
|
||||||
|
|
||||||
for reaction in self.rs.reactions:
|
* those are meant to be used to compute the MAX concentration
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
reactants, inhibitors, products = reaction
|
reactants, inhibitors, products = reaction
|
||||||
|
|
||||||
|
# we need reaction_id to find the intermediate product variable
|
||||||
reaction_id = self.rs.reactions.index(reaction)
|
reaction_id = self.rs.reactions.index(reaction)
|
||||||
|
|
||||||
enc_reactants = True
|
enc_reactants = True
|
||||||
@@ -217,33 +243,56 @@ class SmtCheckerRSCParam(object):
|
|||||||
enc_reaction = simplify(
|
enc_reaction = simplify(
|
||||||
And(enc_reactants, enc_inhibitors) == enc_products)
|
And(enc_reactants, enc_inhibitors) == enc_products)
|
||||||
|
|
||||||
|
return enc_reaction
|
||||||
|
|
||||||
|
def enc_rs_trans(self, level):
|
||||||
|
"""Encodes the transition relation"""
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# That needs to happen automatically (in the MAX encoding) -- for the parametric
|
||||||
|
# case it makes no sense to identify the entities that are never produced, unless
|
||||||
|
# we have no parameters as products (special case, so that could be an
|
||||||
|
# optimisation)
|
||||||
|
#
|
||||||
|
|
||||||
|
enc_trans = True
|
||||||
|
|
||||||
|
for reaction in self.rs.reactions:
|
||||||
|
enc_reaction = self.enc_single_reaction(level, reaction)
|
||||||
enc_trans = simplify(And(enc_trans, enc_reaction))
|
enc_trans = simplify(And(enc_trans, enc_reaction))
|
||||||
|
|
||||||
# print(enc_trans)
|
# Next we encode the MAX concentration values:
|
||||||
|
# we collect those from the intermediate product variables
|
||||||
#
|
|
||||||
# TODO:
|
|
||||||
#
|
|
||||||
# Max of all the produced concentrations for each entity/product...
|
|
||||||
|
|
||||||
enc_max_prod = True
|
enc_max_prod = True
|
||||||
|
|
||||||
|
# Save all the intermediate product variables for a given level:
|
||||||
|
#
|
||||||
|
# - Intermediate products of (level+1) correspond to the next level
|
||||||
|
#
|
||||||
|
# {reactants & inhibitors}[level]
|
||||||
|
# =>
|
||||||
|
# {improd}[level+1]
|
||||||
|
# =>
|
||||||
|
# {products}[level+1]
|
||||||
|
#
|
||||||
current_v_improd_for_entities = self.v_improd_for_entities[level + 1]
|
current_v_improd_for_entities = self.v_improd_for_entities[level + 1]
|
||||||
|
|
||||||
for entity, per_reaction_vars in current_v_improd_for_entities.items():
|
for entity, per_reaction_vars in current_v_improd_for_entities.items():
|
||||||
|
|
||||||
# enc_max_single_ent = True
|
|
||||||
|
|
||||||
# sorted_vars_by_conc = sorted(per_reaction_vars, key=lambda conc_var: conc_var[0])
|
|
||||||
# list_of_vars = [v for c,v in sorted_vars_by_conc]
|
|
||||||
|
|
||||||
# print(per_reaction_vars, "--->", self.enc_max(per_reaction_vars))
|
|
||||||
|
|
||||||
enc_max_prod = simplify(
|
enc_max_prod = simplify(
|
||||||
And(enc_max_prod, self.v[level + 1][entity] == self.enc_max(per_reaction_vars)))
|
And(enc_max_prod, self.v[level + 1][entity] == self.enc_max(per_reaction_vars)))
|
||||||
|
|
||||||
for entity in self.improducible_entities:
|
# for entity in self.improducible_entities:
|
||||||
enc_max_prod = simplify(
|
# enc_max_prod = simplify(
|
||||||
And(enc_max_prod, self.v[level + 1][entity] == 0))
|
# And(enc_max_prod, self.v[level + 1][entity] == 0))
|
||||||
|
|
||||||
enc_trans_with_max = simplify(And(enc_max_prod, enc_trans))
|
enc_trans_with_max = simplify(And(enc_max_prod, enc_trans))
|
||||||
|
|
||||||
@@ -428,6 +477,7 @@ class SmtCheckerRSCParam(object):
|
|||||||
result = self.solver.check()
|
result = self.solver.check()
|
||||||
if result == sat:
|
if result == sat:
|
||||||
print("[" + colour_str(C_BOLD, "+") + "] " + colour_str(C_GREEN, "SAT at level=" + str(self.current_level)))
|
print("[" + colour_str(C_BOLD, "+") + "] " + colour_str(C_GREEN, "SAT at level=" + str(self.current_level)))
|
||||||
|
print(self.solver.model())
|
||||||
if print_witness:
|
if print_witness:
|
||||||
print("\n{:=^70}".format("[ WITNESS ]"))
|
print("\n{:=^70}".format("[ WITNESS ]"))
|
||||||
self.decode_witness(self.current_level)
|
self.decode_witness(self.current_level)
|
||||||
|
|||||||
Reference in New Issue
Block a user