c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Elixir を何故採用したのか

Elixir Advent Calendar 2019 - Qiita 12/11

Kubernetes を何故採用したのかの續きだ。各項目の一般的な前提も前の記事に準ずる。よって讀んでくださってゐる事を期待する。

下記 slide 時期の昔話をする。何故技術撰定で Elixir を採用したのか。

ステートフルで大規模アクセスのある soft-realtime なゲームサーバーを easy につくる

採用後の具体的な運用の話はしない。それが今でも役立つ話題なら別にしやう。今でも個人的に Elixir を續けてゐる理由もここの話題ではない。

何が嬉しいか?

當時 game の rule や cycle は決まってゐなかった。しかし何人かで PvP を realtime に行ひたい、同時に行なはれる PvP は非常に多い (多くしたい) 事は判ってゐた。

組織內での第一の撰擇肢は Rails であったから先づは Rails を檢討した。求められる realtime 性が定かではない。rule や cycle を檢討してゐる途中なので出來るだけ柔軟性を保ちたかった。詰まり常時接續通信 (front は Web front であったから WebSocket の事である) で realtime PvP が行なへれば好ましい。勿論 realtime 性を減じれば Rails で實裝出來る。

  • realtime 性を減じて Rails で實裝する
  • RabbitMQ で client を仲介し、對戰 logic は client に持たせる。RabitMQ で MQTT を介し PvP する前例は經驗を有する。Web front で高速且つ派手な描画をする前例は無かったから描画するだけでも risk であり、更に複雜な logic と云ふ risk を client に持ち込む事に成る
  • Photon。これは組織內で現役であった。ただし Photon 側に對戰 logic は無く Unity で實裝した client 側に有る。それに WebSocket の實績は身近には無かった
  • Elixir / Phoenix。Elixir 自體の運用經驗は有ったが單純な HTTP API server である。Phoenix も同樣
  • node.js。この運用經驗も組織內には有る
  • Go。新規

柔軟性を保ち、安心して運用出來、手慣れてゐ、好みであり、組織內に知見が有る Elixir / Phoenix に決めた。

Phoenix.Channel の backend は Redis である。Redis の運用經驗は豊富であった。Redis で安定して性能が出せるかは不安であったから、随分後まで NATS や Kafka を檢討してゐたが、Redis で充分であった。

作り切れるか?

若し動く物が作れるなら必ず早目に動く物を作ってみなければならない。

既に dummy 的に作られた server が有った。これを模倣する事から始めた。docker-compose、lint、test を調へながらやり、二週間ほどで模倣出來た。dummy は chaos な實裝だったが、模倣はこの時既に函數型 paradigm で game logic を model 化してある。この model 化は假に Elixir を止めても役立つ筈だ。2 つの client で WebSocket を介して對戰出來る樣に成った。

Elixir が動く Erlang VM は實績の多い VM で、規模の大きな常時接續を捌く事で有名だ。

始めは全て Elixir で作る積りだったが、risk が大きく成り過ぎるので、Elixir は新しい PvP のみに限定し、手慣れた残りは手慣れた Rails で作る事に轉換した。これは話し合って決めた (他は決めてから話し合ってゐる……)。

これらから作り切れると判斷した。

また fallback 先としては、realtime 性を減じてでも Rails で實裝出來る見込みは有った。この場合經驗の豊富な者が組織內に多く、助けも借りられる。

運用出來るか?

TCP 接續はともかく、WebSocket をスマホから大量に繋ぎ維持する經驗は誰にも無かった。よってこれは實地試驗や負荷試験をする迄判らない。多分もっと早く實地試驗と負荷試驗をするべきであった。Erlang と Redis の實績は世間的にも豊富だったから油斷してゐたのだ。結果的にはうまくいったが、これは考へられたものではなかった。

Erlang, Elixir, library の ver.に就いて。minor ver.には即座に追隨する。Erlang, Elixir は經驗からすると minor ver.の互換性は安定してゐるから、即座に上げられないなら組織に問題が有る (Erlang, Elixir の話であり他には該当しないかもしれない)。minor ver.の更新で困る library は捨てるべきだ。major ver.の更新には 1 つ遲れ以內で着いてゆく。これらを早く決めた (明文化したのは大分後だが)。

