404

[ Avaa Bypassed ]




Upload:

Command:

elspacio@3.129.45.202: ~ $
class LeftKanExtension:

    # Implementation of algorithms described by Brown and Heyworth (ref.251)
    # and Heyworth (ref.253).

    def __init__(self, mod, A, B, R, X, F):
        # External subsystem dependencies
        #    mod.KnuthBendix
        #    mod.FiniteAutomaton
        #    mod.SolveFSA
        #    mod.Cat
        #       mod.Cat.Function
        #       mod.Cat.Functor
        #       mod.Cat.check_graph
        #       mod.Cat.check_rules

        self.mod = mod
        self.Cat = mod.Cat

        #

        self.Cat.check_graph(A)
        self.Cat.check_graph(B)
        self.Cat.check_rules(R, B)

        #

        self.A = A
        self.B = B
        self.R = [(tuple(g), tuple(h)) for (g, h) in R]
        self.X = X
        self.F = F

        self.general_procedure()

    def general_procedure(self):
        self.initialize_tables()
        self.make_confluent_system()
        self.make_automaton()  # self.make_catalogue()
        self.make_natural_transformation()

    def initialize_tables(self):
        self.obj_to_str_table = {}
        self.str_to_obj_table = {}
        self.make_initial_rules()

    def make_initial_rules(self):

        # Algorithm 6.1 in (251)

        Re = []

        def add_rule(a, b):
            aw = self.make_word(a)
            bw = self.make_word(b)
            if aw != bw:
                Re.append((aw, bw))

        for a in self.A.arrows:
            srca = self.A.source(a)
            tgta = self.A.target(a)
            XA = self.X.fo(srca)
            Xa = self.X.fa(a)
            Fa = tuple(self.F.fa(a))
            Fsrca = self.F.fo(srca)
            Ftgta = self.F.fo(tgta)
            if Fa:
                t = Fsrca
                for b in Fa:
                    srcb = self.B.source(b)
                    if srcb != t:
                        raise ValueError(
                            'Arrow [%s] with source %s does not compose with target %s' % (b, srcb, t))
                    t = self.B.target(b)
                if t != Ftgta:
                    raise ValueError(
                        'Arrow %s with target %s does not compose with %s' % (Fa, t, Ftgta))
            else:
                if Fsrca != Ftgta:
                    raise ValueError(
                        'Source %s does not match target %s' % (Fsrca, Ftgta))
            for x in XA:
                add_rule(((srca, x),) + Fa, ((tgta, Xa(x)),))

        Rk = [(self.make_word(x), self.make_word(y)) for (x, y) in self.R]

        self.Re = Re
        self.Rk = Rk
        self.Rinit = Re + Rk

    def make_confluent_system(self):
        self.rs = self.mod.KnuthBendix(self.Rinit, delim='.')
        self.Rconf = self.rs.reductions

    def make_automaton(self):
        # Make nondeterministic finite automaton

        def target(e):
            if len(e) == 1 and isinstance(e[0], tuple):
                return self.F.fo(e[0][0])
            else:
                return self.B.target(e[-1])

        XA = []
        for A in self.A.objects:
            for x in self.X.fo(A):
                XA.append(((A, x),))

        follows = dict([(B, []) for B in self.B.objects])
        for b, (srcb, tgtb) in list(self.B.arrows.items()):
            follows[srcb].append((b, tgtb))

        IR = dict([(self.make_term(u), self.make_term(v))
                   for u, v in self.Rconf])

        pplR = {}
        for l, r in self.Rconf:
            t = self.make_term(l)
            for i in range(1, len(t)):
                pplR[t[:i]] = 1

        s0 = ('s0',)

        fsa = self.mod.FiniteAutomaton(s0)

        for xi in XA:
            if xi not in IR:
                fsa.add_transition(s0, xi[0], xi)

        for xi in XA:
            for b, tgtb in follows[target(xi)]:
                bterm = (b,)
                xib = xi + bterm
                if xib in pplR:
                    fsa.add_transition(xi, b, xib, tgtb)
                elif (bterm in pplR and xib not in IR):
                    fsa.add_transition(xi, b, bterm, tgtb)
                elif xib not in IR:
                    fsa.add_transition(xi, b, tgtb)

        for Bi in self.B.objects:
            for b, tgtb in follows[Bi]:
                bterm = (b,)
                if bterm in pplR:
                    fsa.add_transition(Bi, b, bterm, tgtb)
                elif bterm not in IR:
                    fsa.add_transition(Bi, b, tgtb)

        for u in pplR:
            if u in XA:
                continue
            for b, tgtb in follows[target(u)]:
                bterm = (b,)
                ub = u + bterm
                if ub in pplR:
                    fsa.add_transition(u, b, ub, tgtb)
                elif self.irreducible(ub):  # ub not in IR:
                    fsa.add_transition(u, b, tgtb)

        def get_RS(Bi):
            finals = {}
            finals[Bi] = 1
            for xi in XA:
                if self.F.fo(xi[0][0]) == Bi:
                    finals[xi] = 1
            for u in pplR:
                if target(u) == Bi:
                    finals[u] = 1

            for c in fsa.get_composites():
                for s in c:
                    if s not in finals:
                        break
                else:
                    finals[c] = 1

            dfa = fsa.get_minimized_dfa(finals)
            regexp = self.mod.SolveFSA(dfa)
            return RegularSet(regexp)

        KB = self.Cat.Function(get_RS, self.B.objects, None)

        Kb = self.Cat.Function(
            lambda a: KanAction(self.B, KB, a, target,
                                self.irreducible, self.reduce),
            self.B.arrows,
            KanAction,
        )

        self.KB = KB
        self.Kb = Kb
        self.K = self.Cat.Functor(KB, Kb)

    def make_catalogue(self):
        # Catalogue the elements of the sets pointed to by extension functor K,
        # according to algorithm described in 7.1 in (251).

        # Precondition:

        # Tables initialized and a confluent system created.
        # The system is assumed to be finite, otherwise we won't terminate.

        # Postcondition:

        # Functor self.K represented as:
        #
        # self.K.tabo = self.KB = dict mapping,
        #               source: {each B in self.B.objects}
        #               target: sets represented as lists
        # self.K.taba = self.Kb = dict, mapping
        #               source: {each a in self.B.arrows}
        #               target: tabulated function, mapping
        #                       source: KB[source of a]
        #                       target: KB[target of a]

        def target(e):
            if len(e) == 1:
                return self.F.fo(e[0][0])
            else:
                return self.B.target(e[-1])

        def add_element(e):
            if self.irreducible(e):
                block.append(e)
                KB[target(e)].append(e)
            else:
                pass

        KB = dict([(B, []) for B in self.B.objects])
        block = []

        for A in self.A.objects:
            for x in self.X.fo(A):
                add_element(((A, x),))

        while block:
            oblock = block
            block = []
            for e in oblock:
                tgt = target(e)
                for a in self.B.arrows:
                    if self.B.source(a) == tgt:
                        add_element(e + (a,))

        Kb = {}

        for a in self.B.arrows:
            src = KB[self.B.source(a)]
            tgt = KB[self.B.target(a)]
            tab = dict([(s, self.reduce(s + (a,))) for s in src])
            Kb[a] = self.Cat.Function(tab, src, tgt)

        KB = self.Cat.Function(KB, self.B.objects, list(KB.values()))
        Kb = self.Cat.Function(Kb, self.B.arrows, list(Kb.values()))

        self.KB = KB
        self.Kb = Kb
        self.K = self.Cat.Functor(KB, Kb)

    def make_natural_transformation(self):

        # Precondition:
        # initial tables should be initialized
        # self.K.fo should exist

        # Postcondition:
        #
        # self.nat[A] for A in self.A.objects

        get_nat_memo = {}

        def get_nat(A):
            if A in get_nat_memo:
                return get_nat_memo[A]

            src = self.X.fo(A)
            tgt = self.K.fo(self.F.fo(A))
            tab = dict([(x, self.reduce(((A, x),))) for x in src])
            get_nat_memo[A] = self.Cat.Function(tab, src, tgt)
            return get_nat_memo[A]

        self.nat = self.Cat.Function(get_nat, self.A.objects, None)

    def make_word(self, x):
        ots = self.obj_to_str
        return '.'.join([ots(e) for e in x if e != ''])

    def obj_to_str(self, x):
        otn = self.obj_to_str_table
        try:
            return otn[x]
        except KeyError:
            assert not (isinstance(x, tuple) and len(x) > 2)
            n = str(len(otn))
            #n = '%d:%s'%(len(otn), x)
            #n = str(x)
            otn[x] = n
            self.str_to_obj_table[n] = x
            return n

    def str_to_obj(self, x):
        return self.str_to_obj_table[x]

    def irreducible(self, x):
        tx = self.make_word(x)
        return tx == self.rs.reduce(tx)

    def reduce(self, x):
        w = self.rs.reduce(self.make_word(x))
        return self.make_term(w)

    def make_term(self, word):
        sto = self.str_to_obj_table
        return tuple([sto[s] for s in word.split('.') if s])


