ビーナスの腰布がハラリと落ちた歴史的瞬間

自然数を四進数表示すると,フルヌードのビーナス像が現れる.ウソだと思ったら自分の目で確かめてみるとよい.ネット上にはN進数表示のためのツールがごろごろしているから,コラッツ木上の隣り合った数字をいくつか比較してみればホントだってことが分かるだろう.君の目の前にあるのは「整った美の完成型」だ.乱雑でカオス的なコラッツ数列の渦の中にこんな「秘密」が隠されていたなんて信じられるだろうか?

ビーナス裸像

これを見たら夜も寝られなくなる人が続出するかもしれない.実際,昨日からこのブログへのアクセスが急増して一日の訪問者数が100を突破している.ともかく,コラッツ完全木ツールをリリースするまでは全力疾走するしかないね.「コラッツの秘密」が開示される日は近い.

もう少し突っ込んで解析したいのだが,そのためにはゼルコバの木で横書き系図を表示できるようにしたい.それができれば一々PDFに落として,云々の手間が省けるのだが…原理的にはそれほど難しくはないが,かなりの手間が掛かりそうだ.コラッツ三本桜の復活とどちらを先に手掛けたらよいか?コラッツ三本桜の復活は「コラッツ完全木」の完成を意味するが,一度仕事に掛かったらA面・B面の5機能すべてに対応しなくてはならないから,かなりの時間を要することになる.むしろ,思い切ってここでゼルコバの木に横書き系図を導入してしまった方が早いのではないか?ゼルコバの木の座標系は現在,X軸は右から左,Y軸は上から下というオリエンテーションになっているが,横書き対応というのは,X軸とY軸を入れ替えることに相当する.X→Y’,Y→X’とすると,X’は左から右,Y’は上から下に描画されなくてはならない.かなり厄介そうな話だが,やってみよう.

内部の計算は完全に温存されるものとし,座標変換は描画関数で直接実行する.ゼルコバの木系図図面に出力される図形には,①人名枠,②人名枠内のテキスト,③親子連結線,④兄弟連結線,⑤人名枠頭部垂線などがある.描画関数はDrawTreeView.cppとDrawTree.cppに入っているとみてよいだろう.可能ならば,最下位の関数で対応するというのがベストなのだが…切り分けができるだろうか?最下位の関数ということは,WindowsのAPIを直接呼び出している関数ということになる.DrawingObject.cppという未使用のCPPファイルがある.内容は「描画要素オブジェクトクラス」となっているが,これは将来,描画要素をオブジェクトとして扱えるようになったときのためにリザーブしておいたものだ.今回の修正は趣旨はまったく異なるが,とりあえず,ここに修正を要する関数を集めてみることにしよう.まず,使われているWindows APIを特定してみよう.デバイスコンテキストクラスの関数がそれに該当する.ざっと拾い出したところ42個あった.

  1. Arc
  2. BitBlt
  3. DPtoLP
  4. Ellipse
  5. EndDoc
  6. EndPage
  7. ExtTextOut
  8. FillRect ●
  9. FillSolidRect ●
  10. GetClipBox
  11. GetDeviceCaps
  12. GetMapMode
  13. GetSafeHdc
  14. GetTextColor
  15. GetTextFace
  16. GetTextMetrics
  17. GetTextExtent
  18. GetOutputTextExtent
  19. LineTo ●
  20. LPtoDP
  21. MoveTo ●
  22. PatBlt
  23. Polygon
  24. RestoreDC
  25. SaveDC
  26. SelectClipRgn
  27. SelectObject
  28. SetBkColor
  29. SetBkMode
  30. SetMapMode
  31. SetPixel
  32. SetROP2
  33. SetTextAlign
  34. SetTextColor
  35. SetStretchBltMode
  36. SetViewportExt
  37. SetWindowExt
  38. SetWindowOrg
  39. StartDoc
  40. StartPage
  41. StretchBlt
  42. TextOut

