コード例 #1
0
    def posit_holding(
        self,
        holding: Union[Holding, Rule],
        holding_anchors: Optional[Union[TextQuoteSelector,
                                        List[TextQuoteSelector]]] = None,
        named_anchors: Optional[TextLinkDict] = None,
        context: Optional[Sequence[Factor]] = None,
    ) -> None:
        r"""Record that this Opinion endorses specified :class:`Holding`\s."""
        if holding_anchors and not isinstance(holding_anchors, List):
            holding_anchors = [holding_anchors]
        if isinstance(holding, Rule):
            logger.warning("posit_holding was called with a Rule "
                           "that was automatically converted to a Holding")
            holding = Holding(rule=holding)

        if not isinstance(holding, Holding):
            raise TypeError('"holding" must be an object of type Holding.')

        if context:
            holding = holding.new_context(context, context_opinion=self)
        self.holding_anchors[holding].extend(holding_anchors or [])
        if named_anchors:
            for factor in (list(holding.recursive_factors) +
                           list(holding.enactments) +
                           list(holding.enactments_despite)):
                if hasattr(factor, "name") and factor.name in named_anchors:
                    for anchor in named_anchors[factor.name]:
                        if anchor not in self.factors[factor]:
                            self.factors[factor].append(anchor)
コード例 #2
0
 def implied_by_holding(self,
                        other: Holding,
                        context: ContextRegister = None) -> bool:
     context = context or ContextRegister()
     return all(
         other.implies(self_holding, context=context.reversed())
         for self_holding in self.holdings)
コード例 #3
0
 def implied_by_holding(self, other: Holding) -> Iterator[Explanation]:
     if all(other.implies(self_holding) for self_holding in self.holdings):
         yield Explanation(
             matches=[(other, self_holding)
                      for self_holding in self.holdings],
             operation=operator.ge,
         )
コード例 #4
0
ファイル: readers.py プロジェクト: mscarey/AuthoritySpoke
def extract_anchors_from_holding_record(
    record: List[RawHolding],
    client: Optional[Client] = None
) -> Tuple[List[Holding], List[EnactmentWithAnchors], List[TermWithAnchors],
           List[Dict[str, str]], ]:
    r"""
    Load a list of Holdings from JSON, with text links.

    :param record:
        a list of dicts representing holdings, in the JSON input format

    :param client:
        Legislice client for downloading missing fields from `record`

    :returns:
        a tuple of four objects containing holdings, terms, enactments,
        and anchors.
    """
    record_post_enactments, enactment_index = collect_enactments(record)
    if client:
        enactment_index_post_client = client.update_entries_in_enactment_index(
            enactment_index)
    else:
        enactment_index_post_client = enactment_index
    enactment_anchors, enactment_index_post_anchors = collect_anchors_from_index(
        enactment_index_post_client, "passage")

    enactment_result = []
    for anchor in enactment_anchors:
        anchor["passage"] = enactment_index_post_anchors.get_if_present(
            anchor["passage"])
        enactment_result.append(EnactmentWithAnchors(**anchor))

    record_post_terms, factor_index = index_names(record_post_enactments)
    factor_anchors, factor_index_post_anchors = collect_anchors_from_index(
        factor_index, "term")

    factor_result = []
    for anchor in factor_anchors:
        anchor["term"] = expand_holding(
            anchor["term"],
            factor_index=factor_index_post_anchors,
            enactment_index=enactment_index_post_anchors,
        )
        factor_result.append(TermWithAnchors(**anchor))

    factor_anchors = [TermWithAnchors(**anchor) for anchor in factor_anchors]

    expanded = expand_holdings(
        record_post_terms,
        factor_index=factor_index_post_anchors,
        enactment_index=enactment_index_post_anchors,
    )
    holding_anchors = [holding.pop("anchors", None) for holding in expanded]

    result = []
    for holding in expanded:
        result.append(Holding(**holding))
    return result, enactment_result, factor_result, holding_anchors
