def test_membership(self): self.assertTrue(is_member(Set(Set(Couplet(1, 2))))) self.assertFalse(is_member(Set(Couplet(3, 4)))) self.assertTrue(is_absolute_member(Set(Set(Couplet(1, 2))))) self.assertFalse(is_absolute_member(Set(Set(Couplet(Set([2, 3]), 4))))) # noinspection PyTypeChecker self.assertRaises(AttributeError, lambda: is_member(3))
def test_set(self): self.print_string('test_set') sets = [ Set(None), Set(False), Set(int(2)), Set(float(2)), Set(complex('1+2j')), Set(str(2)), Set(bytes(2)), Set(range(-1, 5)), Set( frozenset([ None, bool(2), int(2), float(2), complex('1+2j'), str(2), bytes(2), range(-1, 5), frozenset([None, None]), tuple((34, 35)), Atom(int(2)), Couplet(-1, -2), Set('x', 'y', 'z') ])), Set(tuple((34, 35))), Set(Atom('jkh')), Set(Couplet('a', '1')), ] self.verify_string_import_export(sets) self.verify_file_import_export(sets)
def test_equivalence_relation(self): self.assertTrue(is_equivalence_relation(Set())) self.assertFalse(is_equivalence_relation( Set([Couplet(s, c) for c, s in zip('aba', 'bcc')]))) self.assertIs(is_equivalence_relation(Set('a', 'b', 'c')), Undef()) self.assertFalse(is_equivalence_relation( Set([Couplet(s, c) for c, s in zip('aba', 'bcd')]))) f = is_equivalence_relation(basic_sets['left func']) self.assertFalse(f) f = is_equivalence_relation(basic_sets['not left func']) self.assertFalse(f) f = is_equivalence_relation(basic_sets['diagonal']) self.assertTrue(f) f = is_equivalence_relation(basic_clans['not left func']) self.assertFalse(f) f = is_equivalence_relation(basic_clans['diagonal']) self.assertTrue(f) f = is_equivalence_relation(basic_hordes['not left func']) self.assertFalse(f) f = is_equivalence_relation(basic_hordes['diagonal']) self.assertTrue(f) s = basic_sets['diagonal'] self.assertEqual(s.cached_reflexive, CacheStatus.IS) self.assertEqual(s.cached_symmetric, CacheStatus.IS) self.assertEqual(s.cached_transitive, CacheStatus.IS)
def test_diag(self): rel1 = Set(Couplet('a', 'a'), Couplet('b', 'b')) self.assertEqual(diag('a', 'b'), rel1) self.assertEqual(diag(), Set()) self.assertIs(diag(Undef()), Undef()) self.assertIs(diag(Undef(), _checked=False), Undef())
def test_transitive(self): self.assertTrue(is_transitive(Set())) self.assertTrue(is_transitive(Set())) self.assertTrue(is_transitive(Set([Couplet(s, c) for c, s in zip('aba', 'bcc')]))) self.assertIs(is_transitive(Set('a', 'b', 'c')), Undef()) rel = Set(Couplet(s, c) for c, s in zip('aba', 'bcd')) self.assertFalse(is_transitive(rel)) self.assertEqual(rel.cached_transitive, CacheStatus.IS_NOT) f = is_transitive(basic_sets['left func']) self.assertTrue(f) f = is_transitive(basic_sets['not left func']) self.assertTrue(f) f = is_transitive(basic_sets['diagonal']) self.assertTrue(f) f = is_transitive(basic_clans['not left func']) self.assertTrue(f) f = is_transitive(basic_clans['diagonal']) self.assertTrue(f) f = is_transitive(basic_hordes['not left func']) self.assertTrue(f) f = is_transitive(basic_hordes['diagonal']) self.assertTrue(f) s = basic_sets['left func'] self.assertEqual(s.cached_transitive, CacheStatus.IS)
def test_multiset(self): self.print_string('test_multiset') msets = [ Multiset(None, None), Multiset(False, False), Multiset(2, 2, 1), Multiset(2.0, 2.0, 3), Multiset(complex('1+2j')), Multiset('2', '3', '2'), Multiset(bytes(2)), Multiset(range(-1, 5), range(-1, 5), range(1, 5)), Multiset( frozenset([ None, bool(2), int(2), float(2), complex('1+2j'), str(2), bytes(2), range(-1, 5), frozenset([None, None]), tuple((34, 35)), Atom(int(2)), Couplet(-1, -2), Set('x', 'y', 'z') ])), Multiset(tuple((34, 35))), Multiset(Atom('jkh'), Atom('jkh'), Atom('AA'), Atom('jkh')), Multiset(Couplet('a', 1), Couplet('B', 1), Couplet('a', 1)), ] self.verify_string_import_export(msets) self.verify_file_import_export(msets)
def test_project(self): """Basic tests of multiclans.project().""" self.assertIs(project(Undef(), Undef()), Undef()) c1 = ac['clan1'] self.assertIs(project(c1, Undef()), Undef()) c2 = Multiset(Set(Couplet('a', 1)), Set(Couplet('a', 4))) self.assertEqual(project(c1, 'a'), c2)
def test_lhs_cross_functional_union(self): """Test for functional_cross_union.""" table_a = import_csv(self._get_table_a()) table_b = import_csv(self._get_table_b()) self.assertTrue(is_functional(table_a)) self.assertTrue(is_functional(table_b)) # Calculate left join. result = lhs_cross_functional_union(table_a, table_b) # Test result set properties self.assertEqual(result.cached_functional, CacheStatus.IS) self.assertFalse(result.is_empty) self.assertEqual(result.cardinality, 8) expected = import_csv(self._get_result_cross_functional_union()) self.assertEqual(result, expected) import algebraixlib.algebras.sets as sets table_aa = sets.union(table_a, Set(Set(Couplet('PK', '-1'), Couplet('PK', '-2')))) self.assertFalse(is_functional(table_aa)) result = lhs_cross_functional_union(table_aa, table_b) self.assertNotEqual(result.cached_functional, CacheStatus.IS) table_bb = sets.union(table_b, Set(Set(Couplet('PK', '-1'), Couplet('PK', '-2')))) self.assertFalse(is_functional(table_bb)) result = lhs_cross_functional_union(table_a, table_bb) self.assertEqual(result.cached_functional, CacheStatus.IS)
def test_join_binary(self): clan1 = Set(Set([Couplet(1, 'one')])) clan2 = Set(Set([Couplet(2, 'two')])) answer = Set(Set([Couplet(1, 'one'), Couplet(2, 'two')])) joined = join(clan1, clan2) # data is unordered so don't use equality, use symmetric difference self.assertEqual(0, len(answer.data ^ joined.data))
def test_couplet(self): self.print_string('test_couplet') elements = [ None, bool(2), int(2), float(2), complex('1+2j'), str(2), bytes(2), range(-1, 5), frozenset([None, bool(2), int(2), float(2), complex('1+2j'), str(2), bytes(2), range(-1, 5), frozenset([None, None]), tuple((34, 35)), Atom(int(2)), Couplet(-1, -2), Set('x', 'y', 'z') ]), frozenset([Couplet(0, 1), Couplet(2, 3)]), frozenset([Set('a', 'b', 'c'), Set([1, 2, 3])]), tuple((34, 35)), Atom(33), Couplet(0, 'abc'), Set(frozenset([None, 'xyz'])), ] couplets = [Couplet(s, c) for s in elements for c in elements] self.verify_string_import_export(couplets) self.verify_file_import_export(couplets)
def test_is_absolute_member(self): """Basic tests of couplets.is_absolute_member().""" self.assertTrue(is_absolute_member(Couplet(1, 2))) self.assertFalse(is_absolute_member(Couplet(Set(1), 2))) self.assertFalse(is_absolute_member(Undef())) self.assertFalse( is_absolute_member(Couplet(left='b', right=_couplet_a_to_b)))
def test_functional_add(self): rel1 = Set(Couplet('a', 1)) couplet = Couplet('b', 1) rel2 = Set(Couplet('a', 1), Couplet('b', 1)) self.assertEqual(functional_add(rel1, couplet), rel2) self.assertIs(functional_add(rel1, Undef()), Undef()) self.assertIs(functional_add(Undef(), couplet), Undef())
def test_diag(self): """Basic tests of multiclans.diag().""" clan1 = Multiset(Set(Couplet('a'), Couplet('b'))) self.assertEqual(diag('a', 'b'), clan1) self.assertEqual(diag(), Multiset(Set())) self.assertIs(diag(Undef()), Undef()) self.assertIs(diag(Undef(), _checked=False), Undef())
def test_is_transitive(self): """Basic tests of relations.is_transitive().""" self.assertRaises(AttributeError, lambda: is_transitive(3)) self.assertIs(is_transitive(Atom(3)), Undef()) self.assertIs(is_transitive(Undef()), Undef()) self.assertIs(is_transitive(Undef(), _checked=False), Undef()) self.assertTrue(is_transitive(Set(Couplet('a', 'b'), Couplet('b', 'c'), Couplet('a', 'c')))) self.assertFalse(is_transitive(Set(Couplet('a', 'b'), Couplet('b', 'c'))))
def test_getitem(self): self.assertEqual(Multiset()['callable'], Multiset()) # Creating multiclans (multisets of relations) multiset1 = Multiset({Couplet('b', 'w'): 2, Couplet('b', 'y'): 3}) multiset2 = Multiset({Couplet('a', 'x'): 5, Couplet('x', 'y'): 1}) right_values1 = multiset1[Atom('b')] self.assertEqual(right_values1, Multiset({Atom('w'): 2, Atom('y'): 3})) right_values2 = multiset2[Atom('b')] self.assertEqual(right_values2, Multiset())
def aggregate(horde, group_left, aggregation_left, aggregate_func): aggregation = {} for clan in horde: aggregation_value = aggregate_func.identity for relation in clan: aggregation_value = aggregate_func(aggregation_value, relation(aggregation_left).value) first_relation = next(iter(clan)) aggregation[first_relation(group_left)] = aggregation_value return Set([Set(Couplet(group_left, key), Couplet(aggregation_left, aggregation[key])) for key in aggregation])
def test_get_rights_for_left(self): """Basic tests of relations.get_rights_for_left().""" rel1 = Set(Couplet('a', 1), Couplet('a', 2), Couplet('b', 3)) result = Set(1, 2) self.assertEqual(result, get_rights_for_left(rel1, 'a')) self.assertEqual(Set(), get_rights_for_left(rel1, Undef())) self.assertEqual(Set(), get_rights_for_left(rel1, Undef(), _checked=False)) self.assertIs(get_rights_for_left(Undef(), 'a'), Undef()) self.assertRaises(AssertionError, lambda: get_rights_for_left(Undef(), 'a', _checked=False)) self.assertIs(get_rights_for_left(Undef(), Atom('a'), _checked=False), Undef())
def _check_wrong_argument_types_binary(self, operation): self.assertRaises(AttributeError, lambda: operation(3, 4)) self.assertRaises(AttributeError, lambda: operation(Set(Set(Couplet(1, 2))), 3)) self.assertIs(operation(Atom(3), Atom(4)), Undef()) self.assertIs(operation(Set(Set(Couplet(1, 2))), Atom(3)), Undef()) RaiseOnUndef.set_level(1) self.assertRaises(UndefException, lambda: operation(Couplet(1, 2), Couplet(3, 4))) RaiseOnUndef.reset() c = ac['clan1'] self.assertIs(operation(c, Undef()), Undef()) self.assertIs(operation(c, Undef(), _checked=False), Undef()) self.assertIs(operation(Undef(), c), Undef()) self.assertIs(operation(Undef(), c, _checked=False), Undef())
def test_properties(self): def _test_undef(cc): self.assertIs(cc.get_left_set(), Undef()) self.assertIs(is_functional(cc), Undef()) self.assertIs(cc.get_right_set(), Undef()) self.assertIs(is_right_functional(cc), Undef()) self.assertIs(is_bijective(cc), Undef()) self.assertIs(is_transitive(cc), Undef()) self.assertIs(is_equivalence_relation(cc), Undef()) c = Couplet(1, 2) _test_undef(c) self.assertFalse(is_reflexive(c)) c = Couplet(1) _test_undef(c) self.assertTrue(is_reflexive(c))
def test_project(self): clan = basic_clans['left func'] if self.print_examples: ss = clan.get_left_set() pc = _convert_clan_to_list_of_dicts(ss, clan) print(clan) print(ss) print(pc) csv = io.StringIO() export_csv(clan, csv) csv_str = csv.getvalue() self.assertEqual(csv_str, "a,b,c\r\n1,2,3\r\n") if self.print_examples: # \r doesn't print well in the (PyCharm?) console csv_str_pr = 'csv:\n' + csv_str.replace('\r\n', '\n') print(csv_str_pr) clan = Set( Set([Couplet(s, c) for s, c in zip('abcd', [1, 2, 3, "foo, bar"])])) csv = io.StringIO() export_csv(clan, csv) csv_str = csv.getvalue() self.assertEqual(csv_str, """a,b,c,d\r\n1,2,3,"foo, bar"\r\n""")
def test_membership(self): self.assertTrue(is_member(Set())) self.assertTrue(is_member(Set(3))) self.assertFalse(is_member(Atom(3))) self.assertTrue(is_absolute_member(Set(3))) self.assertFalse(is_absolute_member(Set(Couplet(3, 4)))) self.assertRaises(AttributeError, lambda: is_member(3))
def test_permutations(self): self.assertNotEqual(Atom(2), Atom(2.0)) self.assertTrue(Atom(2) != Atom(2.0)) self.assertFalse(Atom(2) == Atom(2.0)) values = [ None, bool(2), int(2), float(2), complex('1+2j'), str(2), bytes(2), range(-1, 5), frozenset([None, None]), tuple((34, 35)), Atom(int(2)), Couplet(-1, -2), Set('x', 'y', 'z') ] test = Atom(frozenset(values)) import itertools def top_n(n, generator): for _ in range(n): yield next(generator) # Test the first 100 permutations of values..frozenset sometimes orders differently # ..need to make sure that doesn't affect our equality check. for p in top_n(100, itertools.permutations(values)): act = Atom(frozenset(p)) if act != test: print("exp", test) print("act", act) self.assertEqual(test, act)
def test_join_quaternary(self): clan1 = Set(Set([Couplet(1, 'one')])) clan2 = Set(Set([Couplet(2, 'two')])) clan3 = Set(Set([Couplet(3, 'three')])) clan4 = Set(Set([Couplet(4, 'four')])) answer = Set( Set(Couplet(1, 'one'), Couplet(2, 'two'), Couplet(3, 'three'), Couplet(4, 'four'))) joined = join(clan1, clan2, clan3, clan4) # data is unordered so don't use equality, use symmetric difference self.assertEqual(0, len(answer.data ^ joined.data))
def test_membership(self): self.assertTrue(is_member(Set(Couplet(1, 2)))) self.assertFalse(is_member(Couplet(3, 4))) self.assertFalse(is_member(Undef())) self.assertTrue(is_absolute_member(Set(Couplet(1, 2)))) self.assertFalse(is_absolute_member(Set(Couplet(Set(3), 4)))) self.assertFalse(is_absolute_member(Undef())) self.assertRaises(AttributeError, lambda: is_member(3)) s = Set(Couplet('field', Set(Couplet('name', 'Value'))), Couplet('field', Set(Couplet('name', 'Year'), Atom('1960')))) self.assertTrue(is_member(s))
def test_less_than(self): for value_key1, set1 in basic_sets.items(): for value_key2, set2 in basic_sets.items(): self.assertNotEqual(set1 < set2, NotImplemented) self.assertNotEqual(set2 < set1, NotImplemented) if set1 == set2: self.assertFalse(set1 < set2) self.assertFalse(set2 < set1) for mo in [Atom(1), Couplet(1, 2), Multiset(1, 2, 3)]: self.assertTrue(mo < set1)
def test_invalid_constructs(self): """Test invalid Atoms.""" self.assertRaises(TypeError, lambda: Atom(MathObject())) self.assertRaises(TypeError, lambda: Atom(Couplet(1, 2))) self.assertRaises(TypeError, lambda: Atom(Set())) self.assertRaises(TypeError, lambda: Atom(Undef())) self.assertRaises(TypeError, lambda: Atom([])) self.assertRaises(TypeError, lambda: Atom([7, '8'])) self.assertRaises(TypeError, lambda: Atom({})) self.assertRaises(TypeError, lambda: Atom({'one': 9, 2: 'ten'}))
def test_is_triple(self): """Test identifying a triple.""" # a relation with left set 'spo' and cardinality 3 triple = Set({Couplet('s', 1), Couplet('p', 2), Couplet('o', 3)}) self.assertTrue(is_triple(triple)) # a relation with left set 'abc' not_triple = Set({Couplet('a', 1), Couplet('b', 2), Couplet('c', 3)}) self.assertFalse(is_triple(not_triple)) # a relation with cardinality 4 not_triple = Set({ Couplet('s', 1), Couplet('p', 2), Couplet('o', 3), Couplet('a', 1) }) self.assertFalse(is_triple(not_triple)) # not a relation not_triple = Set({Atom('s'), Atom('p'), Atom('o')}) self.assertFalse(is_triple(not_triple))
def test_defined_at(self): clan1 = Set(Set(Couplet('a', 1))) self.assertEqual(defined_at(clan1, 'a'), clan1) self.assertIs(defined_at(clan1, 'b'), Undef()) self.assertIs(defined_at(clan1, Undef()), Undef()) self.assertIs(defined_at(Undef(), 'a'), Undef()) self.assertRaises(AssertionError, lambda: defined_at(clan1, 'a', _checked=False)) self.assertIs(defined_at(Undef(), Atom('a'), _checked=False), Undef()) self.assertEqual(defined_at(clan1, Atom('a'), _checked=False), clan1)
def test_flags_relation(self): r = Set(Couplet(s, c) for s, c in zip('abc', [1, 2, 3])) self.assertEqual(r.cached_relation, CacheStatus.UNKNOWN) self.assertEqual(r.cached_clan, CacheStatus.UNKNOWN) self.assertTrue(sets.is_member(r)) # This will NOT trigger structure check self.assertEqual(r.cached_relation, CacheStatus.UNKNOWN) self.assertEqual(r.cached_clan, CacheStatus.UNKNOWN) self.assertTrue(relations.is_member(r)) # This will trigger structure check self.assertEqual(r.cached_relation, CacheStatus.IS) self.assertEqual(r.cached_clan, CacheStatus.IS_NOT)
def test_less_than(self): for value_key1, atom1 in ba.items(): for value_key2, atom2 in ba.items(): self.assertNotEqual(atom1 < atom2, NotImplemented) self.assertNotEqual(atom2 < atom1, NotImplemented) if atom1 == atom2: self.assertFalse(atom1 < atom2) self.assertFalse(atom2 < atom1) for mo in [Couplet(1, 2), Multiset(1, 2, 3), Set(1, 2, 3)]: self.assertTrue(atom1 < mo)
def _couplet_assert(self, test_couplet_name): """Assert that 'couplet' is a proper Couplet with left 'left' and right 'right'.""" test_couplet = basic_couplets[test_couplet_name] left = test_couplet._test_val['left'] right = test_couplet._test_val['right'] couplet = Couplet(left=left, right=right) # Convert the arguments into Atoms if they are values. if not isinstance(left, MathObject): left = Atom(left) if not isinstance(right, MathObject): right = Atom(right) # Test the type structure. self.assertTrue(isinstance(couplet, MathObject)) self.assertFalse(isinstance(couplet, Atom)) self.assertTrue(isinstance(couplet, Couplet)) self.assertFalse(isinstance(couplet, Set)) # Compare the values of right and left. left_val = couplet.left right_val = couplet.right self.assertEqual(left_val, left) self.assertEqual(right_val, right) # Test that the representation caching doesn't change the value. couplet_repr = repr(couplet) self.assertEqual(couplet_repr, repr(couplet)) # Check structure. self.assertEqual(test_couplet.get_ground_set(), _basic_couplets_structs[test_couplet_name]) # Test left set and functionality. self.assertIs(couplet.get_left_set(), Undef()) self.assertIs(is_functional(couplet), Undef()) self.assertIs(couplet('callable'), Undef()) # Make sure that the representation evaluates to a couplet that compares equal. repr_exec = 'self.assertEqual(couplet, {0})'.format(repr(couplet)) exec(repr_exec) # Print the representation and the string conversion. if self.print_examples: print('repr(Couplet(left={left}, right={right})) = {repr}'.format( left=repr(left_val), right=repr(right_val), repr=couplet_repr)) print('str(Couplet(left={left}, right={right})) = {str}'.format( left=str(left_val), right=str(right_val), str=str(couplet)))
def test_properties(self): c = Couplet(1, 2) self.assertIs(c.get_left_set(), Undef()) self.assertIs(c.is_left_functional(), Undef()) self.assertIs(c.get_right_set(), Undef()) self.assertIs(c.is_right_functional(), Undef()) self.assertIs(c.is_bijection(), Undef()) self.assertFalse(c.is_reflexive()) c2 = Couplet(1, 1) self.assertTrue(c2.is_reflexive()) self.assertFalse(c.is_symmetric()) c2 = Couplet(1, 1) self.assertTrue(c2.is_symmetric()) self.assertIs(c.is_transitive(), Undef()) self.assertIs(c.is_equivalence_relation(), Undef())
def test_flags_cache(self): c = Couplet(1, 2) self.assertEqual(c.cached_relation, CacheStatus.IS_NOT) self.assertEqual(c.cached_clan, CacheStatus.IS_NOT) self.assertEqual(c.cached_multiclan, CacheStatus.IS_NOT) self.assertEqual(c.cached_functional, CacheStatus.N_A) self.assertEqual(c.cached_right_functional, CacheStatus.N_A) self.assertEqual(c.cached_regular, CacheStatus.N_A) self.assertEqual(c.cached_reflexive, CacheStatus.UNKNOWN) self.assertEqual(c.cached_symmetric, CacheStatus.N_A) self.assertEqual(c.cached_transitive, CacheStatus.N_A) is_reflexive(c) self.assertEqual(c.cached_reflexive, CacheStatus.IS_NOT) self.assertRaises(AssertionError, lambda: c.cache_relation(CacheStatus.IS)) self.assertRaises(AssertionError, lambda: c.cache_clan(CacheStatus.IS)) self.assertRaises(AssertionError, lambda: c.cache_multiclan(CacheStatus.IS)) self.assertRaises(AssertionError, lambda: c.cache_reflexive(CacheStatus.IS)) self.assertRaises(Exception, lambda: c.cache_transitive(CacheStatus.IS_NOT)) self.assertRaises(Exception, lambda: c.cache_functional(CacheStatus.IS_NOT)) self.assertRaises(Exception, lambda: c.cache_right_functional(CacheStatus.IS_NOT)) self.assertRaises(Exception, lambda: c.cache_regular(CacheStatus.IS_NOT)) self.assertRaises(Exception, lambda: c.cache_symmetric(CacheStatus.IS_NOT)) self.assertRaises(Exception, lambda: c.cache_transitive(CacheStatus.IS_NOT))