ただし,これらの関数でも座標に関わりがないものは対応不要と考えられるので,実際の数はかなり限られていると思う.まず,ともかく矩形と直線の描画に関わるものを対象として修正を試みる.対応が必要な関数は上記リストで●をマークしたFillRect,FillSolidRect,LineTo,MoveToの4関数だけだ.これらはCDCクラスの関数だが,CDCクラスをオーバーライドすることは可能だろうか?⇒できそうだ._CDCという拡張クラスを新設し,以下の関数をDrawingObject.cppに移動した.

  1. Bobject::DrawYlist
  2. Bobject::DrawParentPath
  3. TRIBEBOX::DrawTlist
  4. Bobject::DrawLine
  5. BRect::DrawFrameRect
  6. printtombo
  7. printtombo_yoko
  8. printtombo_tate
  9. Bobject::CallFillRect
  10. TREEVIEW::PaintBackGround
  11. Bobject::FillSolidRect

一応修正は入ったので,走らせてみたが… どうも,これはかなり手強い.画面はほとんど真っ黒で一部描画されている部分もまったく座標変換になっていない…新規ファイルにすると,こんな感じだ.

image

ちょっと頭を冷やして考えなくてはならない… 現行ではデバイスのマッピングモードをMM_ANISOTROPICに設定している.これは座標単位と座標軸の向きを任意に設定できるという便利なものだが,X・Y軸を入れ替えるとしたら,少なくともSetWindowExtExとSetViewportExtExで軸の向きを変更しなくてはならない.ゼルコバの木は画面出力とプリント出力をまったく同じ関数で実行しているので,印刷の方も手当しなくてはならないが,ここのところは暫定的にパスしておくことにしよう.⇒少し状況が変わった.画面にはまだブラックなところが残っているが,人名枠が横書きで表示されている!これはいい傾向だ.

image

おそらく,スケールと軸の向きはこれで正しくなったと思われるが,座標原点の位置が悪いのではないだろうか?SetWindowOrgを呼び出している箇所には修正を入れてみたが,まったく変わらない.なんとか横書きしようとしているのは確かだが…

image

座標がからんでいる関数は上記のリストの中にまだどっさり残っているが,DPtoLP, LPtoDPが動作しないとまずいのではないだろうか?現行では論理座標と物理座標は等スケールになっているはずだが,GetClientRectなどで取得した矩形領域は論理座標系とは反転したものになっているはずだ.CWndの関数もチェックしておく必要がある.座標に関わりがあるのは多分GetClientRectだけだと思う.mmm… だいぶよくなった!

image

▲上下カーソルでカードが移動してしまう.おそらくこれは一覧画面での動作だが,カード画面にフォーカスがあるときは無用な動きだ.

枠線や系線がまったく出ないのはなぜだろう?

コラッツ国の公用語は4進数である

コラッツ国の公用語が4進数であることがわかった.自然数Nの名前を4進数で表記すると,Nの名前の中にはNの親Pの名前と兄弟順位が埋め込まれていることが分かる.簡単な例で見てみよう.下図のボックスには3つの数が入っている.①Nの4進表示(左上),②3N+1の2進表示(右上),③Nの10進表示(下行).

image

上図で奇数17は11, 45, 181, 725, 2901, 11605の6個の子ノードを持っている.これらの数の4進表記を見ると,23, 231, 2311, 23111, 231111, 231111のようになっていて,いずれも23を共通部として持ち,そのあとに1がいくつか並ぶという形式になっている.つまり,

Nの4進表記=共通部+1の並び

という形式になっている.この共通部を親の名前とみなせば,

Nの4進表記=親の名前+兄弟順位

であることは明らかである.「親の名前」はストレートには親ノード17には結びつかないが,バイナリ表記した3N+1にもそれと同様の「共通部」が存在することが見て取れる.今の事例ではこの共通部は「10001」であり,これを4進数に変換すると「101」を得る.これは親の「実名」である.ここで,「親の名前」とはこれまで「コラッツ数」と呼んでいたものにほかならないことは,長子ノードである11の「名前」が「親の名前」そのものであることからも分かる.つまり,長子ノードはある意味で「親の名前」を襲名していると言っても言い過ぎではない.ただし,「親の名前」と「親の実名」は同じではない…

タイトルでは「コラッツ国の公用語は4進数である」としているが,2進数表記,3進数表記も同様の重要性を持つ.つまり,コラッツ国では複数の公用語が併用されていると言うべきだろう.進数表記にはある種の演算が関わっているが,なぜここで問題を「言語」の問題として扱おうとしているのかというと,「言語」には「算術計算」とは異なる「連結(concatenation)」のような操作があるからだ.もちろん,DNAシーケンスなどという発想もその延長上にある.「数」のような抽象物?の中に情報としての記号(具体物)が埋め込まれているというのはかなり重大な発見であるような気がする…