class KanAction:
    def __init__(self, B, KB, a, targetof, irreducible, reduce):
        srca = B.source(a)
        tgta = B.target(a)
        self.src = KB(srca)
        self.tgt = KB(tgta)
        self.a = a
        self.srca = srca
        self.targetof = targetof
        self.irreducible = irreducible
        self.reduce = reduce

    def __call__(self, s):
        if self.targetof(s) != self.srca:
            raise TypeError('''\
Target of %r (= %r) does not match source of %r (= %r)''' % (
                s, self.targetof(s), self.a, self.srca))
        if not self.irreducible(s):
            raise TypeError('''\
Argument %r is reducible to %r; and is thus not in the source set K.fo(%r)''' % (
                s, self.reduce(s), self.srca))
        return self.reduce(s + (self.a,))


class RegularSet:
    # Wraps a regular expression;
    # provides a set protocol for the underlying set of sequences:
    #  o If the RE specifies a finite language, iteration over its strings
    #  [ o set inclusion ]

    is_simplified = 0

    def __init__(self, re):
        self.re = re

    def __iter__(self):
        return iter(self.uniform)

    def __getitem__(self, x):
        return self.uniform[x]

    def __len__(self):
        return len(self.uniform)

    def get_xs_covered(self, coverage):
        N = coverage
        X = self.re.limited(coverage)
        xs = X.sequni()
        return [tuple(x) for x in xs]

    def get_uniform(self):
        self.simplify()
        return self.re.sequni()

    uniform = property(fget=get_uniform)

    def simplify(self):
        if not self.is_simplified:
            self.re = self.re.simplified()
            self.is_simplified = 1


