📦 Out of Context リポジトリ

リポジトリ / emssr / independent_common_compiler

r2
r2 emssr1
# -*- coding: utf-8 -*-
r2 emssr2
"""接合秩。
r2 emssr3
r2 emssr4
doc: joinrank matrix.reduce
r2 emssr5
r2 emssr6
Common-Lang/1 定理 4.1。入力の分割 [n] = A ⊔ B と値の行列
r2 emssr7
r2 emssr8
    F[α][β] = f(α, β)          α ∈ {0,1}^A,  β ∈ {0,1}^B
r2 emssr9
r2 emssr10
に対し、F2 上の階数 ρ = rank F が
r2 emssr11
r2 emssr12
    f(x_A, x_B) = ⊕_{r=1}^{ρ} p_r(x_A) q_r(x_B)
r2 emssr13
r2 emssr14
の分離積の最小本数になる。ρ が「カットを渡る独立影響の本数」であり、
r2 emssr15
分解が立つとき縮約行列はテンソル積へ割れる。
r2 emssr16
r2 emssr17
    M_f = M_g (M_{h_A} ⊗ M_{h_B})
r2 emssr18
r2 emssr19
階数は掃き出しで取らない。ピボットの選び方は文に現れない量になるので、⊕ 閉包の
r2 emssr20
高さで取る(common_apps/joinrank/joinrank/rank.cmn)。
r2 emssr21
r2 emssr22
    V_0 = {0},   V_{α+1} = V_α ∪ (V_α ⊕ R_α),   ρ = log2 |V|
r2 emssr23
r2 emssr24
この module は表を語へ置いて image を実行し、出た語を読むだけになる。
r2 emssr25
"""
r2 emssr26
r2 emssr27
import os
r2 emssr28
r2 emssr29
import lex
r2 emssr30
import vcpu
r2 emssr31
r2 emssr32
_HERE = os.path.dirname(os.path.abspath(__file__))
r2 emssr33
_B = {}
r2 emssr34
r2 emssr35
r2 emssr36
def _addresses(dic):
r2 emssr37
    if dic not in _B:
r2 emssr38
        _B[dic] = lex.addresses(dic)
r2 emssr39
    return _B[dic]
r2 emssr40
r2 emssr41
r2 emssr42
class Joint(object):
r2 emssr43
    """接合秩の image ひとつ。実行に要る語数は辞書の帯が決める。
r2 emssr44
r2 emssr45
    image は二本。`joinrank` が ρ と分離積、`anf` が正規形の台だけを返す。
r2 emssr46
    台は同心円の図(Common-Lang/2 定義 4.1)で p_r と q_r がどの単項式を読むかを
r2 emssr47
    引くために要る。
r2 emssr48
    """
r2 emssr49
r2 emssr50
    def __init__(self, image_path, dic_path, anf_path=None):
r2 emssr51
        a = _addresses(dic_path)
r2 emssr52
        self.NIN, self.KUT = a["pebobe"], a["pebobo"]
r2 emssr53
        self.NAA, self.NBB = a["pebopa"], a["pebopi"]
r2 emssr54
        self.RHO, self.NVT, self.OVF = a["pebopu"], a["pebopo"], a["pepabe"]
r2 emssr55
        self.TAB, self.WIT, self.PCO = a["pepube"], a["pepupu"], a["pepupe"]
r2 emssr56
        self.ANF = a["pobepu"]
r2 emssr57
        self.RHOMAX, self.STRIDE = a["pebebo"], a["pebepa"]
r2 emssr58
        self.words = a["pobepu"] + (1 << 14) + 262144
r2 emssr59
        self.tab = vcpu.translate(vcpu.decode(open(image_path, "rb").read()))[1]
r2 emssr60
        self.anf_tab = None
r2 emssr61
        if anf_path:
r2 emssr62
            self.anf_tab = vcpu.translate(vcpu.decode(open(anf_path, "rb").read()))[1]
r2 emssr63
r2 emssr64
    def _run(self, tab, table, n, cut=None):
r2 emssr65
        lane = vcpu.Lane(self.words)
r2 emssr66
        lane.M[self.NIN] = n
r2 emssr67
        if cut is not None:
r2 emssr68
            lane.M[self.KUT] = cut
r2 emssr69
        for v, b in enumerate(table):
r2 emssr70
            if b:
r2 emssr71
                lane.M[self.TAB + v] = 1
r2 emssr72
        if vcpu.run_lane(tab, lane) != 0:
r2 emssr73
            raise ValueError("接合秩の文が失敗しました")
r2 emssr74
        return lane.M
r2 emssr75
r2 emssr76
    def support(self, table, n):
r2 emssr77
        """正規形の台。a_T = ⊕_{R⊆T} f(R)(R1 のメビウス変換)"""
r2 emssr78
        if self.anf_tab is None:
r2 emssr79
            return []
r2 emssr80
        M = self._run(self.anf_tab, table, n)
r2 emssr81
        return [t for t in range(1 << n) if M[self.ANF + t]]
r2 emssr82
r2 emssr83
    def __call__(self, table, n, cut):
r2 emssr84
        """頂点値の表とカットから ρ、分離積、そして図に要る台を返す。
r2 emssr85
r2 emssr86
        psup[r] は p_r の台。添字はそのまま [n] の番号になる。
r2 emssr87
        qsup[r] は q_r の台。B 側の番号なので κ だけ左へずらす。
r2 emssr88
        """
r2 emssr89
        M = self._run(self.tab, table, n, cut)
r2 emssr90
        if M[self.OVF]:
r2 emssr91
            raise ValueError("接合秩が語の容量 %d を越えた" % (self.RHOMAX - 1))
r2 emssr92
        rho, na, nb = M[self.RHO], M[self.NAA], M[self.NBB]
r2 emssr93
        q = [[M[self.WIT + self.STRIDE * r + b] for b in range(nb)] for r in range(rho)]
r2 emssr94
        p = [[M[self.PCO + self.RHOMAX * x + r] for x in range(na)] for r in range(rho)]
r2 emssr95
        out = {"n": n, "cut": cut, "rho": rho, "p": p, "q": q,
r2 emssr96
               "anf": [t for t in range(1 << n) if M[self.ANF + t]]}
r2 emssr97
        out["psup"] = [self.support(p[r], cut) for r in range(rho)]
r2 emssr98
        out["qsup"] = [[s << cut for s in self.support(q[r], n - cut)] for r in range(rho)]
r2 emssr99
        return out