コラッツ木とはすべての自然数が登録された戸籍簿である

コラッツからゼルコバの木にインポートするという操作がある程度滑らかに実施できるようになってきた.ここまでできると,次はインポートしたファイルをPDFに落として,かつ左90°回転させ,文字が正立した図面として保存したい.PDFの回転はChromeでもできるが,保存ができない.ダウンロードはできるが,保存されたファイルを開くと回転が戻ってしまっている.保存という機能もあり,たまたま保存できたケースもあるが,その手順が確立できない.CubePDFに印刷出力するという手もあるが,やはり回転が戻ってしまう.AdobeのAcrobat Reader DCの有料版なら回転までサポートされているが,買取りではなくサブスクリプションで月2千円も掛かるのでは手が出ない.ゼルコバの木でそこまでできるようにする必要はあるのだが,今日明日というわけにもゆかない.⇒いや,できた!多分この手順で間違いないと思う.

  1. コラッツからCSVファイルをエクスポート
  2. ゼルコバの木でファイル→隣接リストをインポート
  3. プリンタにCubePDFを選択,用紙サイズをA0に設定
  4. 拡大縮小倍率を調整して1ページに収まるようにする
  5. CubePDFに印刷出力してPDFファイルに保存
  6. ChromeでPDFファイルを開き,画像を回転させる
  7. 印刷画面を開き,送信先をCubePDFに設定
  8. 詳細設定で用紙サイズをA0,倍率は既定
  9. CubePDFで印刷→PDFに保存

ダメだ.確かに回転は保存されているが,図面の上半分しか入っていない.LibreOfficeでPDFを読み込んで回転まではできる(かなり時間が掛かる).しかし,図形を拡大縮小操作しているうちにフォントが荒っぽくなってしまうという欠陥がある.⇒最初に図形を全選択してからフォントをメイリオに切り替えておくと多少よい結果になる.図面を回転させたあとはページ設定でページサイズを整えたあと(オリエンテーションを横から縦に変えてもよい),ドラッグ移動してページの中に収まるようにすればよい.まぁ,これなら↓なんとか使えるだろう.

image

上図は1-3-4 511コラッツ木で所属の欄に8進数表示のノード番号を表示している.これを見ると,8進で末尾が5なら非コラッツ数であるということが一目瞭然にわかるが,01の並びを見れば第何子であるかわかるはずなので,それも見られるようにしてみたい.このためには8進ではなくむしろ4進表示が適しているのではないだろうか?ちょっとやってみることにしよう.できた!

image

これはかなりわかり易い図だ.兄弟順位がそのものずばり,4進表記したノード番号に現れている.しかも,4進表示すると,これらの兄弟ノードの名前の語幹部はそのものずばり親ノードを示しているように読める.つまり,すべての兄弟が同じ「姓」を持っている.例として5090020693の子ども枠の中を見ると,第1子が12110201023301301で,第2子は12110201023301301-1,第6子は12110201023301301-11111.親の5090020693自体は,5090020693の6番目の子どもで,102331203203-11111という4進名を持っている.長子12110201023301301の名前には2のべき乗数が入っていたはずだが…一昨日の記事から再掲すると,

P=F(S)=(3S+1)/2   c=1の場合:S=…011, …111の場合
    =(3S+1)/4   c=2の場合:S=…001の場合
    =(3S+1)/16  S=5=101の場合

ということになっているので,4進表記すると,c=1というのは,末尾が3,c=2は1,c=4はS=5しかないので,S=11という場合に限られる.末尾が0ないし2なら偶数だから,末尾が1ならば,c=2,3ならc=1.ノード番号全体が11ならc=4ということになる.cの値が決定できれば,あとは3S+1を計算し,それを2^cで割ってやれば親数を得ることができる.もし,3進数で表示されていれば,3N+1がどんな数になるかはすぐ分かるが,それを2のべき乗で割り込んだ結果は子ノードの名前とはかけ離れたものになるのは避けられないだろう.

