Exemplo n.º 1
0
    def _unsatisfiable_contingencies(self) -> List[Tuple[Reaction, str]]:
        unsatisfiable = []

        for reaction in self.reactions:
            contingencies = self.s_contingencies_for_reaction(reaction)

            total_set = UniversalSet()  # type: Set[State]
            for contingency in contingencies:
                total_set = Intersection(total_set, contingency.to_venn_set())  # pylint: disable=redefined-variable-type

            solutions = total_set.calc_solutions()
            if len(solutions) == 0:
                unsatisfiable.append(
                    (reaction, 'Zero consistent solutions found.'))

            local_unsatisfiables = []
            at_least_one_consistent_soln = False

            for solution in solutions:
                trues = [state for state, val in solution.items() if val]
                if any(
                        state.is_mutually_exclusive_with(other)
                        for state, other in product(trues, trues)):
                    state, other = next(
                        (state, other)
                        for state, other in product(trues, trues)
                        if state.is_mutually_exclusive_with(other))
                    local_unsatisfiables.append(
                        (reaction,
                         'State {} mutually exclusive with {}.'.format(
                             str(state), str(other))))
                else:
                    at_least_one_consistent_soln = True

            if not at_least_one_consistent_soln:
                unsatisfiable += local_unsatisfiables

        return unsatisfiable
Exemplo n.º 2
0
    def _unsatisfiable_contingencies(self) -> List[Tuple[Reaction, str]]:
        """Determines the contingencies that are not satisfiable, returns a list of (Reaction, str) where
        the str contains the human-readable reason for the contingency not being satisfiable."""
        unsatisfiable = []

        for reaction in self.reactions:
            contingencies = self.s_contingencies_for_reaction(reaction)

            # Make sure the contingency does not contain the states produced / consumed by the reaction.
            states = (state for contingency in contingencies
                      for state in contingency.effector.states)

            for state in states:
                # We need to be talking about the states mentioning the reactants.
                if not all(spec.struct_index in (0, 1)
                           for spec in state.specs):
                    continue

                if any(count > 1
                       for count in Counter(reaction.components_rhs).values()):
                    continue

                # States appear non-structured in the '.produced_states' etc. properties.
                state = state.to_non_structured()

                if state in reaction.produced_states and state not in reaction.synthesised_states:
                    unsatisfiable.append(
                        (reaction,
                         'Produced state {} appears in contingencies'.format(
                             str(state))))
                if state in reaction.consumed_states and state not in reaction.degraded_states:
                    unsatisfiable.append(
                        (reaction,
                         'Consumed state {} appears in contingencies'.format(
                             str(state))))

            # Make sure at least one solution is there (this might still contain mutually exclusive states)
            total_set = UniversalSet()  # type: Set[State]
            for contingency in contingencies:
                total_set = Intersection(total_set, contingency.to_venn_set())  # pylint: disable=redefined-variable-type

            solutions = total_set.calc_solutions()
            if len(solutions) == 0:
                unsatisfiable.append(
                    (reaction, 'Zero consistent solutions found.'))

            # Make sure that at least one solution doesn't contain mutually exclusive states.
            local_unsatisfiables = []
            at_least_one_consistent_soln = False

            for solution in solutions:
                trues = [state for state, val in solution.items() if val]
                if any(
                        state.is_mutually_exclusive_with(other)
                        for state, other in product(trues, trues)):
                    state, other = next(
                        (state, other)
                        for state, other in product(trues, trues)
                        if state.is_mutually_exclusive_with(other))
                    local_unsatisfiables.append(
                        (reaction,
                         'State {} mutually exclusive with {}.'.format(
                             str(state), str(other))))
                else:
                    at_least_one_consistent_soln = True

            if not at_least_one_consistent_soln:
                unsatisfiable += local_unsatisfiables

        return unsatisfiable