開發を速く保ち續けられるかも大切だ。これは Elixir に依らない部分が大きい。開發の課題を繼續的に解決出來るか、その cost を如何に払うかは Elixir であってもなくても變はらない。作るものの genre に依る。Elixir が特別 refactoring しづらいなら考へるべきだが、函數型に依り明示的な programming を行なひ、test も書き、process の樣子も見易いならそれ以上特別に考へる事は無い。

人を増やせるか? team を作れるか?

これは難しい所だ。業界で Elixir が支配的に成る事は考へられない。

今から振り返るとこれは失敗したと言へる (更に未來の事はここで話題としない。失敗は一時的なものであり得る)。新しい開發が得意な者は難なく Elixir を習得した。他の product でも Elixir で開發が進んでゐ、組織の backup も得られると油斷した。一時的には成功したと言へる。業界的な圧力が無い所に私が Elixir を広めるのに失敗したと云ふ事だ。その面では Go を使ふのが好かっただらう。支配的には成らなくとも、もう少し魅力を増せれば好かったと思ふ。今後の課題である。

とは云へ巨大でもない組織 Go にも Elixir にも投資する事は無理だから、他の開發も進んでゐる事であったし Elixir を撰んだのは妥當だったと思ふ。

他の product に好い影響を與へられるか?

WebSocket で realtime PvP を實裝する、その函數型的な model 例を提供する、と云ふ意味で know how に成ったと思ふ。先鋒を司るぞ、位いに軽く考へてゐた。

Elixir で non-programmer 向けに DSL を作り提供する

言語実装 Advent Calendar 2019 - Qiita 12/11

C に lex / yacc と云ふ字句解析 generator と構文解析 generator が有る。Erlang には標準 library に leex / yecc と云ふ同じ役割のものが有り簡單に構文解析器を作れる。Elixir からもこれを使える。

昔 Elixir と JavaScript とで game を作る機會が有った。game 中で活動する各 unit は parameter を持ってゐる。parameter の調整に依り game の balance や cycle が變はるのでこの調整を簡單に素早く繰り返せる事は重要だ。調整をする人が直截 data を編輯し反映出來るのが好い。また假に parameter の編輯や反映が programmer の作業と成ってゐると、囘數の多いこの作業に時間を取られ、parameter の反映も game 開發もどちらも後囘しに成ってしまふ。data を例へば CSVGoogle Spreadsheet や理想的には専用の UI で管理して反映出來れば、これは達成出來る。これを整へるのにも開發が要り、白狀すると理想的には出來てゐなかったから一部に programmer や専門の者の手が掛ってしまってゐたが、調整者が出來る丈獨立して反映出來る樣にしてゐた。

各 unit は skill も持ってゐる。skill は一般に複雜に成る。條件と效果、分岐、くり返し、條件の組み合はせ、效果の組み合はせ、條件や效果の打ち消し、それぞれの paramater 等は要るだらう。これを CSV 等表形式で記述しやうとすると、特定の skill 向けの専用 column が大量に生まれ場當り的に logic が増えるだけでなく、skill 設計の柔軟性も失ふ。そこで先述の skill に要る內容を見直すとこれは programming 言語である。skill を program として書いたはうが好い game も有る訣だ。例へば TCG (trading card game) である。

parameter 調整は素早く繰り返し行ふべきだ。skill も parameter である。skill は program だが programmer が skill を書いてゐたのでは開發が停まる。non-programmer が skill を書く樣にするべきだ。これは DSL (domain specific language) の出番である。白狀するとここでも理想的には出來てゐず、相當に後迄調整者が書いてた skill を programmer が review してゐた。この review は後にしなくても囘る樣に成ったから成功したのだと思ふ。

さてこの DSL だが Web server (WebSocket だが) 側である Elixir で實裝する事にした。performance や code の複雜さで苦しむ Web front 側に擔はせるには当時は risk が大き過ぎた。また Elixir には leex / yecc と云ふ DSL 用の library が標準で使へる事を知ってゐた。

言語仕樣は用途に依り異なるだらうが、この樣なものだった。

literal で書ける data 型 :

  • lambda : 遲延評價する手續き
  • number : 整數と浮動小數点數
  • string
  • true, false
  • tuple : 任意の data 型の任意個數の tuple

函數の返り値として得られる data 型 :

  • unit の集合
  • player の集合
  • その他 Elixir 側で自由に定義される

