Viewing file: RefPat.py (18.18 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
def str_as_atr(s): if s == '_': return [] atr = [] i = 0 while i < len(s): v = s[i] if i + 1 < len(s) and s[i+1].isdigit(): n = 0 i = i + 1 while i < len(s) and s[i].isdigit(): n = n * 10 + int(s[i]) i += 1 else: i += 1 n = 1 for j in range(n): atr.append(v) return atr
def atr_as_str(atr): if not atr: return '_' prefl = [] prestr = ''.join([str(x) for x in atr]) i = 0 while i < len(prestr): c = prestr[i] j = i+1 while j < len(prestr) and prestr[j] == c: j += 1 if j - i > 2: prefl.append(c) prefl.append(str(j-i)) else: while i < j: prefl.append(c) i += 1 i = j return ''.join(prefl)
def str_as_ixl(s): return [ord(ch)-ord('a') for ch in str_as_atr(s)]
def ixl_as_str(ixl): return atr_as_str([chr(ix + ord('a')) for ix in ixl])
class Paths: def __init__(self, mod, rp, key, extended=True, andsets=(), variant=2): self.mod = mod self._hiding_tag_ = mod._hiding_tag_ self.key = key self.rp = rp self.extended = extended self.srcrow = rp.get_row(self.key) self.variant = variant self.andsetbyname = {} row = self.srcrow while row is not None: self.andsetbyname[row.ixlstr] = mod.Use.Anything row = row.parent
if isinstance(andsets, dict): self.andsetbyname.update(andsets) elif isinstance(andsets, (tuple, list)): row = self.srcrow for i, s in enumerate(andsets): if row is None: raise ValueError('andsets argument is too long') if s is not None: self.andsetbyname[row.ixlstr] = s row = row.parent else: raise TypeError('andsets argument must be dict, tuple, or list')
mod.OutputHandling.setup_printing( self, stop_only_when_told=variant >= 2)
def get_str_of_path_component_singleton(self, set): return set.brief.lstrip('<1 ').rstrip('>')
def source_to_target_info(self): src = 'Source' tgt = 'Target' via = 'Via'
row = self.srcrow indent = 0 while row is not None: if row.parent is None: a = tgt elif row is srcrow: a = src else: a = via a = ' '*indent + a name = row.ixlstr a = a + ' ' + ' '*(8+srcrow.depth*indinc - len(name)-len(a)) + name + ': ' yield a+row.getsummary(mod.line_length-len(a)) row = row.parent indent += indinc
def _oh_get_label(self): return 'Paths from source %r to target %r.' % (self.srcrow.ixlstr, '_')
def _oh_get_line_iter(self): return getattr(self, 'get_line_iter_%s' % (self.variant,))()
def _oh_get_more_state_msg(self, startindex, lastindex): return ''
def get_line_iter_1(self): # Original variant indenting from left to right
mod = self.mod
srcrow = self.srcrow srcset = srcrow.set
indinc = 2 if srcrow.depth >= 10: indinc = 1
def genlines(row, ks, indent=0): par = row.parent for key, i, set in ks: sidx = '%s[%d]' % (row.ixlstr, i)
if self.extended: strsing = self.get_str_of_path_component_singleton(set) else: strsing = '' vline = '%s %s %s %s' % ( key, ' '*(40-len(key) - len(sidx)), sidx, strsing )
yield vline
if par is None: continue
def get_nks(key, set): parset = set.referents & par.set for i, p in enumerate(parset.byid.parts): rels = mod.Path.relations(set.theone, p.theone) for rel in rels: if rel is mod.Path.identity: continue if rel is mod.Path.norelation: k = '??' else: k = str(rel) % '' k = ' '*(indent+indinc)+k yield k, i, p
for line in genlines(par, get_nks(key, set), indent+indinc): yield line
def get_ks(): for i, s in enumerate(srcset.byid.parts): k = '[%d] ' % i k = k + (' -'*20)[:36-len(k)-srcrow.depth] yield k, i, s
for line in genlines(srcrow, get_ks()): yield line return
def get_line_iter_2(self): # Newer variant
mod = self.mod
srcrow = self.srcrow
indinc = 1 if srcrow.depth >= 10: indinc = 1
lno = [0]
seen = {}
indir = 1
if indir == 1: max_ixlstr_len = 0 max_str_len_set = 0 row = srcrow while row: if len(row.ixlstr) > max_ixlstr_len: max_ixlstr_len = len(row.ixlstr) if len(str(len(row.set.nodes))) > max_str_len_set: max_str_len_set = len(str(len(row.set.nodes))) row = row.parent
def genlines(row, part, idx):
seen[part.nodes, row.depth] = lno[0] sidx = row.ixlstr idxs = '[%d]' % idx if indir < 0: indent = (row.depth)*indinc sidx = '%s%s%s' % ( sidx, ' '*(6+indent-len(sidx)-len(idxs)), idxs) if row.parent is None: sidx += ' == %s' % part.brief
else: #idxs = ('[%.'+str(max_str_len_set)+'d]')%idx sidx = '%s%s%s' % (sidx, ' '*(3+max_str_len_set + max_ixlstr_len-len(sidx)-len(idxs)), idxs) sidx += ' ' * (srcrow.depth + 1 - row.depth) if row.parent is not None: sidx += '@' else: sidx += '= %s' % part.brief
if row.parent is None: #vline += ' == %s'%self.get_str_of_path_component_singleton(part) vline = '%2s: %s' % (lno[0], sidx) lno[0] += 1 yield ('STOP_AFTER', vline) return
referents = part.referents & row.parent.set & self.andsetbyname[row.parent.ixlstr] relations = mod.Path.relations iso = mod.Use.iso s = part.theone t = [(relations(s, p.theone), p.by(referents.er), i) for (i, p) in enumerate(referents.byid.parts)] for (rels, p, i) in t: relstrings = [] for rel in rels: if rel is mod.Path.identity: continue if rel is mod.Path.norelation: k = '??' else: k = str(rel) % '' relstrings.append(k)
relsstr = ' / '.join(relstrings) seenlno = seen.get((p.nodes, row.parent.depth)) vline = '%2s: %s' % (lno[0], sidx) lno[0] += 1 if seenlno is not None: relsstr += ' -> #%d' % seenlno yield ('STOP_AFTER', vline + ' ' + relsstr) else: yield vline + ' ' + relsstr for line in genlines(row.parent, p, i): yield line
for i, p in enumerate((srcrow.set & self.andsetbyname[srcrow.ixlstr]).byid.parts): for line in genlines(srcrow, p, i): yield line
class RefPatIter: def __init__(self, rp, start=0): self.rp = rp self._hiding_tag_ = rp._hiding_tag_ self.ix = start
def __iter__(self): return self
def __next__(self): try: x = self.rp[self.ix] except IndexError: raise StopIteration self.ix += 1 return x
class RefPatRow: def __init__(self, rp, kindset, seenline, ixl, parent): self.rp = rp self._hiding_tag_ = rp._hiding_tag_ self.kindset = kindset self.kind, self.set = kindset assert self.set <= self.kind self.seenline = seenline self.ixl = ixl[:] self.parent = parent if parent is not None: self.depth = parent.depth + 1 else: self.depth = 0
self.index = 0 self.maxdepth = rp.depth self.max_str_len = rp.mod.line_length self.ixlstr = ixl_as_str(ixl) self.isready = 0 self.children = []
def __str__(self): prestr = '%2d: %s ' % (self.index, self.ixlstr)
if self.index & 1: fillpat = ' ' * 100 else: fillpat = '-'*100
lps = len(prestr) fill = fillpat[lps:9+self.depth]
if self.seenline: ref = '[^ %s]' % self.seenline.index elif self.isroot: ref = '[R]' elif self.depth > 0 and self.set <= self.rp.stopkind: ref = '[S]' elif self.depth < self.maxdepth: ref = '[-]' else: ref = '[+]'
prefix = '%s%s %s ' % (prestr, fill, ref) return '%s%s' % (prefix, self.getsummary(self.max_str_len-len(prefix)))
def getchild(self, ix): while ix >= len(self.children) and not self.isready: self.rp.generate(len(self.rp.lines)) return self.children[ix]
def getsummary(self, max_len): kind, set = self.kind, self.set summary = set.fam.get_str_refpat(set, kind, max_len) return summary
class ReferencePattern: __doc__ = '<Help Text' help = """\ Methods
"""
def __init__(self, mod, set, depth, er, relimg, bf, stopkind, nocyc): self.mod = mod self._hiding_tag_ = mod._hiding_tag_ self.View = mod.View self.set = set self.depth = depth self.er = er self.bf = bf self.stopkind = stopkind self.nocyc = nocyc self.is_initialized = 0
self.totcount = set.count self.totsize = set.indisize self.kind = set.kind self.kindset = (self.kind, self.set) self.relimg = relimg self.top = self
mod.OutputHandling.setup_printing(self) self.View.referrers_add_target(self) self.reset_nogc() self.is_initialized = 1
def __getattr__(self, s): if not self.is_initialized: raise AttributeError(s)
try: return getattr(self.__class__, s) except AttributeError: pass try: row = self.get_row_named(s) except ValueError: raise AttributeError(s) return row.set
def __getitem__(self, ix): return self.get_row_indexed(ix).set
def __iter__(self, start=0): return RefPatIter(self, start)
def __len__(self): self.generate() return len(self.lines)
def _oh_get_label(self): return 'Reference Pattern by <' + self.er.classifier.get_byname() + '>.'
def _oh_get_more_state_msg(self, startindex, lastindex): if self.isfullygenerated: msg = '%d more lines. ' % (len(self.lines) - 1-lastindex,) else: msg = '' return msg
def _oh_get_line_iter(self): it = self.iterlines(0) for el in it: yield str(el)
def generate(self, ix=None): while ix is None or ix < 0 or ix >= len(self.lines): try: self.lines.append(next(self.lg)) except StopIteration: self.isfullygenerated = 1 return self.lines[-1].index = len(self.lines) - 1
def get_row(self, key): try: [][key] except TypeError: return self.get_row_named(key) except IndexError: return self.get_row_indexed(key)
def get_row_indexed(self, ix): self.generate(ix) return self.lines[ix]
def get_row_named(self, name): row = self.get_row_indexed(0) for ix in str_as_ixl(name): try: row = row.getchild(ix) except IndexError: raise ValueError( 'Reference pattern has no row named %r' % name) return row
def iterlines(self, start=None): if start is None: start = 0 while 1: try: yield self.get_row_indexed(start) except IndexError: return start += 1
def linegenerator(self, xxx_todo_changeme, ixl, parent=None): (kind, set) = xxx_todo_changeme seenline = self.seensets.get(set.nodes) ixl = list(ixl) line = RefPatRow(self, (kind, set), seenline=seenline, ixl=ixl, parent=parent) children = self.get_children(line) line.isroot = not children if seenline is None: self.seensets[set.nodes] = line if parent is not None: parent.children.append(line) yield line
depth = line.depth if (not seenline and depth < self.depth and (depth == 0 or not (set <= self.stopkind))): for i, cs in enumerate(children): ixl.append(i) for rl in self.linegenerator(cs, ixl, line): yield rl ixl.pop() line.isready = 1
def get_children(self, line): (kind, set) = line.kindset chset = self.relimg(set) if self.nocyc: while line is not None: chset -= line.set line = line.parent return [(row.kind, row.set) for row in self.get_partition(chset, self.er).get_rows()]
def get_partition(self, set, er): p = self.mod.Part.partition(set, er) return p
def paths(self, key, **kwds): return Paths(self.mod, self, key, **kwds)
def reset(self): self.reset_nogc() self.printer.reset() self.mod._root.gc.collect()
def reset_nogc(self): self.isfullygenerated = 0 self.seensets = {} self.lines = [] self.lg = self.linegenerator(self.kindset, []) self.lastindex = None
class _GLUECLAMP_: _preload_ = ('_hiding_tag_',)
depth = 7 line_length = 80
_uniset_exports = ('rp',) _chgable_ = ('er', 'depth', 'line_length', )
# 'module imports'
_imports_ = ( '_parent:OutputHandling', '_parent:Part', '_parent:Path', '_parent:UniSet', '_parent:Use', '_parent:View', '_parent.View:_hiding_tag_', )
#
def _get_er(self): return self.Use.Clodo
def _get_stopkind(self): hp = self.Use return ( hp.Type.Module | hp.Type.Type | hp.Type.Module.dictof | hp.Type.Type.dictof | hp.Type.Code | hp.Type.Frame )
def rp(self, X, depth=None, er=None, imdom=0, bf=0, src=None, stopkind=None, nocyc=False, ref=None): """rp(X, depth=None, er=None, imdom=0, bf=0, src=None, stopkind=None, nocyc=False, ref=None) Reference pattern forming. Arguments X Set of objects for which a reference pattern is sought. depth The depth to which the pattern will be generated. The default is taken from depth of this module. er The equivalence relation to partition the referrers. The default is Clodo. imdom If true, the immediate dominators will be used instead of the referrers. This will take longer time to calculate, but may be useful to reduce the complexity of the reference pattern. bf If true, the pattern will be printed in breadth-first order instead of depth-first. (Experimental.) src If specified, an alternative reference source instead of the default root. stopkind nocyc ref
Description Return a reference pattern object based on the objects in the set X. The reference pattern object is of class ReferencePattern. It is described in XXX. """ if depth is None: depth = self.depth X = self.UniSet.idset_adapt(X) if src is not None: # Creates an entire new guppy tree # Mostly for testing purposes - # can likely cause type problems generally src = self.UniSet.idset_adapt(src) self = self._root.guppy.Root().guppy.heapy.RefPat self.View.root = tuple(src.nodes) X = self.Use.idset(X.nodes)
if er is None: er = self.er # NEEDS to be loaded after new Classifier created if imdom: def relimg(X): return X.imdom elif ref is not None: if ref == 'gc': def relimg(X): return X.referrers_gc elif ref == 'gcx': relimg = (lambda x: x.referrers_gc - self._root.guppy.sets.ImmNodeSet - self._parent.heapyc.NodeGraph - self.View.ObservationList) elif ref == 'imdom': def relimg(X): return X.imdom elif callable(ref): relimg = ref else: raise ValueError( "ref should be 'gc', 'gcx', 'imdom', or a callable") else: def relimg(X): return X.referrers if stopkind is None: stopkind = self.stopkind rp = ReferencePattern(self, X, depth, er, relimg, bf, stopkind, nocyc) return rp
|