# -*- coding: utf-8 -*-
## Filename : TestMCLAnalyser.py
## Author(s) : Michel Le Borgne
## Created : 03/2012
## Revision :
## Source :
##
## Copyright 2012 - 2020 IRISA/IRSET
##
## This library is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published
## by the Free Software Foundation; either version 2.1 of the License, or
## any later version.
##
## This library is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
## MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. The software and
## documentation provided here under is on an "as is" basis, and IRISA has
## no obligations to provide maintenance, support, updates, enhancements
## or modifications.
## In no event shall IRISA be liable to any party for direct, indirect,
## special, incidental or consequential damages, including lost profits,
## arising out of the use of this software and its documentation, even if
## IRISA have been advised of the possibility of such damage. See
## the GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this library; if not, write to the Free Software Foundation,
## Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## The original code contained here was initially developed by:
##
## Michel Le Borgne.
## IRISA
## Symbiose team
## IRISA Campus de Beaulieu
## 35042 RENNES Cedex, FRANCE
##
##
## Contributor(s): Geoffroy Andrieux - IRISA/IRSET
##
"""
Unitary Tests for the MCLAnalyser
"""
from __future__ import print_function
import pkg_resources
import unittest
import os
import itertools as it
from cadbiom.models.clause_constraints.mcl.MCLAnalyser import MCLAnalyser
from cadbiom.models.guard_transitions.simulator.chart_simul import ChartSimulator
from cadbiom.models.guard_transitions.simulator.simul_exceptions import SimulStopException
from cadbiom.models.guard_transitions.chart_model import ChartModel
from cadbiom.models.clause_constraints.mcl.MCLQuery import MCLSimpleQuery
from cadbiom.models.clause_constraints.mcl.MCLSolutions import FrontierSolution
from cadbiom.commons import DIR_LOGS
# helper fonctions for test automation
[docs]def lit_subsol_equal(ssol1, ssol2):
"""
@param ssol1,ssol2: list<string>
CAREFULL: change order in lists
"""
print("subsol type ?", isinstance(ssol2, list))
if not isinstance(ssol2, list):
ssol2 = list(ssol2)
print("SUBSOL", ssol1, ssol2)
return ssol1 == ssol2
[docs]def lit_sol_equal(sol1, sol2):
"""
@param sol1,sol2: list<list<string>>
"""
if not isinstance(sol2, list):
sol1 = tuple(tuple(ssol) for ssol in sol2)
print("LIT_SOL", sol1, sol2)
return sol1 == sol2
# simple reporter
[docs]class ErrorRep(object):
"""
error reporter of the compil type
"""
def __init__(self):
self.context = ""
self.error = False
pass
[docs] def display(self, mess):
"""
just printing
"""
self.error = True
print('\n>> '+self.context+" "+mess)
[docs] def display_info(self, mess):
"""
just printing
"""
print('\n-- '+mess)
[docs] def set_context(self, cont):
"""
for transition compiling
"""
self.context = cont
[docs]class TestMCLAnaLyzer(unittest.TestCase):
"""Unit tests for MCLAnalyser class"""
[docs] def test_lit_sol_equal(self):
"""
Test the test helper function
"""
sol1 = [['-_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', '-A2', '-A4'], \
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4'],\
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4']]
sol2 = [['-_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', '-A2', '-A4'], \
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4'],\
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4']]
res = lit_sol_equal(sol1, sol2)
self.assert_(res, 'Error in lit_sol equality')
sol2 = [['-_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', '-A2', '-A4'], \
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4'],\
['-_lit2', 'C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4']]
res = lit_sol_equal(sol1, sol2)
self.assert_(not res, 'Error in lit_sol inequality')
# test on numbers
sol1 = [[], [3], [], [5]]
sol2 = [[], [3], [], [5]]
res = lit_sol_equal(sol1, sol2)
self.assert_(res, 'Error in lit_sol equality: number case')
sol2 = [[], [3], [2], []]
res = lit_sol_equal(sol1, sol2)
self.assert_(not res, 'Error in lit_sol inequality: number case')
[docs] def test_load1(self):
"""Load from a bcx file"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.bcx"
)
mcla.build_from_chart_file(filename)
res = rep.error
self.assert_(not res, "Error during the load of bcx file")
[docs] def test_load2(self):
"""Load from a cadlang file"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano_cmp.cal"
)
mcla.build_from_cadlang(filename)
res = rep.error
self.assert_(not res, "Error during the load of cadlang file")
[docs] def test_load3(self):
"""Load from a PID file"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano.xml"
)
mcla.build_from_pid_file(filename)
res = rep.error
self.assert_(not res, "during the load of PID xml file")
[docs] def test_delay1(self):
"""
simple delay computation
"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.cal"
)
mcla.build_from_cadlang(filename)
f_prop = "C3 and not C4"
query = MCLSimpleQuery(None, None, f_prop)
lsol = mcla.sq_solutions(query,
4, 1, mcla.unfolder.frontier_values)
# if len(lsol) > 0:
# print 'C3 ALONE'
# print lsol[0] #first solution _ we have two
# else:
# print 'NO SOLUTION C4'
res = len(lsol) == 2
expected_sol = [
['-_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', '-A2', '-A4', '-B2', '-B3', '-_lit3', '-C2', 'C1', '_lit0', '-_lit1', 'B1'],
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4', 'B2', '-B3', '-_lit3', 'C2', '-C1', '-_lit0', '-_lit1', '-B1'],
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', '-A4', '-B2', 'B3', '_lit3', 'C2', '-C1', '-_lit0', '_lit1', '-B1']]
res = res and lit_sol_equal(lsol[0].__str__(), expected_sol)
self.assert_(not res, 'Error in C3 alone')
f_prop = "C4 and not C3"
query = MCLSimpleQuery(None, None, f_prop)
lsol = mcla.sq_solutions(query,
4, 1, mcla.unfolder.frontier_values)
# if len(lsol)>0:
# print 'C4 ALONE', len(lsol)
# print lsol[0]
# else:
# print 'NO SOLUTION C4'
res = len(lsol) == 1
expected_sol = [
['-_lit2', '-C4', '-h2', 'A1', '-C3', '-A3', '-A2', '-A4', '-B2', '-B3', '-_lit3', '-C2', 'C1', '-_lit0', '-_lit1', 'B1'],
['-_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', 'A2', '-A4', '-B2', '-B3', '-_lit3', 'C2', '-C1', '-_lit0', '-_lit1', 'B1'],
['-_lit2', '-C4', '-h2', '-A1', '-C3', 'A3', '-A2', '-A4', '-B2', '-B3', '-_lit3', 'C2', '-C1', '-_lit0', '-_lit1', 'B1'],
['_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', '-A2', 'A4', '-B2', '-B3', '_lit3', 'C2', '-C1', '_lit0', '-_lit1', 'B1']]
res = res and lit_sol_equal(lsol[0].__str__(), expected_sol)
self.assert_(not res, 'Error in C4 alone')
f_prop = "C3 and C4"
query = MCLSimpleQuery(None, None, f_prop)
lsol = mcla.sq_solutions(query,
4, 1, mcla.unfolder.frontier_values)
# if len(lsol)>0:
# print 'C3 and C4'
# print lsol[0]
# else:
# print 'NO SOLUTION'
res = len(lsol) == 1
expected_sol = [
['-_lit2', '-C4', '-h2', 'A1', '-C3', '-A3', '-A2', '-A4', '-B2', '-B3', '-_lit3', '-C2', 'C1', '-_lit0', '-_lit1', 'B1'],
['-_lit2', '-C4', 'h2', '-A1', '-C3', '-A3', 'A2', '-A4', '-B2', '-B3', '-_lit3', 'C2', '-C1', '_lit0', '-_lit1', 'B1'],
['-_lit2', '-C4', '-h2', '-A1', '-C3', 'A3', '-A2', '-A4', 'B2', '-B3', '-_lit3', 'C2', '-C1', '-_lit0', '-_lit1', '-B1'],
['_lit2', '-C4', '-h2', '-A1', '-C3', '-A3', '-A2', 'A4', '-B2', 'B3', '_lit3', 'C2', '-C1', '-_lit0', '_lit1', '-B1']]
res = res and lit_sol_equal(lsol[0].__str__(), expected_sol)
self.assert_(not res, 'Error in C3 and C4')
[docs] def test_delay1_w_ic(self):
"""Simple delay computation with clock sequence
First test: f_prop = "C4"
# old solver
[[], [], [3], []]
[[-1, -2, -3, 4, -5, -6, -7, -8, -9, -10, -11, -12, 13, -14, -15, 16],
[-1, -2, -3, -4, -5, -6, 7, -8, -9, -10, -11, 12, -13, -14, -15, 16],
[-1, -2, 3, -4, -5, 6, -7, -8, -9, -10, -11, 12, -13, 14, -15, 16], #3>0 free clocks: (3, ':', 'h2')
[1, -2, -3, -4, -5, -6, -7, 8, 9, -10, 11, 12, -13, -14, -15, -16]]
['A1', 'C1', 'B1']
['A2', 'C2', 'B1']
['h2', 'A3', 'C2', '_lit0', 'B1'] # activated clock: h2
['_lit2', 'A4', 'B2', '_lit3', 'C2']
[[], [], [], []]
[[-1, -2, -3, 4, -5, -6, -7, -8, -9, -10, -11, -12, 13, -14, -15, -16],
[-1, -2, -3, -4, -5, -6, 7, -8, -9, -10, -11, 12, -13, -14, -15, -16],
[-1, -2, -3, -4, -5, 6, -7, -8, -9, -10, -11, 12, -13, -14, -15, -16],
[1, -2, -3, -4, -5, -6, -7, 8, -9, -10, 11, 12, -13, -14, -15, -16]]
['A1', 'C1']
['A2', 'C2']
['A3', 'C2']
['_lit2', 'A4', '_lit3', 'C2']
# new solver (no clock used => better solution):
[[], [], [], []]
[[-1, -2, -3, 4, -5, -6, -7, -8, -9, -10, -11, -12, 13, -14, -15, -16],
[-1, -2, -3, -4, -5, -6, 7, -8, -9, -10, -11, 12, -13, -14, -15, -16],
[-1, -2, -3, -4, -5, 6, -7, -8, -9, -10, -11, 12, -13, -14, -15, -16],
[1, -2, -3, -4, -5, -6, -7, 8, -9, -10, 11, 12, -13, -14, -15, -16]]
['A1', 'C1']
['A2', 'C2']
['A3', 'C2']
['_lit2', 'A4', '_lit3', 'C2']
[[], [], [], []]
[[-1, -2, -3, 4, -5, -6, -7, -8, -9, -10, -11, -12, 13, -14, -15, 16],
[-1, -2, -3, -4, -5, -6, 7, -8, -9, -10, -11, 12, -13, -14, -15, 16],
[-1, -2, -3, -4, -5, 6, -7, -8, -9, -10, -11, 12, -13, -14, -15, 16],
[1, -2, -3, -4, -5, -6, -7, 8, -9, -10, 11, 12, -13, -14, -15, 16]]
['A1', 'C1', 'B1']
['A2', 'C2', 'B1']
['A3', 'C2', 'B1']
['_lit2', 'A4', '_lit3', 'C2', 'B1']
.. note:: Debugging of solutions - help:
.. code-block:: python
for i, sol in enumerate(lsol, 1):
print("Sol", i)
# [[], [], [], []]
print(sol.extract_act_input_clock_seq())
# [[....], [....], [....], [....]]
print(x.unflatten())
# Convert literal values to str, display only activated ones (val > 0)
for step in sol.unflatten():
print([sol.unfolder.get_var_name(val) for val in step if val > 0])
"""
def debug_solutions(lsol):
"""Make human readable the status of literals at each step of a sol
"""
for i, sol in enumerate(lsol, 1):
print("Sol", i)
# [[], [], [], []]
print(sol.extract_act_input_clock_seq())
# [[....], [....], [....], [....]]
print(sol.unflatten())
# Convert literal values to str, display only activated ones (val > 0)
for step in sol.unflatten():
print([sol.unfolder.get_var_name(val) for val in step
if val > 0])
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.cal"
)
mcla.build_from_cadlang(filename)
st_prop = None
inv_prop = None
f_prop = "C4"
query = MCLSimpleQuery(st_prop, inv_prop, f_prop)
# 4 steps, 1 solution
lsol = mcla.sq_solutions(query, 4, 1, mcla.unfolder.frontier_values)
sol = lsol[0]
ic_seq = sol.extract_act_input_clock_seq()
#print ic_seq
expected_sol = [[], [], [], []]
debug_solutions(lsol)
res = len(lsol) != 0
res = res and lit_sol_equal(expected_sol, ic_seq)
self.assert_(res, 'Error clock sequence for C4; expected: {}'.format(expected_sol))
f_prop = "C4 and not C3"
query = MCLSimpleQuery(None, None, f_prop)
lsol = mcla.sq_solutions(query, 4, 1, mcla.unfolder.frontier_values)
sol = lsol[0]
ic_seq = sol.extract_act_input_clock_seq()
#print ic_seq
expected_sol = [[], [], [], []]
debug_solutions(lsol)
res = len(lsol) != 0
res = res and lit_sol_equal(expected_sol, ic_seq)
self.assert_(res, 'Error clock sequence for C4 and not C3; expected: {}'.format(expected_sol))
f_prop = "C3 and C4"
query = MCLSimpleQuery(None, None, f_prop)
lsol = mcla.sq_solutions(query, 4, 1, mcla.unfolder.frontier_values)
sol = lsol[0]
ic_seq = sol.extract_act_input_clock_seq()
#print ic_seq
# h2 is mandatory to get C3
expected_sol = [[], [3], [], []]
debug_solutions(lsol)
res = len(lsol) != 0
res = res and lit_sol_equal(expected_sol, ic_seq)
self.assert_(res, 'Error clock sequence for C4; expected: {}'.format(expected_sol))
[docs] def test_unflatten(self):
"""
Test unflatten trajectory
"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.cal"
)
mcla.build_from_cadlang(filename)
st_prop = None
inv_prop = None
f_prop = "C3"
query = MCLSimpleQuery(st_prop, inv_prop, f_prop)
lsol = mcla.sq_solutions(query, 4, 1, mcla.unfolder.frontier_values)
ufl = lsol[0].unflatten()
expected_ufl = [
[-1, -2, 3, -4, -5, -6, -7, -8, -9, -10, -11, -12, 13, 14, -15, 16],
[-1, -2, -3, -4, -5, -6, -7, -8, 9, -10, -11, 12, -13, -14, -15, -16],
[-1, -2, -3, -4, -5, -6, -7, -8, -9, 10, 11, 12, -13, -14, 15, -16]
]
res = lit_sol_equal(expected_ufl, ufl)
self.assert_(res, 'Error unflatten')
[docs] def test_dimacs_frontier_ban(self):
"""Ban previous solution and try to get a new different one"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
prop = "p15INK4b and p21CIP1"
query = MCLSimpleQuery(None, None, prop)
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano_noclock_cmp.cal"
)
mcla.build_from_cadlang(filename)
# Get <tuple <DimacsFrontierSol>>
lsol = mcla._MCLAnalyser__sq_dimacs_frontier_solutions(query, 8, 1)
forbidden_sol = [
# Get all activated frontiers in the DimacsFrontierSol
[-var for var in dimacs_front_sol.activated_frontier_values]
for dimacs_front_sol in lsol
]
# Try another solution
query.dim_start = forbidden_sol
# Get <tuple <DimacsFrontierSol>>
lsol2 = mcla._MCLAnalyser__sq_dimacs_frontier_solutions(query, 8, 1)
# comparison: solution are ordered and must be different
# remains true if all components are equal (equal solutions)
self.assertNotEqual(
set(lsol),
set(lsol2),
"Error dimacs_frontier: solutions not different"
)
[docs] def test_solution_pruning(self):
"""Pruning a solution by trying to get a new solution with a smaller
number of active frontier places"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
prop = "p15INK4b and p21CIP1"
query = MCLSimpleQuery(None, None, prop)
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano_noclock_cmp.cal"
)
mcla.build_from_cadlang(filename)
# lsol: list<dimacs frontier solution>
lsol = mcla._MCLAnalyser__sq_dimacs_frontier_solutions(query, 8, 10)
small_sol = mcla.less_activated_solution(lsol)
# Count number of activated frontiers
activated_frontiers_old_method = 0
for varcod in small_sol.frontier_values:
if varcod > 0:
activated_frontiers_old_method += 1
activated_frontiers_1 = small_sol.nb_activated_frontiers
self.assertEqual(activated_frontiers_old_method, activated_frontiers_1)
# Check solution
# Reload frontiers (activated and unactivated)
# PS: quiet deprecated: usually, we just put negative values of frontiers
start = [[var] for var in small_sol.frontier_values]
query.dim_start = start
res = mcla.sq_is_satisfiable(query, 8)
self.assert_(res, 'Small sol is not a solution')
# Find if there are solutions when forcing unactivated fontiers
old_negative_fronts = [[var] for var in small_sol.frontier_values if var < 0]
negative_fronts = \
[[var] for var in
mcla.unfolder.frontiers_negative_values & small_sol.frontier_values]
assert set(it.chain(*negative_fronts)) == set(it.chain(*old_negative_fronts))
# In practice we just append the clause of unactivated frontiers
# But query.dim_start contains nothing but user settings (here it
# contains the status of the border places of the previous solution)
query.dim_start = negative_fronts
res = mcla.sq_is_satisfiable(query, 8)
self.assert_(res, 'No solution with same unactivated places')
# Prune small_sol
pruned = mcla._MCLAnalyser__prune_frontier_solution(small_sol, query, 8)
# Compare sizes
self.assertLessEqual(
pruned.nb_activated_frontiers,
activated_frontiers_1,
msg="Prune did not reduce nb of activated places"
)
[docs] def test_mac_no_clock(self):
"""
test mac without clocks
"""
# solving
rep = ErrorRep()
mcla = MCLAnalyser(rep)
prop = 'p15INK4b and p21CIP1'
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano_noclock_cmp.cal"
)
mcla.build_from_cadlang(filename)
mcla.unfolder.set_stats()
query = MCLSimpleQuery(None, None, prop)
mac_list = tuple(mcla.mac_search(query, 10))
print(mac_list)
found = len(mac_list)
res = found == 8
self.assert_(res, 'Incorrect number of mac')
expected = [
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'importinbeta', 'MIZ_1', 'DAB2', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'MIZ_1', 'DAB2', 'TGFBfamily__dimer___active_exCellRegion', 'NUP214', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'MIZ_1', 'DAB2', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'NUP153', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'MIZ_1', 'DAB2', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'importinalpha', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'FOXO1_3a_4_active_nucl', 'DAB2', 'CEBPB', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'NUP153', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF', 'FOXG1'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'importinbeta', 'FOXO1_3a_4_active_nucl', 'DAB2', 'CEBPB', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF', 'FOXG1'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'FOXO1_3a_4_active_nucl', 'DAB2', 'CEBPB', 'TGFBfamily__dimer___active_exCellRegion', 'NUP214', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF', 'FOXG1'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'FOXO1_3a_4_active_nucl', 'DAB2', 'CEBPB', 'TGFBfamily__dimer___active_exCellRegion', 'TGFBR2__dimer___active_intToMb', 'Axin_SMAD3', 'SMAD4_cy', 'importinalpha', 'SMAD2_3', 'FKBP12_TGFBR1__dimer___inactive_intToMb', 'CTGF', 'FOXG1'})
]
found = [front_sol.activated_frontier for front_sol in mac_list]
print("found test_mac_no_clock", found)
# Forget the order with sets...
res = set(expected) == set(found)
self.assert_(res, 'Incorrect list of MAC (no clock)')
[docs] def test_mac_clock(self):
"""
mac with clocks
"""
# solving
rep = ErrorRep()
mcla = MCLAnalyser(rep)
prop = 'p15INK4b'
#p = "C3"
filename = pkg_resources.resource_filename(
__name__, # package name
"../../guard_transitions/translators/tests/tgf_cano_cmp.cal"
)
mcla.build_from_cadlang(filename)
#mcla.build_from_cadlang("examples/delay2.cal")
#mcla.unfolder.set_stats()
query = MCLSimpleQuery(None, None, prop)
# return iterable of FrontierSolution objects
mac_list = tuple(mcla.mac_search(query, 10))
expected = [
frozenset({'SP1', 'SMAD4_nucl', 'MIZ_1', 'TGFB_TGFBR2_TGFBR1_DAB2_active_intToMb', 'SMAD2_3'}),
frozenset({'SMAD4_nucl', 'FOXO1_3a_4_active_nucl', 'CEBPB', 'TGFB_TGFBR2_TGFBR1_DAB2_active_intToMb', 'SMAD2_3', 'FOXG1'}),
frozenset({'SP1', 'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'Caveolin_1', 'MIZ_1', 'TRAP_1_TGFBR1__dimer___inactive_intToMb', 'AP2B2', 'TGFBR2__dimer___active_intToMb', 'PML_SARA_SMAD2_3_earlyendosome', 'TGFBfamily__dimer___active_exCellRegion', 'SMAD7_SMURF1_2_nucl', 'CTGF'}),
frozenset({'betaglycan__dimer___intToMb', 'SMAD4_nucl', 'Caveolin_1', 'FOXO1_3a_4_active_nucl', 'TRAP_1_TGFBR1__dimer___inactive_intToMb', 'AP2B2', 'CEBPB', 'TGFBR2__dimer___active_intToMb', 'PML_SARA_SMAD2_3_earlyendosome', 'TGFBfamily__dimer___active_exCellRegion', 'SMAD7_SMURF1_2_nucl', 'CTGF', 'FOXG1'})
]
found = [front_sol.activated_frontier for front_sol in mac_list]
print("found test_mac_no_clock", found)
# Forget the order with sets...
res = set(expected) == set(found)
self.assert_(res, 'Incorrect list of MAC (clock)')
[docs] def test_valid_simul_delay(self):
"""
Test simulation of the delay example
"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.cal"
)
mcla.build_from_cadlang(filename)
st_prop = None
inv_prop = None
f_prop = "C3 and C4"
query = MCLSimpleQuery(st_prop, inv_prop, f_prop)
# lsol: list<RawSolution>
lsol = mcla.sq_solutions(query, 4, 1, mcla.unfolder.frontier_values)
sol = lsol[0]
f_sol = FrontierSolution.from_raw(sol)
# independant simulation
chm = ChartModel(" ")
chm.build_from_cadlang(filename, rep)
sim = ChartSimulator()
sim.build(chm, True, rep)
sim.simul_init_places(f_sol.activated_frontier)
sim.set_act_input_stream(f_sol.ic_sequence)
sim.set_reachable_prop(f_prop)
while True:
try:
sim.simul_step()
except SimulStopException as exc:
exc_txt = exc.__str__()
self.assert_(exc_txt == 'STOP', "Error: " + exc_txt)
break
# test if property reached
res = sim.check_reachable_property()
self.assert_(res, "Property not reached")
[docs] def test_mac_delay_save(self):
"""Test save on the delay example
x_file content:
A1 B1 C1
%
% h2
%
%
"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay1.cal"
)
mcla.build_from_cadlang(filename)
f_prop = "C3 and C4"
query = MCLSimpleQuery(None, None, f_prop)
macwic = tuple(mcla.mac_search(query, 10))
# Just save the first solution
with open(DIR_LOGS + "x_file", 'w') as f_out:
# print macwic[0].activated_frontier
# print macwic[0].ic_sequence
# print '---------------'
macwic[0].save(f_out)
# Note: use cadbiom_cmd/tools/solutions.py functions to reload frontiers
# Just reload the first solution
r_front = FrontierSolution.from_file(DIR_LOGS + "x_file")
expected = {'A1', 'B1', 'C1'}
assert r_front.activated_frontier == expected, "Bad activated frontiers from file"
expected = ['%', '% h2', '%', '%']
assert r_front.ic_sequence == expected, "Bad ic_sequence from file"
assert r_front.current_step == 4, "Bad max steps from file"
res = macwic[0].activated_frontier == r_front.activated_frontier
res = res and macwic[0].ic_sequence == r_front.ic_sequence
res = res and r_front == macwic[0]
self.assert_(res, "Frontier solutions differ after read")
os.remove(DIR_LOGS + "x_file")
[docs] def test_mcl_query_merge(self):
"""Test zone for some MCLSimpleQuery merge functions used in
MCLAnalyser.is_strong_activator()
"""
## Setup
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay3.cal"
)
mcla.build_from_cadlang(filename)
f_prop = "C3 and C4"
query = MCLSimpleQuery(None, None, f_prop)
frontier_sols = tuple(mcla.mac_search(query, 10))
## Begin tests
query_1 = MCLSimpleQuery.from_frontier_sol_same_timing(frontier_sols[0], mcla.unfolder)
# Test interpretation of activated_frontier into human readable format
expected = 'A1 and C1 and B1'
assert query_1.start_prop == expected
# Test interpretation of ic_sequence into variant property
expected = ['', 'h2', '', '']
assert query_1.variant_prop == expected
# Test interpretation of activated_frontier into start property in DIMACS format
expected = [[-2]]
assert query_1.dim_start == expected
assert query_1.final_prop == None
assert query_1.inv_prop == None
inv_prop = 'not(' + query.final_prop + ')'
query_2 = MCLSimpleQuery(None, inv_prop, None)
expected = "not(C3 and C4)"
assert query_2.inv_prop == expected
# Test merge of queries
query_1 = query_2.merge(query_1)
#(None, 'not(C3 and C4)', 'A1 and C1 and B1', ['', 'h2', '', '']
expected = ['', 'h2', '', '']
assert query_1.variant_prop == expected
# Test merge of queries with both variant properties
# 2 empty, 1 empty and not the other, none empty
query_1.dim_variant = []
query_1.variant_prop = ['h2', 'h2', '', '']
query_2.variant_prop = ['', 'h2', '', 'h2']
query_1 = query_2.merge(query_1)
expected = ['h2', 'h2 and h2', '', 'h2']
assert query_1.variant_prop == expected
[docs] def test_mac_inhibitor(self):
"""
test
[A1, B1, C1] not strong activator, D is a strong inhibitor
"""
rep = ErrorRep()
mcla = MCLAnalyser(rep)
filename = pkg_resources.resource_filename(
__name__, # package name
"examples/delay3.cal"
)
mcla.build_from_cadlang(filename)
f_prop = "C3 and C4"
query = MCLSimpleQuery(None, None, f_prop)
frontier_sols = tuple(mcla.mac_search(query, 10))
exp_act_front = {'A1', 'C1', 'B1'}
obt_act_front = frontier_sols[0].activated_frontier
res = exp_act_front == obt_act_front
self.assert_(res, "Bad mac frontier solution")
exp_timing = ["%", "% h2", "%", "%"]
res = lit_subsol_equal(exp_timing, frontier_sols[0].ic_sequence)
self.assert_(res, "Bad mac timing solution")
# Strong activator search
# return True
res = mcla.is_strong_activator(frontier_sols[0], query)
print(res)
# it is not a strong activator
# Refactor Note:
# switch to res instead of not res; i think there is a logical inversion here
self.assert_(res, "Not a strong activator")
# Get FrontierSolutions
inhib = mcla.mac_inhibitor_search(frontier_sols[0], query, 10)
print('INHIB: found', len(inhib))
for isol in inhib:
print("Inhib sol:", isol)
# Solution 1: {'D', 'A1', 'C1', 'B1'} or {'A1', 'C1', 'B1'}
exp_act_front1 = {'D', 'A1', 'C1', 'B1'}
obt_act_front = inhib[0].activated_frontier
obt_timing = inhib[0].ic_sequence
res = exp_act_front1 == obt_act_front
# 2 possible timings
if res:
# not used
exp_timing = ["%", "% h2", "%", "%"]
res = res and lit_subsol_equal(exp_timing, obt_timing)
self.assert_(res, "Bad inhib timing solution")
else:
# Condition used (sol: {'A1', 'C1', 'B1'})
res = exp_act_front == obt_act_front
exp_timing = ["% h2", "% h2", "%", "%"]
res = res and lit_subsol_equal(exp_timing, obt_timing)
self.assert_(res, "Bad inhib timing solution")
# Solution 2: {'D', 'A1', 'C1', 'B1'} or {'A1', 'C1', 'B1'} (different of sol1)
# obt_act_front = inhib[1].activated_frontier
# obt_timing = inhib[1].ic_sequence
# res = exp_act_front == obt_act_front
# # 2 possible timings
# if res:
# exp_timing = ["% h2", "% h2", "%", "%"]
# res = res and lit_subsol_equal(exp_timing, obt_timing)
# self.assert_(res, "Bad inhib timing solution")
# else:
# res = exp_act_front1 == obt_act_front
# exp_timing = ["%", "% h2", "%", "%"]
# res = res and lit_subsol_equal(exp_timing, obt_timing)
# self.assert_(res, "Bad inhib timing solution")
# Strong inhibitor search
# return False
res = mcla.is_strong_inhibitor(inhib[0], query)
query_1 = MCLSimpleQuery.from_frontier_sol_new_timing(inhib[0], mcla.unfolder)
found = query_1.start_prop
assert "A1 and C1 and B1" == found
found = query_1.inv_prop
assert found == None
found == query_1.final_prop
assert found == None
found = query_1.variant_prop
assert found == ['not (h2)', 'not (h2)', '', '']
# Inactivation of of other frontier places (not used in the solution)
found = query_1.dim_start
assert found == [[-2]] # D
print("is strong inhibitor ?", res)
# it is a strong inhibitor
# Refactor Note:
# Switch to not res instead of res; i think there is a logical inversion here
self.assert_(not res, "Bad answer - strong inhibitor")