コード例 #5
0
 def test_implies_holding(self, make_complex_rule):
     """
     The Rule class doesn't know anything about the Holding class, but it
     should check whether Holding has an is_implied_by method and call it.
     """
     small_reliable = make_complex_rule["accept_small_weight_reliable"]
     small_more_reliable_holding = Holding(rule=make_complex_rule[
         "accept_small_weight_reliable_more_evidence"])
     assert small_reliable >= small_more_reliable_holding
コード例 #6
0
 def test_dump_and_load_holding(self, fake_usc_client, make_holding):
     """Dump holding and load it as if it was a JSON API response."""
     holding = make_holding["h2"]
     dumped = holding.dict()
     content = dumped["rule"]["procedure"]["inputs"][1]["predicate"][
         "content"]
     assert content == "$thing was a stockpile of Christmas trees"
     loaded = Holding(**dumped)
     loaded_content = loaded.inputs[0].predicate.content
     assert "$thing was on the premises of $place" in loaded_content
コード例 #7
0
 def implied_by_holding(
     self, other: Holding, context: Optional[ContextRegister] = None
 ) -> Iterator[Explanation]:
     """Check if a Holding implies all the Holdings of self."""
     if all(
         other.implies(self_holding, context=context)
         for self_holding in self.holdings
     ):
         yield Explanation(
             reasons=[(other, self_holding) for self_holding in self.holdings],
             operation=operator.ge,
         )
コード例 #8
0
 def test_does_not_imply_holding_due_to_context(self, make_complex_rule):
     """
     The Rule class doesn't know anything about the Holding class, but it
     should check whether Holding has an is_implied_by method and call it.
     """
     small_reliable = make_complex_rule["accept_small_weight_reliable"]
     small_more_reliable_holding = Holding(rule=make_complex_rule[
         "accept_small_weight_reliable_more_evidence"])
     assert not small_reliable.implies(
         small_more_reliable_holding,
         context=ContextRegister.from_lists([Entity(name="Alice")],
                                            [Entity(name="Bob")]),
     )
コード例 #9
0
 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)
コード例 #10
0
 def test_getting_factors_from_new_holding(self, make_opinion_with_holding):
     watt = make_opinion_with_holding["watt_majority"]
     watt.clear_holdings()
     elephants = Fact(predicate="$animal was an elephant",
                      terms=Entity(name="the elephant"))
     mouseholes = Fact(
         predicate=Predicate(content="$animal hides in mouseholes",
                             truth=False),
         terms=Entity(name="the elephant"),
     )
     procedure = Procedure(inputs=elephants, outputs=mouseholes)
     rule = Rule(procedure=procedure)
     holding = Holding(rule=rule)
     watt.posit(holding)
     factors = watt.factors_by_name()
     factor = factors["the fact that <the elephant> was an elephant"]
     assert factor.terms[0].name == "the elephant"
コード例 #11
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
    def posit_holding(
        self,
        holding: Union[Holding, Rule, HoldingWithAnchors],
        holding_anchors: Optional[Union[TextPositionSelector,
                                        TextQuoteSelector,
                                        TextPositionSet]] = None,
        named_anchors: Optional[List[TermWithAnchors]] = None,
        enactment_anchors: Optional[List[EnactmentWithAnchors]] = None,
        context: Optional[Sequence[Factor]] = None,
    ) -> None:
        r"""Record that this Opinion endorses specified :class:`Holding`\s."""
        named_anchors = named_anchors or []
        enactment_anchors = enactment_anchors or []

        if isinstance(holding, HoldingWithAnchors):
            holding, holding_anchors = holding.holding, holding.anchors
        if isinstance(holding_anchors, (TextQuoteSelector, str)):
            holding_anchors = [holding_anchors]
        if isinstance(holding_anchors, List) and isinstance(
                holding_anchors[0], (str, TextQuoteSelector)):
            holding_anchors = TextPositionSet.from_quotes(holding_anchors)
        if isinstance(holding, Rule):
            logger.warning("posit_holding was called with a Rule "
                           "that was automatically converted to a Holding")
            holding = Holding(rule=holding)

        if not isinstance(holding, Holding):
            raise TypeError('"holding" must be an object of type Holding.')

        for named_anchor in named_anchors:
            self.anchored_holdings.add_term(term=named_anchor.term,
                                            anchors=named_anchor.anchors)

        for enactment_anchor in enactment_anchors:
            self.anchored_holdings.add_enactment(
                enactment=enactment_anchor.passage,
                anchors=named_anchor.anchors)

        matching_holding = self.get_matching_holding(holding)
        if matching_holding:
            matching_holding.anchors += holding.anchors
        else:
            if context:
                holding = holding.new_context(context, source=self)
            self.anchored_holdings.holdings.append(
                HoldingWithAnchors(holding=holding, anchors=holding_anchors))
