def verify_associate_data(*, expected_input_size, input2output, num_outputs): if not is_UInt(expected_input_size): raise TypeError if not is_UInt(num_outputs): raise TypeError if not is_uint_sequence(input2output): raise TypeError if len(input2output) != expected_input_size: raise ValueError if not num_outputs <= expected_input_size: raise ValueError if not max(input2output, default=-1) < num_outputs: raise ValueError return True
def __init__(self, *, num_colors, column2color): if not is_UInt(num_colors): raise TypeError if not is_uint_sequence(column2color): raise TypeError if not max(column2color, default=-1) < num_colors: raise ValueError num_columns = len(column2color) if not num_colors <= num_columns: raise ValueError super().__init__(num_colors=num_colors, column2color=column2color)
def is_maybe_empty_path_ex(ops, obj_to_be_path, obj_to_be_end_fvertex): if not is_UInt(obj_to_be_end_fvertex): return False try: _check_maybe_empty_path_ex(ops.ugraph_fake_embedding, obj_to_be_path, obj_to_be_end_fvertex) except PathInputError: return False return True
def __init__(self, *, num_colors, row2column2color): if not is_UInt(num_colors): raise TypeError if not is_Sequence.of(row2column2color, is_uint_sequence): raise TypeError if not max(chain.from_iterable(row2column2color), default=-1) < num_colors: raise ValueError num_elements = sum(map(len, row2column2color)) if not num_colors <= num_elements: raise ValueError super().__init__(num_colors=num_colors, row2column2color=row2column2color)
def verify_associate_data_ex(*, expected_input_size, maybe_input2output, maybe_num_outputs): if (maybe_num_outputs is None) is not (maybe_input2output is None): raise TypeError if maybe_input2output is None: if not is_UInt(expected_input_size): raise TypeError return True return verify_associate_data(expected_input_size=expected_input_size, input2output=maybe_input2output, num_outputs=maybe_num_outputs)
def __init__(self, *, num_old_colors, compact_new_color2old_color): if not is_UInt(num_old_colors): raise TypeError if not is_uint_sequence(compact_new_color2old_color): raise TypeError if not max(compact_new_color2old_color, default=-1) < num_old_colors: raise ValueError if not is_strictly_increasing(compact_new_color2old_color): raise ValueError num_new_colors = len(compact_new_color2old_color) if not num_new_colors <= num_old_colors: raise ValueError super().__init__( num_old_colors=num_old_colors, compact_new_color2old_color=compact_new_color2old_color)
def _check_maybe_empty_path_ex(ugraph_fake_embedding, path, maybe_end_fvertex): #assert isinstance(ugraph_fake_embedding, UGraphFakeEmbedding) if not is_tuple_of_UInt(path): raise PathInputTypeError if path and not max(path) < ugraph_fake_embedding.num_hedges: raise PathInputTypeError if not (maybe_end_fvertex is None or is_UInt(maybe_end_fvertex)): raise PathInputTypeError if not path and maybe_end_fvertex is None: raise PathInputValueError('empty path should offer end_fvertex') if path: expected_end_fvertex = nonempty_path2end_fvertex__basic(ugraph_fake_embedding, path) if maybe_end_fvertex is None: end_fvertex = expected_end_fvertex else: end_fvertex = maybe_end_fvertex if not end_fvertex < ugraph_fake_embedding.num_hedges: raise PathInputTypeError if path and end_fvertex != expected_end_fvertex: raise PathInputValueError if path: if not is_connected_hedges1__prime(ugraph_fake_embedding, path): raise PathInputValueError('diconnected path') return path, end_fvertex
def is_alternative_idx_maybe_pair(may_pair): if not may_pair: return True ref_symbol_psidx, alternative_tail_idx = pair = may_pair return (is_int(ref_symbol_psidx) and is_UInt(alternative_tail_idx) and is_alternative_tail_idx(alternative_tail_idx) and is_ref_symbol_psidx(ref_symbol_psidx))
def _iter_verify_object_(_, obj): # -> Iter (bool, err_msg_or_f) attr_nums = ''' num_nonterminals num_terminal_sets num_productions num_alternative_tails '''.split() for attr in attr_nums: u = getattr(obj, attr) yield (is_UInt(u), lambda: '{} is not UInt: {!r}'.format(attr, u)) num_nonterminals = obj.num_nonterminals num_terminal_sets = obj.num_terminal_sets num_productions = obj.num_productions num_alternative_tails = obj.num_alternative_tails def is_production_idx(u): return u < num_productions def is_production_idx_seq(ls): return is_Sequence.of(ls, is_production_idx) def is_nonterminal_idx(u): return u < num_nonterminals def is_alternative_tail_idx(u): return u < num_alternative_tails def is_ref_symbol_psidx(i): return -num_terminal_sets <= i < num_nonterminals def is_maybe_pair(x): return is_tuple(x) and len(x) in (2, 0) def is_alternative_idx_maybe_pair(may_pair): if not may_pair: return True ref_symbol_psidx, alternative_tail_idx = pair = may_pair return (is_int(ref_symbol_psidx) and is_UInt(alternative_tail_idx) and is_alternative_tail_idx(alternative_tail_idx) and is_ref_symbol_psidx(ref_symbol_psidx)) def is_strict_sorted_uint_sequence(ls): return is_strict_sorted_sequence.of(ls, is_UInt) triples = \ [('production_idx2nonterminal_idx', num_productions , is_UInt, is_nonterminal_idx) ,('production_idx2alternative_tail_idx', num_productions , is_UInt, is_alternative_tail_idx) ,('alternative_tail_idx2alternative_idx_maybe_pair' , num_alternative_tails , is_maybe_pair, is_alternative_idx_maybe_pair) #('nonterminal_idx2sorted_production_idc' # , num_nonterminals # , is_strict_sorted_uint_sequence, is_production_idx_seq) ] for attr, size, is_type, is_obj in triples: array = getattr(obj, attr) yield (is_Sequence(array), '{} is not Sequence: {!r}'.format(attr, array)) yield (len(array) == size, 'len({}) != {}: {}'.format(attr, size, len(array))) for is_a in [is_type, is_obj]: yield (is_Sequence.of(array, is_a), lambda: '{} is not Sequence<{}>: {!r}'.format( attr, is_a.__name__[3:], array)) pairs = \ [('terminal_set_idx2terminal_set_name', num_terminal_sets) ,('nonterminal_idx2nonterminal_name', num_nonterminals) ,('production_idx2production_name', num_productions) ,('terminal_set_idx2terminal_set', num_terminal_sets) ] for attr, size in pairs: array = getattr(obj, attr) yield (is_Sequence(array), '{} is not Sequence: {!r}'.format(attr, array)) yield (len(array) == size, 'len({}) != {}: {}'.format(attr, size, len(array))) pairs = \ [('alternative_idx_maybe_pair2alternative_tail_idx' ,'alternative_tail_idx2alternative_idx_maybe_pair') ,('terminal_set_name2terminal_set_idx' ,'terminal_set_idx2terminal_set_name') ,('nonterminal_name2nonterminal_idx' ,'nonterminal_idx2nonterminal_name') ,('production_name2production_idx' ,'production_idx2production_name') ] for callable_attr, sequence_attr in pairs: f = getattr(obj, callable_attr) c = getattr(obj, sequence_attr) yield (callable(f), lambda: '{} is not callable: {!r}'.format(callable_attr, f)) for idx, elem in enumerate(c): back_idx = f(elem) yield (is_int(back_idx), lambda: '{}({!r}) is not int: {!r}'. format(callable_attr, elem, back_idx)) yield (back_idx == idx, lambda: '{}({!r}) == {} != {}'.format( callable_attr, elem, back_idx, idx)) ''' ## more for nonterminal_idx2sorted_production_idc nonterminal_idx2sorted_production_idc = obj.nonterminal_idx2sorted_production_idc production_idx2nonterminal_idx = obj.production_idx2nonterminal_idx it = enumerate(nonterminal_idx2sorted_production_idc) for nonterminal_idx, sorted_production_idc in it: for production_idx in sorted_production_idc: _nonterminal_idx = production_idx2nonterminal_idx[production_idx] yield (nonterminal_idx == _nonterminal_idx, lambda: '{pidx} in nonterminal_idx2sorted_production_idc[{nidx}]' ', but production_idx2nonterminal_idx[{pidx}] != {nidx}' .format(nidx=nonterminal_idx, pidx=production_idx) ) L = sum(map(len, nonterminal_idx2sorted_production_idc)) yield (num_productions == L, lambda: 'nonterminal_idx2sorted_production_idc miss some production_idc: {}' .format(set(range(num_productions)) - set(sum(nonterminal_idx2sorted_production_idc)) ) ) ## end of nonterminal_idx2sorted_production_idc ''' attrs = ''' is_empty is_disjoint contains intersection union '''.split() yield (has_attrs(obj.terminal_set_ops, attrs=attrs), lambda: 'terminal_set_ops donot have enough methods: {}'.format(attrs)) # alternative_tail_idx form a DAG u2vtc = [ may_pair[-1:] if may_pair else () for may_pair in obj.alternative_tail_idx2alternative_idx_maybe_pair ] yield (is_u2vtc_DAG(u2vtc, using_std_vertex=True), lambda: 'alternative_tail_idx2alternative_idx_maybe_pair is not DAG')
def _iter_verify_object_(_, obj): # -> Iter (bool, err_msg_or_f) def is_uint_seq(obj): return is_Sequence.of(obj, is_UInt) attrs = UGraphBasic.all_UGraphBasic_attr_seq yield (has_attrs(obj, attrs=attrs), lambda: f'missing some attrs: {attrs!r}') for attr in attrs: value = getattr(obj, attr) if attr.startswith('num_'): yield (is_UInt(value), lambda: f'{attr} is not UInt: {value!r}') else: yield (is_uint_seq(value), lambda: f'{attr} is not UInt sequence: {value!r}') num_vertices = obj.num_vertices num_aedges = obj.num_aedges num_hedges = obj.num_hedges yield (num_hedges == num_aedges * 2, lambda: f'{num_hedges} == num_hedges != num_aedges*2 == {num_aedges}*2') hedge2vertex = obj.hedge2vertex hedge2aedge = obj.hedge2aedge hedge2another_hedge = obj.hedge2another_hedge vertex2degree = obj.vertex2degree # verify len(XXX2YYY) yield ( num_vertices == len(vertex2degree), lambda: f'{num_vertices} == num_vertices != len(vertex2degree) == {len(vertex2degree)}' ) attrs__hedge2XXX = (attr for attr in attrs if attr.startswith('hedge2')) for attr__hedge2XXX in attrs__hedge2XXX: hedge2XXX = getattr(obj, attr__hedge2XXX) len_hedge2XXX = len(hedge2XXX) yield ( num_hedges == len_hedge2XXX, lambda: f'{num_hedges} == num_hedges != len({attr__hedge2XXX!s}) == {len_hedge2XXX!r}' ) # verify max items pairs = [('hedge2vertex', 'num_vertices'), ('hedge2aedge', 'num_aedges'), ('hedge2another_hedge', 'num_hedges') #,('vertex2degree', 'num_vertices') ] for attr__hedge2XXX, attr__num_XXXs in pairs: hedge2XXX = getattr(obj, attr__hedge2XXX) num_XXXs = getattr(obj, attr__num_XXXs) yield ( max(hedge2XXX, default=-1) < num_XXXs, lambda: f'not max({attr__hedge2XXX!s}) < {attr__num_XXXs!s}: max({hedge2XXX!r}) >= {num_XXXs!r}' ) # verify vertex2degree yield (sum(vertex2degree) == num_hedges, lambda: f'sum(vertex2degree) != num_hedges') # verify vertex2degree & hedge2vertex vertex2degree_ = make_vertex2degree.from_hedge2vertex( num_vertices=num_vertices, hedge2vertex=hedge2vertex) yield (all(d == d_ for d, d_ in zip(vertex2degree, vertex2degree_)), lambda: f'hedge2vertex & vertex2degree: wrong vertex degree') # verify hedge2aedge aedge2degree_ = make_vertex2degree.from_hedge2vertex( num_vertices=num_aedges, hedge2vertex=hedge2aedge) yield (all(d_ == 2 for d_ in aedge2degree_), lambda: f'hedge2aedge: wrong aedge degree') #verify hedge2another_hedge yield ( is_uint_bijection_without_self_reflect(hedge2another_hedge, hedge2another_hedge), lambda: f'hedge2another_hedge is not uint_bijection without self_reflect: {hedge2another_hedge!r}' ) # verify hedge2aedge & hedge2another_hedge hedge2another_hedge_ = make_hedge2another_hedge.from_hedge2aedge( hedge2aedge=hedge2aedge) yield ( all(h == h_ for h, h_ in zip(hedge2another_hedge, hedge2another_hedge_)), lambda: f'hedge2aedge & hedge2another_hedge: wrong hedge reversal')
def is_mayuint(obj): return obj is None or is_UInt(obj)
def _iter_verify_object_(_, obj): # -> Iter (bool, err_msg_or_f) def is_uint_seq(obj): return is_Sequence.of(obj, is_UInt) attrs = UGraphFakeEmbedding.all_UGraphFakeEmbedding_attr_seq yield (has_attrs(obj, attrs=attrs), lambda: f'missing some attrs: {attrs!r}') for attr in attrs: value = getattr(obj, attr) if attr.startswith('num_'): yield (is_UInt(value), lambda: f'{attr} is not UInt: {value!r}') else: yield (is_uint_seq(value), lambda: f'{attr} is not UInt sequence: {value!r}') num_hedges = obj.num_hedges num_ffaces = obj.num_ffaces num_fvertices = obj.num_fvertices #verify len of hedge2... #verify len of fface2... #verify len of fvertex2... d = { 'hedge2': 'num_hedges', 'fface2': 'num_ffaces', 'fvertex2': 'num_fvertices' } for attr in attrs: attr_head = attr[:attr.find('2') + 1] if not attr_head: continue attr__XXX2YYY = attr del attr XXX2YYY = getattr(obj, attr__XXX2YYY) len_XXX2YYY = len(XXX2YYY) attr__num_XXXs = d[attr_head] num_XXXs = getattr(obj, attr__num_XXXs) yield ( len_XXX2YYY == num_XXXs, lambda: f'len({attr__XXX2YYY!s}) != {attr__num_XXXs!s}: {len_XXX2YYY!r} != {num_XXXs!r}' ) del d pairs = [('hedge2fake_clockwise_next_hedge_around_vertex', 'hedge2fake_clockwise_prev_hedge_around_vertex'), ('hedge2fake_clockwise_next_hedge_around_fface', 'hedge2fake_clockwise_prev_hedge_around_fface')] for forward_mapping_attr, backward_mapping_attr in pairs: forward_mapping = getattr(obj, forward_mapping_attr) backward_mapping = getattr(obj, backward_mapping_attr) yield ( is_uint_bijection(forward_mapping, backward_mapping), lambda: '({forward_mapping_attr},{backward_mapping_attr}) is not bijection: ({forward_mapping!r}, {backward_mapping!r})' ) hedge2fake_clockwise_next_hedge_around_vertex =\ obj.hedge2fake_clockwise_next_hedge_around_vertex hedge2fake_clockwise_prev_hedge_around_vertex =\ obj.hedge2fake_clockwise_prev_hedge_around_vertex hedge2fake_clockwise_next_hedge_around_fface =\ obj.hedge2fake_clockwise_next_hedge_around_fface hedge2fake_clockwise_prev_hedge_around_fface =\ obj.hedge2fake_clockwise_prev_hedge_around_fface (hedge2another_hedge) = make_hedge2another_hedge( hedge2fake_clockwise_next_hedge_around_vertex= hedge2fake_clockwise_next_hedge_around_vertex, hedge2fake_clockwise_next_hedge_around_fface= hedge2fake_clockwise_next_hedge_around_fface) yield ( is_uint_bijection(hedge2another_hedge, hedge2another_hedge), lambda: f'(hedge2fake_clockwise_next_hedge_around_vertex,hedge2fake_clockwise_next_hedge_around_fface) mismatch: ({hedge2fake_clockwise_next_hedge_around_vertex!r}, {hedge2fake_clockwise_next_hedge_around_fface!r})' ) yield ( all(hedge__from != hedge__to for hedge__from, hedge__to in enumerate(hedge2another_hedge)), lambda: 'hedge2another_hedge should have no self-reflect hedge: hedge2another_hedge={hedge2another_hedge!r}' ) assert num_hedges & 1 == 0 # even fface2degree = obj.fface2degree hedge2fake_clockwise_fface = obj.hedge2fake_clockwise_fface fface2arbitrary_hedge = obj.fface2arbitrary_hedge fvertex2degree = obj.fvertex2degree hedge2fvertex = obj.hedge2fvertex fvertex2arbitrary_hedge = obj.fvertex2arbitrary_hedge #verify value range of XXX2...degree... #verify value range of XXX2...hedge... #verify value range of XXX2...fface... #verify value range of XXX2...fvertex... d = { 'hedge': 'num_hedges', 'fface': 'num_ffaces', 'fvertex': 'num_fvertices' } s = ''' fface2degree hedge2fake_clockwise_fface fface2arbitrary_hedge fvertex2degree hedge2fvertex fvertex2arbitrary_hedge '''.split() for attr__XXX2YYY in s: XXX2YYY = getattr(obj, attr__XXX2YYY) i = max(attr__XXX2YYY.rfind('2'), attr__XXX2YYY.rfind('_')) assert i > 0 attr__YYY = attr__XXX2YYY[i + 1:] if attr__YYY == 'degree': min_XXX2YYY = min(XXX2YYY, default=1) yield ( min_XXX2YYY >= 1, lambda: f'min({attr__XXX2YYY!s}) == {min_XXX2YYY!r} < 1: {XXX2YYY!r}' ) else: attr__num_YYYs = d[attr__YYY] num_YYYs = getattr(obj, attr__num_YYYs) max_XXX2YYY = max(XXX2YYY, default=-1) yield ( max_XXX2YYY < num_YYYs, lambda: f'max({attr__XXX2YYY!s}) == {max_XXX2YYY!r} >= {num_YYYs!r} == {attr__num_YYYs!s}: {XXX2YYY!r}' ) del d, s yield from _verify_3(obj, attr__XXX2degree='fface2degree', attr__hedge2XXX='hedge2fake_clockwise_fface', attr__XXX2arbitrary_hedge='fface2arbitrary_hedge', attr__hedge2next_hedge_around_XXX= 'hedge2fake_clockwise_next_hedge_around_fface', attr__num_XXXs='num_ffaces') yield from _verify_3( obj, attr__XXX2degree='fvertex2degree', attr__hedge2XXX='hedge2fvertex', attr__XXX2arbitrary_hedge='fvertex2arbitrary_hedge', attr__hedge2next_hedge_around_XXX= 'hedge2fake_clockwise_next_hedge_around_vertex', attr__num_XXXs='num_fvertices')
def __init__(self, *, upper_bound, serialization): if not is_UInt(upper_bound): raise TypeError if not is_uint_sequence(serialization): raise TypeError if not max(serialization, default=-1) < upper_bound: raise ValueError super().__init__(upper_bound=upper_bound, serialization=serialization)