リポジトリ / emssr / independent_common_compiler
r2
| r2 emssr | 1 | # -*- coding: utf-8 -*- |
| r2 emssr | 2 | """接合秩。 |
| r2 emssr | 3 | |
| r2 emssr | 4 | doc: joinrank matrix.reduce |
| r2 emssr | 5 | |
| r2 emssr | 6 | Common-Lang/1 定理 4.1。入力の分割 [n] = A ⊔ B と値の行列 |
| r2 emssr | 7 | |
| r2 emssr | 8 | F[α][β] = f(α, β) α ∈ {0,1}^A, β ∈ {0,1}^B |
| r2 emssr | 9 | |
| r2 emssr | 10 | に対し、F2 上の階数 ρ = rank F が |
| r2 emssr | 11 | |
| r2 emssr | 12 | f(x_A, x_B) = ⊕_{r=1}^{ρ} p_r(x_A) q_r(x_B) |
| r2 emssr | 13 | |
| r2 emssr | 14 | の分離積の最小本数になる。ρ が「カットを渡る独立影響の本数」であり、 |
| r2 emssr | 15 | 分解が立つとき縮約行列はテンソル積へ割れる。 |
| r2 emssr | 16 | |
| r2 emssr | 17 | M_f = M_g (M_{h_A} ⊗ M_{h_B}) |
| r2 emssr | 18 | |
| r2 emssr | 19 | 階数は掃き出しで取らない。ピボットの選び方は文に現れない量になるので、⊕ 閉包の |
| r2 emssr | 20 | 高さで取る(common_apps/joinrank/joinrank/rank.cmn)。 |
| r2 emssr | 21 | |
| r2 emssr | 22 | V_0 = {0}, V_{α+1} = V_α ∪ (V_α ⊕ R_α), ρ = log2 |V| |
| r2 emssr | 23 | |
| r2 emssr | 24 | この module は表を語へ置いて image を実行し、出た語を読むだけになる。 |
| r2 emssr | 25 | """ |
| r2 emssr | 26 | |
| r2 emssr | 27 | import os |
| r2 emssr | 28 | |
| r2 emssr | 29 | import lex |
| r2 emssr | 30 | import vcpu |
| r2 emssr | 31 | |
| r2 emssr | 32 | _HERE = os.path.dirname(os.path.abspath(__file__)) |
| r2 emssr | 33 | _B = {} |
| r2 emssr | 34 | |
| r2 emssr | 35 | |
| r2 emssr | 36 | def _addresses(dic): |
| r2 emssr | 37 | if dic not in _B: |
| r2 emssr | 38 | _B[dic] = lex.addresses(dic) |
| r2 emssr | 39 | return _B[dic] |
| r2 emssr | 40 | |
| r2 emssr | 41 | |
| r2 emssr | 42 | class Joint(object): |
| r2 emssr | 43 | """接合秩の image ひとつ。実行に要る語数は辞書の帯が決める。 |
| r2 emssr | 44 | |
| r2 emssr | 45 | image は二本。`joinrank` が ρ と分離積、`anf` が正規形の台だけを返す。 |
| r2 emssr | 46 | 台は同心円の図(Common-Lang/2 定義 4.1)で p_r と q_r がどの単項式を読むかを |
| r2 emssr | 47 | 引くために要る。 |
| r2 emssr | 48 | """ |
| r2 emssr | 49 | |
| r2 emssr | 50 | def __init__(self, image_path, dic_path, anf_path=None): |
| r2 emssr | 51 | a = _addresses(dic_path) |
| r2 emssr | 52 | self.NIN, self.KUT = a["pebobe"], a["pebobo"] |
| r2 emssr | 53 | self.NAA, self.NBB = a["pebopa"], a["pebopi"] |
| r2 emssr | 54 | self.RHO, self.NVT, self.OVF = a["pebopu"], a["pebopo"], a["pepabe"] |
| r2 emssr | 55 | self.TAB, self.WIT, self.PCO = a["pepube"], a["pepupu"], a["pepupe"] |
| r2 emssr | 56 | self.ANF = a["pobepu"] |
| r2 emssr | 57 | self.RHOMAX, self.STRIDE = a["pebebo"], a["pebepa"] |
| r2 emssr | 58 | self.words = a["pobepu"] + (1 << 14) + 262144 |
| r2 emssr | 59 | self.tab = vcpu.translate(vcpu.decode(open(image_path, "rb").read()))[1] |
| r2 emssr | 60 | self.anf_tab = None |
| r2 emssr | 61 | if anf_path: |
| r2 emssr | 62 | self.anf_tab = vcpu.translate(vcpu.decode(open(anf_path, "rb").read()))[1] |
| r2 emssr | 63 | |
| r2 emssr | 64 | def _run(self, tab, table, n, cut=None): |
| r2 emssr | 65 | lane = vcpu.Lane(self.words) |
| r2 emssr | 66 | lane.M[self.NIN] = n |
| r2 emssr | 67 | if cut is not None: |
| r2 emssr | 68 | lane.M[self.KUT] = cut |
| r2 emssr | 69 | for v, b in enumerate(table): |
| r2 emssr | 70 | if b: |
| r2 emssr | 71 | lane.M[self.TAB + v] = 1 |
| r2 emssr | 72 | if vcpu.run_lane(tab, lane) != 0: |
| r2 emssr | 73 | raise ValueError("接合秩の文が失敗しました") |
| r2 emssr | 74 | return lane.M |
| r2 emssr | 75 | |
| r2 emssr | 76 | def support(self, table, n): |
| r2 emssr | 77 | """正規形の台。a_T = ⊕_{R⊆T} f(R)(R1 のメビウス変換)""" |
| r2 emssr | 78 | if self.anf_tab is None: |
| r2 emssr | 79 | return [] |
| r2 emssr | 80 | M = self._run(self.anf_tab, table, n) |
| r2 emssr | 81 | return [t for t in range(1 << n) if M[self.ANF + t]] |
| r2 emssr | 82 | |
| r2 emssr | 83 | def __call__(self, table, n, cut): |
| r2 emssr | 84 | """頂点値の表とカットから ρ、分離積、そして図に要る台を返す。 |
| r2 emssr | 85 | |
| r2 emssr | 86 | psup[r] は p_r の台。添字はそのまま [n] の番号になる。 |
| r2 emssr | 87 | qsup[r] は q_r の台。B 側の番号なので κ だけ左へずらす。 |
| r2 emssr | 88 | """ |
| r2 emssr | 89 | M = self._run(self.tab, table, n, cut) |
| r2 emssr | 90 | if M[self.OVF]: |
| r2 emssr | 91 | raise ValueError("接合秩が語の容量 %d を越えた" % (self.RHOMAX - 1)) |
| r2 emssr | 92 | rho, na, nb = M[self.RHO], M[self.NAA], M[self.NBB] |
| r2 emssr | 93 | q = [[M[self.WIT + self.STRIDE * r + b] for b in range(nb)] for r in range(rho)] |
| r2 emssr | 94 | p = [[M[self.PCO + self.RHOMAX * x + r] for x in range(na)] for r in range(rho)] |
| r2 emssr | 95 | out = {"n": n, "cut": cut, "rho": rho, "p": p, "q": q, |
| r2 emssr | 96 | "anf": [t for t in range(1 << n) if M[self.ANF + t]]} |
| r2 emssr | 97 | out["psup"] = [self.support(p[r], cut) for r in range(rho)] |
| r2 emssr | 98 | out["qsup"] = [[s << cut for s in self.support(q[r], n - cut)] for r in range(rho)] |
| r2 emssr | 99 | return out |