それにしても,兄弟の氏名がこんなにシンプルな構成だということを想像したことがあったろうか?これはもはやコラッツ問題が完全に解かれたということの証左以外のなにものでもない.子ノードの3S+1という数を計算してそれをバイナリ表示してやれば,この辺りの関係もある程度見えてくるのではないだろうか?それをやってみよう.

この値を生没日付欄に表示してやろうとしたのだが,出てこない.本来日付は内部的には文字列としてしか扱っていないはずなのだが…日付データとしての有効性をどこかでチェックしているのだろう.仕方ないので肩書欄に記入してみた.長くなってしまうが,仕方ない.

image

もはや,これ以上のことを言う必要はないだろう.子どもノードSのノード番号に3S+1という変換を掛けて得た数値はそのものずばり,親ノード番号+右シフトの回数になっている.この兄弟ノードの親ノードである5090020693を4進表記した数字はすべての子どもノードの4進表記の中に埋め込まれている.また,子どもノードSの3S+1のバイナリ表現の中にも完全に親ノード番号が埋め込まれ,それを2^c倍したものになっている.明らかにこれは一種の戸籍システムであり,あるノードのノード番号がわかればそれを順繰りに手繰って,先祖ノードまで遡ることができることは明らかだ.これは家系図を作成するときに本籍地から本人の戸籍→父の戸籍→祖父の戸籍を手繰るのとまったく同じ手順である.4進表記と3N+1の2進表記の間に,3進表記というのを挿入すれば,計算するまでもなく,子ノードのDNAが親ノードのDNAを正確にコピーしたものであることが分かるだろう.この図面はほぼ,コラッツ予想問題の「完全な証明」に相当するものになっていると思う.

親ノード5090020693を2進表記すると,100101111011000111000110101010101のようになる.その子どもの6949574919509の3N+1を2進表記したものは

100101111011000111000110101010101000000000000

のようになる.この末尾の0を取り除くと,100101111011000111000110101010101となって完全に一致する.これは計算の結果そうなったのではなく,もともと埋め込まれていたものであることを示すにはやはり3進数表記を見るのが一番早いと思う.やってみよう.⇒いや,ダメだ.思ったような結果にはならない.当然かもしれないが,3進表記した場合には兄弟ノードのすべてで異なる名前が生成され,共通部を見出すことはできない.これをやるとしたら,長子木を使った方がよいかもしれない.長子ノードの3進表示を左に1シフトして1を加えたものを2ないし4で割ったものが親ノード数になる.従って,親ノードを2ないし4倍したものから1を減じたものを3進表示すれば共通部が見えてくるのではないかと思う.これは長子木が復活したあとで試してみることにしよう.「親ノードを2ないし4倍したものから1を減ずる」のような操作は一種の「計算」ではあるが,2進ないし4進数としてみると,これはDNAの文字並びを壊さない操作になっているので,それと子ノードの3進数が共通部を持つことを示すことができれば,「DNA保存」という文脈の中で説明可能になる.

我々の意図するところは,子ノードが親ノードのDNAを引き継いでいること,そのDNAシーケンスから先祖ノードまでの遺伝子継承関係を手繰ることが可能であることを示すことにある.その目標はすでにほぼ達成されているのではないかと思う.4進表記したときの下位ビットはそのノードの兄弟順位を示すものであり,たとえば,太郎・次郎・三郎などのような一般的な呼称になっている.上位ビットは親の名前だが,暗号化されているため親の実名とは一致しない.しかし,すべての兄弟が同じ親の名前を共有していることは確かだ.親ノード番号を親の実名とすると,子ノードの中に埋め込まれている親の名前は親の戸籍名(暗号化された実名)であると言える.しかし,暗号化された親の実名をデコードするのは難しくない.そして,親の実名もまた,親の親の戸籍名+太郎・次郎などの兄弟順位名から構成されている…結構単純な仕掛けだが,我々が「アドレスコード」と呼ぶものと「ノード番号」が完全に等価であることの実証であると言ってよい.

一言でまとめれば,「自然数の原戸籍簿は4進数によって標記されている」ということになるだろう.4進数のアルファベットは0, 1, 2, 3の4文字である.ここでピンと来たあなたは確かにいい感をしている.人間に限らず,すべての生物のDNAがACGTの4文字から構成されていることはよく知られた事実であり,自然数の4進数表記がDNA配列になっていることはいまさら驚くべきことではないのかもしれない.