class ObjectTester:
    def __init__(self, category_tester, object, code):
        self.category_tester = category_tester
        self.functor = category_tester.functor
        self.object = object
        self.code = code

    def get_all_arrows(self):
        return self.category_tester.arrows[self.object]

    def get_intermediate_test_code(self):
        return self.code

    def get_python_test_source_code(self):
        cmap = {
            'aseq': 'assert e[%r] == e[%r]',
            'evalfa': 'e[%r] = fa[%r](e[%r])',
            'asfo': 'assert fo[%r](e[%r])'
        }

        return '\n'.join([cmap[c[0]] % c[1:] for c in self.code])

    def execode(self, arg):
        code = self.get_python_test_source_code()

        e = {'arg': arg}
        d = {'fa': self.functor.fa,
             'fo': self.functor.fo,
             'e': e,
             }
        exec(code, d)
        return e

    def intercode(self, arg):
        e = {'arg': arg}
        fa = self.functor.fa
        fo = self.functor.fo
        for c in self.code:
            a = c[0]
            if a == 'evalfa':
                dst, ar, src = c[1:]
                e[dst] = fa[ar](e[src])
            elif a == 'asfo':
                ob, src = c[1:]
                if not fo[ob](e[src]):
                    raise ValueError('Predicate failed')
            elif a == 'aseq':
                na, nb = c[1:]
                if e[na] != e[nb]:
                    raise ValueError('e[%r] != e[%r]' % (na, nb))
            else:
                raise ValueError('Invalid code: %r' % (a,))

    def test(self, arg):
        return self.intercode(arg)