コード例 #12
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
 def explanations_implication(
     self,
     other: Comparable,
 ) -> Iterator[Union[ContextRegister, Explanation]]:
     """Yield contexts that would result in self implying other."""
     if not self.comparable_with(other):
         raise TypeError(
             f"'Implies' test not implemented for types {self.__class__} and {other.__class__}."
         )
     if isinstance(other, Rule):
         other = Holding(rule=other)
     if isinstance(other, Holding):
         for self_holding in self.holdings:
             yield from self_holding.explanations_implication(other)
     if isinstance(other, HoldingGroup):
         yield from self.holdings.explanations_implication(other)
     elif isinstance(other, self.__class__):
         yield from self.holdings.explanations_implication(other.holdings)
     else:
         yield from other.explanations_implied_by(self)
コード例 #13
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
    def explanations_contradiction(
        self,
        other: Comparable,
    ) -> Iterator[Explanation]:
        """Yield contexts that would result in a contradiction between self and other."""
        if not self.comparable_with(other):
            raise TypeError(
                f"'Implies' test not implemented for types {self.__class__} and {other.__class__}."
            )
        if isinstance(other, Rule):
            other = Holding(rule=other)
        if isinstance(other, Holding):
            yield from self.holdings.explanations_contradiction(other)

        if isinstance(other, HoldingGroup):
            yield from self.holdings.explanations_contradiction(other)

        elif isinstance(other, self.__class__):
            yield from self.holdings.explanations_contradiction(other.holdings)

        elif hasattr(other, "explanations_contradiction"):
            yield from other.explanations_contradiction(self)
コード例 #14
0
 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__}."
         )
コード例 #15
0
 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__}.")
コード例 #16
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
 def _implied_by_rule(self, other: Rule, context: Explanation) -> bool:
     return self._implied_by_holding(other=Holding(rule=other),
                                     context=context)
コード例 #17
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
 def _implied_by_holding(self, other: Holding,
                         context: Explanation) -> bool:
     return all(
         other.implies(self_holding, context=context.reversed_context())
         for self_holding in self.holdings)
コード例 #18
0
ファイル: opinions.py プロジェクト: mscarey/AuthoritySpoke
 def get_matching_holding(self, holding: Holding) -> Optional[Holding]:
     """Check self's Holdings for a Holding with the same meaning."""
     for known_holding in self.holdings:
         if holding.means(known_holding):
             return known_holding
     return None
コード例 #19
0
ファイル: test_spec.py プロジェクト: mscarey/AuthoritySpoke
 def test_fact_in_spec(self):
     spec = Holding.schema()
     assert "Fact" in spec["definitions"]
コード例 #20
0
 def implies_rule(self,
                  other: Rule,
                  context: Optional[ContextRegister] = None) -> bool:
     return self.implies_holding(Holding(other), context=context)
コード例 #21
0
 def implied_by_rule(self,
                     other: Rule,
                     context: ContextRegister = None) -> bool:
     return self.implied_by_holding(other=Holding(other), context=context)
コード例 #22
0
 def implies_rule(
     self, other: Rule, context: Optional[ContextRegister] = None
 ) -> bool:
     """Check if a Holding of self implies a Holding made from other Rule."""
     return self.implies_holding(Holding(rule=other), context=context)
コード例 #23
0
ファイル: test_spec.py プロジェクト: mscarey/AuthoritySpoke
 def test_factor_one_of(self):
     spec = Holding.schema()
     factor_schema = spec["definitions"]["Procedure"]["properties"][
         "outputs"]
     assert "anyOf" in factor_schema["items"]