組み込み演算子。名前が豫約されてゐるだけで、Elixir 側で函數として定義する :

  • !
  • +
  • - : 數値演算と集合演算とに override されてある
  • *
  • /
  • = : 代入ではなく比較演算子。代入演算子は無い
  • <
  • >
  • <=
  • >=
  • | : 論理演算と集合演算とに override されてある
  • & : 論理演算と集合演算とに override されてある

その他の literal :

  • () : tuple を生成する、或いは評價の優先順位を決める。長さ 1 の tuple は單に値と同一視する
  • 函數名 : A で函數 A を呼び出す (Aは Elixir 側で定義する)。A Bで B を引數として函數 A を呼び出す。特に引數が文字列ならE"光"の樣に書ける。tuple の同一視の規則からこれはA(B)とも書ける。引數が複數在る場合はA(B,C)と tuple を引數に與へる
  • 變數名 : $Aで變數 A の値を得る (正確にはget_var("A")と云ふ Elixir 側で定義した函數を呼ぶ)。$A Bで變數 A に B を代入する (これはset_var("A",B))。

他の構文 :

  • IF END : else は無い。DSL は if を實行する仕組みを持たず、「if 文の始めが在る」「if 文の終はりが在る」 (入れ子には成れる樣に一意な識別子は持つ) と云ふ情報のみを library に渡す。library が自由に實裝する

函數定義は無い。函數は programmer が Elixir で定義する。

入力された DSL 文字列は Elixir の函數に成り、:erlang.term_to_binary/2で file (ETS (Erlang term storage) 形式) に保存される。

DSL 文字列
-[leex]-> 字句列
-[yecc]-> AST (abstract syntax tree)
-[dsl.ex]-> Elixir 函數
-[term_to_binary]-> binary

Elixir 函數は單に Elixir のfn -> endである。Elixir は正格評價だからここに工夫は無い。

compiler は library を持つ。programmer はここに型と函數を定義する。引數の型が異なれば同じ名で函數を複數定義出來る。compiler は引數の型を見てどの函數を呼び出すか決める (compile 時に決まる)。ここで呼び出す函數が見附からなければ compile error に成る。型 error もさうだが、typo も檢出出來る。型は部分型を持てる。函數は引數に對して共變である。generics は實裝しなかった。

DSL には表はれないが Elixir で定義した函數は第一引數に環境を表はす値を受け取る。しかし DSL 側はこの邊りを規定せず library 實裝者 (どちらも我々だが…) が自由に決める。

一部の DSLVM を持ち、if 文を goto に置き換へ實行した。また特定の函數で實行を一時停止する機能も持った。これらは單に Elixir 上の實裝であり、game logic としての工夫は有るが、言語としての工夫は無い。

Kubernetes を何故採用したのか

Kubernetes3 Advent Calendar 2019 - Qiita 12/11

Kubernetes を技術撰定した事が有ったのでその時の話をする。以下の slide の時の話だ。

ステートフルで大規模アクセスのある soft-realtime なゲームサーバーを easy につくる

採用後の具体的な運用の話はしない。流石に昔話に過ぎる。

何が嬉しいか?

前提 :

  • 代替手段でも充分、と云ふだけでは代替手段を撰ぶ理由には成らない
  • 自分の學習 cost は氣にしない。學習せずに濟む手段は私には常に無いので

検討を始めた時には何となく動く Elixir application は既に在り、infrastructure に求められる事も判ってゐた。Elixir application を動かす。多くの WebSocket を安定して繋ぐ。極端に好い network 性能は求めない。application は素早く scala-in/out する。寢てゐても scale-in/out すると嬉しい。幾つかの subsystem が動く。subsystem は増えたり種類が換はったりするかもしれない。よって構成を變へる柔軟性を保ちたい。出來れば server programmer が變更したい。Elixir application を EC2 上に直截置くのではなく container に入れる事で、下の server から抽象化したい。

組織內にこのやうな前例は無かった。世間には在る樣だったが詳細は判らない。そこで技術撰定をしなければならなく成った。

先づ Elixir application を動かす前例は組織內に有った。また新たに開發されつつもあった。しかし多くの常時接續を行ふ例は無く (Elixir 以外では有った)、scale-in/out も遲い。新たに開發されつつあった手法は、動かす application の logic は我々と比較すると單純で構成が安定し、負荷も豫測し易いものだった。また container は考慮されてゐない。

