def explanations_implication(self, other: Comparable, context: Optional[ContextRegister] = None ) -> Iterator[ContextRegister]: r""" Generate :class:`.ContextRegister`\s that cause `self` to imply `other`. If self is `absent`, then generate a ContextRegister from other's point of view and then swap the keys and values. """ if context is None: context = ContextRegister() if not isinstance(other, Factor): raise TypeError( f"{self.__class__} objects may only be compared for " + "implication with other Factor objects or None.") if isinstance(other, self.__class__): if not self.__dict__.get("absent"): if not other.__dict__.get("absent"): yield from self._implies_if_present(other, context) else: yield from self._contradicts_if_present(other, context) else: if other.__dict__.get("absent"): test = other._implies_if_present(self, context.reversed()) else: test = other._contradicts_if_present( self, context.reversed()) yield from (register.reversed() for register in test)
def explanations_contradiction(self, other: Comparable, context: Optional[ContextRegister] = None ) -> Iterator[ContextRegister]: """ Test whether ``self`` :meth:`implies` the absence of ``other``. This should only be called after confirming that ``other`` is not ``None``. :returns: ``True`` if self and other can't both be true at the same time. Otherwise returns ``False``. """ if context is None: context = ContextRegister() if not isinstance(other, Factor): raise TypeError( f"{self.__class__} objects may only be compared for " + "contradiction with other Factor objects or None.") if isinstance(other, self.__class__): if not self.__dict__.get("absent"): if not other.__dict__.get("absent"): yield from self._contradicts_if_present(other, context) else: yield from self._implies_if_present(other, context) elif self.__dict__.get("absent"): if not other.__dict__.get("absent"): test = other._implies_if_present(self, context.reversed()) else: test = other._contradicts_if_present( self, context.reversed()) yield from (register.reversed() for register in test)
def partial_explanations_union( self, other: Comparable, context: ContextRegister) -> Iterator[ContextRegister]: for likely in self.likely_contexts(other, context): partial = self + other.new_context(likely.reversed()) if partial.internally_consistent(): yield likely
def _likely_context_from_implication( self, other: Comparable, context: ContextRegister) -> Optional[ContextRegister]: new_context = None if self.implies(other, context=context) or other.implies( self, context=context.reversed()): new_context = self._update_context_from_factors(other, context) if new_context and new_context != context: return new_context return None
def explanations_implied_by(self, other: Comparable, context: Optional[ContextRegister] = None ) -> Iterator[Explanation]: context = context or ContextRegister() if isinstance(other, Opinion): other = other.holdings if isinstance(other, HoldingGroup): yield from other.explanations_implication( self.holdings, context=context.reversed()) if isinstance(other, Rule): other = Holding(rule=other) if isinstance(other, Holding): yield from self.implied_by_holding(other, context)
def explanations_contradiction( self, other: Comparable, context: Optional[ContextRegister] = None, ) -> Iterator[Explanation]: """Yield contexts that would result in a contradiction between self and other.""" if isinstance(other, Rule): other = Holding(rule=other) if isinstance(other, Holding): for self_holding in self.holdings: for explanation in self_holding.explanations_contradiction( other, context): yield explanation elif isinstance(other, self.__class__): for self_holding in self.holdings: for other_holding in other.holdings: for explanation in self_holding.explanations_contradiction( other_holding, context): yield explanation elif hasattr(other, "explanations_contradiction"): yield from other.explanations_contradiction(self) else: raise TypeError(f"'Contradicts' test not implemented for types " + f"{self.__class__} and {other.__class__}.")
def explanations_implication( self, other: Comparable, context: Optional[ContextRegister] = None ) -> Iterator[Union[ContextRegister, Explanation]]: """Yield contexts that would result in self implying other.""" if isinstance(other, Rule): other = Holding(rule=other) if isinstance(other, Holding): for self_holding in self.holdings: for explanation in self_holding.explanations_implication( other, context): yield explanation elif isinstance(other, self.__class__): yield from self.holdings.explanations_implication(other.holdings, context=context) elif hasattr(other, "explanations_implication"): if context: context = context.reversed() yield from other.explanations_implication(self, context=context) else: raise TypeError( f"'Implies' test not implemented for types {self.__class__} and {other.__class__}." )