예제 #1
0
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))))
예제 #2
0
def test_intersection_properties(sets: List[Set]) -> None:
    for x in sets:
        assert EmptySet().is_equivalent_to(Intersection(x, Complement(x)))
        assert EmptySet().is_equivalent_to(Intersection(Complement(x), x))

        assert EmptySet().is_equivalent_to(Intersection(EmptySet(), x))
        assert EmptySet().is_equivalent_to(Intersection(x, EmptySet()))

        assert x.is_equivalent_to(Intersection(UniversalSet(), x))
        assert x.is_equivalent_to(Intersection(x, UniversalSet()))

        assert x.is_equivalent_to(Intersection(x, x))
예제 #3
0
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)))
    ]
예제 #4
0
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
예제 #5
0
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))))
예제 #6
0
        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))
예제 #7
0
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
예제 #8
0
        def _effector_to_vennset(eff: Effector, con_type: Optional[ContingencyType]=None) -> VennSet:
            """
            Preprocessing effector. Save information in leafs.

            Note:
                We need the contingency information later on in the process. Since, this information is lost during the
                calculation of the disjunctive normal form we have to add it beforehand. For this we say an inhibiting
                contingency is the complement of everything afterwards.

                The contingency type is only needed at the beginning of the recursion step.

            Args:
                eff: rxncon Effector.
                cont_type: Contingency type.

            Returns:
                Return VennSet

            Raises:
                AssertionError if the eff is not an effector.

            """

            if isinstance(eff, StateEffector):
                if con_type is ContingencyType.inhibition:
                    return Complement(ValueSet(eff.expr.to_non_structured()))
                return ValueSet(eff.expr.to_non_structured())
            elif isinstance(eff, NotEffector):
                if con_type is ContingencyType.inhibition:
                    return _effector_to_vennset(eff.expr)
                return Complement(_effector_to_vennset(eff.expr))
            elif isinstance(eff, OrEffector):
                if con_type is ContingencyType.inhibition:
                    return Complement(VennUnion(*[_effector_to_vennset(expr) for expr in eff.exprs]))
                return VennUnion(*[_effector_to_vennset(expr) for expr in eff.exprs])
            elif isinstance(eff, AndEffector):
                if con_type is ContingencyType.inhibition:
                    return Complement(Intersection(*[_effector_to_vennset(expr) for expr in eff.exprs]))
                return Intersection(*[_effector_to_vennset(expr) for expr in eff.exprs])
            else:
                raise AssertionError
예제 #9
0
 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)))
예제 #10
0
    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)
예제 #11
0
    def to_venn_set(
            self,
            k_plus_strict: bool = False,
            k_minus_strict: bool = False,
            structured: bool = True,
            state_wrapper: Callable[[State],
                                    Any] = lambda x: x) -> VennSet[Any]:
        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

        if k_plus_strict:
            positive = (ContingencyType.requirement, ContingencyType.positive)
        else:
            positive = (ContingencyType.requirement, )  # type: ignore

        if k_minus_strict:
            negative = (ContingencyType.inhibition, ContingencyType.negative)
        else:
            negative = (ContingencyType.inhibition, )  # type: ignore

        if self.contingency_type in positive:
            return parse_effector(self.effector)
        elif self.contingency_type in negative:
            return Complement(parse_effector(self.effector))
        else:
            return UniversalSet()
예제 #12
0
    def to_venn_set(self, k_plus_strict: bool=False, k_minus_strict: bool=False, structured: bool=True,
                    state_wrapper: Callable[[State], Any]=lambda x: x) -> VennSet[Any]:
        """Returns a Venntastic Set object corresponding to the Contingency: requirements are put in a ValueSet,
        inhibitions in a ValueSet within a Complement. If `k_plus_strict` / `k_minus_strict`, then positive and
        negative Contingencies are translated into strict requirements resp. strict inhibitions. If `structured`
        is False, the structure information is discarded. Optionally all States can be wrapped in some other
        class by providing a `state_wrapper`."""
        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)))

        if k_plus_strict:
            positive = (ContingencyType.requirement, ContingencyType.positive)
        else:
            positive = (ContingencyType.requirement,)  # type: ignore

        if k_minus_strict:
            negative = (ContingencyType.inhibition, ContingencyType.negative)
        else:
            negative = (ContingencyType.inhibition,)  # type: ignore

        if self.contingency_type in positive:
            return parse_effector(self.effector)
        elif self.contingency_type in negative:
            return Complement(parse_effector(self.effector))
        else:
            return UniversalSet()