これを採用しても運用出來ただらうが、Kubernetes はより好い撰擇だと思はれた。

先づ Kubernetes には實績が有る。eco-system も揃い rail が敷かれつつあった。組織的にもいずれは採用しなければならない。container を動かす前例は組織內に無かったから自由に撰べる。組織の全体は cloud service を限定してゐなかったので、AWS 以外も使ふ。そこでも使へると know how を共有出來て好ましい。これも rail だ。構成の變更も Kubernetes 上で出來る。

そこで試してみる事にした。

作り切れるか?

實際には作り切ってみなければ作り切れるか否かは判定出來ない。常に不測の事が起きるだらうから。それはどの手段を取らうと同じだ。しかし判斷する必要が有る。

世間には Kubernetes で似た system の實績は有るので、理論的に「作れない」事は無い。

運好く team 內に或る程度の規模で Kubernetes を構築し運用した經驗の有る者がゐた。

組織に infrastructure を開發・管理する team が有り、そこの協力は得られた。(その後實際には cluster の構築と、管理の大部分とをやっていただいた。勿論ありがたいが、私の力不足でもあった)

また fallback 先に、組織內で開發されつつあった手法を取れると判ってゐた。cluster を構築し始めか、或いは開發が進み subsystem の構成が決まった後なら fallback 出來る。

そこで作り切れると判斷した。

運用出來るか?

これも上と同じく運用してみなければ運用出來るか否かは判定出來ない。運用は續くものだから、ずっと後で「これは出來なかった」事が判るかもしれない (往々にして有り、infrastructure の乘り換へと云ふ形で現れる。いつ現れるか、と云ふのは大きな違ひを生む)。この判斷は、product や世間の變化を見込み過ぎてはいけないが、「一切見込まない」訣にはいかない。

先づ世間には前例が有る。これも上と同じ。これは大きい。「出來た人はゐる」と云ふ安心だけでなく、know how も少しは共有されてゐると云ふ事だから。

後は經驗者に頼るか、實際に触ってみるしかない。cluster 構築中に触ってみて (私が作った cluster は product-ready ではなかったが…)、出來るだらうと判斷した。それから開發中に色々と試して simulation してゐる。負荷試驗も fallback しなければならないかもしれない timing だ。ここでも問題は解決出來た。

人を増やせるか? team を作れるか?

組織內に前例が無く、業界にも前例が少ない application であるから、經驗者を呼ぶ事はどの手段を取ってもそもそも望めない。

組織的にも Kubernetes は進めなければならないものだったから、backup は期待出來る。これも rail である。

學習に就いて。そもそも私は力の無い者 (「知識が無い」ではない。知識は學習できる) に力をつけさせるのは無理だと思ってゐるから (力がつく事は有るがそれは豫測出來ない)、筋の好い技術であれば學習 cost は適正に成ると思ふ。技術は行ふものであるから、一般に「充分に」理解すれば好いのであって、「全てを」理解する事は些事であり必要無い (これが探求であれば「全て」が不可能なのは當然として「充分に」と云ふ概念は片面からしか定義されない)Kubernetes は既知の技術の集まりであり (既知の技術の集まり自體が既知のものに成るとは限らない。それは新しく興味深いものに成り得る)、集め方も筋が好いものに思はれた。rail の考へで云へば、know how や教材も世間に増えると思はれた (實際にその後増えたと思ふ)。

他の product に好い影響を與へられるか?

これは組織的にやってゆくべき事を率先してやるので滿たされる。

Elixir の application を Mackerel で監視する

Mackerel Advent Calendar 2019 - Qiita 12/11

以前にKubernetes 上で動く Elixir アプリを監視するを書いた。これが完成した。

確かに Erlang/Elixir の system は落ちない。programmer が落ちないやうに書けば落ちなく出來るからだ。基本的な道具は BEAM VM (Erlang VM) と Supervisor の木である。