class CategoryTester:
    def __init__(self, mod, functor, arrows, get_arrow_name=None):
        self.mod = mod
        self.cat = functor.src
        self.functor = functor
        self.arrows = arrows
        if get_arrow_name is not None:
            self.get_arrow_name = get_arrow_name

    def get_arrow_name(self, a):
        return '.'.join(a)

    def get_eval_arrows_code(self, object, argname):
        fa = self.functor.fa

        name = argname
        memo = {(): name}
        memolist = [((), name)]

        codes = []

        def eval_arrow(a):
            if a in memo:
                return memo[a]
            a0 = a[:-1]
            a1 = a[-1]
            name = self.get_arrow_name(a)
            na0 = eval_arrow(a0)
            #codes.append('%s = fa[%r](%s)'%(name, a1, na0))
            codes.append(('evalfa', name, a1, na0))
            memo[a] = name
            memolist.append((a, name))
            return name

        for ar in self.arrows[object]:
            eval_arrow(ar)

        return codes, memolist

    def get_object_tester(self, object):
        code = self.get_test_object_code(object)
        return ObjectTester(self, object, code)

    def get_test_inclusion_code(self, object, ml):
        codes = []
        src = self.functor.fo.src
        for arrow, value in ml:
            ob = object
            if arrow:
                ob = self.cat.graph.target(arrow[-1])
            #codes.append('assert fo[%r](%s)'%(ob, value))
            if src is None or ob in src:
                codes.append(('asfo', ob, value))
        return codes

    def get_test_object_code(self, object):
        argname = 'arg'
        evalcodes, memolist = self.get_eval_arrows_code(object, argname)

        relcodes = self.get_test_relations_code(object, memolist)

        incodes = self.get_test_inclusion_code(object, memolist)

        return evalcodes+relcodes+incodes

    def get_test_relations_code(self, object, memolist):
        codes = []
        cat = self.cat
        fa = self.functor.fa
        memo = dict(memolist)

        def teval_arrow(ar):
            if ar in memo:
                return memo[ar]
            a0 = teval_arrow(ar[:-1])
            name = self.get_arrow_name(ar)
            #codes.append('%s = fa[%r](%s)'%(name, ar[-1], a0))
            codes.append(('evalfa', name, ar[-1], a0))
            memo[ar] = name
            return name

        # Check that the equality relations really match up
        # for all arrows in old memolist, i.e. original unique arrows
        # which is arguably overkill sometimes?..
        for a, b in cat.relations:
            a = tuple(a)
            b = tuple(b)
            src = cat.graph.source(a[0])
            for (arr, val) in memolist:
                if arr:
                    tgt = cat.graph.target(arr[-1])
                else:
                    tgt = object
                if src == tgt:
                    ara = arr + a
                    arb = arr + b
                    if ara != arb:
                        va = teval_arrow(ara)
                        vb = teval_arrow(arb)
                        assert va != vb
                        #codes.append('assert %s == %s'%(va, vb))
                        codes.append(('aseq', va, vb))
        return codes

    def test_object(self, object, value):
        tester = self.get_object_tester(object)
        tester.test(value)
        return tester

    def test_object_fail(self, object, value):
        try:
            self.test_object(object, value)
        except Exception:
            pass
        else:
            raise Exception('Exception excepted')


