def test_default_terms_for_fact(self, make_predicate): f1 = Statement( predicate=make_predicate["shooting"], terms=[Entity(name="Al"), Entity(name="Ed")], ) assert f1.terms[0].short_string == Entity(name="Al").short_string
def test_insert_pair_with_wrong_type(self): context = ContextRegister() with pytest.raises(TypeError): context.insert_pair(Entity(name="Bob"), Predicate(content="events transpired"))
def test_load_entity_with_type_field(self): data = {"type": "Entity", "name": "Ed"} loaded = Entity(**data) assert loaded.name == "Ed"
def test_likely_context_implication_one_factor(self, make_statement): left = make_statement["large_weight"] right = make_statement["small_weight"] context = next(left.likely_contexts(right)) assert context.check_match(Entity(name="Alice"), Entity(name="Alice"))
def test_not_same_register_one_term(self): left = ContextRegister.from_lists([Entity(name="Odysseus")], [Entity(name="Ulysses")]) right = ContextRegister.from_lists([Entity(name="Odysseus")], [Entity(name="Jason")]) assert not right.means(left)
def test_explain_consistency(self): register = ContextRegister() register.insert_pair(Entity(name="Al"), Entity(name="Alice")) explanation = self.fact_al.explain_consistent_with( self.fact_alice, register) assert "<the bull> is like <the cow>" in str(explanation.context)
def test_cannot_create_register_from_one_list(self): with pytest.raises(ValueError): ContextRegister.create([Entity(name="Alice"), Entity(name="Bob")])
def test_two_inconsistent_groups(self): left = FactorGroup([self.slower_specific_statement]) right = FactorGroup([self.faster_statement]) context = ContextRegister() context.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert not left.consistent_with(right, context=context)
def test_cannot_add_entity(self): with pytest.raises(TypeError): FactorGroup(Entity(name="Morning Star"))
def test_not_implied_by_statement(self, make_rule): assert not Statement( predicate=Predicate(content="$person was a person"), terms=Entity(name="Alice"), ).implies(make_rule["h1"])
def test_new_concrete_context(self, make_holding): different = make_holding["h1"].new_context( [Entity(name="Castle Grayskull"), Entity(name="He-Man")]) assert "<He-Man> operated" in str(different)
def test_inconsistent_two_terms(self, make_statement): context = ContextRegister() context.insert_pair(Entity(name="Alice"), Entity(name="Alice")) context.insert_pair(Entity(name="Bob"), Entity(name="Bob")) assert not make_statement["shooting"].consistent_with( make_statement["no_shooting"], context=context)
def test_inconsistent(self, make_statement): context = ContextRegister() context.insert_pair(Entity(name="Alice"), Entity(name="Alice")) assert not make_statement["crime"].consistent_with( make_statement["no_crime"], context=context)
def test_specific_fact_does_not_imply_generic_entity(self, make_statement): assert not make_statement["crime"] > Entity(name="Bob")
def test_impossible_register(self): context = ContextRegister() context.insert_pair(Entity(name="Al"), Entity(name="Bob")) answers = self.fact_al.update_context_register(self.fact_alice, context, means) assert not any(answers)
def test_context_prevents_implied_by_factor(self, make_statement): left = FactorGroup(make_statement["more"]) assert not left.implied_by( make_statement["way_more"], context=(["<San Francisco>"], [Entity(name="Richmond")]), )
def test_possible_register(self): register = ContextRegister() register.insert_pair(Entity(name="Al"), Entity(name="Alice")) answers = self.fact_al.update_context_register(self.fact_alice, register, means) assert Entity(name="the bull").key in next(answers).keys()
def test_interchangeable_contradiction_no_repeated_explanations(self): nafta = FactorGroup([ Statement( predicate="$country1 signed a treaty with $country2", terms=[Entity(name="Mexico"), Entity(name="USA")], ), Statement( predicate="$country2 signed a treaty with $country3", terms=[Entity(name="USA"), Entity(name="Canada")], ), Statement( predicate="$country3 signed a treaty with $country1", terms=[Entity(name="Canada"), Entity(name="Mexico")], ), ]) brexit = FactorGroup([ Statement( predicate="$country1 signed a treaty with $country2", terms=[Entity(name="UK"), Entity(name="European Union")], ), Statement( predicate="$country2 signed a treaty with $country3", terms=[Entity(name="European Union"), Entity(name="Germany")], ), Statement( predicate="$country3 signed a treaty with $country1", terms=[Entity(name="Germany"), Entity(name="UK")], truth=False, ), ]) assert nafta.contradicts(brexit) explanations_usa_like_uk = nafta.explanations_contradiction( brexit, context=([Entity(name="USA")], [Entity(name="UK")])) assert len(list(explanations_usa_like_uk)) == 2
def test_possible_context_without_empty_spaces(self): left = Statement(predicate=self.bird, terms=Entity(name="Owl")) right = Statement(predicate=self.bird, terms=Entity(name="Owl")) contexts = list(left.possible_contexts(right)) assert len(contexts) == 1 assert contexts[0].check_match(Entity(name="Owl"), Entity(name="Owl"))
def test_interchangeable_implication_no_repeated_explanations(self): nafta = FactorGroup([ Statement( predicate="$country1 signed a treaty with $country2", terms=[Entity(name="Mexico"), Entity(name="USA")], ), Statement( predicate="$country2 signed a treaty with $country3", terms=[Entity(name="USA"), Entity(name="Canada")], ), Statement( predicate="$country3 signed a treaty with $country1", terms=[Entity(name="Canada"), Entity(name="Mexico")], ), ]) nato = FactorGroup([ Statement( predicate="$country1 signed a treaty with $country2", terms=[Entity(name="USA"), Entity(name="UK")], ), Statement( predicate="$country2 signed a treaty with $country3", terms=[Entity(name="UK"), Entity(name="Germany")], ), Statement( predicate="$country3 signed a treaty with $country1", terms=[Entity(name="Germany"), Entity(name="USA")], ), ]) assert nafta.implies(nato) all_answers = list(nafta.explanations_implication(nato)) assert len(all_answers) == 6 limited_answers = list( nafta.explanations_implication(nato, context=([Entity(name="USA")], [Entity(name="UK")]))) assert len(limited_answers) == 2
def test_likely_context_one_factor(self, make_statement): left = make_statement["murder"] right = make_statement["murder"] context = next(left.likely_contexts(right)) assert context.check_match(Entity(name="Bob"), Entity(name="Bob"))
class TestConsistent: predicate_less_specific = Comparison( content="${vehicle}'s speed was", sign="<", expression="30 miles per hour", ) predicate_less_general = Comparison( content="${vehicle}'s speed was", sign="<", expression="60 miles per hour", ) predicate_more = Comparison( content="${vehicle}'s speed was", sign=">", expression="55 miles per hour", ) predicate_farm = Predicate(content="$person had a farm") slower_specific_statement = Statement(predicate=predicate_less_specific, terms=Entity(name="the car")) slower_general_statement = Statement(predicate=predicate_less_general, terms=Entity(name="the pickup")) faster_statement = Statement(predicate=predicate_more, terms=Entity(name="the pickup")) farm_statement = Statement(predicate=predicate_farm, terms=Entity(name="Old MacDonald")) def test_group_contradicts_single_factor(self): group = FactorGroup( [self.slower_specific_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert group.contradicts(self.faster_statement, context=register) def test_one_statement_does_not_contradict_group(self): group = FactorGroup( [self.slower_general_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the pickup"), Entity(name="the pickup")) assert not self.faster_statement.contradicts(group, context=register) def test_group_inconsistent_with_single_factor(self): group = FactorGroup( [self.slower_specific_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert not group.consistent_with(self.faster_statement, context=register) assert not consistent_with( group, self.faster_statement, context=register) assert repr(group).startswith("FactorGroup([Statement") assert "30.0 mile / hour" in repr(group) def test_no_duplicate_explanations_consistent(self): large_payments = FactorGroup([ Statement( predicate=Comparison( content= "the number of dollars that $payer paid to $payee was", sign=">", expression=10000, ), terms=[Entity(name="Alice"), Entity(name="Bob")], ), Statement( predicate=Comparison( content= "the number of dollars that $payer paid to $payee was", sign=">", expression=1000, ), terms=[Entity(name="Dan"), Entity(name="Eve")], ), ]) small_payments = FactorGroup([ Statement( predicate=Comparison( content= "the number of dollars that $payer paid to $payee was", sign=">", expression=100, ), terms={ "payer": Entity(name="Fred"), "payee": Entity(name="Greg") }, ), Statement( predicate=Comparison( content= "the number of dollars that $payer paid to $payee was", sign=">", expression=10, ), terms={ "payer": Entity(name="Jim"), "payee": Entity(name="Kim") }, ), ]) assert large_payments.consistent_with(small_payments) all_explanations = list( large_payments.explanations_consistent_with(small_payments)) assert len(all_explanations) == 24 limited_explanations = list( large_payments.explanations_consistent_with( small_payments, context=([Entity(name="Alice")], [Entity(name="Jim")]))) assert len(limited_explanations) == 6 def test_groups_with_one_statement_consistent(self): specific_group = FactorGroup([self.slower_specific_statement]) general_group = FactorGroup([self.faster_statement]) assert specific_group.consistent_with(general_group) assert consistent_with(specific_group, general_group) def test_group_inconsistent_with_one_statement(self): group = FactorGroup( [self.slower_specific_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert not group.consistent_with(self.faster_statement, context=register) def test_one_statement_inconsistent_with_group(self): group = FactorGroup( [self.slower_specific_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the pickup"), Entity(name="the car")) assert not self.faster_statement.consistent_with(group, context=register) def test_one_statement_consistent_with_group(self): group = FactorGroup( [self.slower_general_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the pickup"), Entity(name="the pickup")) assert self.faster_statement.consistent_with(group, context=register) def test_no_contradiction_of_none(self): group = FactorGroup( [self.slower_general_statement, self.farm_statement]) assert not group.contradicts(None) def test_consistent_with_none(self): group = FactorGroup( [self.slower_general_statement, self.farm_statement]) assert group.consistent_with(None) def test_two_inconsistent_groups(self): left = FactorGroup([self.slower_specific_statement]) right = FactorGroup([self.faster_statement]) context = ContextRegister() context.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert not left.consistent_with(right, context=context) def test_not_internally_consistent_with_context(self, make_statement): context = ContextRegister() context.insert_pair(Entity(name="Alice"), Entity(name="Alice")) context.insert_pair(Entity(name="Bob"), Entity(name="Bob")) group = FactorGroup( [make_statement["shooting"], make_statement["no_shooting"]]) with pytest.raises(ValueError): group.internally_consistent() def test_not_internally_consistent(self, make_statement): group = FactorGroup( [make_statement["shooting"], make_statement["no_shooting"]]) with pytest.raises(ValueError): group.internally_consistent() def test_all_generic_terms_match_in_statement(self): predicate = Predicate(content="the telescope pointed at $object") morning = Statement(predicate=predicate, terms=Entity(name="Morning Star")) evening = Statement(predicate=predicate, terms=Entity(name="Evening Star")) left = FactorGroup(morning) right = FactorGroup(evening) context = ContextRegister() context.insert_pair(Entity(name="Morning Star"), Entity(name="Evening Star")) assert left._all_generic_terms_match(right, context=context)
def test_likely_context_two_factors(self, make_statement): left = FactorGroup( [make_statement["murder"], make_statement["large_weight"]]) right = make_statement["small_weight_bob"] context = next(left.likely_contexts(right)) assert context.check_match(Entity(name="Alice"), Entity(name="Bob"))
def test_group_contradicts_single_factor(self): group = FactorGroup( [self.slower_specific_statement, self.farm_statement]) register = ContextRegister() register.insert_pair(Entity(name="the car"), Entity(name="the pickup")) assert group.contradicts(self.faster_statement, context=register)
def test_context_not_equal_to_list(self): changes = ContextRegister.from_lists( [Entity(name="Alice")], [Entity(name="Dan")], ) assert changes != [[Entity(name="Alice")], [Entity(name="Dan")]]
def make_statement(make_predicate, make_comparison) -> Dict[str, Statement]: p = make_predicate c = make_comparison return { "irrelevant_0": Statement( predicate=p["irrelevant_0"], terms=[Entity(name="Craig")] ), "irrelevant_1": Statement( predicate=p["irrelevant_1"], terms=[Entity(name="Dan")] ), "irrelevant_2": Statement( predicate=p["irrelevant_2"], terms=Entity(name="Dan") ), "irrelevant_3": Statement( predicate=p["irrelevant_3"], terms=[Entity(name="Craig"), Entity(name="circus")], ), "irrelevant_3_new_context": Statement( predicate=p["irrelevant_3"], terms=[Entity(name="Craig"), Entity(name="Dan")], ), "irrelevant_3_context_0": Statement( predicate=p["irrelevant_3"], terms=[Entity(name="Craig"), Entity(name="Alice")], ), "crime": Statement(predicate=p["crime"], terms=Entity(name="Alice")), "crime_bob": Statement(predicate=p["crime"], terms=Entity(name="Bob")), "crime_craig": Statement(predicate=p["crime"], terms=Entity(name="Craig")), "crime_generic": Statement( predicate=p["crime"], terms=Entity(name="Alice"), generic=True ), "crime_specific_person": Statement( predicate=p["crime"], terms=Entity(name="Alice", generic=False) ), "absent_no_crime": Statement( predicate=p["no_crime"], terms=Entity(name="Alice"), absent=True ), "no_crime": Statement(predicate=p["no_crime"], terms=Entity(name="Alice")), "no_crime_entity_order": Statement( predicate=p["no_crime"], terms=[Entity(name="Bob")] ), "murder": Statement( predicate=p["murder"], terms=[Entity(name="Alice"), Entity(name="Bob")] ), "murder_false": Statement( predicate=p["murder_false"], terms=[Entity(name="Alice"), Entity(name="Bob")], ), "murder_entity_order": Statement( predicate=p["murder"], terms=[Entity(name="Bob"), Entity(name="Alice")] ), "murder_craig": Statement( predicate=p["murder"], terms=[Entity(name="Craig"), Entity(name="Dan")] ), "murder_whether": Statement( predicate=p["murder_whether"], terms=[Entity(name="Alice"), Entity(name="Bob")], ), "shooting": Statement( predicate=p["shooting"], terms=[Entity(name="Alice"), Entity(name="Bob")] ), "shooting_self": Statement( predicate=p["shooting_self"], terms=[Entity(name="Alice")] ), "shooting_craig": Statement( predicate=p["shooting"], terms=[Entity(name="Craig"), Entity(name="Dan")] ), "shooting_entity_order": Statement( predicate=p["shooting"], terms=[Entity(name="Bob"), Entity(name="Alice")] ), "no_shooting": Statement( predicate=p["no_shooting"], terms=[Entity(name="Alice"), Entity(name="Bob")] ), "shooting_whether": Statement( predicate=p["shooting_whether"], terms=[Entity(name="Alice"), Entity(name="Bob")], ), "no_shooting_entity_order": Statement( predicate=p["no_shooting"], terms=[Entity(name="Bob"), Entity(name="Alice")] ), "plotted": Statement( predicate=p["plotted"], terms=[Entity(name="Alice"), Entity(name="Craig")] ), "plotted_reversed": Statement( predicate=p["plotted"], terms=[Entity(name="Alice"), Entity(name="Craig")] ), "three_entities": Statement( predicate=p["three_entities"], terms=[Entity(name="Alice"), Entity(name="Bob"), Entity(name="Craig")], ), "large_weight": Statement( predicate=c["large_weight"], terms=Entity(name="Alice"), ), "large_weight_craig": Statement( predicate=c["large_weight"], terms=Entity(name="Craig"), ), "small_weight": Statement( predicate=c["small_weight"], terms=Entity(name="Alice"), ), "small_weight_bob": Statement( predicate=c["small_weight"], terms=Entity(name="Bob"), ), "friends": Statement( predicate=p["friends"], terms=[Entity(name="Alice"), Entity(name="Bob")] ), "no_context": Statement(predicate=p["no_context"]), "exact": Statement( predicate=c["exact"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "less": Statement( predicate=c["less"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "less_than_20": Statement( predicate=c["less_than_20"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "less_whether": Statement( predicate=c["less_whether"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "more": Statement( predicate=c["more"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "more_atlanta": Statement( predicate=c["more"], terms=[Entity(name="Atlanta"), Entity(name="Marietta")] ), "more_meters": Statement( predicate=c["meters"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "not_more": Statement( predicate=c["not_more"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "float_distance": Statement( predicate=c["float_distance"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "int_distance": Statement( predicate=c["int_distance"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "higher_int": Statement( predicate=c["higher_int"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "way_more": Statement( predicate=c["way_more"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], ), "absent_less": Statement( predicate=c["less"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], absent=True, ), "absent_more": Statement( predicate=c["more"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], absent=True, ), "absent_way_more": Statement( predicate=c["way_more"], terms=[Entity(name="San Francisco"), Entity(name="Oakland")], absent=True, ), }
def test_failed_match(self): context = ContextRegister() context.insert_pair(Entity(name="Bob"), Entity(name="Alice")) assert context.check_match(Entity(name="Craig"), Entity(name="Dan")) is False
def make_context_register() -> ContextRegister: context_names = ContextRegister() context_names.insert_pair(key=Entity(name="Alice"), value=Entity(name="Craig")) context_names.insert_pair(key=Entity(name="Bob"), value=Entity(name="Dan")) return context_names
def test_load_entity_with_wrong_type_field(self): data = {"type": "Statement", "name": "Ed"} with pytest.raises(ValidationError): Entity(**data)
def test_reciprocal_with_wrong_number_of_entities(self, make_statement): with pytest.raises(ValueError): make_statement["crime"].predicate._content_with_terms( (Entity(name="Al"), Entity(name="Ben")))