勿論落ちる事は在る。tuple の入れ子が深過ぎて SEGV したり、memory を使ひ過ぎて OOM Killer に落とされたりだ。memory の使ひ過ぎは、ETS からの data copy (通常の代入や message passing と違ひ、同じ data でも毎囘 copy される):erlang.binary_to_term/2 (理由は ETS のに近い)atom の増大、process の増大、大きな binary の GC の遲れ、message queue の溢れ (back-pressure の仕組みを作らなければならない。back-pressure により處理速度が激減する事も有るので注意する。或いは process 自身が message queue の長さを監視して自殺する) 等に依り起こる。これらの問題は process 內に閉じ込められたり runtime で解決出來るものも有れば、成す術も無くただ設計や logic を直すものも有る。

また落ちない事は所詮落ちないだけに過ぎない。處理速度が一時的/恒常的に下がったり、長期的な leak は知らなければならない。

詰まり BEAM VM の狀態を知っておく事が要る。私は偶々 KomachiHeartbeat と云ふ、Elixir application の狀態を知る爲の library を作ってゐたから、これに VM の狀態を見る機能を追加した。v0.5.0 以降で使へる。この library で BEAM VM の狀態を見る事が出來る。

komachi_heartbeat | Hex

今囘は更に、その狀態を Mackerel に送る。先づは動いてゐる樣子を。

Elixir の application を Mackerel で監視する

見られる情報は (それぞれが何であるかは Erlang の公式 document を參照のこと)、

  • context_switches
  • port_count
  • process_count
  • reductions
  • run_queue
  • gc
    • count
    • words_reclaimed
  • io
    • in
    • out
  • memory
    • atom
    • binary
    • code
    • ets
    • processes
  • scheduler_usage
    • 各 scheduler 毎

これは普段見るものに絞った。

KomachiHeartbeat とは Elixir application に healthcheck 用 endpoint を追加する library だ。healthcheck は樣々に要る場面が在る。ELB ALB の healthcheck や、Kubernetes であれば readyness probe, liveness probe が要る。そこで統一された healthcheck 確認方法が有れば便利だ。(何を healthy であるとするかと云ふ話題は他へ譲る。)これにはGET 〜/heartbeatと云ふ path を提供する。

更に KomachiHeartbeat は、system の狀態を JSON で返す endpoint も追加する。これにはGET 〜/statsと云ふ path を提供する。

github.com

先づ HTTP server が要る。HTTP で應答する application であればそこに追加するし、さうでなくても cowboy を Application にぶら下げれば好い。process を簡單に増やせるのは Erlang/Elixir の好い所だ。今囘は plug_cowboy を追加する。mix.exsに、

defp deps do
  [
    # …
    {:cowboy, "~> 2.7"},
    {:jason, "~> 1.1"},
    {:komachi_heartbeat, "~> 0.5"},
    {:plug, "~> 1.8"},
    {:plug_cowboy, "~> 2.1"}
  ]
end

を加える。Application (大抵はapplication.exs) に、

def start(_type, _args) do
  # …
  children = [
    # …
    {Plug.Cowboy, scheme: :http, plug: Example.Router, options: [port: 4000]}
  ]
  # …
  Supervisor.start_link(children, opts)
end

を加え plug_cowboy を起動する。port は 4000 番にしたが他でも好い。router を、

defmodule Example.Router do
  use Plug.Router
  plug(:match)
  plug(:dispatch)
  forward("/ops", to: KomachiHeartbeat, init_opts: [vitals: [KomachiHeartbeat.BeamVital]])
  match(_, do: send_resp(conn, 404, "Not Found"))
end

等とし、/ops/〜に KomachiHeartbeat を mount する。この時KomachiHeartbeat.BeamVitalを設定すると BEAM VM の情報を取れる。GET http://〜/ops/statsが endpoint だ。

次に mackerel-agent を設定する。私は Kubernetes で動かしてゐるから mackerel-container-agent を。

mackerel-plugin-jsonJSON で吐かれたメトリックを Mackerel のカスタムメトリックとして投稿する、mackerel-agent の plugin だ。

github.com

先づ plugin を呼ぶので簡便にmackerel/mackerel-container-agent:plugins image を使ふ。agent 用の設定は以下に成る。

---
readinessProbe:
  http:
    path: /ops/heartbeat
    port: 4000
plugin:
  metrics:
    json:
      command: |
        mackerel-plugin-json \
          -url="http://localhost:4000/ops/stats" \
          -prefix='beam'

この設定を ConfigMap に置いて agent に読ませれば好い。そこで volumeMounts する。