class _GLUECLAMP_:
    # 'imports'

    def _get_KnuthBendix(self): return self._parent.KnuthBendix.KnuthBendix
    def _get_FiniteAutomaton(self): return self._parent.FSA.FiniteAutomaton
    def _get_SolveFSA(self): return self._parent.RE.SolveFSA
    def _get_Cat(self): return self._parent.Cat

    # Main exported interface is the lke method
    # which provides a context for the LeftKanExtension class.

    def lke(self, A, B, R, X, F):
        return LeftKanExtension(self, A, B, R, X, F)

    # Other functions - examples of applications of Kan extension
    # in alphabetic order

    def arrows_map(self, cat, from_objects=0, coverage=1):
        if from_objects:
            cat = cat.get_dual()

        A = self.Cat.Graph(cat.graph.objects, [])
        B = cat.graph
        R = cat.relations
        X = self.Cat.Functor(lambda x: [1], lambda x: lambda y: y)
        F = self.Cat.Functor(lambda x: x, lambda x: [])
        ke = self.lke(A, B, R, X, F)

        memo = {}

        def get_arrows(object):
            if object in memo:
                return memo[object]
            re = ke.K.fo[object].re.rempretup()
            if from_objects:
                re = re.reversed()
            if str(coverage).startswith('length'):
                maxlen = int(coverage[6:])
                ar = []
                xs = re.get_words_memo()
                for i in range(1, maxlen+1):
                    ar.extend([tuple(x) for x in xs.get_words_of_length(i)])
            else:
                re = re.limited(coverage)
                xs = re.sequni()
                ar = [tuple(x) for x in xs]
            memo[object] = ar
            return ar

        return self.Cat.Function(
            get_arrows,
            src=ke.K.fo.src,
            tgt=None
        )

    def category_tester(self, functor, arrows=None, coverage=1):
        if isinstance(functor, tuple):
            fo, fa, src = functor
            if fo is None:
                def fo(x): return lambda y: 1
            functor = self.Cat.Functor(fo, fa, src)
        if arrows is None:
            arrows = self.arrows_map(
                functor.src, from_objects=1, coverage=coverage)
        return CategoryTester(self, functor, arrows)

    def coequalizer(self, S0, S1, f0, f1):
        # Given
        #
        # S0, S1 sets (objects that can be iterated over)
        # f0, f1 functions from S0 to S1
        #
        # Return a coequalizing function,
        # such that in the following diagram:

        #
        #  S0 ===== S0
        #  |        |
        #  | f0     | f1
        #  |        |
        #  V        V
        #  S1 ===== S1 ==== coequalizing_function.src
        #  |
        #  | coequalizing_function
        #  |
        #  V
        #  coequalizing_function.tgt

        # both paths from S0 to coequalizing_function.tgt will be equivalent,
        # and coequalizing_function.tgt is a colimit of all such sets.
        #
        # The coequalizing_function object is callable with
        # an argument from S1, and has the following attributes:
        #   .src                is identical to S1
        #   .tgt                is a set in iterable form
        #   .asdict()           returns a dict representing the mapping

        objects = [0, 1]
        arrows = {'a0': (0, 1), 'a1': (0, 1)}
        A = self.Cat.Graph(objects, arrows)

        Xo = self.Cat.Function({0: S0, 1: S1}, objects, [S0, S1])
        Xa = self.Cat.Function({'a0': f0, 'a1': f1}, arrows, [f0, f1])
        X = self.Cat.Functor(Xo, Xa)

        colimit_object, colimit_functions = self.colimit(A, X)
        return colimit_functions[1]

    def colimit(self, A, X):
        # According to 9.6 in (ref.251)

        B = self.Cat.Graph([0], {})
        R = []
        F = self.Cat.Functor(lambda x: 0, lambda x: ())

        lka = self.lke(A, B, R, X, F)

        colimit_object = lka.KB[0]
        colimit_functions = lka.nat

        # Reduce elements to a smaller (but isomorphic) form
        # I.E since elements are all of the form
        #       ((A, X),)
        # they can be reduced to the form
        #       (A, X)
        #

        colimit_object = [x[0] for x in colimit_object]

        colimit_functions = dict([
            (A, self.Cat.Function(
                dict([(a, k[0])
                      for (a, k) in list(cof.items())]),
                cof.src,
                colimit_object,
            )
            )
            for (A, cof) in list(colimit_functions.items())])

        return colimit_object, colimit_functions

    def test_arrows(self, functor, object, value):
        # Application of arrow listing to test sequencing
        # Discussed in Notes Mar 9 2005

        tester = self.category_tester(functor)
        return tester.test_object(object, value)

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
Cat.py File 3.99 KB 0644
Code.py File 1.03 KB 0644
Descriptor.py File 903 B 0644
FSA.py File 7.2 KB 0644
Glue.py File 13.68 KB 0644
Help.py File 6.71 KB 0644
IterPermute.py File 2.22 KB 0644
KanExtension.py File 20.71 KB 0644
KnuthBendix.py File 8.81 KB 0644
RE.py File 23.59 KB 0644
RE_Rect.py File 10.39 KB 0644
__init__.py File 87 B 0644
cmd.py File 14.72 KB 0644
etc.py File 1.66 KB 0644
textView.py File 3.07 KB 0644
tkcursors.py File 2.13 KB 0644
xterm.py File 2.31 KB 0644