class TestConsistent: p_small_weight = Comparison( content="the amount of gold $person possessed was", sign="<", expression=Q_("1 gram"), ) p_large_weight = Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("100 kilograms"), ) small = Fact(predicate=p_large_weight, terms=Entity(name="Alice")) big = Fact(predicate=p_small_weight, terms=Entity(name="Bob")) def test_contradictory_facts_about_same_entity(self): register = ContextRegister() register.insert_pair(Entity(name="Alice"), Entity(name="Bob")) assert not self.small.consistent_with(self.big, register) explanations = list( self.small.explanations_consistent_with(self.big, context=register)) assert not explanations def test_factor_consistent_with_none(self): assert self.small.consistent_with(None)
def test_compare_intervals_different_units(self): miles = Comparison( content="the distance was", sign="<", expression=Q_("30 miles") ) kilos = Comparison( content="the distance was", sign="<", expression=Q_("40 kilometers") ) assert kilos.quantity_range.implies(miles.quantity_range)
def test_no_contradiction_exact_different_unit(self): acres = Comparison( content="the size of the farm was", sign=">", expression=Q_("20 acres") ) kilometers = Comparison( content="the size of the farm was", sign="=", expression=Q_("100 square kilometers"), ) assert not acres.contradicts(kilometers)
def test_predicate_not_same_with_interchangeable_terms(self): interchangeable = Comparison( content="the distance between $place1 and $place2 was", sign="<", expression=Q_("20 feet"), ) not_interchangeable = Comparison( content="the distance between $west and $east was", sign="<", expression=Q_("20 feet"), ) assert not interchangeable.means(not_interchangeable)
def test_does_not_exclude_other_quantity(self): comparison = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("20 miles"), ) comparison_opposite = Comparison( content="the distance between $place1 and $place2 was", sign="<", expression=Q_("30 miles"), ) left = comparison.quantity_range right = comparison_opposite.quantity_range assert left.contradicts(right.interval) is False
def test_convert_quantity_of_Comparison(self): comparison = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("20 miles"), ) comparison_km = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("30 kilometers"), ) result = comparison.quantity_range.get_unit_converted_interval( comparison_km.quantity_range ) assert 18 < result.left < 19
def test_comparison_with_wrong_comparison_symbol(self): with pytest.raises(ValueError): _ = Comparison( content="the height of {} was {}", sign=">>", expression=Q_("160 centimeters"), )
def test_content_not_ending_with_was(self): with pytest.raises(ValueError): Comparison( content="$person drove for", sign=">=", expression=Q_("20 miles"), )
def test_no_contradiction_between_classes(self): left = UnitRange(quantity=Q_("2000 days"), sign="<") right = IntRange(quantity=2000, sign=">") assert right.q == 2000 assert right.domain == S.Naturals0 assert str(right) == "greater than 2000" assert left.magnitude == right.magnitude assert not left.contradicts(right)
def test_comparison_interval(self): comparison = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("20 miles"), ) assert comparison.interval == Interval(20, oo, left_open=True) assert "quantity='20 mile'" in repr(comparison)
def test_factor_different_predicate_truth_contradicts(self): predicate = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("30 miles"), ) predicate_opposite = Comparison( content="the distance between $place1 and $place2 was", sign="<", expression=Q_("30 miles"), ) terms = [Entity(name="New York"), Entity(name="Los Angeles")] fact = Fact(predicate=predicate, terms=terms) fact_opposite = Fact(predicate=predicate_opposite, terms=terms) assert fact.contradicts(fact_opposite) assert fact_opposite.contradicts(fact)
def test_dump_to_dict_with_units(self): predicate = Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="<>", expression=Q_("35 feet"), ) dumped = predicate.dict() assert dumped["quantity_range"]["quantity"] == "35 foot"
def test_comparison_not_equal(self): comparison = Comparison( content="the distance between $place1 and $place2 was", sign="!=", expression=Q_("20 miles"), ) assert comparison.interval == sympy.Union( Interval(0, 20, right_open=True), Interval(20, oo, left_open=True) )
def test_absences_of_contradictory_facts_consistent(self): predicate = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("30 miles"), ) predicate_opposite = Comparison( content="the distance between $place1 and $place2 was", sign="<", expression=Q_("30 miles"), ) terms = [Entity(name="New York"), Entity(name="Los Angeles")] fact = Fact(predicate=predicate, terms=terms, absent=True) fact_opposite = Fact(predicate=predicate_opposite, terms=terms, absent=True) assert not fact.contradicts(fact_opposite) assert not fact_opposite.contradicts(fact)
def test_broader_absent_factor_contradicts_quantity_statement(self): predicate_less = Comparison( content="${vehicle}'s speed was", sign=">", expression=Q_("30 miles per hour"), ) predicate_more = Comparison( content="${vehicle}'s speed was", sign=">", expression=Q_("60 miles per hour"), ) terms = [Entity(name="the car")] absent_general_fact = Fact(predicate=predicate_less, terms=terms, absent=True) specific_fact = Fact(predicate=predicate_more, terms=terms) assert absent_general_fact.contradicts(specific_fact) assert specific_fact.contradicts(absent_general_fact)
def test_no_contradiction_with_more_specific_absent(self): predicate_less = Comparison( content="${vehicle}'s speed was", sign="<", expression=Q_("30 miles per hour"), ) predicate_more = Comparison( content="${vehicle}'s speed was", sign="<", expression=Q_("60 miles per hour"), ) terms = [Entity(name="the car")] general_fact = Fact(predicate=predicate_more, terms=terms) absent_specific_fact = Fact(predicate=predicate_less, terms=terms, absent=True) assert not general_fact.contradicts(absent_specific_fact) assert not absent_specific_fact.contradicts(general_fact)
def test_factor_implies_because_of_quantity(self, make_statement): meters = Comparison( content="the distance between $place1 and $place2 was", sign=">=", expression=Q_("10 meters"), ) left = Statement(predicate=meters, terms=[Entity(name="Al"), Entity(name="Bob")]) more = Comparison( content="the distance between $place1 and $place2 was", truth=True, sign=">", expression=Q_("30 feet"), ) right = Statement(predicate=more, terms=[Entity(name="Al"), Entity(name="Bob")]) assert left > right
class TestAddition: predicate_less = Comparison( content="${vehicle}'s speed was", sign=">", expression=Q_("30 miles per hour"), ) predicate_more = Comparison( content="${vehicle}'s speed was", sign=">=", expression=Q_("60 miles per hour"), ) general_fact = Fact(predicate=predicate_less, terms=Entity(name="the car")) specific_fact = Fact(predicate=predicate_more, terms=Entity(name="the motorcycle")) def test_addition_returns_broader_operand(self): answer = self.specific_fact + self.general_fact assert answer.means(self.specific_fact) def test_addition_uses_terms_from_left(self): answer = self.general_fact + self.specific_fact assert "<the car>" in str(answer) def test_add_unrelated_factors(self): murder = Fact( predicate=Predicate(content="$person committed a murder"), terms=Entity(name="Al"), ) crime = Fact( predicate=Predicate(content="$person committed a crime"), terms=Entity(name="Al"), ) assert murder + crime is None def test_union_with_string_fails(self): murder = Fact( predicate=Predicate(content="$person committed a murder"), terms=Entity(name="Al"), ) with pytest.raises(TypeError): murder | "a string"
def test_convert_false_statement_about_quantity_to_obverse(self): distance = Comparison( content="the distance between $place1 and $place2 was", truth=False, sign=">", expression=Q_("35 feet"), ) assert distance.truth is True assert distance.sign == "<=" assert isinstance(distance.quantity, Quantity) assert str(distance.quantity) == "35 foot"
def test_inconsistent_statements_about_different_entities(self): """ Alice and Bob are both generics. So it's possible to reach a contradiction if you assume they correspond to one another. """ p_small_weight = Comparison( content="the amount of gold $person possessed was", sign="<", expression=Q_("1 gram"), ) p_large_weight = Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("100 kilograms"), ) alice = Entity(name="Alice") bob = Entity(name="Bob") alice_rich = Statement(predicate=p_large_weight, terms=alice) bob_poor = Statement(predicate=p_small_weight, terms=bob) assert alice_rich.contradicts(bob_poor)
def test_is_beard_implied( self, facial_hair_over_5mm, facial_hair_on_or_below_chin, facial_hair_uninterrupted, outcome, fake_beard_client, make_beard_rule, ): beard = Entity(name="a facial feature") sec_4 = fake_beard_client.read("/test/acts/47/4/") was_facial_hair = Predicate(content="$thing was facial hair") fact_was_facial_hair = Fact(predicate=was_facial_hair, terms=beard) hypothetical = Rule( procedure=Procedure( inputs=[ fact_was_facial_hair, Fact( predicate=Comparison( content="the length of $thing was", sign=">=", expression=Q_("5 millimeters"), truth=facial_hair_over_5mm, ), terms=beard, ), Fact( predicate=Predicate( content="$thing occurred on or below the chin", truth=facial_hair_on_or_below_chin, ), terms=beard, ), Fact( predicate=Predicate( content= "$thing existed in an uninterrupted line from the front " "of one ear to the front of the other ear below the nose", truth=facial_hair_uninterrupted, ), terms=beard, ), ], outputs=Fact(predicate=Predicate(content="$thing was a beard"), terms=beard), ), enactments=sec_4, ) meets_chin_test = make_beard_rule[0].implies(hypothetical) meets_ear_test = make_beard_rule[1].implies(hypothetical) assert outcome == meets_chin_test or meets_ear_test
def test_cannot_convert_date_to_time_period(self): time = Comparison( content="the time $object took to biodegrade was", sign=">", expression=Q_("2000 years"), ) day = Comparison( content="the day was", sign="=", expression=date(2020, 1, 1), ) with pytest.raises(TypeError): time.quantity_range.get_unit_converted_interval(day.quantity_range)
def test_inconsistent_statements_about_corresponding_entities(self): """ Even though Alice and Bob are both generics, it's known that Alice in the first context corresponds with Alice in the second. So there's no contradiction. """ p_small_weight = Comparison( content="the amount of gold $person possessed was", sign="<", expression=Q_("1 gram"), ) p_large_weight = Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("100 kilograms"), ) alice = Entity(name="Alice") bob = Entity(name="Bob") alice_rich = Statement(predicate=p_large_weight, terms=alice) bob_poor = Statement(predicate=p_small_weight, terms=bob) register = ContextRegister() register.insert_pair(alice, alice) assert not alice_rich.contradicts(bob_poor, context=register)
def test_inconsistent_dimensionality_quantity(self): number = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=20, ) distance = Comparison( content="the distance between $place1 and $place2 was", sign=">", expression=Q_("20 miles"), ) assert not number.quantity_range.consistent_dimensionality( distance.quantity_range ) assert not distance.quantity_range.consistent_dimensionality( number.quantity_range )
def make_comparison() -> Dict[str, Predicate]: return { "small_weight": Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("1 gram"), ), "large_weight": Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("100 kilograms"), ), "quantity=3": Comparison( content="The number of mice was", sign="==", expression=3 ), "quantity>=4": Comparison( content="The number of mice was", sign=">=", expression=4 ), "quantity>5": Comparison( content="The number of mice was", sign=">", expression=5 ), "acres": Comparison( content="the distance between $place1 and $place2 was", sign=">=", expression=Q_("10 acres"), ), "exact": Comparison( content="the distance between $place1 and $place2 was", sign="==", expression=Q_("25 feet"), ), "float_distance": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="<", expression=20.0, ), "higher_int": Comparison( content="the distance between $place1 and $place2 was", sign="<=", expression=30, ), "int_distance": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="<", expression=20, ), "int_higher": Comparison( content="the distance between $place1 and $place2 was", sign="<=", expression=30, ), "less": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="<", expression=Q_("35 feet"), ), "less_whether": Comparison( content="the distance between $place1 and $place2 was", truth=None, sign="<", expression=Q_("35 feet"), ), "less_than_20": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="<", expression=Q_("20 feet"), ), "meters": Comparison( content="the distance between $place1 and $place2 was", sign=">=", expression=Q_("10 meters"), ), "not_equal": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign="!=", expression=Q_("35 feet"), ), "more": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign=">=", expression=Q_("35 feet"), ), "not_more": Comparison( content="the distance between $place1 and $place2 was", truth=False, sign=">", expression=Q_("35 feet"), ), "way_more": Comparison( content="the distance between $place1 and $place2 was", truth=True, sign=">=", expression=Q_("30 miles"), ), }
class TestProcedureUnion: def test_simple_union(self, make_opinion_with_holding): feist = make_opinion_with_holding["feist_majority"] procedure_from_union = feist.holdings[0].procedure | feist.holdings[2].procedure procedure_from_adding = ( feist.holdings[0].procedure + feist.holdings[2].procedure.inputs[0] ) assert procedure_from_union.means(procedure_from_adding) p_small_weight = Comparison( content="the amount of gold $person possessed was", sign="<", expression=Q_("1 gram"), ) p_large_weight = Comparison( content="the amount of gold $person possessed was", sign=">=", expression=Q_("100 kilograms"), ) alice = Entity(name="Alice") bob = Entity(name="Bob") craig = Entity(name="Craig") dan = Entity(name="Dan") alice_rich = Fact(predicate=p_large_weight, terms=alice) bob_poor = Fact(predicate=p_small_weight, terms=bob) craig_rich = Fact(predicate=p_large_weight, terms=craig) dan_poor = Fact(predicate=p_small_weight, terms=dan)
def test_unitregistry_imports_do_not_conflict(self, make_comparison): left = UnitRange(quantity=Q_("20 meters"), sign=">") right = make_comparison["meters"].quantity_range assert left.implies(right) assert left.pint_quantity == Q_("20 meters")