---
apiVersion: apps/v1
kind: Deployment
# …
spec:
  # …
  template:
    spec:
      # …
      volumes:
        - name: mackerel-agent-config
          configMap:
            name: mackerel-agent-config
      containers:
        - name: # …
          image: # …
          # …
          ports:
            - containerPort: 4000
              protocol: TCP
          readinessProbe:
            httpGet:
              path: /ops/heartbeat
              port: 4000
        - name: mackerel-container-agent
          image: mackerel/mackerel-container-agent:plugins
          imagePullPolicy: Always
          resources:
            limits:
              memory: 128Mi
          env:
            - name: MACKEREL_AGENT_CONFIG
              value: /etc/mackerel/mackerel.yaml
            - name: MACKEREL_CONTAINER_PLATFORM
              value: kubernetes
            - name: MACKEREL_KUBERNETES_KUBELET_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: MACKEREL_KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MACKEREL_KUBERNETES_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: MACKEREL_ROLES
              value: # …
          envFrom:
            - secretRef:
                name: # …
          volumeMounts:
            - name: mackerel-agent-config
              mountPath: /etc/mackerel
              readOnly: true

MACKEREL_APIKEYは Secret から讀ませてゐる。ConfigMap は、

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mackerel-agent-config
data:
  mackerel.yaml: |
    ---
    readinessProbe:
      http:
        path: /ops/heartbeat
        port: 4000
    plugin:
      metrics:
        json:
          command: |
            mackerel-plugin-json \
              -url="http://localhost:4000/ops/stats" \
              -prefix='beam'

で好い。私はkustomize build … | kubectl apply … -f - --pruneで deploy してゐるがこれは都合次第だ。

眞に關する三角形 : S/, S1, S2

ももんが Advent Calendar 2019 - Adventar 12/7

3 : 不安定、調停

3 は不安定、調停である。3 を A, B, C とし、三角形を作る。すると順序を無視した組み合はせ {A, B}, {B, C}, {C, A} の個數も 3 であり、これは三角形の邊である。A からは {B, C} が見え、B からは {C, A} が、C からは {A, B} が見える。こうして 3 は 3 に轉化する。

典型的にはキリスト教の三位一體である。また創造 (母)、維持 (老婆)、破壊 (娘) である三相の女神も典型的である。

2→3 : 調停、欲望

2 から 3 への移行は調停、欲望である。3 は 2 の對立を媒介し調停する。また對立物を無と見做し、無を欲望の對象とする事で欲望を可能にする。欲望を媒介し產む第三項はそれ自身が無である。

3→2 : 排除、充足

3 から 2 への移行は排除、充足である。2 は媒介を排除し、相補性に充足する。

4→3 : 二重性

4 から 3 への移行は二重性である。二軸 A/B と +/- が有り、A/B の A 側に注目した時に B+/B- の違ひを無視して A+/A-/B の 3 を作れる。

原理の個數 : 1, 2, 3, 4, 5

眞の三種

三角形の各點がそれぞれ不可能性と不可避性を示す。

  • S \llap /, S_1, S_2
  • 根據 : 無根據な斷定, 循環論法, 無限後退
  • 論理 : 矛盾許容論理, 非安定な論理 (自己認識論理, abduction), 無限論理
  • 移行 (migration) の禁止 : 悟達, 輪廻, 極限
  • 局所性の禁止, 決定論の禁止, 自由意志の禁止
  • 三位一體 : 聖霊, 子, 父
  • 三相の女神 : 破壊する娘, 維持する老婆, 創造する母
  • 個體化 : 實存 (固有名が普遍に先立つ), 否定に依る個體化, 潜在性からの生成

これらが正確に對應すると云ふのが假説である。あらゆる 3 がこれに對應する訣ではない。例へば三種の神器 : 剣, 鏡, 勾玉は (今後解釋を施さない限り) これに對應しない。

また三邊をそれぞれ點に換へて三角形を作る事が出來る。即ち、

  • \lbrace S \llap /,S_1 \rbrace, \lbrace S_1,S_2 \rbrace, \lbrace S_2,S \llap / \rbrace
  • 自由意志, 局所性, 決定論
  • 知 (想像a), 眞理 (象徴S(A \llap /)), 現實性 (現實\Phi)