def test_disjunctive_union(sets: List[Set]) -> None: for x, y in itt.product(sets, sets): assert DisjunctiveUnion(x, y).is_equivalent_to(Union(Difference(x, y), Difference(y, x))) assert Union(Difference(x, y), Difference(y, x)).is_equivalent_to(DisjunctiveUnion(x, y)) assert DisjunctiveUnion(x, y).is_equivalent_to(Difference(Union(x, y), Intersection(x, y))) assert Difference(Union(x, y), Intersection(x, y)).is_equivalent_to(DisjunctiveUnion(x, y))
def test_superset_subset_for_nested_unions() -> None: x = ValueSet(1) y = ValueSet(2) z = ValueSet(3) xy = Union(x, y) yz = Union(y, z) xz = Union(x, z) xyz = Union(x, Union(y, z)) for a in [x, y, z, xy, yz, xz, xyz]: for b in [x, y, z, xy, yz, xz, xyz]: if a != b: assert not a.is_equivalent_to(b) assert xyz.is_superset_of(x) assert xyz.is_superset_of(y) assert xyz.is_superset_of(z) assert xyz.is_superset_of(xy) assert xyz.is_superset_of(yz) assert xyz.is_superset_of(xz) assert x.is_subset_of(xyz) assert y.is_subset_of(xyz) assert z.is_subset_of(xyz) assert xy.is_subset_of(xyz) assert yz.is_subset_of(xyz) assert xz.is_subset_of(xyz)
def synthesis_factor(state_target: StateTarget) -> VennSet[Target]: fac = EmptySet() # type: VennSet[Target] for rxn in (x for x in reaction_targets if x.synthesises(state_target)): fac = Union(fac, ValueSet(rxn)) for prod_rxn in (x for x in reaction_targets if x.produces(state_target)): sources = [] for source in prod_rxn.consumed_targets: sources.append( [source] + [x for x in reaction_targets if x.synthesises(source)]) for source_combi in product(*sources): # At least one source should be synthesised. if all(isinstance(x, StateTarget) for x in source_combi): continue assert any( isinstance(x, ReactionTarget) and x.synthesised_targets for x in source_combi) fac = Union( fac, Intersection(ValueSet(prod_rxn), *(ValueSet(x) for x in source_combi))) return fac
def test_nary_sets_constructor() -> None: assert Union() == EmptySet() assert Intersection() == UniversalSet() assert DisjunctiveUnion() == EmptySet() assert Union(venn_from_str('1', int)).is_equivalent_to(venn_from_str('1', int)) assert Intersection(venn_from_str('1', int)).is_equivalent_to(venn_from_str('1', int)) assert DisjunctiveUnion(venn_from_str('1', int)).is_equivalent_to(venn_from_str('1', int))
def sigma(state_target: StateTarget, level: int) -> VennSet[Target]: prod_cons_factor = Union( pi(state_target, level), Intersection(ValueSet(state_target), Complement(kappa(state_target, level)))) return Union( synthesis_factor(state_target), Intersection(degradation_factor(state_target), component_factor(state_target), prod_cons_factor))
def sets() -> List[Set]: return [ EmptySet(), ValueSet(1), UniversalSet(), Union(ValueSet(1), ValueSet(2)), Intersection(ValueSet(1), ValueSet(2)), Intersection(ValueSet(1), Complement(ValueSet(2))), Union(Intersection(ValueSet(1), ValueSet(2)), ValueSet(3)), Union(Intersection(ValueSet(1), ValueSet(2)), Intersection(ValueSet(3), ValueSet(4))), Union(Complement(Union(ValueSet(1), Complement(ValueSet(2)))), Intersection(ValueSet(3), ValueSet(4))) ]
def calc_component_presence_factors( ) -> Tuple[Dict[Spec, VennSet[StateTarget]], List[ComponentStateTarget]]: """The form of the component presence factor is: (state_a1 | ... | state_an) & (state_b1 | ... | state_bm) & ... Mutually exclusive states are combined by boolean OR (state_a1 ... state_an , state_b1 ... state_bm). These ORs are then combines with ANDs. If a component does not carry states, this will be a ComponentStateTarget. """ component_state_targets = [] # type: List[ComponentStateTarget] component_to_factor = {} # type: Dict[Spec, VennSet[StateTarget]] for component in rxncon_sys.components(): grouped_states = rxncon_sys.states_for_component_grouped(component) # component is not part of any state if not grouped_states.values(): component_state_targets.append(ComponentStateTarget(component)) component_to_factor[component] = ValueSet( ComponentStateTarget(component)) # component is part of at least one state else: # mutually exclusive states are combined by OR component_to_factor[component] = \ Intersection( *(Union(*(ValueSet(StateTarget(x)) for x in group)) for group in grouped_states.values())) return component_to_factor, component_state_targets
def test_with_connectivity_constraints() -> None: first_states = [ ValueSet(state_from_str(x)) for x in ('A@0_[ac]--C@2_[ca]', 'C@2_[ce]--E@4_[ec]') ] second_states = [ ValueSet(state_from_str(x)) for x in ('B@1_[bd]--D@3_[db]', 'D@3_[df]--F@5_[fd]') ] contingency = Union(Intersection(*first_states), Intersection(*second_states)) connected = with_connectivity_constraints(contingency) print(connected) print('Not connected:') for soln in contingency.calc_solutions(): print(soln) print() print('Connected:') for soln in connected.calc_solutions(): print(soln)
def with_connectivity_constraints(cont_set: VennSet[State]) -> VennSet: complexes = calc_connected_complexes(cont_set.values) complex_constraints = [] for complex in complexes: # pylint: disable=redefined-builtin state_paths = calc_state_paths(complex) constraint = UniversalSet() # type: VennSet[State] for state in complex: assert not state.is_global, 'Global state {} appearing in connectivity constraints.'.format(state) if any(path == [] for path in state_paths[state]): continue state_constraints = [Complement(ValueSet(state))] # type: List[VennSet[State]] for path in state_paths[state]: state_constraints.append(Intersection(*(ValueSet(x) for x in path))) constraint = Intersection(constraint, Union(*state_constraints)) # pylint: disable=redefined-variable-type complex_constraints.append(constraint.to_simplified_set()) if complex_constraints: LOGGER.debug('{} : Complex constraints {}'.format(current_function_name(), ' XOR '.join(str(x) for x in complex_constraints))) return Intersection(cont_set, DisjunctiveUnion(*complex_constraints)) else: return cont_set
def test_is_equivalent_to() -> None: assert UniversalSet().is_equivalent_to(UniversalSet()) assert EmptySet().is_equivalent_to(EmptySet()) assert not UniversalSet().is_equivalent_to(ValueSet(1)) assert not ValueSet(1).is_equivalent_to(UniversalSet()) assert UniversalSet().is_equivalent_to(Union(ValueSet(1), Complement(ValueSet(1))))
def pi(state_target: StateTarget, level: int) -> VennSet[Target]: res = EmptySet() # type: VennSet[Target] for r in (x for x in reaction_targets if x.produces(state_target)): rxn_term = ValueSet(r) # type: VennSet[Target] for s in (x for x in state_targets if r.consumes(x)): if r.degraded_targets: state_term = ValueSet(s) # type: VennSet[Target] else: state_term = Intersection(ValueSet(s), degradation_factor(s)) for l in range(level): state_term = Union(state_term, sigma(s, level - 1)) rxn_term = Intersection(rxn_term, state_term) res = Union(res, rxn_term) return res
def indirect_synth_path( state_target: StateTarget) -> VennSet[ReactionTarget]: my_brothers = [ x for x in state_targets if state_target.shares_component_with(x) and x != state_target ] return Union(*(ValueSet(rxn) for state in my_brothers for rxn in reaction_targets if rxn.synthesises(state)))
def test_union_properties(sets: List[Set]) -> None: for x in sets: assert UniversalSet().is_equivalent_to(Union(x, Complement(x))) assert UniversalSet().is_equivalent_to(Union(Complement(x), x)) assert Union(x, Complement(x)).is_equivalent_to(UniversalSet()) assert Union(Complement(x), x).is_equivalent_to(UniversalSet()) assert x.is_equivalent_to(Union(EmptySet(), x)) assert x.is_equivalent_to(Union(x, EmptySet())) assert UniversalSet().is_equivalent_to(Union(UniversalSet(), x)) assert UniversalSet().is_equivalent_to(Union(x, UniversalSet())) assert x.is_equivalent_to(Union(x, x))
def test_parser() -> None: assert venn_from_str('1 & 2', int).is_equivalent_to( Intersection(ValueSet(1), ValueSet(2))) assert venn_from_str('1 & 2', str).is_equivalent_to( Intersection(ValueSet('1'), ValueSet('2'))) assert venn_from_str('( 1 | 2 ) & 3', int).is_equivalent_to( Intersection(ValueSet(3), Union(ValueSet(1), ValueSet(2)))) assert venn_from_str('~ 1', int).is_equivalent_to(Complement(ValueSet(1))) assert venn_from_str('~( 1 | 2 )', int).is_equivalent_to( Intersection(Complement(ValueSet(1)), Complement(ValueSet(2))))
def venn_from_effector(effector: Effector) -> VennSet[State]: if isinstance(effector, StateEffector): return ValueSet(effector.expr) elif isinstance(effector, AndEffector): return Intersection(*(venn_from_effector(x) for x in effector.exprs)) elif isinstance(effector, OrEffector): return Union(*(venn_from_effector(x) for x in effector.exprs)) elif isinstance(effector, NotEffector): return Complement(venn_from_effector(effector.expr)) else: raise AssertionError
def kappa(state_target: StateTarget, level: int) -> VennSet[Target]: res = EmptySet() # type: VennSet[Target] for r in (x for x in reaction_targets if x.consumes(state_target)): rxn_term = ValueSet(r) # type: VennSet[Target] for s in (x for x in state_targets if r.consumes(x)): rxn_term = Intersection(rxn_term, ValueSet(s), degradation_factor(s)) res = Union(res, rxn_term) return res
def parse_effector(eff: Effector) -> VennSet: if isinstance(eff, StateEffector): if structured: return ValueSet(state_wrapper(eff.expr)) else: return ValueSet(state_wrapper(eff.expr.to_non_structured())) elif isinstance(eff, NotEffector): return Complement(parse_effector(eff.expr)) elif isinstance(eff, OrEffector): return Union(*(parse_effector(x) for x in eff.exprs)) elif isinstance(eff, AndEffector): return Intersection(*(parse_effector(x) for x in eff.exprs)) else: raise AssertionError('Unknown Effector {}'.format(str(eff)))
def test_superset_subset_for_flat_unions() -> None: assert Union(ValueSet(1), ValueSet(2)).is_superset_of(ValueSet(1)) assert Union(ValueSet(1), ValueSet(2)).is_superset_of(ValueSet(2)) assert not Union(ValueSet(1), ValueSet(2)).is_equivalent_to(ValueSet(1)) assert not Union(ValueSet(1), ValueSet(2)).is_equivalent_to(ValueSet(2)) assert ValueSet(1).is_subset_of(Union(ValueSet(1), ValueSet(2))) assert ValueSet(2).is_subset_of(Union(ValueSet(1), ValueSet(2)))
def update_state_rules_with_knockouts( knockout_strategy: KnockoutStrategy) -> None: if knockout_strategy == KnockoutStrategy.no_knockout: return elif knockout_strategy in (KnockoutStrategy.knockout_all_states, KnockoutStrategy.knockout_neutral_states): for state_rule in state_rules: assert isinstance(state_rule.target, StateTarget) if knockout_strategy == KnockoutStrategy.knockout_neutral_states and not state_rule.target.is_neutral: continue knockout_factor = Complement( Union(*(ValueSet(KnockoutTarget(component)) for component in state_rule.target.components))) state_rule.factor = Intersection(knockout_factor, state_rule.factor)
def update_state_rules_with_overexpressions( overexpression_strategy: OverexpressionStrategy) -> None: if overexpression_strategy == OverexpressionStrategy.no_overexpression: return elif overexpression_strategy in ( OverexpressionStrategy.overexpress_all_states, OverexpressionStrategy.overexpress_neutral_states): for state_rule in state_rules: assert isinstance(state_rule.target, StateTarget) if overexpression_strategy == OverexpressionStrategy.overexpress_neutral_states and not state_rule.target.is_neutral: continue overexpression_factor = Intersection( *(ValueSet(OverexpressionTarget(component)) for component in state_rule.target.components)) state_rule.factor = Union(overexpression_factor, state_rule.factor)
def with_connectivity_constraints(cont_set: VennSet[State], rxncon_system: RxnConSystem) -> VennSet: """Intersect the contingencies with the connectivity constraints.""" if cont_set.is_equivalent_to(UniversalSet()): return cont_set LOGGER.debug( 'with_connectivity_constraints : calculating molecular microstates') components = components_microstate(cont_set, rxncon_system) LOGGER.debug('with_connectivity_constraints : calculating complexes') complexes = bond_complexes(cont_set) constraints = [] for cx in complexes: constraints.append( Intersection(cx.to_venn_set(), *(components[cp] for cp in cx.components))) return Intersection(cont_set, Union(*constraints))
def calc_component_presence_factors( ) -> Tuple[Dict[Spec, VennSet[StateTarget]], List[ComponentStateTarget]]: """ Calculates the factors for components. Note: The form is: (state_a1 | ... | state_an) & (state_b1 | ... | state_bm) & ... Non-mutually exclusive states are combined by boolean AND (state_a and state_b). Mutually exclusive states are combined by boolean OR (state_a1 to state_an as well as state_b1 to state_bm). If a component is not part of any state of the system, the component will hold itself as ValueSet of a ComponentStateTarget. Mutates: component_to_factor: Mapping of components and VennSets, containing all the states the component is involved in. Returns: None """ component_state_targets = [] # type: List[ComponentStateTarget] component_to_factor = {} # type: Dict[Spec, VennSet[StateTarget]] for component in rxncon_sys.components(): grouped_states = rxncon_sys.states_for_component_grouped(component) # component is not part of any state if not grouped_states.values(): component_state_targets.append(ComponentStateTarget(component)) component_to_factor[component] = ValueSet( ComponentStateTarget(component)) # component is part of at least one state else: # mutually exclusive states are combined by OR component_to_factor[component] = \ Intersection(*(Union(*(ValueSet(StateTarget(x)) for x in group)) for group in grouped_states.values())) return component_to_factor, component_state_targets
def test_absolute_relative_complement_identities(sets: List[Set]) -> None: for x, y in itt.product(sets, sets): assert Intersection(x, Complement(y)).is_equivalent_to(Difference(x, y)) assert Union(Complement(x), y).is_equivalent_to(Complement(Difference(x, y)))
def test_simplifies() -> None: x1 = Intersection(ValueSet(1), ValueSet(2)) x2 = Intersection(ValueSet(1), Complement(ValueSet(2))) assert Union(x1, x2).is_equivalent_to(ValueSet(1))
def test_bond_complexes_ring_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[B]--B@2_[A]', 'B@2_[C]--C@3_[B]', 'C@3_[D]--D@4_[C]', 'D@4_[A]--A@0_[D]'))) assert len(bond_complexes(states)) == 11
def test_bond_complexes_calculation_unordered() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[C]--C@5_[A]', 'C@5_[B]--B@3_[C]', 'B@3_[D]--D@2_[B]'))) assert len(bond_complexes(states)) == 4
def test_bond_complexes_poly_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('R@1_[Y]--Y@2_[R]', 'Y@2_[Y]--Y@3_[Y]', 'Y@3_[R]--R@4_[Y]', 'R@4_[Ras]--Ras@5_[R]'))) assert len(bond_complexes(states)) == 5
def test_distributive_properties(sets: List[Set]) -> None: for x, y, z in itt.product(sets, sets, sets): assert Union(x, Intersection(y, z)).is_equivalent_to(Intersection(Union(x, y), Union(x, z))) assert Intersection(x, Union(y, z)).is_equivalent_to(Union(Intersection(x, y), Intersection(x, z)))
def test_bond_complexes_calculation() -> None: states = Union(*(ValueSet(state_from_str(x)) for x in ('A@0_[C]--C@2_[A]', 'C@2_[(r)]-{p}', 'A@0_[C]--0', 'C@2_[A]--0', 'C@2_[(r)]-{0}'))) assert len(bond_complexes(states)) == 3
def test_absorption_properties(sets: List[Set]) -> None: for x, y in itt.product(sets, sets): assert x.is_equivalent_to(Union(x, Intersection(x, y))) assert x.is_equivalent_to(Intersection(x, Union(x, y)))