def test_create_AP_labels(self): model = Model(set(), collections.Counter(), dict(), set()) complex_parser = Parser("rate_complex") complex_1 = complex_parser.parse("K(S{i},T{a}).B{o}::cyt").data.children[0] complex_2 = complex_parser.parse("K(S{a},T{a}).B{o}::cyt").data.children[0] complex_3 = complex_parser.parse("K(S{a},T{i}).B{o}::cyt").data.children[0] complex_abstract = complex_parser.parse("K(S{a}).B{_}::cyt").data.children[0] ordering = (complex_1, complex_2, complex_3) APs = [Core.Formula.AtomicProposition(complex_abstract, " >= ", "3"), Core.Formula.AtomicProposition(complex_1, " < ", 2)] s1 = State(np.array((1, 2, 2))) s2 = State(np.array((5, 1, 1))) s3 = State(np.array((2, 4, 3))) s4 = State(np.array((1, 4, 3))) states_encoding = {s1: 1, s2: 2, s3: 3, s4: 4} result_AP_lables = {APs[0]: 'property_0', APs[1]: 'property_1'} result_state_labels = {1: {'property_0', 'property_1'}, 3: {'property_0', 'init'}, 4: {'property_0', 'property_1'}} ts = TS.TransitionSystem.TransitionSystem(ordering) ts.states_encoding = states_encoding ts.init = 3 state_labels, AP_lables = model.create_AP_labels(APs, ts, 0) self.assertEqual(state_labels, result_state_labels) self.assertEqual(AP_lables, result_AP_lables)
def test_exists_compatible_agent(self): complex_parser = Parser("rate_complex") agent = "K(S{a}).A{a}::cyt" complex = complex_parser.parse(agent).data.children[0] rule_expr = "K().A{i}::cyt => K().A{a}::cyt" rule = self.parser.parse(rule_expr).data self.assertTrue(rule.exists_compatible_agent(complex))
def test_nonreachability(self): complex_parser = Parser("rate_complex") agent = "K(S{a}).A{a}::cyt" complex = complex_parser.parse(agent).data.children[0] model_reach = self.model_parser.parse(self.model_reachable).data model_nonreach = self.model_parser.parse(self.model_nonreachable).data self.assertTrue(model_reach.static_non_reachability(complex)) self.assertFalse(model_nonreach.static_non_reachability(complex))
def parse(): if request.method == 'POST': data = request.get_json() start = data['start'] expression = data['expression'] parser = Parser(start) result = parser.syntax_check(expression) response = {"success": result.success} if not result.success: response.update(result.data) response["expected"] = list(response["expected"]) return json.dumps(response)
def test_create_complex_labels(self): model = Model(set(), collections.Counter(), dict(), set()) complex_parser = Parser("rate_complex") complex_1 = complex_parser.parse("K(S{i},T{a}).B{o}::cyt").data.children[0] complex_2 = complex_parser.parse("K(S{a},T{a}).B{o}::cyt").data.children[0] complex_3 = complex_parser.parse("K(S{a},T{i}).B{o}::cyt").data.children[0] complex_abstract = complex_parser.parse("K(S{a}).B{_}::cyt").data.children[0] ordering = (complex_1, complex_2, complex_3) complexes = [complex_2, complex_abstract, complex_1] result_labels = {complex_2: "VAR_1",complex_abstract: "ABSTRACT_VAR_12", complex_1: "VAR_0"} result_formulas = ['ABSTRACT_VAR_12 = VAR_1+VAR_2; // K(S{a}).B{_}::cyt'] labels, prism_formulas = model.create_complex_labels(complexes, ordering) self.assertEqual(labels, result_labels) self.assertEqual(prism_formulas, result_formulas)
def setUp(self): self.model_parser = Parser("model") self.url = 'http://biodivine-vm.fi.muni.cz/BCSLparser/' self.model_wrong_1 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o}):;rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_with_complexes = """
def setUp(self): # agents self.a1 = AtomicAgent("T", "i") self.a2 = AtomicAgent("S", "i") self.a3 = AtomicAgent("T", "a") self.a4 = AtomicAgent("S", "a") self.s1 = StructureAgent("X", {self.a4}) self.s2 = StructureAgent("X", {self.a2}) self.s3 = StructureAgent("K", {self.a3}) self.s4 = StructureAgent("K", {self.a1}) self.s5 = StructureAgent("X", set()) self.s6 = StructureAgent("K", set()) self.c1 = Complex([self.s6], "cyt") # K()::cyt self.c2 = Complex([self.s3], "cyt") # K(T{a})::cyt self.c3 = Complex([self.s4], "cyt") # K(T{i})::cyt self.c4 = Complex([self.s4, self.s1], "cyt") # K(T{i}).X(S{a})::cyt self.c5 = Complex([self.s4, self.s2], "cyt") # K(T{i}).X(S{i})::cyt self.c6 = Complex([self.s3, self.s1], "cyt") # K(T{a}).X(S{a})::cyt self.c7 = Complex([self.s3, self.s2], "cyt") # K(T{a}).X(S{i})::cyt # rates self.parser = Parser("rate") rate_expr = "3.0*[K()::cyt]/2.0*v_1" self.rate_1 = Core.Rate.Rate(self.parser.parse(rate_expr).data) rate_expr = "3.0*[K(T{i}).X()::cyt] + [K()::cyt]" self.rate_2 = Core.Rate.Rate(self.parser.parse(rate_expr).data) # states self.state_1 = State(np.array([2, 3])) self.state_2 = State(np.array([2, 0, 3, 1, 6, 2]))
def setUp(self): self.parser = Parsing.ParsePCTLformula.PCTLparser() self.model_parser = Parser("model") self.model = """ #! rules Y{i}::rep => Y{a}::rep @ p*[Y{i}::rep] Y{i}::rep => Y{-}::rep @ (1-p)*[Y{i}::rep] X()::rep + Y{a}::rep => X().Y{a}::rep @ q*[X()::rep]*[Y{a}::rep] X(K{i}).Y{_}::rep => X(K{p}).Y{_}::rep @ p*[X(K{i}).Y{_}::rep] // also here #! inits 2 X(K{i})::rep 1 Y{i}::rep #! definitions p = 0.3 """ self.tumor = """ #! rules T(P{i})::x => T(P{m})::x @ a1*[T(P{i})::x] T(P{m})::x => T(P{i})::x + T(P{i})::x @ a2*[T(P{m})::x] T(P{i})::x => @ d1*[T(P{i})::x] T(P{m})::x => @ d2*[T(P{m})::x] #! inits 2 T(P{m})::x 1 T(P{i})::x #! definitions a1 = 1.2 a2 = 2 d1 = 0.8 d2 = 0.5 """ self.tumor_parametric = """
args_parser = argparse.ArgumentParser(description='Model checking') args_parser._action_groups.pop() required = args_parser.add_argument_group('required arguments') optional = args_parser.add_argument_group('optional arguments') required.add_argument('--model', type=str, required=True) required.add_argument('--output', type=str, required=True) optional.add_argument('--bound', type=int, default=None) required.add_argument('--formula', type=str, required=True) optional.add_argument('--local_storm', nargs="?", const=True) args = args_parser.parse_args() model_parser = Parser("model") model_str = open(args.model, "r").read() model = model_parser.parse(model_str) if args.bound: bound = int(args.bound) else: bound = None if args.local_storm: local_storm = True else: local_storm = False if model.success: if len(model.data.params) != 0:
def setUp(self): self.a1 = AtomicAgent("S", "u") self.a2 = AtomicAgent("S", "p") self.a3 = AtomicAgent("B", "_") self.a4 = AtomicAgent("B", "-") self.a5 = AtomicAgent("B", "+") self.s1 = StructureAgent("K", {self.a1}) self.s2 = StructureAgent("B", set()) self.s3 = StructureAgent("K", {self.a2}) self.s4 = StructureAgent("B", set()) self.s5 = StructureAgent("D", {self.a3}) self.s6 = StructureAgent("K", {self.a4}) self.s7 = StructureAgent("K", {self.a5}) self.c1 = Complex([self.s1, self.s2], "cyt") self.c2 = Complex([self.s3], "cyt") self.c3 = Complex([self.s2], "cyt") self.c4 = Complex([self.s5], "cell") # rules sequence_1 = (self.s1, self.s2, self.s3, self.s4) mid_1 = 2 compartments_1 = ["cyt"] * 4 complexes_1 = [(0, 1), (2, 2), (3, 3)] pairs_1 = [(0, 2), (1, 3)] rate_1 = Rate("3.0*[K()::cyt]/2.0*v_1") self.r1 = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, rate_1) sequence_2 = (self.s1, self.s2, self.s3, self.s4, self.s5) mid_2 = 2 compartments_2 = ["cyt"] * 4 + ["cell"] complexes_2 = [(0, 1), (2, 2), (3, 3), (4, 4)] pairs_2 = [(0, 2), (1, 3), (None, 4)] rate_2 = Rate("3.0*[K()::cyt]/2.0*v_1") self.r2 = Rule(sequence_2, mid_2, compartments_2, complexes_2, pairs_2, rate_2) sequence_3 = (self.s6, self.s2, self.s5, self.s7, self.s4) mid_3 = 3 compartments_3 = ["cyt"] * 2 + ["cell"] + ["cyt"] * 2 complexes_3 = [(0, 1), (2, 2), (3, 3), (4, 4)] pairs_3 = [(0, 3), (1, 4), (2, None)] rate_3 = Rate("3.0*[K(T{3+})::cyt]/2.0*v_1") self.r3 = Rule(sequence_3, mid_3, compartments_3, complexes_3, pairs_3, rate_3) # special cases self.s1_s = StructureAgent("X", set()) self.s2_s = StructureAgent("Y", set()) self.s3_s = StructureAgent("Z", set()) sequence_4 = (self.s1_s, ) mid_4 = 1 compartments_4 = ["rep"] complexes_4 = [(0, 0)] pairs_4 = [(0, None)] rate_4 = Rate("k1*[X()::rep]") self.r4 = Rule(sequence_4, mid_4, compartments_4, complexes_4, pairs_4, rate_4) sequence_5 = (self.s2_s, ) mid_5 = 0 compartments_5 = ["rep"] complexes_5 = [(0, 0)] pairs_5 = [(None, 0)] rate_5 = Rate("1.0/(1.0+([X()::rep])**4.0)") self.r5 = Rule(sequence_5, mid_5, compartments_5, complexes_5, pairs_5, rate_5) # reactions lhs = Side([self.c1]) rhs = Side([self.c2, self.c3, self.c4]) self.reaction1 = Reaction(lhs, rhs, rate_2) # create self.t_i = AtomicAgent("T", "i") self.t_a = AtomicAgent("T", "a") self.a4_p = AtomicAgent("C", "p") self.a4_u = AtomicAgent("C", "u") self.u2_c1_p = AtomicAgent("U", "p") self.u2_c1_u = AtomicAgent("U", "u") self.s6 = StructureAgent("D", set()) self.s6_c1_p = StructureAgent("D", {self.a4_p}) self.s6_c1_u = StructureAgent("D", {self.a4_u}) self.s2_c1_p = StructureAgent("B", {self.u2_c1_p}) self.s2_c1_u = StructureAgent("B", {self.u2_c1_u}) self.s1_c1_a = StructureAgent("K", {self.a1, self.t_a}) self.s1_c1_i = StructureAgent("K", {self.a1, self.t_i}) self.s3_c1_a = StructureAgent("K", {self.a2, self.t_a}) self.s3_c1_i = StructureAgent("K", {self.a2, self.t_i}) sequence_c1 = (self.s1, self.s2, self.s3, self.s4, self.s6) mid_c1 = 2 compartments_c1 = ["cyt"] * 5 complexes_c1 = [(0, 0), (1, 1), (2, 3), (4, 4)] pairs_c1 = [(0, 2), (1, 3), (None, 4)] rate_c1 = Rate("3*[K()::cyt]/2*v_1") self.c1_c1 = Complex([self.s2_c1_u], "cyt") # B(U{u})::cyt self.c1_c2 = Complex([self.s2_c1_p], "cyt") # B(U{p})::cyt self.c1_c3 = Complex([self.s1_c1_a], "cyt") # K(S{u},T{a})::cyt self.c1_c4 = Complex([self.s1_c1_i], "cyt") # K(S{u},T{i})::cyt self.c1_c5 = Complex([self.s3_c1_a, self.s2_c1_u], "cyt") # K(S{p},T{a}).B(U{u})::c self.c1_c6 = Complex([self.s3_c1_i, self.s2_c1_u], "cyt") # K(S{p},T{i}).B(U{u})::c self.c1_c7 = Complex([self.s3_c1_i, self.s2_c1_p], "cyt") # K(S{p},T{i}).B(U{p})::c self.c1_c8 = Complex([self.s3_c1_a, self.s2_c1_p], "cyt") # K(S{p},T{a}).B(U{p})::c self.c1_c9 = Complex([self.s6_c1_p], "cyt") # D(C{p})::cyt self.c1_c10 = Complex([self.s6_c1_u], "cyt") # D(C{u})::cyt self.rule_c1 = Rule(sequence_c1, mid_c1, compartments_c1, complexes_c1, pairs_c1, rate_c1) self.reaction_c1_1 = Reaction(Side([self.c1_c1, self.c1_c3]), Side([self.c1_c5, self.c1_c9]), rate_c1) self.reaction_c1_2 = Reaction(Side([self.c1_c1, self.c1_c3]), Side([self.c1_c5, self.c1_c10]), rate_c1) self.reaction_c1_3 = Reaction(Side([self.c1_c2, self.c1_c4]), Side([self.c1_c7, self.c1_c10]), rate_c1) self.reaction_c1_4 = Reaction(Side([self.c1_c1, self.c1_c4]), Side([self.c1_c6, self.c1_c9]), rate_c1) self.reaction_c1_5 = Reaction(Side([self.c1_c2, self.c1_c3]), Side([self.c1_c8, self.c1_c9]), rate_c1) self.reaction_c1_6 = Reaction(Side([self.c1_c2, self.c1_c3]), Side([self.c1_c8, self.c1_c10]), rate_c1) self.reaction_c1_7 = Reaction(Side([self.c1_c1, self.c1_c4]), Side([self.c1_c6, self.c1_c10]), rate_c1) self.reaction_c1_8 = Reaction(Side([self.c1_c2, self.c1_c4]), Side([self.c1_c7, self.c1_c9]), rate_c1) self.reactions_c1 = { self.reaction_c1_1, self.reaction_c1_2, self.reaction_c1_3, self.reaction_c1_4, self.reaction_c1_5, self.reaction_c1_6, self.reaction_c1_7, self.reaction_c1_8 } # context no change sequence_no_change = (self.s1_c1_a, self.s2_c1_u, self.s3_c1_a, self.s2_c1_u, self.s6_c1_p) self.rule_no_change = Rule(sequence_no_change, mid_c1, compartments_c1, complexes_c1, pairs_c1, rate_c1) # parsing self.parser = Parser("rule") self.rule_no_rate = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, None)
""" args_parser = argparse.ArgumentParser(description='Static analysis') args_parser._action_groups.pop() required = args_parser.add_argument_group('required arguments') optional = args_parser.add_argument_group('optional arguments') required.add_argument('--model', type=str, required=True) required.add_argument('--output', type=str, required=True) required.add_argument('--method', type=str, required=True) optional.add_argument('--complex') args = args_parser.parse_args() model_parser = Parser("model") model_str = open(args.model, "r").read() model = model_parser.parse(model_str) if model.success: if args.method == "reduce": model.data.reduce_context() save_model(model.data, args.output) elif args.method == "eliminate": model.data.eliminate_redundant() save_model(model.data, args.output) else: complex_parser = Parser("rate_complex") complex = complex_parser.parse(args.complex) if complex.success: result = model.data.static_non_reachability(
def setUp(self): self.model_parser = Parser("model") """ Model 1 - Transition system of die model Analysis of a PRISM example model from the Knuth-Yao source: storm website """ self.str1 = StructureAgent("S", set()) self.str2 = StructureAgent("D", set()) self.c1 = Complex([self.str1], "rep") self.c2 = Complex([self.str2], "rep") ordering = (self.c1, self.c2) self.s1 = State(np.array((0, 0))) self.s2 = State(np.array((1, 0))) self.s3 = State(np.array((2, 0))) self.s4 = State(np.array((3, 0))) self.s5 = State(np.array((4, 0))) self.s6 = State(np.array((5, 0))) self.s7 = State(np.array((6, 0))) self.s8 = State(np.array((7, 1))) self.s9 = State(np.array((7, 2))) self.s10 = State(np.array((7, 3))) self.s11 = State(np.array((7, 4))) self.s12 = State(np.array((7, 5))) self.s13 = State(np.array((7, 6))) self.die_ts = TransitionSystem(ordering) self.die_ts.init = 0 self.die_ts.states_encoding = {self.s1: 0, self.s2: 1, self.s3: 2, self.s4: 3, self.s5: 4, self.s6: 5, self.s7: 6, self.s8: 7, self.s9: 8, self.s10: 9, self.s11: 10, self.s12: 11, self.s13: 12} self.die_ts.edges = {Edge(0, 1, 0.5), Edge(0, 2, 0.5), Edge(1, 3, 0.5), Edge(1, 4, 0.5), Edge(2, 5, 0.5), Edge(2, 6, 0.5), Edge(3, 1, 0.5), Edge(3, 7, 0.5), Edge(4, 8, 0.5), Edge(4, 9, 0.5), Edge(5, 10, 0.5), Edge(5, 11, 0.5), Edge(6, 2, 0.5), Edge(6, 12, 0.5), Edge(7, 7, 1), Edge(8, 8, 1), Edge(9, 9, 1), Edge(10, 10, 1), Edge(11, 11, 1), Edge(12, 12, 1)} # die parametric TS self.die_ts_parametric = TransitionSystem(ordering) self.die_ts_parametric.init = 0 self.die_ts_parametric.states_encoding = {self.s1: 0, self.s2: 1, self.s3: 2, self.s4: 3, self.s5: 4, self.s6: 5, self.s7: 6, self.s8: 7, self.s9: 8, self.s10: 9, self.s11: 10, self.s12: 11, self.s13: 12} self.die_ts_parametric.edges = {Edge(0, 1, "p"), Edge(0, 2, "(1-p)"), Edge(1, 3, "p"), Edge(1, 4, "(1-p)"), Edge(2, 5, "p"), Edge(2, 6, "(1-p)"), Edge(3, 1, "p"), Edge(3, 7, "(1-p)"), Edge(4, 8, "p"), Edge(4, 9, "(1-p)"), Edge(5, 10, "p"), Edge(5, 11, "(1-p)"), Edge(6, 2, "p"), Edge(6, 12, "(1-p)"), Edge(7, 7, 1), Edge(8, 8, 1), Edge(9, 9, 1), Edge(10, 10, 1), Edge(11, 11, 1), Edge(12, 12, 1)} self.labels = {0: {'init'}, 7: {'one', 'done'}, 9: {'done'}, 8: {'done'}, 10: {'done'}, 11: {'done'}, 12: {'done'}} # PCTL formulas for model checking self.die_pctl_prism = "P=? [F VAR_0=7&VAR_1=1]" # 0.1666666667 self.die_pctl_explicit = "P=? [F \"one\"]" # 0.1666666667 self.die_pctl_parametric = "P=? [F VAR_0=7&VAR_1=1]" self.die_pctl1 = "P=? [F VAR_0=7&VAR_1=1 || F VAR_0=7&VAR_1<4]" # 0.3333333333 not used self.die_pctl2 = "P<=0.15 [F VAR_0=7&VAR_1=1]" # false not used self.result = 0.166666667
def setUp(self): # agents self.s1 = StructureAgent("X", set()) self.s2 = StructureAgent("Y", set()) self.s3 = StructureAgent("Z", set()) self.c1 = Complex([self.s1], "rep") self.c2 = Complex([self.s2], "rep") self.c3 = Complex([self.s3], "rep") # rules sequence_1 = (self.s1,) mid_1 = 1 compartments_1 = ["rep"] complexes_1 = [(0, 0)] pairs_1 = [(0, None)] rate_1 = Rate("k1*[X()::rep]") self.r1 = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, rate_1) sequence_2 = (self.s3, self.s1) mid_2 = 1 compartments_2 = ["rep"] * 2 complexes_2 = [(0, 0), (1, 1)] pairs_2 = [(0, 1)] self.r2 = Rule(sequence_2, mid_2, compartments_2, complexes_2, pairs_2, None) sequence_3 = (self.s2,) mid_3 = 0 compartments_3 = ["rep"] complexes_3 = [(0, 0)] pairs_3 = [(None, 0)] rate_3 = Rate("1.0/(1.0+([X()::rep])**4.0)") self.r3 = Rule(sequence_3, mid_3, compartments_3, complexes_3, pairs_3, rate_3) # inits self.inits = collections.Counter({self.c1: 2, self.c2: 1}) # defs self.defs = {'k1': 0.05, 'k2': 0.12} self.model = Model({self.r1, self.r2, self.r3}, self.inits, self.defs, set()) # model self.model_str_1 = """ #! rules X()::rep => @ k1*[X()::rep] Z()::rep => X()::rep => Y()::rep @ 1/(1+([X()::rep])**4) #! inits 2 X()::rep Y()::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_parser = Parser("model") self.model_str_2 = """ #! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ # vectors ordering = (self.c1, self.c2, self.c3) self.rate_parser = Parser("rate") rate_expr = "1/(1+([X()::rep])**4)" rate_1 = Rate(self.rate_parser.parse(rate_expr).data) rate_1.vectorize(ordering, dict()) rate_expr = "k1*[X()::rep]" rate_2 = Rate(self.rate_parser.parse(rate_expr).data) rate_2.vectorize(ordering, {"k1": 0.05}) init = State(np.array([2, 1, 0])) vector_reactions = {VectorReaction(State(np.array([0, 0, 0])), State(np.array([0, 1, 0])), rate_1), VectorReaction(State(np.array([1, 0, 0])), State(np.array([0, 0, 0])), rate_2), VectorReaction(State(np.array([0, 0, 1])), State(np.array([1, 0, 0])), None)} self.vm_1 = VectorModel(vector_reactions, init, ordering, None) # wrong models self.model_wrong_1 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o}):;rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_wrong_2 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep = X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_with_comments = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_complexes = """ #! rules // commenting X(T{a}):XX::rep => X(T{o}):XX::rep @ k2*[X().X()::rep] K{i}:X():XYZ::rep => K{p}:X():XYZ::rep @ k1*[X().Y().Z()::rep] // also here => P{f}:XP::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 #! complexes XYZ = X().Y().Z() // a big complex XX = X().X() XP = X().P{_} """ self.model_without_complexes = """ #! rules // commenting X(T{a}).X()::rep => X(T{o}).X()::rep @ k2*[X().X()::rep] X(K{i}).Y().Z()::rep => X(K{p}).Y().Z()::rep @ k1*[X().Y().Z()::rep] // also here => X().P{f}::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_variable = """ #! rules // commenting T{a}:X():?::rep => T{o}:X():?::rep @ k2*[X().X()::rep] ; ? = { XX, XY } K{i}:X():XY::rep => K{p}:X():XY::rep @ k1*[X().Y().Z().X()::rep] // also here #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions // and k1 = 0.05 // also k2 = 0.12 #! complexes XX = X().X() XY = X().Y() """ self.model_without_variable = """ #! rules // commenting X(K{i}).Y()::rep => X(K{p}).Y()::rep @ k1*[X().Y().Z().X()::rep] X(T{a}).X()::rep => X(T{o}).X()::rep @ k2*[X().X()::rep] X(T{a}).Y()::rep => X(T{o}).Y()::rep @ k2*[X().X()::rep] #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_redundant = """ #! rules K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().B()::cyt => K()::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().K()::cyt => K()::cyt + K()::cyt K(S{i}).K()::cyt => K(S{a})::cyt + K()::cyt K(S{i}, T{p}).K()::cyt => K(S{a}, T{p})::cyt + K()::cyt #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_without_redundant = """ #! rules K().B()::cyt => K()::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().K()::cyt => K()::cyt + K()::cyt #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_with_context = """ #! rules K(S{i}).B(T{a})::cyt => K(S{i})::cyt + B(T{a})::cyt @ 3*[K(S{i}).B(T{a})::cyt]/2*v_1 A{p}.K(S{i},T{i})::cyt => A{i}::cyt + K(S{a},T{a})::cyt K(S{i},T{i})::cyt => K(S{a},T{i})::cyt #! inits 2 K(S{i}).B(T{a})::cyt 1 A{p}.K(S{i},T{i})::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_without_context = """ #! rules K().B()::cyt => K()::cyt + B()::cyt @ 3*[K().B()::cyt]/2*v_1 A{_}.K()::cyt => A{_}::cyt + K()::cyt #! inits 2 K().B()::cyt 1 A{_}.K()::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_reachable = """ #! rules K(S{i}).B()::cyt => K(S{a})::cyt + B()::cyt @ 3*[K(S{i}).B()::cyt]/2*v_1 K(S{a})::cyt + A{i}::cyt => K(S{a}).A{i}::cyt K().A{i}::cyt => K().A{a}::cyt #! inits 2 K(S{i}).B()::cyt 1 A{i}::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_nonreachable = """ #! rules K(S{i}).B()::cyt => K(S{a})::cyt + B()::cyt @ 3*[K(S{i}).B()::cyt]/2*v_1 K(S{a})::cyt + A{i}::cyt => K(S{a}).A{i}::cyt #! inits 2 K(S{i}).B()::cyt 1 A{i}::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_parametrised = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(v_3+([X()::rep])**4) // ** means power (^) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions k1 = 0.05 """ self.miyoshi = """
class TestModel(unittest.TestCase): def setUp(self): # agents self.s1 = StructureAgent("X", set()) self.s2 = StructureAgent("Y", set()) self.s3 = StructureAgent("Z", set()) self.c1 = Complex([self.s1], "rep") self.c2 = Complex([self.s2], "rep") self.c3 = Complex([self.s3], "rep") # rules sequence_1 = (self.s1,) mid_1 = 1 compartments_1 = ["rep"] complexes_1 = [(0, 0)] pairs_1 = [(0, None)] rate_1 = Rate("k1*[X()::rep]") self.r1 = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, rate_1) sequence_2 = (self.s3, self.s1) mid_2 = 1 compartments_2 = ["rep"] * 2 complexes_2 = [(0, 0), (1, 1)] pairs_2 = [(0, 1)] self.r2 = Rule(sequence_2, mid_2, compartments_2, complexes_2, pairs_2, None) sequence_3 = (self.s2,) mid_3 = 0 compartments_3 = ["rep"] complexes_3 = [(0, 0)] pairs_3 = [(None, 0)] rate_3 = Rate("1.0/(1.0+([X()::rep])**4.0)") self.r3 = Rule(sequence_3, mid_3, compartments_3, complexes_3, pairs_3, rate_3) # inits self.inits = collections.Counter({self.c1: 2, self.c2: 1}) # defs self.defs = {'k1': 0.05, 'k2': 0.12} self.model = Model({self.r1, self.r2, self.r3}, self.inits, self.defs, set()) # model self.model_str_1 = """ #! rules X()::rep => @ k1*[X()::rep] Z()::rep => X()::rep => Y()::rep @ 1/(1+([X()::rep])**4) #! inits 2 X()::rep Y()::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_parser = Parser("model") self.model_str_2 = """ #! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ # vectors ordering = (self.c1, self.c2, self.c3) self.rate_parser = Parser("rate") rate_expr = "1/(1+([X()::rep])**4)" rate_1 = Rate(self.rate_parser.parse(rate_expr).data) rate_1.vectorize(ordering, dict()) rate_expr = "k1*[X()::rep]" rate_2 = Rate(self.rate_parser.parse(rate_expr).data) rate_2.vectorize(ordering, {"k1": 0.05}) init = State(np.array([2, 1, 0])) vector_reactions = {VectorReaction(State(np.array([0, 0, 0])), State(np.array([0, 1, 0])), rate_1), VectorReaction(State(np.array([1, 0, 0])), State(np.array([0, 0, 0])), rate_2), VectorReaction(State(np.array([0, 0, 1])), State(np.array([1, 0, 0])), None)} self.vm_1 = VectorModel(vector_reactions, init, ordering, None) # wrong models self.model_wrong_1 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o}):;rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_wrong_2 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep = X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_with_comments = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_complexes = """ #! rules // commenting X(T{a}):XX::rep => X(T{o}):XX::rep @ k2*[X().X()::rep] K{i}:X():XYZ::rep => K{p}:X():XYZ::rep @ k1*[X().Y().Z()::rep] // also here => P{f}:XP::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 #! complexes XYZ = X().Y().Z() // a big complex XX = X().X() XP = X().P{_} """ self.model_without_complexes = """ #! rules // commenting X(T{a}).X()::rep => X(T{o}).X()::rep @ k2*[X().X()::rep] X(K{i}).Y().Z()::rep => X(K{p}).Y().Z()::rep @ k1*[X().Y().Z()::rep] // also here => X().P{f}::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_variable = """ #! rules // commenting T{a}:X():?::rep => T{o}:X():?::rep @ k2*[X().X()::rep] ; ? = { XX, XY } K{i}:X():XY::rep => K{p}:X():XY::rep @ k1*[X().Y().Z().X()::rep] // also here #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions // and k1 = 0.05 // also k2 = 0.12 #! complexes XX = X().X() XY = X().Y() """ self.model_without_variable = """ #! rules // commenting X(K{i}).Y()::rep => X(K{p}).Y()::rep @ k1*[X().Y().Z().X()::rep] X(T{a}).X()::rep => X(T{o}).X()::rep @ k2*[X().X()::rep] X(T{a}).Y()::rep => X(T{o}).Y()::rep @ k2*[X().X()::rep] #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions // and k1 = 0.05 // also k2 = 0.12 """ self.model_with_redundant = """ #! rules K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().B()::cyt => K()::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().K()::cyt => K()::cyt + K()::cyt K(S{i}).K()::cyt => K(S{a})::cyt + K()::cyt K(S{i}, T{p}).K()::cyt => K(S{a}, T{p})::cyt + K()::cyt #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_without_redundant = """ #! rules K().B()::cyt => K()::cyt + B()::cyt + D(A{_})::cell @ 3*[K().B()::cyt]/2*v_1 K().K()::cyt => K()::cyt + K()::cyt #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_with_context = """ #! rules K(S{i}).B(T{a})::cyt => K(S{i})::cyt + B(T{a})::cyt @ 3*[K(S{i}).B(T{a})::cyt]/2*v_1 A{p}.K(S{i},T{i})::cyt => A{i}::cyt + K(S{a},T{a})::cyt K(S{i},T{i})::cyt => K(S{a},T{i})::cyt #! inits 2 K(S{i}).B(T{a})::cyt 1 A{p}.K(S{i},T{i})::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_without_context = """ #! rules K().B()::cyt => K()::cyt + B()::cyt @ 3*[K().B()::cyt]/2*v_1 A{_}.K()::cyt => A{_}::cyt + K()::cyt #! inits 2 K().B()::cyt 1 A{_}.K()::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_reachable = """ #! rules K(S{i}).B()::cyt => K(S{a})::cyt + B()::cyt @ 3*[K(S{i}).B()::cyt]/2*v_1 K(S{a})::cyt + A{i}::cyt => K(S{a}).A{i}::cyt K().A{i}::cyt => K().A{a}::cyt #! inits 2 K(S{i}).B()::cyt 1 A{i}::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_nonreachable = """ #! rules K(S{i}).B()::cyt => K(S{a})::cyt + B()::cyt @ 3*[K(S{i}).B()::cyt]/2*v_1 K(S{a})::cyt + A{i}::cyt => K(S{a}).A{i}::cyt #! inits 2 K(S{i}).B()::cyt 1 A{i}::cyt #! definitions v_1 = 0.05 k2 = 0.12 """ self.model_parametrised = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(v_3+([X()::rep])**4) // ** means power (^) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions k1 = 0.05 """ self.miyoshi = """ #! rules S{u}:KaiC():KaiC6::cyt => S{p}:KaiC():KaiC6::cyt @ (kcat1*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) S{p}:KaiC():KaiC6::cyt => S{u}:KaiC():KaiC6::cyt @ (kcat2*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) T{u}:KaiC():KaiC6::cyt => T{p}:KaiC():KaiC6::cyt @ (kcat3*[KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) T{p}:KaiC():KaiC6::cyt => T{u}:KaiC():KaiC6::cyt @ (kcat4*[KaiB4{a}.KaiA2()::cyt]*[KaiC6::cyt])/(Km + [KaiC6::cyt]) KaiB4{i}::cyt => KaiB4{a}::cyt @ (kcatb2*[KaiB4{i}::cyt])/(Kmb2 + [KaiB4{i}::cyt]) KaiB4{a}::cyt => KaiB4{i}::cyt @ (kcatb1*[KaiB4{a}::cyt])/(Kmb1 + [KaiB4{a}::cyt]) KaiB4{a}.KaiA2()::cyt => KaiB4{a}::cyt + KaiA2()::cyt @ k12*[KaiB4{a}.KaiA2()::cyt] KaiC6::cyt => 6 KaiC()::cyt @ kdimer*[KaiC6::cyt] 6 KaiC()::cyt => KaiC6::cyt @ kdimer*[KaiC()::cyt]*([KaiC()::cyt] - 1)*([KaiC()::cyt] - 2)*([KaiC()::cyt] - 3)*([KaiC()::cyt] - 4)*([KaiC()::cyt] - 5) #! inits 6 KaiC(S{p},T{p})::cyt 1 KaiB4{a}.KaiA2()::cyt #! definitions kcat1 = 0.539 kcat3 = 0.89 Km = 0.602 kcatb2 = 0.346 kcatb1 = 0.602 Kmb2 = 66.75 Kmb1 = 2.423 k12 = 0.0008756 kdimer = 1.77 #! complexes KaiC6 = KaiC().KaiC().KaiC().KaiC().KaiC().KaiC() """ def test_str(self): model = self.model_parser.parse(self.model_str_1).data back_to_str = repr(model) parsed_again = self.model_parser.parse(back_to_str).data self.assertEqual(model, parsed_again) def test_comments(self): model_with_comments = self.model_parser.parse(self.model_with_comments) model_without_comments = self.model_parser.parse(self.model_str_2).data self.assertEqual(model_with_comments.data, model_without_comments) def test_parser(self): self.assertEqual(self.model_parser.parse(self.model_str_1).data, self.model) def test_signatures(self): model = self.model_parser.parse(self.model_str_2).data self.assertEqual(model.atomic_signature, {'K': {'c', 'i', 'p'}, 'T': {'e', 'a', 'o', 'j'}, 'P': {'g', 'f'}, 'N': {'l'}}) self.assertEqual(model.structure_signature, {'X': {'K', 'T'}, 'Y': {'P', 'N'}}) def test_to_vector_model(self): model = self.model_parser.parse(self.model_str_1).data self.assertTrue(model.to_vector_model() == self.vm_1) def test_parser_errors(self): self.assertEqual(self.model_parser.parse(self.model_wrong_1).data, {"unexpected": ";", "expected": {'?', 'name'}, "line": 3, "column": 37}) self.assertEqual(self.model_parser.parse(self.model_wrong_2).data, {"expected": {'decimal', '#! inits', ']', '#! definitions', '=>', '@', 'int', '+', 'name', ';'}, "line": 3, "column": 26, "unexpected": "="}) def test_zooming_syntax(self): model_abstract = self.model_parser.parse(self.model_with_complexes).data model_base = self.model_parser.parse(self.model_without_complexes).data self.assertEqual(model_abstract, model_base) def test_variables(self): model_abstract = self.model_parser.parse(self.model_with_variable).data model_base = self.model_parser.parse(self.model_without_variable).data self.assertEqual(model_abstract, model_base) def test_redundant(self): model = self.model_parser.parse(self.model_with_redundant).data model.eliminate_redundant() model_eliminated = self.model_parser.parse(repr(model)).data model_check = self.model_parser.parse(self.model_without_redundant).data self.assertEqual(model_eliminated, model_check) def test_reduce_context(self): model = self.model_parser.parse(self.model_with_context).data model.reduce_context() model_check = self.model_parser.parse(self.model_without_context).data self.assertEqual(model, model_check) def test_nonreachability(self): complex_parser = Parser("rate_complex") agent = "K(S{a}).A{a}::cyt" complex = complex_parser.parse(agent).data.children[0] model_reach = self.model_parser.parse(self.model_reachable).data model_nonreach = self.model_parser.parse(self.model_nonreachable).data self.assertTrue(model_reach.static_non_reachability(complex)) self.assertFalse(model_nonreach.static_non_reachability(complex)) def test_parametrised_model(self): model = self.model_parser.parse(self.model_parametrised).data self.assertTrue(len(model.params) == 2) def test_create_complex_labels(self): model = Model(set(), collections.Counter(), dict(), set()) complex_parser = Parser("rate_complex") complex_1 = complex_parser.parse("K(S{i},T{a}).B{o}::cyt").data.children[0] complex_2 = complex_parser.parse("K(S{a},T{a}).B{o}::cyt").data.children[0] complex_3 = complex_parser.parse("K(S{a},T{i}).B{o}::cyt").data.children[0] complex_abstract = complex_parser.parse("K(S{a}).B{_}::cyt").data.children[0] ordering = (complex_1, complex_2, complex_3) complexes = [complex_2, complex_abstract, complex_1] result_labels = {complex_2: "VAR_1",complex_abstract: "ABSTRACT_VAR_12", complex_1: "VAR_0"} result_formulas = ['ABSTRACT_VAR_12 = VAR_1+VAR_2; // K(S{a}).B{_}::cyt'] labels, prism_formulas = model.create_complex_labels(complexes, ordering) self.assertEqual(labels, result_labels) self.assertEqual(prism_formulas, result_formulas) def test_create_AP_labels(self): model = Model(set(), collections.Counter(), dict(), set()) complex_parser = Parser("rate_complex") complex_1 = complex_parser.parse("K(S{i},T{a}).B{o}::cyt").data.children[0] complex_2 = complex_parser.parse("K(S{a},T{a}).B{o}::cyt").data.children[0] complex_3 = complex_parser.parse("K(S{a},T{i}).B{o}::cyt").data.children[0] complex_abstract = complex_parser.parse("K(S{a}).B{_}::cyt").data.children[0] ordering = (complex_1, complex_2, complex_3) APs = [Core.Formula.AtomicProposition(complex_abstract, " >= ", "3"), Core.Formula.AtomicProposition(complex_1, " < ", 2)] s1 = State(np.array((1, 2, 2))) s2 = State(np.array((5, 1, 1))) s3 = State(np.array((2, 4, 3))) s4 = State(np.array((1, 4, 3))) states_encoding = {s1: 1, s2: 2, s3: 3, s4: 4} result_AP_lables = {APs[0]: 'property_0', APs[1]: 'property_1'} result_state_labels = {1: {'property_0', 'property_1'}, 3: {'property_0', 'init'}, 4: {'property_0', 'property_1'}} ts = TS.TransitionSystem.TransitionSystem(ordering) ts.states_encoding = states_encoding ts.init = 3 state_labels, AP_lables = model.create_AP_labels(APs, ts, 0) self.assertEqual(state_labels, result_state_labels) self.assertEqual(AP_lables, result_AP_lables) def test_create_unique_agents(self): model = self.model_parser.parse(self.miyoshi).data reactions = set() unique_complexes = set() for rule in model.rules: reactions |= rule.create_reactions(model.atomic_signature, model.structure_signature) for reaction in reactions: unique_complexes |= set(reaction.lhs.to_counter()) | set(reaction.rhs.to_counter()) unique_complexes |= set(model.init) ordering = model.create_ordering() self.assertEqual(unique_complexes, set(ordering))
class TestRule(unittest.TestCase): def setUp(self): self.a1 = AtomicAgent("S", "u") self.a2 = AtomicAgent("S", "p") self.a3 = AtomicAgent("B", "_") self.a4 = AtomicAgent("B", "-") self.a5 = AtomicAgent("B", "+") self.s1 = StructureAgent("K", {self.a1}) self.s2 = StructureAgent("B", set()) self.s3 = StructureAgent("K", {self.a2}) self.s4 = StructureAgent("B", set()) self.s5 = StructureAgent("D", {self.a3}) self.s6 = StructureAgent("K", {self.a4}) self.s7 = StructureAgent("K", {self.a5}) self.c1 = Complex([self.s1, self.s2], "cyt") self.c2 = Complex([self.s3], "cyt") self.c3 = Complex([self.s2], "cyt") self.c4 = Complex([self.s5], "cell") # rules sequence_1 = (self.s1, self.s2, self.s3, self.s4) mid_1 = 2 compartments_1 = ["cyt"] * 4 complexes_1 = [(0, 1), (2, 2), (3, 3)] pairs_1 = [(0, 2), (1, 3)] rate_1 = Rate("3.0*[K()::cyt]/2.0*v_1") self.r1 = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, rate_1) sequence_2 = (self.s1, self.s2, self.s3, self.s4, self.s5) mid_2 = 2 compartments_2 = ["cyt"] * 4 + ["cell"] complexes_2 = [(0, 1), (2, 2), (3, 3), (4, 4)] pairs_2 = [(0, 2), (1, 3), (None, 4)] rate_2 = Rate("3.0*[K()::cyt]/2.0*v_1") self.r2 = Rule(sequence_2, mid_2, compartments_2, complexes_2, pairs_2, rate_2) sequence_3 = (self.s6, self.s2, self.s5, self.s7, self.s4) mid_3 = 3 compartments_3 = ["cyt"] * 2 + ["cell"] + ["cyt"] * 2 complexes_3 = [(0, 1), (2, 2), (3, 3), (4, 4)] pairs_3 = [(0, 3), (1, 4), (2, None)] rate_3 = Rate("3.0*[K(T{3+})::cyt]/2.0*v_1") self.r3 = Rule(sequence_3, mid_3, compartments_3, complexes_3, pairs_3, rate_3) # special cases self.s1_s = StructureAgent("X", set()) self.s2_s = StructureAgent("Y", set()) self.s3_s = StructureAgent("Z", set()) sequence_4 = (self.s1_s, ) mid_4 = 1 compartments_4 = ["rep"] complexes_4 = [(0, 0)] pairs_4 = [(0, None)] rate_4 = Rate("k1*[X()::rep]") self.r4 = Rule(sequence_4, mid_4, compartments_4, complexes_4, pairs_4, rate_4) sequence_5 = (self.s2_s, ) mid_5 = 0 compartments_5 = ["rep"] complexes_5 = [(0, 0)] pairs_5 = [(None, 0)] rate_5 = Rate("1.0/(1.0+([X()::rep])**4.0)") self.r5 = Rule(sequence_5, mid_5, compartments_5, complexes_5, pairs_5, rate_5) # reactions lhs = Side([self.c1]) rhs = Side([self.c2, self.c3, self.c4]) self.reaction1 = Reaction(lhs, rhs, rate_2) # create self.t_i = AtomicAgent("T", "i") self.t_a = AtomicAgent("T", "a") self.a4_p = AtomicAgent("C", "p") self.a4_u = AtomicAgent("C", "u") self.u2_c1_p = AtomicAgent("U", "p") self.u2_c1_u = AtomicAgent("U", "u") self.s6 = StructureAgent("D", set()) self.s6_c1_p = StructureAgent("D", {self.a4_p}) self.s6_c1_u = StructureAgent("D", {self.a4_u}) self.s2_c1_p = StructureAgent("B", {self.u2_c1_p}) self.s2_c1_u = StructureAgent("B", {self.u2_c1_u}) self.s1_c1_a = StructureAgent("K", {self.a1, self.t_a}) self.s1_c1_i = StructureAgent("K", {self.a1, self.t_i}) self.s3_c1_a = StructureAgent("K", {self.a2, self.t_a}) self.s3_c1_i = StructureAgent("K", {self.a2, self.t_i}) sequence_c1 = (self.s1, self.s2, self.s3, self.s4, self.s6) mid_c1 = 2 compartments_c1 = ["cyt"] * 5 complexes_c1 = [(0, 0), (1, 1), (2, 3), (4, 4)] pairs_c1 = [(0, 2), (1, 3), (None, 4)] rate_c1 = Rate("3*[K()::cyt]/2*v_1") self.c1_c1 = Complex([self.s2_c1_u], "cyt") # B(U{u})::cyt self.c1_c2 = Complex([self.s2_c1_p], "cyt") # B(U{p})::cyt self.c1_c3 = Complex([self.s1_c1_a], "cyt") # K(S{u},T{a})::cyt self.c1_c4 = Complex([self.s1_c1_i], "cyt") # K(S{u},T{i})::cyt self.c1_c5 = Complex([self.s3_c1_a, self.s2_c1_u], "cyt") # K(S{p},T{a}).B(U{u})::c self.c1_c6 = Complex([self.s3_c1_i, self.s2_c1_u], "cyt") # K(S{p},T{i}).B(U{u})::c self.c1_c7 = Complex([self.s3_c1_i, self.s2_c1_p], "cyt") # K(S{p},T{i}).B(U{p})::c self.c1_c8 = Complex([self.s3_c1_a, self.s2_c1_p], "cyt") # K(S{p},T{a}).B(U{p})::c self.c1_c9 = Complex([self.s6_c1_p], "cyt") # D(C{p})::cyt self.c1_c10 = Complex([self.s6_c1_u], "cyt") # D(C{u})::cyt self.rule_c1 = Rule(sequence_c1, mid_c1, compartments_c1, complexes_c1, pairs_c1, rate_c1) self.reaction_c1_1 = Reaction(Side([self.c1_c1, self.c1_c3]), Side([self.c1_c5, self.c1_c9]), rate_c1) self.reaction_c1_2 = Reaction(Side([self.c1_c1, self.c1_c3]), Side([self.c1_c5, self.c1_c10]), rate_c1) self.reaction_c1_3 = Reaction(Side([self.c1_c2, self.c1_c4]), Side([self.c1_c7, self.c1_c10]), rate_c1) self.reaction_c1_4 = Reaction(Side([self.c1_c1, self.c1_c4]), Side([self.c1_c6, self.c1_c9]), rate_c1) self.reaction_c1_5 = Reaction(Side([self.c1_c2, self.c1_c3]), Side([self.c1_c8, self.c1_c9]), rate_c1) self.reaction_c1_6 = Reaction(Side([self.c1_c2, self.c1_c3]), Side([self.c1_c8, self.c1_c10]), rate_c1) self.reaction_c1_7 = Reaction(Side([self.c1_c1, self.c1_c4]), Side([self.c1_c6, self.c1_c10]), rate_c1) self.reaction_c1_8 = Reaction(Side([self.c1_c2, self.c1_c4]), Side([self.c1_c7, self.c1_c9]), rate_c1) self.reactions_c1 = { self.reaction_c1_1, self.reaction_c1_2, self.reaction_c1_3, self.reaction_c1_4, self.reaction_c1_5, self.reaction_c1_6, self.reaction_c1_7, self.reaction_c1_8 } # context no change sequence_no_change = (self.s1_c1_a, self.s2_c1_u, self.s3_c1_a, self.s2_c1_u, self.s6_c1_p) self.rule_no_change = Rule(sequence_no_change, mid_c1, compartments_c1, complexes_c1, pairs_c1, rate_c1) # parsing self.parser = Parser("rule") self.rule_no_rate = Rule(sequence_1, mid_1, compartments_1, complexes_1, pairs_1, None) def test_eq(self): self.assertEqual(self.r1, self.r1) def test_print(self): self.assertEqual( str(self.r1), "K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt @ 3.0*[K()::cyt]/2.0*v_1" ) self.assertEqual( str(self.r2), "K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt + D(B{_})::cell @ 3.0*[K()::cyt]/2.0*v_1" ) def test_create_complexes(self): lhs = Side([self.c1]) rhs = Side([self.c2, self.c3, self.c4]) self.assertEqual(self.r2.create_complexes(), (lhs, rhs)) def test_to_reaction(self): self.assertEqual(self.r2.to_reaction(), self.reaction1) def test_create_reactions(self): atomic_signature = { "T": {"a", "i"}, "U": {"p", "u"}, "C": {"p", "u"}, "S": {"p", "u"} } structure_signature = {"K": {"T", "S"}, "B": {"U"}, "D": {"C"}} self.assertEqual( self.rule_c1.create_reactions(atomic_signature, structure_signature), self.reactions_c1) self.assertEqual( self.rule_no_change.create_reactions(atomic_signature, structure_signature), {self.reaction_c1_1}) rule_exp = "K(T{a}).K().K()::cyt => K(T{i}).K().K()::cyt @ k1*[K(T{a}).K().K()::cyt]" rule = self.parser.parse(rule_exp).data result = rule.create_reactions(atomic_signature, structure_signature) reactions = set() with open("Testing/reactions.txt") as file: for complex in file.readlines(): rule = self.parser.parse(complex).data reactions.add(rule.to_reaction()) self.assertEqual(result, reactions) def test_parser(self): rule_expr = "K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt + D(B{_})::cell @ 3*[K()::cyt]/2*v_1" self.assertEqual(self.parser.parse(rule_expr).data, self.r2) rule_expr = "K(B{-}).B()::cyt + D(B{_})::cell => K(B{+})::cyt + B()::cyt @ 3*[K(T{3+})::cyt]/2*v_1" self.assertEqual(self.parser.parse(rule_expr).data, self.r3) rule_expr = "X()::rep => @ k1*[X()::rep]" self.assertEqual(self.parser.parse(rule_expr).data, self.r4) rule_expr = "=> Y()::rep @ 1/(1+([X()::rep])**4)" self.assertEqual(self.parser.parse(rule_expr).data, self.r5) rule_expr = "K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt" self.assertEqual(self.parser.parse(rule_expr).data, self.rule_no_rate) def test_compatible(self): self.assertTrue(self.r1.compatible(self.r2)) self.assertFalse(self.r2.compatible(self.r1)) rule_expr_1 = "K(S{u}).B()::cyt => K(S{p})::cyt + B()::cyt + D(B{_})::cell @ 3*[K()::cyt]/2*v_1" rule_expr_2 = "K().B()::cyt => K()::cyt + B()::cyt + D(B{_})::cell @ 3*[K()::cyt]/2*v_1" rule1 = self.parser.parse(rule_expr_1).data rule2 = self.parser.parse(rule_expr_2).data self.assertFalse(rule1.compatible(rule2)) self.assertTrue(rule2.compatible(rule1)) def test_reduce_context(self): rule_expr_1 = "K(S{u}).B{i}::cyt => K(S{p})::cyt + B{a}::cyt + D(B{_})::cell @ 3*[K(S{u}).B{i}::cyt]/2*v_1" rule1 = self.parser.parse(rule_expr_1).data rule_expr_2 = "K().B{_}::cyt => K()::cyt + B{_}::cyt + D()::cell @ 3*[K().B{_}::cyt]/2*v_1" rule2 = self.parser.parse(rule_expr_2).data self.assertEqual(rule1.reduce_context(), rule2) def test_exists_compatible_agent(self): complex_parser = Parser("rate_complex") agent = "K(S{a}).A{a}::cyt" complex = complex_parser.parse(agent).data.children[0] rule_expr = "K().A{i}::cyt => K().A{a}::cyt" rule = self.parser.parse(rule_expr).data self.assertTrue(rule.exists_compatible_agent(complex))
class TestVectorModel(unittest.TestCase): def setUp(self): self.s1 = StructureAgent("X", set()) self.s2 = StructureAgent("Y", set()) self.s3 = StructureAgent("Z", set()) self.c1 = Complex([self.s1], "rep") self.c2 = Complex([self.s2], "rep") self.c3 = Complex([self.s3], "rep") ordering = (self.c1, self.c2, self.c3) params = {"k1": 0.05, "k2": 0.1} self.rate_parser = Parser("rate") rate_expr = "1/(1+([X()::rep])**2)" rate_1 = Rate(self.rate_parser.parse(rate_expr).data) rate_1.vectorize(ordering, params) rate_expr = "k1*[X()::rep]" rate_2 = Rate(self.rate_parser.parse(rate_expr).data) rate_2.vectorize(ordering, params) rate_expr = "k2*[Z()::rep]" rate_3 = Rate(self.rate_parser.parse(rate_expr).data) rate_3.vectorize(ordering, params) init = State(np.array([2.0, 1.0, 1.0])) vector_reactions = { VectorReaction(State(np.array([0.0, 0.0, 0.0])), State(np.array([0.0, 1.0, 0.0])), rate_1), VectorReaction(State(np.array([1.0, 0.0, 0.0])), State(np.array([0.0, 0.0, 0.0])), rate_2), VectorReaction(State(np.array([0.0, 0.0, 1.0])), State(np.array([1.0, 0.0, 0.0])), None) } self.vm_1 = VectorModel(vector_reactions, init, ordering, None) vector_reactions = { VectorReaction(State(np.array([0.0, 0.0, 0.0])), State(np.array([0.0, 1.0, 0.0])), rate_1), VectorReaction(State(np.array([1.0, 0.0, 0.0])), State(np.array([0.0, 0.0, 0.0])), rate_2), VectorReaction(State(np.array([0.0, 0.0, 1.0])), State(np.array([1.0, 0.0, 0.0])), rate_3) } self.vm_2 = VectorModel(vector_reactions, init, ordering, None) # test abstract model self.model_parser = Parser("model") self.model_abstract = \ """#! rules => X()::rep @ k2*[T{_}::rep] T{a}::rep => T{i}::rep @ k1*[T{_}::rep] #! inits 10 T{a}::rep #! definitions k1 = 0.05 k2 = 0.12 """ # test transition system generating a1 = AtomicAgent("B", "a") a2 = AtomicAgent("S", "u") a3 = AtomicAgent("S", "p") a4 = AtomicAgent("T", "i") s1 = StructureAgent("K", {a3, a4}) s2 = StructureAgent("K", {a2, a4}) cx1 = Complex([a1], "cyt") cx2 = Complex([s1], "cyt") cx3 = Complex([s2], "cyt") cx4 = Complex([s1, a1], "cyt") cx5 = Complex([s2, a1], "cyt") ordering = (cx5, cx4, cx3, cx2, cx1) # (K(S{u},T{i}).B{a}::cyt, K(S{p},T{i}).B{a}::cyt, K(S{u},T{i})::cyt, K(S{p},T{i})::cyt, B{a}::cyt) self.model_TS = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 1 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ alpha = 10 beta = 5 gamma = 2 omega = 3 self.test_ts = TransitionSystem(ordering) states = [ State(np.array((0.0, 0.0, 0.0, 0.0, 1.0))), State(np.array((0.0, 0.0, 0.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 0.0, 1.0))), State(np.array((np.inf, np.inf, np.inf, np.inf, np.inf))), State(np.array((0.0, 0.0, 0.0, 1.0, 1.0))), State(np.array((0.0, 0.0, 1.0, 1.0, 1.0))), State(np.array((0.0, 1.0, 0.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 0.0, 1.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 1.0, 0.0))), State(np.array((0.0, 1.0, 1.0, 0.0, 0.0))), State(np.array((0.0, 1.0, 0.0, 1.0, 0.0))), State(np.array((0.0, 1.0, 1.0, 1.0, 0.0))) ] # in edges we have probabilities, not rates, so we must normalise go = gamma + omega # 5 goa = gamma + omega + alpha # 15 goab = gamma + omega + alpha + beta # 20 gob = gamma + omega + beta # 10 oa = omega + alpha # 13 self.test_ts.processed = set(states) self.test_ts.edges = { Edge(states[0], states[1], gamma / go), Edge(states[0], states[3], omega / go), Edge(states[1], states[2], omega / omega), Edge(states[2], states[4], omega / oa), Edge(states[2], states[8], alpha / oa), Edge(states[3], states[2], gamma / goa), Edge(states[3], states[4], omega / goa), Edge(states[3], states[5], alpha / goa), Edge(states[4], states[4], 1), Edge(states[5], states[6], omega / gob), Edge(states[5], states[7], beta / gob), Edge(states[5], states[8], gamma / gob), Edge(states[6], states[4], oa / goab), Edge(states[6], states[9], gamma / goab), Edge(states[6], states[10], beta / goab), Edge(states[7], states[10], omega / omega), Edge(states[8], states[9], gamma / gamma), Edge(states[9], states[4], 1), Edge(states[10], states[4], omega / oa), Edge(states[10], states[11], alpha / oa), Edge(states[11], states[12], omega / omega), Edge(states[12], states[4], 1) } self.test_ts.encode(states[0]) # bigger TS self.model_bigger_TS = \ """#! rules => 2 K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 6 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ # even bigger TS self.model_even_bigger_TS = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 10 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ self.model_parametrised = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 1 B{a}::cyt #! definitions alpha = 10 beta = 5 //gamma = 2 omega = 3 """ self.model_with_sinks = \ """#! rules K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{a}::cyt => B{i}::cyt @ alpha*[B{_}::cyt] #! inits 1 B{a}::cyt 1 K(S{u})::cyt #! definitions alpha = 10 beta = 5 """ def test_compute_bound(self): self.assertEqual(self.vm_1.bound, 2) def test_deterministic_simulation(self): # simple rates data_simulated = self.vm_2.deterministic_simulation( 3, 1 / (6.022 * 10**23)) data_loaded = pd.read_csv("Testing/simple_out.csv") pd.testing.assert_frame_equal(data_simulated, data_loaded) # more abstract rates model = self.model_parser.parse(self.model_abstract).data vector_model = model.to_vector_model() data_simulated = vector_model.deterministic_simulation( 3, 1 / (6.022 * 10**23)) data_loaded = pd.read_csv("Testing/abstract_out.csv") pd.testing.assert_frame_equal(data_simulated, data_loaded) def test_stochastic_simulation(self): model = self.model_parser.parse(self.model_abstract).data vector_model = model.to_vector_model() data_simulated = vector_model.stochastic_simulation(5, 4, testing=True) # to save dataframe to csv file # data_simulated.to_csv("Testing/stochastic_out.csv", index=None, header=True) data_loaded = pd.read_csv("Testing/stochastic_out.csv") pd.testing.assert_frame_equal(data_simulated, data_loaded) def test_generate_transition_system(self): model = self.model_parser.parse(self.model_TS).data vector_model = model.to_vector_model() generated_ts = vector_model.generate_transition_system() self.assertEqual(self.test_ts, generated_ts) # bigger TS model = self.model_parser.parse(self.model_bigger_TS).data vector_model = model.to_vector_model() generated_ts = vector_model.generate_transition_system() loaded_ts = load_TS_from_json("Testing/testing_bigger_ts.json") self.assertEqual(generated_ts, loaded_ts) def test_save_to_json(self): model = self.model_parser.parse(self.model_TS).data vector_model = model.to_vector_model() generated_ts = vector_model.generate_transition_system() generated_ts.save_to_json("Testing/testing_ts.json") loaded_ts = load_TS_from_json("Testing/testing_ts.json") self.assertEqual(generated_ts, loaded_ts) def test_generate_pMC(self): model = self.model_parser.parse(self.model_parametrised).data vector_model = model.to_vector_model() generated_ts = vector_model.generate_transition_system() loaded_ts = load_TS_from_json("Testing/ts_pMC.json") self.assertEqual(generated_ts, loaded_ts) def test_generate_transition_system_interrupt(self): model = self.model_parser.parse(self.model_even_bigger_TS).data vector_model = model.to_vector_model() # partially generate TS with max ~1000 states generated_ts = vector_model.generate_transition_system(max_size=1000) # was interrupted generated_ts.save_to_json("Testing/TS_in_progress.json") loaded_unfinished_ts = load_TS_from_json("Testing/TS_in_progress.json") # continue in generating with max ~5000 states generated_ts = vector_model.generate_transition_system( loaded_unfinished_ts, max_size=5000) generated_ts.save_to_json("Testing/TS_in_progress.json") loaded_unfinished_ts = load_TS_from_json("Testing/TS_in_progress.json") # finish the TS generated_ts = vector_model.generate_transition_system( loaded_unfinished_ts) generated_ts.save_to_json("Testing/TS_finished.json") loaded_ts = load_TS_from_json("Testing/interrupt_even_bigger_ts.json") self.assertEqual(generated_ts, loaded_ts) def test_handle_sinks(self): model = self.model_parser.parse(self.model_with_sinks).data vector_model = model.to_vector_model() generated_ts = vector_model.generate_transition_system() loaded_ts = load_TS_from_json("Testing/TS_with_sinks.json") self.assertEqual(generated_ts, loaded_ts)
class TestRate(unittest.TestCase): def setUp(self): # agents self.a1 = AtomicAgent("T", "i") self.a2 = AtomicAgent("S", "i") self.a3 = AtomicAgent("T", "a") self.a4 = AtomicAgent("S", "a") self.s1 = StructureAgent("X", {self.a4}) self.s2 = StructureAgent("X", {self.a2}) self.s3 = StructureAgent("K", {self.a3}) self.s4 = StructureAgent("K", {self.a1}) self.s5 = StructureAgent("X", set()) self.s6 = StructureAgent("K", set()) self.c1 = Complex([self.s6], "cyt") # K()::cyt self.c2 = Complex([self.s3], "cyt") # K(T{a})::cyt self.c3 = Complex([self.s4], "cyt") # K(T{i})::cyt self.c4 = Complex([self.s4, self.s1], "cyt") # K(T{i}).X(S{a})::cyt self.c5 = Complex([self.s4, self.s2], "cyt") # K(T{i}).X(S{i})::cyt self.c6 = Complex([self.s3, self.s1], "cyt") # K(T{a}).X(S{a})::cyt self.c7 = Complex([self.s3, self.s2], "cyt") # K(T{a}).X(S{i})::cyt # rates self.parser = Parser("rate") rate_expr = "3.0*[K()::cyt]/2.0*v_1" self.rate_1 = Core.Rate.Rate(self.parser.parse(rate_expr).data) rate_expr = "3.0*[K(T{i}).X()::cyt] + [K()::cyt]" self.rate_2 = Core.Rate.Rate(self.parser.parse(rate_expr).data) # states self.state_1 = State(np.array([2, 3])) self.state_2 = State(np.array([2, 0, 3, 1, 6, 2])) def test_to_str(self): self.assertEqual(str(self.rate_1), "3.0*[K()::cyt]/2.0*v_1") def test_eq(self): self.assertEqual(self.rate_2, self.rate_2) self.assertNotEqual(self.rate_1, self.rate_2) def test_vectorize(self): ordering = (self.c2, self.c3) self.assertEqual(self.rate_1.vectorize(ordering, dict()), [State(np.array([1, 1]))]) ordering = (self.c2, self.c3, self.c4, self.c5, self.c6, self.c7) self.assertEqual(self.rate_2.vectorize(ordering, dict()), [ State(np.array([0, 0, 1, 1, 0, 0])), State(np.array([1, 1, 0, 0, 0, 0])) ]) def test_evaluate(self): ordering = (self.c2, self.c3) self.rate_1.vectorize(ordering, {"v_1": 5}) self.assertEqual(self.rate_1.evaluate(self.state_1), sympy.sympify("3*5.0/2*5")) ordering = (self.c2, self.c3, self.c4, self.c5, self.c6, self.c7) self.rate_2.vectorize(ordering, dict()) self.assertEqual(self.rate_2.evaluate(self.state_2), sympy.sympify("3*4.0 + 2")) def test_to_symbolic(self): ordering = (self.c2, self.c3) self.rate_1.vectorize(ordering, dict()) self.rate_1.to_symbolic() self.assertEqual(str(self.rate_1), "3.0*(y[0] + y[1])/2.0*v_1") ordering = (self.c2, self.c3, self.c4, self.c5, self.c6, self.c7) self.rate_2.vectorize(ordering, dict()) self.rate_2.to_symbolic() self.assertEqual(str(self.rate_2), "3.0*(y[2] + y[3])+(y[0] + y[1])") def test_reduce_context(self): rate_expr = "3.0*[K(S{i})::cyt]/2.0*v_1" rate = Core.Rate.Rate(self.parser.parse(rate_expr).data) self.assertEqual(rate.reduce_context(), self.rate_1)
class TestModel(unittest.TestCase): def setUp(self): self.model_parser = Parser("model") self.url = 'http://biodivine-vm.fi.muni.cz/BCSLparser/' self.model_wrong_1 = \ """#! rules X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] X(T{a})::rep => X(T{o}):;rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k1 = 0.05 k2 = 0.12 """ self.model_with_complexes = """ #! rules // commenting X(T{a}):XX::rep => X(T{o}):XX::rep @ k2*[X().X()::rep] K{i}:X():XYZ::rep => K{p}:X():XYZ::rep @ k1*[X().Y().Z()::rep] // also here => P{f}:XP::rep @ 1/(1+([X().P{_}::rep])**4) // ** means power (^) #! inits // here 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep // comment just 1 item #! definitions // and k1 = 0.05 // also k2 = 0.12 #! complexes XYZ = X().Y().Z() // a big complex XX = X().X() XP = X().P{_} """ def test_remote_request(self): try: response = requests.get(self.url + 'ping') self.assertTrue(response.status_code == 200) except requests.exceptions.ConnectionError: raise AssertionError("API not available") def test_remote_parsing_model(self): try: # correct one result_local = self.model_parser.syntax_check( self.model_with_complexes) headers = {'content-type': 'application/json'} response = requests.post(self.url + 'parse', data=json.dumps({ 'start': 'model', 'expression': self.model_with_complexes }), headers=headers) result_remote = eval(response.text.replace("true", "True")) self.assertEqual(result_remote['success'], result_local.success) # wrong one result_local = self.model_parser.syntax_check(self.model_wrong_1) response = requests.post(self.url + 'parse', data=json.dumps({ 'start': 'model', 'expression': self.model_wrong_1 }), headers=headers) result_remote = eval(response.text.replace("false", "False")) self.assertEqual(result_remote['success'], result_local.success) self.assertEqual([ result_remote["line"], result_remote["column"], result_remote["unexpected"], sorted(result_remote["expected"]) ], [ result_local.data["line"], result_local.data["column"], result_local.data["unexpected"], sorted(result_local.data["expected"]) ]) except requests.exceptions.ConnectionError: raise AssertionError("API not available")
def setUp(self): self.s1 = StructureAgent("X", set()) self.s2 = StructureAgent("Y", set()) self.s3 = StructureAgent("Z", set()) self.c1 = Complex([self.s1], "rep") self.c2 = Complex([self.s2], "rep") self.c3 = Complex([self.s3], "rep") ordering = (self.c1, self.c2, self.c3) params = {"k1": 0.05, "k2": 0.1} self.rate_parser = Parser("rate") rate_expr = "1/(1+([X()::rep])**2)" rate_1 = Rate(self.rate_parser.parse(rate_expr).data) rate_1.vectorize(ordering, params) rate_expr = "k1*[X()::rep]" rate_2 = Rate(self.rate_parser.parse(rate_expr).data) rate_2.vectorize(ordering, params) rate_expr = "k2*[Z()::rep]" rate_3 = Rate(self.rate_parser.parse(rate_expr).data) rate_3.vectorize(ordering, params) init = State(np.array([2.0, 1.0, 1.0])) vector_reactions = { VectorReaction(State(np.array([0.0, 0.0, 0.0])), State(np.array([0.0, 1.0, 0.0])), rate_1), VectorReaction(State(np.array([1.0, 0.0, 0.0])), State(np.array([0.0, 0.0, 0.0])), rate_2), VectorReaction(State(np.array([0.0, 0.0, 1.0])), State(np.array([1.0, 0.0, 0.0])), None) } self.vm_1 = VectorModel(vector_reactions, init, ordering, None) vector_reactions = { VectorReaction(State(np.array([0.0, 0.0, 0.0])), State(np.array([0.0, 1.0, 0.0])), rate_1), VectorReaction(State(np.array([1.0, 0.0, 0.0])), State(np.array([0.0, 0.0, 0.0])), rate_2), VectorReaction(State(np.array([0.0, 0.0, 1.0])), State(np.array([1.0, 0.0, 0.0])), rate_3) } self.vm_2 = VectorModel(vector_reactions, init, ordering, None) # test abstract model self.model_parser = Parser("model") self.model_abstract = \ """#! rules => X()::rep @ k2*[T{_}::rep] T{a}::rep => T{i}::rep @ k1*[T{_}::rep] #! inits 10 T{a}::rep #! definitions k1 = 0.05 k2 = 0.12 """ # test transition system generating a1 = AtomicAgent("B", "a") a2 = AtomicAgent("S", "u") a3 = AtomicAgent("S", "p") a4 = AtomicAgent("T", "i") s1 = StructureAgent("K", {a3, a4}) s2 = StructureAgent("K", {a2, a4}) cx1 = Complex([a1], "cyt") cx2 = Complex([s1], "cyt") cx3 = Complex([s2], "cyt") cx4 = Complex([s1, a1], "cyt") cx5 = Complex([s2, a1], "cyt") ordering = (cx5, cx4, cx3, cx2, cx1) # (K(S{u},T{i}).B{a}::cyt, K(S{p},T{i}).B{a}::cyt, K(S{u},T{i})::cyt, K(S{p},T{i})::cyt, B{a}::cyt) self.model_TS = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 1 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ alpha = 10 beta = 5 gamma = 2 omega = 3 self.test_ts = TransitionSystem(ordering) states = [ State(np.array((0.0, 0.0, 0.0, 0.0, 1.0))), State(np.array((0.0, 0.0, 0.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 0.0, 1.0))), State(np.array((np.inf, np.inf, np.inf, np.inf, np.inf))), State(np.array((0.0, 0.0, 0.0, 1.0, 1.0))), State(np.array((0.0, 0.0, 1.0, 1.0, 1.0))), State(np.array((0.0, 1.0, 0.0, 0.0, 0.0))), State(np.array((0.0, 0.0, 0.0, 1.0, 0.0))), State(np.array((0.0, 0.0, 1.0, 1.0, 0.0))), State(np.array((0.0, 1.0, 1.0, 0.0, 0.0))), State(np.array((0.0, 1.0, 0.0, 1.0, 0.0))), State(np.array((0.0, 1.0, 1.0, 1.0, 0.0))) ] # in edges we have probabilities, not rates, so we must normalise go = gamma + omega # 5 goa = gamma + omega + alpha # 15 goab = gamma + omega + alpha + beta # 20 gob = gamma + omega + beta # 10 oa = omega + alpha # 13 self.test_ts.processed = set(states) self.test_ts.edges = { Edge(states[0], states[1], gamma / go), Edge(states[0], states[3], omega / go), Edge(states[1], states[2], omega / omega), Edge(states[2], states[4], omega / oa), Edge(states[2], states[8], alpha / oa), Edge(states[3], states[2], gamma / goa), Edge(states[3], states[4], omega / goa), Edge(states[3], states[5], alpha / goa), Edge(states[4], states[4], 1), Edge(states[5], states[6], omega / gob), Edge(states[5], states[7], beta / gob), Edge(states[5], states[8], gamma / gob), Edge(states[6], states[4], oa / goab), Edge(states[6], states[9], gamma / goab), Edge(states[6], states[10], beta / goab), Edge(states[7], states[10], omega / omega), Edge(states[8], states[9], gamma / gamma), Edge(states[9], states[4], 1), Edge(states[10], states[4], omega / oa), Edge(states[10], states[11], alpha / oa), Edge(states[11], states[12], omega / omega), Edge(states[12], states[4], 1) } self.test_ts.encode(states[0]) # bigger TS self.model_bigger_TS = \ """#! rules => 2 K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 6 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ # even bigger TS self.model_even_bigger_TS = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 10 B{a}::cyt #! definitions alpha = 10 beta = 5 gamma = 2 omega = 3 """ self.model_parametrised = \ """#! rules => K(S{u},T{i})::cyt @ omega K(S{u})::cyt => K(S{p})::cyt @ alpha*[K(S{u})::cyt] K(S{p})::cyt + B{a}::cyt => K(S{p}).B{a}::cyt @ beta*[K(S{p})::cyt]*[B{a}::cyt] B{_}::cyt => @ gamma*[B{_}::cyt] K(S{u},T{i}).B{a}::cyt => @ 5 #! inits 1 B{a}::cyt #! definitions alpha = 10 beta = 5 //gamma = 2 omega = 3 """ self.model_with_sinks = \ """#! rules
class TestFormalMethods(unittest.TestCase): def setUp(self): self.parser = Parsing.ParsePCTLformula.PCTLparser() self.model_parser = Parser("model") self.model = """ #! rules Y{i}::rep => Y{a}::rep @ p*[Y{i}::rep] Y{i}::rep => Y{-}::rep @ (1-p)*[Y{i}::rep] X()::rep + Y{a}::rep => X().Y{a}::rep @ q*[X()::rep]*[Y{a}::rep] X(K{i}).Y{_}::rep => X(K{p}).Y{_}::rep @ p*[X(K{i}).Y{_}::rep] // also here #! inits 2 X(K{i})::rep 1 Y{i}::rep #! definitions p = 0.3 """ self.tumor = """ #! rules T(P{i})::x => T(P{m})::x @ a1*[T(P{i})::x] T(P{m})::x => T(P{i})::x + T(P{i})::x @ a2*[T(P{m})::x] T(P{i})::x => @ d1*[T(P{i})::x] T(P{m})::x => @ d2*[T(P{m})::x] #! inits 2 T(P{m})::x 1 T(P{i})::x #! definitions a1 = 1.2 a2 = 2 d1 = 0.8 d2 = 0.5 """ self.tumor_parametric = """ #! rules T(P{i})::x => T(P{m})::x @ a1*[T(P{i})::x] T(P{m})::x => T(P{i})::x + T(P{i})::x @ a2*[T(P{m})::x] T(P{i})::x => @ d1*[T(P{i})::x] T(P{m})::x => @ d2*[T(P{m})::x] #! inits 2 T(P{m})::x 1 T(P{i})::x #! definitions a1 = 1.2 a2 = 2 d1 = 0.8 """ def test_tumor_modelchecking(self): model_parsed = self.model_parser.parse(self.tumor).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P=? [F T(P{m})::x>2 & T(P{i})::x>=0 & T(P{i})::x<2]") result = model_parsed.PCTL_model_checking(formula) self.assertTrue("Result" in str(result)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P > 0.5 [F T(P{m})::x>2]") result = model_parsed.PCTL_model_checking(formula) self.assertTrue("Result" in str(result)) def test_tumor_modelchecking_wrong_formula(self): formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P > 0.5 [F T(P{m}):x>2]") error_message = { 'line': 1, 'column': 19, 'unexpected': ':', 'expected': {'::', '.'} } self.assertEqual(formula.data, error_message) def test_parameter_synthesis(self): model_parsed = self.model_parser.parse(self.tumor_parametric).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P=? [F T(P{m})::x>2]") result = model_parsed.PCTL_synthesis(formula, None) self.assertTrue("Result" in str(result)) def test_parametric_model(self): model_parsed = self.model_parser.parse(self.model).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P<=0.3 [F X().Y{_}::rep >= 1]") result = model_parsed.PCTL_synthesis(formula, '0<=q<=1') self.assertTrue("Result (initial states)" in str(result)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( "P=? [F X().Y{_}::rep >= 1]") result = model_parsed.PCTL_synthesis(formula, None) self.assertTrue("Result (initial states)" in str(result)) def test_synthesis_out_of_scope(self): model_str = """ #! rules X()::rep => @ k1*[X()::rep] Z()::rep => X()::rep @ k2 => Y()::rep @ 1/(1+([X()::rep])**4) #! inits 2 X()::rep Y()::rep #! definitions k2 = 5 """ model = self.model_parser.parse(model_str).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P <= 0.5[F X()::out = 1]') region = '0<=k1<=1' self.assertRaises(ComplexOutOfScope, model.PCTL_synthesis, formula, region) def test_synthesis_simple(self): model_str = """ #! rules X()::rep => @ k1*[X()::rep] Z()::rep => X()::rep @ k2 => Y()::rep @ 1/(1+([X()::rep])**4) #! inits 2 X()::rep Y()::rep #! definitions k2 = 5 """ model = self.model_parser.parse(model_str).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P <= 0.5[F X()::rep = 1]') region = '0<=k1<=1' output = model.PCTL_synthesis(formula, region) self.assertTrue("Region results" in str(output)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P=? [F X()::rep = 1]') output = model.PCTL_synthesis(formula, None) self.assertTrue("Result (initial states)" in str(output)) def test_synthesis_advanced(self): model_str = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) // ** means power (^) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k2 = 0.05 // also comment """ model = self.model_parser.parse(model_str).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P <= 0.5[F X()::rep = 1]') region = '0<=k1<=1' output = model.PCTL_synthesis(formula, region) self.assertTrue("Region results" in str(output)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P=? [F X()::rep = 1]') output = model.PCTL_synthesis(formula, None) self.assertTrue("Result (initial states)" in str(output)) def test_model_checking_simple(self): model_str = """ #! rules X()::rep => @ k1*[X()::rep] Z()::rep => X()::rep @ k2 => Y()::rep @ 1/(1+([X()::rep])**4) #! inits 2 X()::rep Y()::rep #! definitions k2 = 5 k1 = 2 """ model = self.model_parser.parse(model_str).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P <= 0.5[F X()::rep=1]') output = model.PCTL_model_checking(formula) self.assertTrue("Result (for initial states)" in str(output)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P=? [F X()::rep = 1]') output = model.PCTL_model_checking(formula) self.assertTrue("Result (for initial states)" in str(output)) def test_model_checking_advanced(self): model_str = """ #! rules // commenting X(K{i})::rep => X(K{p})::rep @ k1*[X()::rep] // also here X(T{a})::rep => X(T{o})::rep @ k2*[Z()::rep] => Y(P{f})::rep @ 1/(1+([X()::rep])**4) // ** means power (^) #! inits 2 X(K{c}, T{e}).X(K{c}, T{j})::rep Y(P{g}, N{l})::rep #! definitions k2 = 0.05 // also comment k1 = 2 """ model = self.model_parser.parse(model_str).data formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P >= 0.5[F X()::rep=1]') output = model.PCTL_model_checking(formula) self.assertTrue("Result (for initial states)" in str(output)) formula = Parsing.ParsePCTLformula.PCTLparser().parse( 'P=? [F X()::rep = 1]') output = model.PCTL_model_checking(formula) self.assertTrue("Result (for initial states)" in str(output))