예제 #13
0
 def to_venn_set(self) -> VennSet[State]:
     return Intersection(
         *(ValueSet(s) for s in self.true_states()),
         *(Complement(ValueSet(s)) for s in self.false_states()))
예제 #14
0
    def calc_state_rules() -> None:
        """
        Calculates the rules of state targets.

        Note:
            The factor for a state target has the from:
            synthesis OR (components AND NOT degradation AND ((production AND sources) OR (state AND NOT (consumption AND sources))))

        Returns:
            A list of updating rules for states.

      """
        def reaction_with_sources(
                reaction_target: ReactionTarget) -> VennSet[Target]:
            """
            Calculates the source states of the respective reaction target

            Args:
                reaction_target: Reaction of the boolean model producing, consuming, degrading or synthesising state targets.

            Returns:
                VennSet of the reaction target and its source states

            """
            sources = Intersection(
                *(ValueSet(x) for x in reaction_target.consumed_targets))
            return Intersection(ValueSet(reaction_target), sources)

        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 synthesis_factor(
                state_target: StateTarget) -> VennSet[ReactionTarget]:
            return Union(*(ValueSet(x) for x in reaction_targets
                           if x.synthesises(state_target)))

        def component_factor(
                state_target: StateTarget) -> VennSet[StateTarget]:
            return Intersection(*(component_presence_factor[x]
                                  for x in state_target.components))

        def degradation_factor(
                state_target: StateTarget) -> VennSet[ReactionTarget]:
            return Complement(
                Union(*(ValueSet(x) for x in reaction_targets
                        if x.degrades(state_target))))

        for state_target in state_targets:
            synt_fac = synthesis_factor(state_target)
            comp_fac = component_factor(state_target)
            degr_fac = degradation_factor(state_target)

            prod_facs = []  # type: List[VennSet]
            cons_facs = []  # type: List[VennSet]

            for reaction_target in (target for target in reaction_targets
                                    if target.produces(state_target)):
                if smoothing_strategy == SmoothingStrategy.no_smoothing:
                    prod_facs.append(reaction_with_sources(reaction_target))
                elif smoothing_strategy == SmoothingStrategy.smooth_production_sources:
                    smoothed_prod_facs = []
                    for primary_source in reaction_target.consumed_targets:
                        smooth_source = Union(
                            ValueSet(primary_source),
                            Intersection(
                                Union(*(reaction_with_sources(rxn)
                                        for rxn in reaction_targets
                                        if rxn.produces(primary_source))),
                                Union(degradation_factor(primary_source),
                                      indirect_synth_path(primary_source))))

                        smoothed_prod_facs.append(smooth_source)
                    prod_facs.append(
                        Intersection(ValueSet(reaction_target),
                                     *smoothed_prod_facs))
                else:
                    raise AssertionError

            for reaction_target in (target for target in reaction_targets
                                    if target.consumes(state_target)):
                cons_facs.append(
                    Complement(reaction_with_sources(reaction_target)))

            tot_prod_fac = Intersection(
                comp_fac, Union(*prod_facs),
                Union(degr_fac, indirect_synth_path(state_target)))
            tot_cons_fac = Intersection(comp_fac, ValueSet(state_target),
                                        Intersection(*cons_facs), degr_fac)

            state_rules.append(
                UpdateRule(
                    state_target,
                    Union(synt_fac, tot_prod_fac,
                          tot_cons_fac).to_simplified_set()))
예제 #15
0
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))
예제 #16
0
 def degradation_factor(
         state_target: StateTarget) -> VennSet[ReactionTarget]:
     return Complement(
         Union(*(ValueSet(x) for x in reaction_targets
                 if x.degrades(state_target))))
예제 #17
0
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)))
예제 #18
0
def test_complement_squares_to_no_op(sets: List[Set]) -> None:
    for x in sets:
        assert x.is_equivalent_to(Complement(Complement(x)))
예제 #19
0
def test_de_morgan_s_identities(sets: List[Set]) -> None:
    for x, y in itt.product(sets, sets):
        assert Intersection(Complement(x), Complement(y)).is_equivalent_to(Complement(Union(x, y)))
        assert Union(Complement(x), Complement(y)).is_equivalent_to(Complement(Intersection(x, y)))