Skip to content

Commit

Permalink
Rule.add_factor returns None if contradiction is caused
Browse files Browse the repository at this point in the history
  • Loading branch information
mscarey committed Apr 7, 2021
1 parent cac2724 commit e274230
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 9 deletions.
2 changes: 1 addition & 1 deletion authorityspoke/holdings.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def add_holding(self, other: Holding) -> Optional[Holding]:
return added
return None

def __add__(self, other: Factor) -> Optional[Union[Rule, Holding]]:
def __add__(self, other: Comparable) -> Optional[Union[Rule, Holding]]:
"""
Create new Holding combining self and other into a single step, if possible.
Expand Down
6 changes: 4 additions & 2 deletions authorityspoke/procedures.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def generic_terms_by_str(self) -> Dict[str, Term]:
}
return generic_dict

def add_factor(self, incoming: Factor) -> Procedure:
def add_factor(self, incoming: Factor) -> Optional[Procedure]:
"""
Add an input :class:`.Factor`.
Expand All @@ -303,7 +303,9 @@ def add_factor(self, incoming: Factor) -> Procedure:
:returns:
a new version of ``self`` with the specified change
"""
new_factors = list(self.inputs) + [incoming]
new_factors = self.inputs + incoming
if new_factors is None:
return None
result = deepcopy(self)
result.set_inputs(new_factors)
return result
Expand Down
4 changes: 3 additions & 1 deletion authorityspoke/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def add_enactment_despite(self, incoming: Enactment) -> Rule:
result.set_enactments_despite(new_enactments)
return result

def add_factor(self, incoming: Factor) -> Rule:
def add_factor(self, incoming: Factor) -> Optional[Rule]:
"""
Make new version of ``self`` with an added input, output, or despite :class:`.Factor`.
Expand All @@ -287,6 +287,8 @@ def add_factor(self, incoming: Factor) -> Rule:
a new version of ``self`` with the specified change
"""
new_procedure = self.procedure.add_factor(incoming)
if new_procedure is None:
return None
result = deepcopy(self)
result.procedure = new_procedure
return result
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ anchorpoint>=0.4.4
apispec[validation]~=4.3.0
marshmallow>=3.10
legislice>=0.5.0
git+git://github.com/mscarey/nettlesome.git@c1c680b542ce74edc39747d32ea024ff24363ae6#egg=nettlesome
git+git://github.com/mscarey/nettlesome.git@beb4d3f6eb2c731d47afcdcec4d422745400a3d0#egg=nettlesome
pint>=0.15
python-dotenv
python-slugify
Expand Down
8 changes: 8 additions & 0 deletions tests/test_holdings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def test_string_indentation(self, make_opinion_with_holding):
lotus = make_opinion_with_holding["lotus_majority"]
assert " OF:\n" in str(lotus.holdings[2])

def test_repr(self, make_holding):
assert "rule=Rule(" in repr(make_holding["h1"])

def test_line_break_in_fact_within_holding(self, make_opinion_with_holding):
"""
Test that holding uses the Fact string method with line breaks.
Expand Down Expand Up @@ -600,6 +603,11 @@ def test_universal_holding_that_cannot_be_added(self, make_rule):
right = make_rule["h3_ALL"]
assert left + right is None

def test_add_contradictory_factor(self, make_holding):
holding = make_holding["h1"]
factor = holding.inputs[0].negated()
assert holding + factor is None


class TestUnion:
def test_union_neither_universal(self, make_opinion_with_holding):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def test_opinion_explain_contradiction(self, make_opinion_with_holding):
assert "<the Lotus menu command hierarchy> is like <the Java API>" in str(
explanation
)
assert 'Entity(name="the Java API"' in repr(explanation)
assert "Entity(name='the Java API'" in repr(explanation)

def test_decision_explain_contradiction(self, make_decision_with_holding):
oracle = make_decision_with_holding["oracle"]
Expand Down
5 changes: 2 additions & 3 deletions tests/test_procedures.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ def test_type_of_terms(self, make_procedure):
assert isinstance(make_procedure["c3"].terms, TermSequence)

def test_repr(self, make_procedure):
assert 'to_effect=Fact(Predicate(template="$person committed a crime"' in repr(
make_procedure["c3"]
)
rep = repr(make_procedure["c3"])
assert "to_effect=Fact(predicate=Predicate(template='$person committed" in rep

def test_entities_of_inputs_for_identical_procedure(
self, watt_factor, make_procedure, watt_mentioned
Expand Down

0 comments on commit e274230

Please sign in to comment.