「不正 UndoNumber」に対処

昨日のログでは「保留」としていた「不正 UndoNumber」に対処.

複数カードの削除を2回以上実行した後,Undoで最初の状態まで戻り,そこで再度複数カードを削除すると,SetUndoListで(object->UndoNumber > UndoNumber)という「不正UndoNumber」エラーが発生する.⇒object->UndoNumber が0になっていれば,このエラーは発生しないので,PergeZenpoChainで前方コマンドチェーンをカットするときに,始末しておけばよいのではないか?

オブジェクトへのリンクはUNDONODE::addressにベタ参照として入っている.UNDONODEのデストラクタでaddress->UndoNumberをリセットしてやればよいのではないだろうか?⇒実オブジェクトはShadowチェーンを構成している.⇒Shadowはオブジェクトのバックアップされたイメージだ.この中にはバックアップ時のUndoNumberも含まれている.従って,ここでUndoNumberをリセットしても,オブジェクトのUndoNumberはつねに正当な値を保持していると言える.⇒対処した.

▲setmaxrefnumで最終レコード番号をmaxrefnumに代入している.⇒最終レコード番号=maxrefnumという決め付けは危険だ.⇒setmaxrefnumがつねに危険という訳ではない.引数で「レコード番号」を渡しているケースを拾い出す必要がある.maxrefnumはリンクを生成するか,削除した場合以外には変化しないと考えられるから,これらのケースに漏れ落ちがなければ,それ以外の場所でmaxrefnumを更新する必要はない.まず,setmaxrefnumで同じ値を設定しようとしたときに停止するようにしてみよう.⇒さっぱりヒットしない.おそらく,処理の冒頭でmaxrefnumを初期化しているのだろう.

テーブルで行選択してカード削除しようとすると,対象カードが変化してしまう.⇒カード画面でカード番号欄が4桁しか見えないため,数字が隠れてしまう.⇒カード削除パネルに出てくるカード番号が間違っている.カード画面の主選択カードは正しい.⇒操作を間違えていた.「番号列セル」のクリックでは選択状態は変わらず,「現参照カード」のみ変化する.「現参照カード」というのは,カード画面上に表示されたカードだ.これまではこれを「主選択カード」と呼んできたが,「選択操作」と独立に操作できるようになっていることを忘れていた.というか,そうなっていることを知らなかった!

newlinkでもレコード番号をmaxrefnumに格納している.⇒setmaxrefnumの参照箇所は15箇所ある.結婚リンクの場合,MARGTABLE::makenewlinkでは親のスロット番号をそのまま参照番号としている.CARDTABLE::makelinkでも実質,レコード番号をセットしている.COUPLING::InitLinkTableでは,参照番号をレコード番号とみなしてテーブルを構築lしている.従って,参照番号=レコード番号が本則であると考えるべきである.ただし,参照番号は論理番号であり,レコード番号は物理番号であるから,つねに両者が一致していると仮定すべきではない.実際,ファイルロード時には参照番号の付け替えは行われていないから,古いファイルの中には一致していないものが多数あると考えるべきだ.少し,整理する必要がある.

①getmaxrecnではつねにテーブルサイズを返している.②テーブルは一般にはスパースであると考えられるが,最大レコード番号がカウントされていない.③maxrecnum(以前のmaxrecn)はlookupテーブルのレコードカウントであり,②の最大レコード番号ではない.④maxrecnumをrecordcountとリネームし,maxrecordという変数を新設して,ここに②の最大レコード番号を格納する.⑤getmaxrecnでは④のmaxrecordを返すようにする.⑥recordcountをメンテナンスする関数の中で,maxrecordを更新する.

▲delrecnを廃止する@20221226をフィックス,longtableのaddを使う@20221226をフィックス

maxrecordは単調に増加するものとし,テーブルの縮小は行わない.maxrecordの参照関数をmaxRecordとする._maxrecnをリネームしてrecordCountとする.MakingLookUpは17箇所から呼び出されている.UNDOではUndoEndとUndoProcessでMakingLookUpを実行しているので,DEFINEUNDOSYSTEMは多くの場合,省略できるのではないか?CommandStartFlagがオンの場合はすべてパスするようにしてみよう.

▲BUG3000-1906.ZELを開いて,1906-543=1363点を削除→基準ソート→UndoでTREEVIEW::CheckSelectListのエラーが発生した.selectcardlist->countと実カウントの不一致1が起きている.⇒何かやり損なったのだろうか?再描画が掛かってこない.どうも,バックアップに戻って作り直しするしかなさそうだ.修正手順を記録しながら進めることにする.最初にまずいくつかの過去の修正をフィックスしておこう.ただし,定義文はコメントとして残しておく.

  1. delrecnを廃止する@20221226をフィックス
  2. longtableのaddを使う@20221226をフィックス
  3. getmaxrecnを廃止@20221226をフィックス
  4. setmaxrefnumでレコード番号を禁止@20221227をフィックス

やはり,ダメだ.CheckSelectListのエラーが発生するほか,Undo→ Undo→ Redo→ Redo→ Undoで,参照カウント 不一致が大量に発生する.ここまでは単純に修正をフィックスしただけなので,バックアップに戻っても同じだと思う.このままシューティングするしかない.もう少し小さなサンプルでテストすることにする.極小反例307.ZEL(66点)でやってみよう.⇒再現する.手順は,①カードを大量一括削除,②基準ソート,③Undo→ Undo→ Redo→ Redo→ Undoだ.

テーブル並び替えの時点では選択カードは1点という状態になっている.最初のUndoでCheckSelectListのエラーになる.selectcardlist->countは1だが,selectflagはすべて落ちている.そもそも,UNDOでは選択状態を保全していたのだろうか?⇒保全している.いや,selectcardlistそのものは保全していないが,カードの保持するselectflagから復元している.⇒どうも,かなりおかしい.lookup.countが307もある.いや,この時点ではそれで正しい.

元々の論理ではUNDO時には,選択はすべて解除するということになっていたものと思われる.ただし,冒頭でカウントをリセットする処理が(意図的に外されていたため)不整合が発生していたものと思われる.いろいろな意味でUNDO時に選択状態を維持するというのは無理があると思われるので,「UNDO時はつねに無選択状態」ということにしたい.⇒いや,selectflagから復元するという方式で動作しているようだ.これでもよいのではないか?

UNDO中はつねにカードリンクが保持するselectflagからselectcardlistを復元できるので,基本的に選択状態は維持可能と思われる.ただし,これは選択状態が復元できるという意味ではない.選択領域全体をキープしようとしたら,コマンドのたびにすべてのカードリンクをバックアップしなくてはならなくなってしまう.それはおよそ不可能だ.

「被参照カウント不一致」の問題に移ろう.これはかなり,手強いと思う.再現手順は,基準ソート→Undo→Redo→Undoだ.その後は,RedoでもUndoでも同じになる.手順から見ると,Redoで壊しているように思われるのだが… 障害が発生しているのはCARDLINKとMARGLINKで,これらはバックアップとは無縁のように思われるのだが… ⇒いや,2回目のUndoで起きているようだ.UNDOコマンドのリングを巡回処理中に不良が起きている.ここで実行されているのは,RestoreShadowとUndoRestoreくらいだが… ⇒UndoRestoreが元凶だ.

Collatz12146.ZELを開けるようになった

Collatz12146.ZELをようやく安定的に開くことができるようになった.ただし,開くまでには相当な時間が掛かっている.どこがネックになっているのか,シューティングしたいところだが,それはもう少し落ち着いてからの課題としておこう.

巨大ファイルでメモリ不足が発生しないようになったのは,MAXPDBxMAXMDBという巨大配列の使用を一時的に止めたことが効いているのではないかと思う.DTおよびKTという名前のshort型の2元配列で,親等計算に使われている.とりあえず,親等を計算する必要はないので当面は停止で問題ない.親等計算は結構時間を消費するので,オプションで止められるようにしておいた方がよいかもしれない.

Collatz12146.ZELでは三極検定レッドラインオーバーが発生している.

image

上図では小さ過ぎて見えないが,図面の左上隅に#1のカードが取り残されている.その他にも何点か隔離された点が残っているが,おそらく,これらがレッドラインオーバーの原因になっているものと思われる.極小反例抽出というのは,この問題をシューティングする目的で始まったのだろう.⇒極小反例サンプルのコレクションがある.極小反例 371.zelが多分最小と思われるので,試しに開いてみよう.⇒開けてしまう.反例になっていない.⇒この問題は後からやることにしよう.

CARDTABLEとMARGTABLEにはRenumberという関数がある.これが使えるのではないだろうか?⇒NAMESORT::NameNarabekaeには元々その処理が入っている.基準ソート(参照番号による並び替え)では,PDBとMDBのRenumberを実行している.ただし,現行の「特注版」では基準ソートの代わりに番外として「カード番号によるソート」が実行されているため,適用されていない.⇒参照番号とカード番号はまったく同一なので,「特注版」として特に別扱いする理由はないような気がする.オプションを止めてみよう.⇒うまく行ったようだ.

テーブルサイズを16384まで拡大してCollatz12146.ZELを読み込んでみた.系統並び替えだけで16分掛かっている.テーブルのロードでもその位掛かるので,トータルでは20~30分くらい掛かっているのではないだろうか?パフォーマンスに関してはもっと後で取り組むことになるが,getnewRefnumの仮修正はフィックスしておいた方がよい.getnewRefnumのオリジナルバージョンではmaxrefnumの次の番号を返すようになっているが,暫定的に空スロットを見つけてその番号を返すようにしている.一般にはこちらの仕様の方が適していると考えられるので修正を戻しておくことにしよう.ただし,maxrefnumがテーブルサイズを超えた場合には,任意の空スロット番号を返すということにする.⇒いや,emptyrecn自体そういう作りになっている.

この関数はテーブルフルになった場合にはエラーコードを返しているのだが,それに対応するようになっているだろうか?⇒一応対処した.emptyrecnとgetnewRefnumの最大の違いはテーブルサイズオーバーのとき,エラーパネルを出すか出さないか?だ.emptyrecnでは,「%sデータベースの容量%d件を超えています.\nこれ以上%sリンクを追加することはできません.」のようなメッセージが表示される.これが頻発するというのは望ましくない.⇒emptyrecnに引数を一つ追加して切り分けるようにした.⇒いや,コンパイルが通らない.BASETABLEはテンプレートクラスなので,ヘッダファイルの中で初期化できない.

そもそも,このBASETABLE::emptyrecn自体間違っているのではないか?この関数は冒頭,max = getmaxrecn()で最大レコード番号を取り出しているが,現行ではgetmaxrecnはtablesizeを返すようになっている.従って,(max < tablesize)はつねに偽となり,つねに空スロットの探索という動作になってしまう.これはここで予定している動作になっていないのではないか?maxrecnというメンバー変数もある.この値はメンテナンスされているのだろうか?

_maxrecnという参照関数でアクセスするようになっている.この値は,MakingLookUpで更新される.また,delrecnという変数も持っているが,これはもう廃止してもよいのではないだろうか?また,incmaxrecn,decmaxrecnという関数も使われている.今度はCollatz3900-6165.ZELでテストしてみよう.このファイルのサイズはCollatz12146.ZELの半分くらいだ(6165点).⇒時間は掛かるが問題なく開けた.三極検定では30回ループを回している.

BASETABLE::getmaxrecnがつねにtablesizeを返しているとすると,getmaxrecnを呼び出しているところでは,つねにテーブルサイズ分のリンクをチェックしていることになる.これはあまりにタイムロスが大き過ぎる.lookupテーブルには前詰めしたリンクが入っているはずだ X.基本的にレコード単位にアクセスするときは,このテーブル(lookup)を使っているはずだが,全テーブルに直接アクセスしているところも無数にあるに違いない.lookupを使うためにはMakingLookUpが実行されている必要がある.getmaxrecnの呼び出しは194箇所もある.

とりあえず,delrecnを廃止しておこう.今度はBUG3000-1906.ZELを開いてみた(1906点).そこそこの時間で開けた.系統並び替えの所要時間は34秒.このサンプルはどうやって作ったのか分からないが,最小番号は15で,ルートは35になっている.

▲一覧画面を開いたとき,必ずカード番号の降順で初期表示されるのはなぜか?また,起動時には元の画面を復元してもらいたい.

一度バックアップを取ってから始めよう.lookupというのは,longtable型のオブジェクトで,テーブルサイズはMAXPDBに固定されている.結婚テーブルもlookupを持っているが,サイズ調整はしていない.通常,longtableには参照番号などの整数値が格納されるが,lookupの場合にはテーブルのインデックス(1発進)が入っている.この値はMakingLookUpで常時メンテナンスする必要がある.⇒チェックすれば死亡していることは確認できる… longtableにCountという参照関数を追加してcountを取り出せるようにしておこう.

lookupにアクセスしているところでは,getmaxrecnを使うのを止めて,この関数を使うことができる.⇒いや,MakingLookUpでlookup.countをmaxrecnumに格納しているので,この値を直接取り出すことにする.lookupは59箇所から参照されている.lookupを参照する関数として,getlinkとgetrefnumがある.テーブル並び替えはlookupを対象に実行されている.つまり,リンクテーブルは操作されない.

▲setmaxrefnumで最終レコード番号をmaxrefnumに代入している.⇒最終レコード番号=maxrefnumという決め付けは危険だ.

▲CommandStart~CommandEndではlookupは使用不可(MakingLookUpが実行されていない)⇒これは,フラグを見れば確認できるだろう.

▲getrecn(refnum)という関数は,リンクテーブルでアクセスした方が効率がよいが,ヒットしない場合はlookupを使った方が無駄が少ない.

効率にはほとんど影響しないが,多少なりコードを読みやすくするために,longtableにaddという関数を追加しておこう.

▲上記サンプルでツリーの裾の方をまとめて1304点全削除したところ,SetUndoListで (object->UndoNumber && object->UndoNumber > UndoNumber)というエラーになった.object->UndoNumberは3, UndoNumberは1.その前に複数のカード削除とUndo/Redoを実行している.この全削除はUndoで振り出しに戻ったところでやっているので,前方チェーンはすべて削除されているはずなのだが… オブジェクトのUndoNumberがリセットされていなかったのだろうか?⇒同じエラーが無数に起こるので,一旦終了する.

オブジェクトの輪切りを反復しても再現しない.おそらく,先行実行されたカード削除に関係するオブジェクトで削除対象ではないオブジェクトが存在し,Undoで復活した図面ではそのときに設定したUndoNumberが残っていたのではないだろうか?そのようなことは起こり得るように思われる.⇒UndoNumberを上書きしてやればそれまでだが,それではUndoNumberを導入した意味がなくなってしまうのではないか?⇒再現手順を確立しておこう.⇒少なくとも2回以上全削除を繰り返し,それらをすべてUndoした状態でそれに関係した領域をまとめて全削除すると発生する.⇒かなり難しいので一時保留としておこう.

同上サンプルで,ルートから底辺までの帯状の領域222点を全削除して,SetUndoListの出口で(object->UndoNumber != UndoCurptr->UndoNumber)が出た.object->UndoNumberは0,UndoCurptr->UndoNumberは1.CommandStart→ BackupPointData→ SetUndoListで発生している.objectはPARTIALNAME.⇒これは上記の「保留」に関わる修正ミスだ.

ようやく作業がルーチンで回り始めた

ようやく作業がルーチンで回り始めた.こうなれば,もう怖いものなしだ.今回作業再開の目的は一義的には「Sultanの論文の検証」だが,その前に「コラッツ木生成ツールの再構築」と「ゼルコバの木の増強」に取り組まなくてはならない.現在,ゼルコバの木は「コラッツ特注版」というかなり変則的な方向に進んでいるが,この方向性をむしろ「本則」として標準化する必要がある.

コラッツ木は単純な木であり,これを最大限・最高速で処理できるようにすることは,一般の系図を扱う上での前提であると考える.ゼルコバの木はこれまで,最大1000点というスケールの領域を扱ってきたが,これを機会に1万点を超えるデータを扱えるように仕立て直したい.かなりハードルは高いが,やっておく必要がある.

カードを2点削除した後で,Undoを2回行うと,UndoNumberの不一致が発生する. (UndoCurptr-> UndoNumber != UndoNumber)が起きている.UndoCurptr-> UndoNumber=1, UndoNumber=2だ.このエラーは初回だけで,その後の Redo,Undoでは収まってしまう.

UndoNumberという値は,①UNDOBASE,②UNDOCOMMAND,③noduleの各クラスで保持されている.UndoNumberは「重複バックアップの回避用」.UNDOBASE::MakeNewCommandでシステムとチェーンのUndoNumberの同期がなされている.SetUndoListではバックアップの対象となるオブジェクトに現UndoNumberが格納される.

UNDOBASE::CommandEndでは出口でUndoNumberの調整が行われる.⇒UndoStartでコマンドを開始する時点で,前方のコマンドチェーンがパージされる.このとき同期が一時的に崩れる場合がある.UndoCurptrが変更された場合には,つねにUndoNumberを更新する必要があるのではないか?UndoCurptrは以下で切り替えが発生する.

  1. UndoBase::UndoProcessの出口
  2. UndoSystem::UndoProcessの出口
  3. PergeZenpoChainの出口
  4. UNDOBASE::MakeNewCommandの出口
  5. UNDOBASE::CommandEndの出口で(UndoCount <= 2)のとき

UndoBase::UndoProcessは実質的には(ほぼ)使われていない.UndoBase::CommandEndで例外がキャッチされた場合にのみ,強制的にUNDOを実行して復帰するような作りになっているが,これが実行された試しはないと考えられる.

MAXUNDOCOUNT=5のとき,最大4コマンドまでしか保持できない.なぜか?⇒MakeNewCommandで(UndoCount >= MAXUNDOCOUNT)で打ち切っているためではないか?等号を外せば,MAXUNDOCOUNTまで作れるはずだ.⇒これでよい.

ここで一旦バックアップを取っておこう.

一覧画面の列ラベルをクリックしたときのテーブル並び替えが実行できないのはなぜか?⇒いや,動いている.セル項目をテキストしてソートしているので期待したような結果にならなかったためではないか?⇒カード番号は数値としてソートしているのに正しい並びになっている.見間違えだったのだろうか?まぁ,ともかく,これでよしとしよう.

少なくとも今当面の目的では,①カード番号,②氏名,③所属,④肩書きだけは数値としてソートしたい.⇒特注版の「数値で並び替え@20221225」オプションとして処理しておく.⇒うまく行った!

NAMESORT::NameNarabekaeのcheckがオンになっているとき,STOP文で止まらない(場合がある)のはなぜか?⇒ブレークポイントを置けば停止する.⇒STOP try {__asm { int 3} } catch (…){}を{ int 0}に書き換えたら毎回停止するようになった.

コラッツ木生成ツールから出力される隣接リストファイル(ADL)では,氏名欄にそのノードの値である巨大整数が入っている.カード番号はテーブルの範囲内であれば,その値をそのまま採用する場合もあるが,通常はオーバーフローしてしまうため,ハッシュして小さな数に変換している.ここで使っているハッシュ関数は単純なもので,すべてのビットが1であるようなある桁数の整数とANDを取っているだけだ.テーブルサイズを2のべき乗にしていたのはこのような事情による.

テーブルサイズが小さくなった場合はどういうことになるのか?現行では,0x1FFFという定数に固定されている.この値はテーブルサイズによって伸縮されるべきだと思う.カード番号のデータ型はlongなので,最大でもその範囲を超えることはできないが,テーブルサイズ AND FFFFFFFF まで使えるのではないだろうか?

▲発行されたカード番号が実際のテーブルサイズより大きくなる場合がある.テーブルサイズが1000のとき,最大#1097というカードが存在する.登録データはきっかり1000点だ.つまり,1000より小さい領域に97個分の穴が開いているということになるのだが… 実用的にはこれでも特に問題はないとも言えるが,参照番号はテーブルのレコード番号と一致するのがベストであるという観点からすれば,見直しの余地はあるのではないだろうか?⇒やってみることにしよう.

多少厄介なので,一度バックアップを取っておいた方がよいかもしれない.⇒どうも見ているところが違うようだ.カード番号はLINKTABLE::GetRefnumで決めていると思っていたが,通っていない.いや,いまテストしているのはADLファイルではなく,ZELファイルだ.⇒テーブルサイズを6000に拡大して読み込んだら,カード番号も振り直しされている.ただし,最大6000を超えるカードが97点ある.どこで振り直しをやっているのだろう?

カード番号が決定しないとテーブルは構成できない… COUPLING:InitLinkTable辺りでやっているのではないだろうか?⇒確かにそのようだ.参照番号が空スロットならばそこを使い,空いていないときは,空スロットを探してそこに居を定める論理になっている.BASETABLE:newlinkでは,まず指定番号のスロットが空いていればリンクを生成してそこにリンクする.空いていない場合は,makenewlinkを使って空スロットを探し,そこにリンクを(newlinkを使って)生成する.

しかし,この方式なら参照番号がテーブルサイズを超えることはないように思われるのだが… makenewlinkには2つのバージョンがあり,emptyrecnを使うパターンとgetnewRefnumを使うパターンがある.後者はmaxrefnumをインクリメントした番号を返すので増長してゆく可能性がある.⇒getnewRefnumの代わりにemptyrecnを使うようにしてみたが,効果なかった.⇒現行方式では参照番号の振り直しまでは実行していないので,テーブルサイズより大きなカード番号の存在は不可避である.⇒参照番号の振り直しというのがどこかにあったのではないか?

▲テーブル並び替えで系統並び替えが実行される.

テーブルサイズ8192(0x2000)でテストしてみた.最大で8289というカードがある.8289-8192=97でこの場合もはみ出しているカードのオーダーは同じだ.⇒MAXPDB=12300, MAXMDB=10300でCollatz12146.ZELを開くことができた.カード番号のはみ出しは解消した.ただし,三極検定でループカウントオーバーが発生している.

修正のフィックスでバグを作り込むとは

デバッグ作業が少し進み始めた.バグというのはとんでもないところに潜んでいるものだ.「デバッグにはいかなる予断も許されない」

UNDOBASE::SetUndoList→ で(!copynode->shadow)が発生

GetNewCard→ MakeNewCardで引数のrefnumが0のときは,mCreateCardで新規カードを作っている.mCreateCard→ CreateCard→ FAMILYTREE::getNewCard→ UNDOSYSTEM:CommandStart→ UNDOBASE::CommandStart→ BackupPointData→ SetUndoList→ で(!copynode->shadow)が発生している.⇒「生成したばかりでshadowを持つはずがない@20170823」というブロックが削除され,代わりに「1行削除@20220423」が入っている.この日付は2022-04-23だが,この修正は実際には2022-04-26-1で初めて入っている.この辺りのログを読んでみよう.

2022-04-29のログはそのものずばり,「UNDOBASE::SetUndoList で(!copynode->shadow)により停止した」となっている.⇒この記事では対処されていない.問題がメモリ不足の問題にすり替わっている.⇒2022-04-27で「UNDOに関する修正をフィックス」している.おそらく,ここで誤ったものと思われる.「UNDOのShadowをfreeblock化@20220423」2箇所 に該当するのではないか?

「UNDOのShadowをfreeblock化@20220423」というのがある.この日付が20220423となっているので,整合している.この定義はFIXED@20220426でフィックスされている.#ifndefのマクロで#elseが活きなくてはならないところを誤って削ってしまったのだろう.⇒復活させた.修正のフィックスでバグを作り込んでしまっていた.⇒別のエラーが出るようになった.

UNDOBASE::CommandEndでUndoCurptrが空になった.⇒PergeZenpoChainで空にしている.UNDOBASE::CommandEndは戻り値としてlongを返しているが,この値は初期値0のままで使われていない.⇒「ringTopが空のときはつねにPergeZenpoChainを実行する@20170515」となっているため,PergeZenpoChainが実行されている.UNDOSYSTEM::CommandEndには「UndoCurptrが空となる場合があり得る?@20220418」というコメントが付いている.この関数は外部で致命的エラーが発生したときには,fatalerrorを返している.

PergeZenpoChainでは,Undoチェーンの後方ノードが空,つまり,UndoCurptrが末尾ノードである場合は,UndoChain,UndoCurptr,UndoNumberをリセットしている.また,UndoCurptr=UndoChainの場合(UndoCurptrが先頭ノードの場合)も同様動作となる.従って,UndoCurptrが空となるのはノーマルな状態であると考えられる.

if (lret >= 0 && !UndoCurptr) STOP; あり得る@20220418 となっていたのだが,同日付であり得ないに変わっている.⇒lretにUndoNumberを格納してチェックを回避するように修正した.⇒どこかでハングしている.強制ブレーク→続行しようとして,以下のような見たこともないパネルが出た.

image

デバッグの中止もできない.どうも,このエラーは「Attempting to get the view from an adapter in state TextDocDataAvailable」はかなり始末が悪そうだ.ネット上にも情報はあるが,あまり役に立たない… デバッガに関係するものであるような気がするが…

PHASEがINITIALIZINGのままになっている.どこかで横道に逸れてしまっているのだろうか?エラーが発生しているのだろうか?CZelkovaCtrl3::TopologicalSortで-1017を返している.この値はCallSortLineageの戻り値だ.ERR_AUTOCORECTEDDATA(自動補正されたデータ:保存が必要)という通知だ.InitializeDisplayではUpdateFlagをオンにして対応しているが,Currefnumに0を格納しているため,動作がおかしくなっているのではないか?

Z.BaseRefnumには1が入っていて,GetRecordNumberでレコード番号を取り出そうとしているが,0が戻ってくる.Z.mSendRequest(4) ‘基準ノードの参照番号を請求する @@2016-10-22 というのがあるので,これで取り出してみてはどうか?⇒対処した.これで描画できるようになった.⇒この修正でGetNewCard→ MakeNewCard→ mCreateCard を通らなくなってしまったので,UNDOが掛からないようになっている.暫定修正を入れてもう一度動作確認してみよう.CommandEndの動作にはまだ少し疑問がある.

  1. (UndoCount <= 2)のときは,なぜUndoCurptrを繋ぎ変えてUndoChainに戻しているのか?
  2. なぜ,UndoCurptr->ringTopは空になっているのか?

FAMILYTREE::getNewCardは-10018を返している.⇒このエラーコードは「カード登録数がカードリンクテーブルのサイズを超えた」の意味だ.しかし,UNDOBASE::CommandEndにはアプリケーションの処理結果は一切入ってこない.⇒一手間かかってしまうが,アプリの処理結果をCommandEndに渡すようにしておいた方がよいのではないか?処理が失敗したときには,そのコマンドは破棄されるというのが当然の動作になるのではないかと思う.⇒一度バックアップを取ってから取り組むことにしよう.⇒ZELKOVA 2022-12-24 Aとして保全した.

「CommandEndに処理結果を渡す@20221224」で修正しておこう.⇒処理により,戻り値が結構あいまいな場合があるので,ケースバイケースで導入するものとし,今回はMAKENEWCARDにのみ限定適用とする.⇒PergeZenpoChainを実行して0復帰するようにした.UndoCurptr, UndoCount, UndoNumberはすべて初期化されている.

CommandEnd(DELCARD)では負値を返している.CommandEnd(DELALLCARD),CommandEnd(MERGECARDS)も同じ.これは別途チェックしておく必要がある.⇒UNDOBASE:CommandEndでは特に何もしていない.現行ではUndoNumberを返すようになっている.UNDOSYSTEM::CommandEndではTopologicalSortの結果を返すようになっている.致命的エラーが発生したときには,fatalerrorで復帰する.

UNDOSYSTEM::CommandEndで0復帰すると,画面が表示されない.なぜだろう?⇒GetNewCardで新規ファイルに失敗しただけで何も表示されないというのはかなりおかしい.⇒画面の更新はRefreshSubで実行されるが,更新のダブりを抑制するためのRefreshFlagはデータベースの読み込みが完了するまでは落ちない.このため,事実上UndoStatusの実行時にしか画面は更新されないようになっているが,これまでの論理ではZ.mUndoStatusがゼロの場合には画面の更新は実行されなかった.⇒UNDOSTAT.UPDATEDIAGRAM) <> 0 の場合はつねにZView.RefreshSubを呼び出すように修正した.

ここで一度バックアップを取っておこう.

▼MAXUNDOCOUNTに達したときの動作を確認する

Undoでテーブルが更新されていない.⇒UndoStatusに組み込んで動作するようになったが,呼び出し頻度が高過ぎる.⇒CardUndoRedoから呼び出すのが適切だ.⇒もともとこの位置から呼び出していた.

▲カードを1点づつ5点削除したあと,Undoを2回反復して,UndoProcessでUndoNumberの不一致 (UndoCurptr-> UndoNumber != UndoNumber)が発生.前者が7,後者が8.また,Undoで最初の50点まで戻れなくなる.

一覧画面が毎回同じ場所・サイズで開く.前回の場所を覚えていない.⇒現在位置は覚えているが,ファイルを閉じると忘れてしまうようだ.⇒ダブルクリックでオープンしたときは,DockingWindowFunc(False) が実行され,このときのウィンドウ位置を記憶するという動作になっている.⇒暫定的にこの動作を止めて任意の場所で開けるようになった.

▲テーブルをクリックしてCardTable_MouseClickが起動しない.⇒MouseClickというイベントが見当たらない.MouseDownというのはある.⇒MouseDownでも入ってこない.

▲CardGridView_CurrentCellChanged→EditTableEnd→…FAMILYTREE:GetCardBaseで(PHASE < DRAWSTAGE) で停止した.



MiniTool Partition Wizard でOSドライブの移行を試みる

アクセス解析プラグイン Site Kit でようやく詳細情報が出てきた.これで見ると,テント村の来訪者のプロフィールをまったく誤解していたようだ.STATISTICSで見ると最近の一日の来訪者は200人くらいになっているが,そのほとんどは検索エンジン経由で,URLでストレートにジャンプしてくるケースはごくわずかしかない.その検索ワードも,①regsvr32とか,②タイプ初期化子が例外をスローしました,③blend for visual studio, ④xoops 開発 終了など,ごく特殊なキーワードばかり.このようなキーワードについての記事を書いている訳ではないので,読んでもほとんど役に立っていないと思う.そんなことであれば,もう少し詳しい解説記事を書いた方がよいくらいだが,この辺りに関してはわたしもあまり専門的な知識を持ち合わせていない…

メール受信専用に使っているBlackHawkがメモリ不足で動作が悪いので,ディスククリーンアップの記事を探していたら,MiniTool Partition Wizard というのを見つけた.OSドライブを丸ごと引っ越しさせるという機能を持っている.ダウンロードに時間が掛かりそうなので,povo1.0の24時間使い放題220円を使ったが,ディスク容量不足で途中で中断してしまった.ただし,プログラムの本体はインストールされているようで,立ち上がってきた.無料評価版だが,果たして安全にOSドライブの移行が実行可能なのだろうか?失敗すればとんでもないことになる虞がある.⇒そもそも,それをやると移行先ディスクのデータはすべて消去される.もしやるとすれば移行先ドライブを空っぽにしてからでないと始められない.このドライブは238GBだが,うち,31GBが使用済みになっている.USBメモリに移せない容量ではないが…

このBlackHawkというマシンはかなり脆弱で外付けHDを接続できなかったのではないだろうか?確かにそのようだ.画面が不安定になって,おそらくどこかでクラッシュしてしまうだろう.⇒32GBのUSBメモリは装着できた.ここに一旦すべてのデータを退避させてみよう.残り時間20分となっているので,それほどの時間は掛からない.本体のMiniTool Partition Wizard と一緒にMiniTool ShadowMakerという別製品もインストールするようになっていたので,多分メモリ不足は後者のダウンロードで起きたのだろう.製品として購入すると8200円掛かる.⇒やってみよう.移行先ドライグを指定後,以下のパネルが出た.

image

よくわからないが,GPTでは2TB以上のドライブが扱える,UEFIというのはブートモードでWindows 11はUEFIにのみ対応という話なので,多分関係ないと思う.⇒移行した後,BIOSで起動ドライブを設定しなくてはならない.これができないとお釈迦になってしまう.試しておいた方がよいのではないか?⇒Windowsキー→設定→回復→今すぐ再起動→…→オプションの選択→トラブルシューティング→詳細オプション→UEFIファームウェアの設定→再起動→BIOS設定画面が起動という手順で起動できる.電源オンの直後にF2,ないしDelキーを押すということになっている.F2かDelかどちらかわからないがBIOS設定画面に出た.

移行先のSDDドライブはGPTディスクになっているようだ.⇒やはり,購入しないとOS移行はサポートされないようだ.8200円というのは買い切りではなく,年額だ.このソフトはかなりグレードが高いのでそれだけの価値はあると思うが… ここで8千円出費したら年が越せなくなるのではないか?そもそも,このマシンがあと1年持つのかさえ分からないというのに… とりあえず,ここは保留とするしかなさそうだ…

▲「メモリ描画環境用のメモリが不足しているため,生描画に切り替えます」が出て,モノクロに切り替えた後,倍率などを変えると同じメッセージが出て,生描画に戻ってしまう.

▲現行版では「氏名を表示」のみになっているのに,2行出ている.これはどういう設定になっているのか?

Collatz12146.ZELを開いて,例外が発生する.「ucrtbased.pdbは読み込まれていません」が出力画面に表示される.

image

続行で”Buffer too small”のエラーが起きる.

image

再試行でucrtbased.dllで停止するが,トレースはできない.⇒この障害は事前に大きめのファイルを2つ開いた後の読み込みで起きる.この後,「一部データに…修復されました」を表示してVBに制御が戻っているが,SetSingleSelection中にTREEVIEW::CheckSelectListのエラーが出る.selectcardlistのカウント1と現物カウント0で不一致が生じている.また,UNDOBASE::SetUndoListでcopynode->shadowが空で停止する.⇒この後,dp空で例外が発生するため,修正した.⇒ダメだ.”Buffer too small”がパスできなくなってしまった.⇒上で読み込めたというのは,「偶々」だったのだろうか?⇒コマンドライン引数で渡すようにしたら開けた.

見たことのないエラーが出た.

DataWarehouse ホストへの要求に失敗しました: ‘Invalid task token: 88802e77-79a6-4e8c-a1d0-60b392b93d34’

コマンドライン引数渡しも効果なかった.結局同じだ.

!ひどいバグがあった.CARDLINK::CheckCardLinkのダンプ文に一つ余分な引数が入っていた.⇒解決

SetSingleSelection中にTREEVIEW::CheckSelectListのエラーが出る.selectcardlistのカウント1と現物カウント0で不一致が生じている.⇒SetSingleSelectionは単選択を強制する関数なのだから,選択1でなくてはならないが,Currefnumがゼロとなっているため,選択されたカードが存在しない状態になっている.まず,これを一致させる必要がある.⇒対処した.⇒データベースのオープン関数ZView.Zelkova1.Openの戻り値をCurrefnumに格納する処理が落ちている.⇒修正した.⇒これで動作するようになった.

上記の「copynode->shadowが空で停止」も発生しないようになったが,なぜここでエラーが起きていたのかは別途調べておく必要がある.

GetNewCard→ MakeNewCardで引数のrefnumが0のときは,mCreateCardで新規カードを作っている.mCreateCard→ CreateCard→ FAMILYTREE::getNewCard→ UNDOSYSTEM::CommandStart→ UNDOBASE::CommandStart→ BackupPointData→ SetUndoList→ でエラーが発生している.この時点ではまだ新規カードは生成されていない.MAKENEWCARDではまず,partialmapを引数にSetUndoListが実行される.

アクセス解析ツールがようやく動き始めた

インストールしたアクセス解析ツールがようやく動き始めた.現在トータルユーザ36という表示が出ている.うちダイレクトアクセスは2人,それ以外はすべてOrganic Search,つまり検索エンジン経由ということになる.国別ではUSAから1人アクセスがあるようだ.テント村のサイドバーに出しているSTATISTICSでは今日の来訪者101,アクテイブ来訪者24となっているので,数字にはかなり開きがある.Site Kitの使い方はまだよくわからないので,調整が必要なのかもしれないが…

揚陸地点は決まった.ZELKOVA 再開発 2022-12-12,ここから始めるしかない.この版では人名テーブルと結婚テーブルのサイズはいずれも0x2000=8192となっている.

▲初期起動時,TREEVIEW::Refresh→…NAMEBOX::getGeneration中に(coordinate() == ABSOLUTE)で停止する.続行で新規ファイルになってしまう.この一行をコメントアウトすればファイルを開くことができる.DEBUG_NEVERというマクロはSTOPマクロを実行しているだけなので,動作に差の出る理由がよくわからない.

Refreshが呼び出されているということはすでに絶対座標系に切り替わっているはずなので,この位置でgetGenerationが呼び出されていることに問題があるように思われる.これは,「確定世代番号を導入する@20201121」という修正に関わるもので,Bobject::setabsoluteの中で,_generation = GetGeneration()が実行されている.ただし,GetGeneration関数の中で_generationを返しているので,この動作にはやや疑問がある.また,GetGenerationという関数があちこちで重複定義されている点も疑問だ.以下のクラスで再定義されている.

  1. GENEBOX
  2. PAIRBOX
  3. MARGBOX
  4. TRIBEBOX
  5. NAMEBOX
  6. TREEVIEW 相対座標系ではつねに0を返す
  7. TITLEBOX 相対座標系ではつねに0を返す

その理由はこの関数が仮想関数になっているためだろう.仮想関数にする必要があるのかどうか?というのがそもそも疑問だ._generation に値を代入しているのは,Bobject::setabsoluteだけで,この関数の中ではGetGenerationが呼び出されている.⇒MakeAbsoluteではSetAbsoluteを実行後にCOORDINATE = ABSOLUTEを実行しているので,これで問題ないのではないか?

getGenerationという関数は「常用世代番号」を返すことになっている.この関数をPrintParameterの中から呼び出しているところに問題があるのではないか?PrintParameterという関数は人名枠の中に付加情報として各種パラメータをプリントするための関数であり,絶対座標系以外では使われることはないのではないだろうか?

Collatz12146.ZELを開こうとすると,「登録リンク数が上限の8192を超えました」というエラーが二度発生したあと,「夫・妻リンクともに不在」が多量発生し,CARDLINK::CheckCardLink sc=3840 不正親番号の補正が実行された後,”Buffer too small”という例外が発生する.

image

今度は「データ不整合がありましたが…」を出したあと,描画できた.

image

ただし,以下のような複数の障害が発生している.

TREEVIEW::CheckSelectList

UNDOBASE::SetUndoList

UNDOBASE::UndoCopy

UNDONODE::Dispose

特にUNDOでポインタ空が発生しているというのは致命的だ.データ数は8192点まで削減されている.

image

まず,テーブルサイズを倍増(→16384)させて動作するかどうかを見てみよう.⇒リンカーでエラーになってしまった.

LINK : fatal error LNK1248: イメージ サイズ (823DC000) が最大許容サイズ (80000000) を超えています

「Win32 では1プロセスあたりのユーザーメモリ空間は 2GB」で0x80000000はその上限と思われる.これはWin32の制約なので,どうすることもできない.ちなみに現在の構成プロパティは,スタックサイズ2147483648,ヒープサイズ1073741824,ヒープコミットサイズ1048576に設定されている.現行では「テーブルサイズを2のべき乗にする@20220316」というオプションになっているので,8192点を超えることはできないということになってしまうのだが,「テーブルサイズを2のべき乗にする」というのはどういう効果があるのか?

いや,少なくともこの版では実効性はないようだ.ということは任意の値が取れるということなので,もう少し増やしてみよう.最終版では人名テーブル12300,結婚テーブル10300となっているが,この辺りがギリギリの範囲なのではないだろうか?

サイトにデータ解析ツールを組み込んでみた

サイトにデータ解析ツールを組み込んでみた.Google アナリティクスのアカウントを取得し,Site KitというプラグインをWordPressにインストールした.設定は簡単に終わったが,「データを収集中」という表示から抜けてこない.最初の表示が出るまでに最長48時間掛かるということになっているので,多分,問題なく動作しているのだとは思うが…

「サイトのユーザエクスペリエンスを測定」というカテゴリで,一つだけ確定している値がある.Largest Contentful Paintという項目で 4.4秒 「悪い」 という評価が出ている.読み込みに時間がかかり過ぎという意味だ.Total Blocking Time(ページの読み込み完了からクリック可能になるまでの待ち時間)は 60ミリ秒で「良い」という評価をもらった.過去に遡ることはできないはずなのだが,「過去7日間」に絞っても状態は変わらない.Googleの過去ログをすべて再解析しているのだろうか?もし,それができたらかなりおもしろいが…

バックアップドライブの整理は遅々として進まない.昨日仕掛けたファイル転送は夜通し掛かってもまだ,73%というところだ.コラッツ解析ツールに関してはある程度状況はつかめたので,ゼルコバの木の状況を確認しておこう.現在開発機にインストールされているバージョンはV2.2.2.008 R2022-04-26,このソースを押さえておく必要がある.デスクトップ上にはコラッツツールのプロジェクトフォルダはあるが,ゼルコバの木のフォルダはない.D:開発用ドライブにあるZELKOVAというフォルダが最終版と思われるが,この版は2.2.2.009 R2022-04-29でこちらの方が少し新しい.

ログ上では2022-05-03の「あきらめてここで打ち切るか,何か対策を考えるか?それが問題だ」というのが最終日付だ.やっていたのは,「CollatzTest 4000.ADLの極小反例サンプル抽出」という作業だが,このあと興味が「経済循環マトリックス」の方に移ってしまっているので,おそらく打ち切りになってしまったのだろう.何件か障害が発生している.Dドライブの最終バックアップは2022-05-06だ.問題は「メモリ不足」だが,解決できなかったようだ.「極小反例サンプル抽出」というのがどういうものであるかはわかったが,どういう障害が起きていたのかはまだつかめていない.

2022/05/01に①UNDOでShadowが空というエラーが起きている,②Collatz4000-12243.ZELでループカウントオーバーという2つの障害が記録されている.「極小反例サンプル抽出」の対象となっているのは②の問題だ.「極小反例サンプル抽出」というのは時間コストが掛かる処理なので,いくつかの機能を暫定的に停止しているところがある.5月3日付けのログは

「そもそも,バージョンが戻ってしまっている.というか,最終版がバックアップされていない.最終バックアップは2022-05-01-2で,これには2022/05/01のログの修正のすべては反映されていない.「BUNSFILEのバッファは常設とする@20220430」は入っているが,UNDOの修正は入っていないように思われる.ここからやり直すしかない.一度仮眠してデバッグを再開するときには,必ずバックアップを取るようにしないと失敗する…」

で終わっている.最終バックアップは5月6日という日付になっているので,この辺りはクリアされているのだろうか?いずれにせよ,ゼルコバの木に関してはここから進むしかないのではないだろうか?ZELKOVA 2022-05-03のバックアップはBAD, BAD2, BAD3, BAD4, NOGOODとなっていて,悪戦苦闘している状況が伺える.2022-05-06というのはおそらく,事後に形式的にバックアップしただけのものと思われるので,問題は解決していないと考えるしかないのではないか?

ここはもう腹を決めてここから再出発するしかないのではないだろうか?実際,現況は大海原で難破して漂流しているのに等しいと思った方がよい.⇒既定の開発用フォルダ ZELKOVA を ZELKOVA 2022-05-08にリネームしてここを再開発地点とすることにする.⇒どうも,この版はVS2017で開発されていた模様だ.すでにVS2019に移行済みだったはずだが,何らかの理由でVS2017に戻っているのではないだろうか?

image

確かに,VS2017なら問題なく開ける.とりあえず,バージョン番号を変えておこう.Version 2.2.2.000 Release 2022-12-21.⇒なぜだろう?バージョン番号など微細な修正を加えただけなのに,「アプリケーションはブレークモードになっています」で停止してしまった.

System.TypeInitializationException
   HResult=0x80131534
   Message=’ZelkovaTree.Program’ のタイプ初期化子が例外をスローしました。
   Source=<例外のソースを評価できません>
   スタック トレース:
<例外のスタック トレースを評価できません>

内部例外 1:
FileLoadException: ファイルまたはアセンブリ ‘ZelkovaGC3.dll’、またはその依存関係の 1 つが読み込めませんでした。このコマンドを処理するにはメモリ リソースが足りません。 (HRESULT からの例外:0x80070008)

クリーンビルドしたら動作するようになった.⇒53直系血族図.ZELというサンプルを開いて例外が出た.アクセス違反が発生している.

image

NAMEBOX::DrawFooterLineの中で(vpos == MAXMDB)で停止している.vposの値は10299,

MAXMDB=MAXMARGTABLESIZE-1 MAXMARGTABLESIZE=10300

まったく見たこともないエラーパネルまで出てきた.

image

エラーを無視して続行する.53直系血族図.ZELというファイルは点数1931でそれほど大きなサンプルではない.上記のエラーが影響しているのだろうか?先祖ノードとその直下のノードが孤立してしまう.

image

Collatz12146.ZELを開こうとしたら,うんともすんとも言わなくなってしまった.BUG3000-1906.ZEL(1906点)は開けたが配置が悪い.

image

この版よりは,現在インストール済の版の方がよほどましだ.

image

インストール版のソースを探して,そこから開始することにしよう.2022-04-27という版が一番まともな動作になっているようなので,ここまで戻ることにする.とは言え,ここでもいくつかのエラーは出ているが… いずれにせよ,これより後の版を追いかけても泥沼に入ることは避けられないので,できるだけ乾いた土地にスタートラインを置いた方がよいと思う.とりあえず,この版をデバッグしてある程度の安定版を構築することにしよう.この版では上記53直系血族図.ZEL,BUG3000-1906.ZEL,Collatz12146.ZELの3ファイルを開くことができる.

コラッツ木生成ツールの仕様は変遷している

コラッツ木生成ツールは仕様が変遷しているので,どの版をベースとして進めるかを決めておかなくてはならない.2022-03-10という版は「三本桜の復活」という方向に向かう途上と考えられるが,2022/04/05で方向転換して「銀河系の再構築」に切り替えている.この辺りから「コラッツ中核木」という言葉が使われ始めている.

実際,アプリのボタンにもCoreという語が用いられているのだが,この「中核木」というのは,完全木なのか?仮想木(長子木)なのか?⇒中核木=長子木でよい.やはり「長子木」と呼んだ方が直観的で間違いないような気がする.もう一つ分かりづらいのが「完全木」だ.「完全木は1を含む」という記述もあり,「中核木から1を除外した部分木は完全正則木の条件を満たす」という記述も見られる.整理しておこう.

  1. コラッツ一般木:すべての奇数を含むコラッツ木(偶数を除外)
  2. コラッツ仮想木:コラッツ数(長子ノード)のみを含むコラッツ木
  3. コラッツ完全木:3倍数を含まないコラッツ木→ユニバーサルアドレス

仮想木=中核木であり,仮想木から1を除いたものを長子木とする.(長子木は完全正則である)長子ノードとはコラッツ一般木上の兄弟ノードのうちの最右ノードであり,コラッツ仮想木はコラッツ一般木の縮約グラフである.長子ノード(1を含む)はコラッツ数と呼ばれる.ただし,「コラッツ数」を「完全木上のノード」としているところもある.これはSultanのコラッツ数の定義と一致する.2022/03/29「素数pとその倍数を除去したコラッツ完全木」には,以下のような記述がある.

前提:ある任意の素数Pより小さい素数はすべてコラッツ数である
帰結:素数Pより大きい素数で最小のものをP’とするとき,素数P’はコラッツ数である

これは数学的帰納法を証明に適用しようとする試みだが,望みはあるだろうか?※ともかく,コラッツツールの最終版を見て,どこまで進んでいたのかを確認しておこう.この版はV3.0.3となっているが,もう少し新しい版がある.CollatzCoreTree 2022-04-16 というのがとりあえず最新版のようだ.ただし,バージョン番号はV3.0.3で変わりない.

※すべての自然数からなるコラッツ全体木から2の倍数を縮約/除去したものをコラッツ一般木,3の倍数を縮約/除去したものをコラッツ完全木とすれば,コラッツ全体木から素数p以下のすべての素数の倍数を縮約/除去したグラフは連結な無限木を構成すると考えられる.このグラフのノードはすべてkより大きい素数のみからなる整数である.

動かしてみよう.⇒A面では正則木が出力される.デフォルト設定の ルート=1,枝数=4,樹高=5で,Max node count=1365を実行すると,カード数:373の3-正則木が出力された.どうもよくわからない.Max-branches=4で3-正則では数字が合わない.画面に表示されているMax node count=1365が何を意味しているのかもよくわからない.Core treeをオンにすると,342点の4-正則木が出力された.ただし,1の直下には5しかないので,厳密には正則木ではない.

Max node countには無効ノードカウント(void node count)が入っているため大きくなっているのだろう.有効ノードカウント(valid node count)と無効カウントを足すと,Max node countになっている.有効ノードカウントは出力データの有効カード数と一致している.Core tree(中核木)は長子木を指しているのだろう.この図版には3倍数が114点含まれている.(3倍数が長子ノードになる場合がある)

image

このグラフの樹高は実際には6になっているのに,設定が5というのもあまりうれしくない.それを除けば,大体のところは整合しているようだ.Core treeを指定しないときの出力が3-正則になっているというのはどういうことだろう.⇒core treeでないときでも,樹高は5になっているので,ルートは樹高に勘定されていないのだろう.つまり,ルートのみの木は樹高ゼロとみなしているものと思われる.core treeのオン・オフに関わりなくMax node count=1365になっているというのは,次数と樹高を指定したときの正則木のノード数を単純にカウントしてその範囲で計算を行っているものと思われるが,いまいち納得できない…

いずれにしても,この版では「完全木」という概念はまったく放棄されているように思われる.というか,「3倍数を除外する計算」を実装できなかったのではないだろうか?しかし,CollatzCompleteというプロジェクト名が使われていた時期もあるので,まったく試みたことがないというのではないはずだが… ⇒確かに,CollatzComplete 最終版 2022-04-03という版では,一般木,仮想木・完全木の3種が出力されるようになっている.ただし,この版では一般木と仮想木の出力が同じだ.つまり,仮想木出力は実際には実装されていなかったのではないか?⇒データを取り損なっていたかもしれない.仮想木の出力は一般木と同じではない.同じではないのはよいが,でき損なっているようだ.

image

このファイルを「隣接リストのインポート」で開くとエラーが出る.

image

一般木はまともに出力できている.

image

完全木の出力も問題ないようだ.

image

V3.0.0では仮想木の出力に失敗している.V3.0.3には完全木は実装されていないが,仮想木(中核木/長子木)の出力には成功している.この2つの版を組み合わせれば原理的には完全な「コラッツ三本桜」を実現できると考えられる.それをやるしかないのではないだろうか?よく読んでいないので本当のところはわからないが,Sultanは「完全木」の方から攻めているのではないだろうか?

我々の方法はベースに長子木があり,その上に一般木を展開していると考えられる.とは言っても,長子木を構築した上で一般木のノードを追加するという仕掛けにはなっていない.一般木を構築するための代数的基礎は一応確立しているが,長子木に関してはまだ不明のところが少し残っているのではなかったろうか?完全木の方が先に動作しているところから見ると,構成的には完全木の方が易しいのかもしれない.

だとすれば,Sultanがすでに問題を解いている可能性は十分ある.いずれにしても,まず当座の課題は「コラッツ三本桜」を実装することではないだろうか?それができていれば,Sultanの論文を読み進む上でもいろいろ役に立つのではないかと思う.もし,Sultanの論文の結論が正しいとすれば,少なくともそれを「追試」することにはなるだろう.

2022/03/21にヤマダ電機から HDD 5TB

モバイルWiFiで月額固定3~4千円というのは探せば見つかる可能性がある.これとpovo2.0(基本料金無料)を組み合わせると常時ネットに接続して4千円以下という環境が構築できる.これは結構現実的なソリューションになるかもしれない.ただし,このようなサービスを行っているところは結構怪しいところが多いので,迂闊に手をだすのも危ない…

クラウドWiFi/クラウドSIMというのがあった.AiR-WiFiなら100GBで2980円(税込み2980円)と格安だ.1ヶ月間のお試しというのがある.これは乗ってもよさそうな気がする.お試し期間中にpovo1.0から2.0に乗り換えればよい.電話番号を捨てるという選択肢もあり得るが,あちこちでスマホを2段階認証に使っているので,電話番号が無効になるというのは結構面倒な話かもしれない…

状況は大体掴めたのではないかと思うが,どちらの方向に踏み出せばよいのか?コラッツ木作成ツールV.3.1を仕上げるという方向がまず考えられるが,ある意味で方向転換が必要なのではないか?という気もしている.コラッツ木作成ツールV.3.1というのは,結局,「完全正則木をベースとしてユニバーサルアドレスコードを確立する」というのが主たる目標になっているように思われるが,コラッツ木ツールの用途としては,もっと一般的なコラッツ木データが出力できるようになっていることが必要だ.つまり,Sultanの方法と比較するような場合には完全木の範囲では十分なデータが取れない.

できるだけ仕様をコンパクトなものにしたいというところから,機能を大幅に絞り込むということをやってきたが,むしろ「三本桜」と言っていた頃の構想の方がむしろ適切だった可能性もある.「三本桜」というのは,①一般コラッツ木,②仮想コラッツ木(長子木),③完全コラッツ木の三種を包含するものだ.これらの中で一番重要なのは「長子木」ではないかと思われるが,完全木には3倍数が含まれないため長子木の一部ノードが欠けたものになってしまう.「コラッツ銀河鉄道系」というのは仮想コラッツ木のことを指しているので,CollatzCoreTree 2022-02-22-1の一つ前のバージョンがその最終版なのではないかと思う.いや,2022/04/05『「三本桜の復活」→「銀河系の再構築」』には,『「三本桜の復活」を止めて,「銀河系の再構築」に方向転換した』とある.どうも,またわからなくなってきた.

まず,ともかく,現在のバックアップの状況を確認しておくことにしよう.2022/03/21に「ようやくUSB HDD 5TBを入手した」とあるが,そんなことも忘れてしまっている.現在開発機にはA:~J:までの8ドライブがインストールされている.うち内蔵ドライブは,C:とD:の2つでそれ以外は外付けHDだ.H:は57.6GBのUSBメモリで,それ以外の5つが5TB HDDのパーティションということになる.G:には「開発履歴」という名前が付いているので,これを見てみよう.確かにここがバックアップの保管場所になっているようだ.以下のフォルダがある.

  1. ZELKOVA 2022
  2. コラッツプロジェクト
  3. コラッツマニュアル

ZELKOVAはゼルコバの木プロジェクトで,最終版は2022-05-01辺り.それより後の版にはBADなどのサフィックスが付いているので,2022/05/03辺りで挫折している模様だ.コラッツプロジェクトの方は

  1. コラッツ生成ツール 2022-01-27~2022-02-12
  2. コラッツ銀河高速系 2022-02-09~2022-02-20
  3. コラッツ長子木検定 2022-02-22
  4. コラッツ完全木検定 2022-02-23~2022-02-25, 2022-04-03 他
  5. Collatz Tree Projcect 2022-04-06~2022-04-14
  6. 公式リリース版 Collatz Tree Generator V1.0.2~1.1.1
  7. 資材 CSV,PDF,ZEL,画像

のようになっている(日付順に並び替え).2月頃のログは精読していないので,少し拾い読みしてみよう.というか,公開版の内容をまず確認しておこう.コラッツツールのバージョンは2022/01/29リリースのV1.1.5.これはテント村のトップページの表示と一致している.同梱されているマニュアルのリリースも同日でED:1.02になっている.マニュアルは多分これが最新版ではないかと思う.2022/02/28のログのタイトルは「小学校入学記念写真は三本桜の下で撮影する」となっていて,

偶数を含めたすべての整数にコラッツ木上のユニークなアドレスを与えるユニバーサルアドレスコードという着想はコラッツ問題の最終解決に資すると考えられたので,すべてのリソースをここに集中させるという選択を行い,それ以外の部分はいわばノイズとして廃棄するという大胆な改造を行ったが,一般コラッツ木,仮想コラッツ木(長子木),完全コラッツ木という3種のコラッツ木にはそれぞれの存在意義があり,いずれも欠くことはできないという考え方に戻ってきた.この3種のコラッツ木をコラッツ三本桜と呼んでおこう.

としている.「思い切って余分なコードを完全にソースコードから削除してしまっているので,もう一度一から作り直すことになる.」とあるが,どうなっているのだろう.「ビーナスの腰布」は2022/03/03だ.この日付は上のリストでは「コラッツ完全木検定」に含まれる.

しかし,フォルダの中には3月期のバックアップはまったく残っていない.2月25日から一挙に4月3日にジャンプしている.リリース版のV1.1.5のソースコードも見当たらない.Eドライブ(開発用)には2022-03-10~15のプロジェクトが残っている.このフォルダの中に,2022-02-26~03-09の分が残っていた.Fドライブ(未整理)にも2022-03-10~15のバックアップがある.とりあえず,この辺りを全部整理しておいた方がよいのではないか?⇒下記手順を実行しておこう.

  1. E:バックアップ→F:未整理に移動して,バックアップを一旦空にする
  2. F:未整理のフォルダを整理して開発履歴のコラッツプロジェクトに移動
  3. G:開発履歴をE:バックアップにバックアップする
  4. G:開発履歴/コラッツプロジェクトの内容を日付で整理する

かなり大仕事になってしまうが,やっておいた方がよい.5TBのHDDに無秩序にダンプしていたら,ゴミの山になってしまう.⇒ファイルの移動には相当時間が掛かりそうなので,三本桜の続きを読むことにしよう.3月3日頃のコラッツツールの動作を確認しておいた方がよいのではないか?3月3日というバージョンはまだ出てこないが,3月10日というのがあるので動かしてみよう.⇒A面にはFull regularというオプションがある.完全木という意味だと思われるが… 隣接リストは出力できるようになっているが,ADL形式にはなっていない.

開発機にインストールされているゼルコバの木は「コラッツ特注版」で,V2.2.2.008 REL 2022-04-26となっている.これが最終版ということなのだろう.テストカウントとメール送信ボタンが重なってしまっているが,数値ボックスが上になっているので操作はできる.

image

デフォルト設定で,コラッツ木を出力してみる.CSVファイルを読み込むとエラーが出て異常終了してしまった.

image

拡張子をADLに付け替えたら,難なく読み込むことができた.

image

設定はルートノード1,次数3, 木高4で,カードは46点.Full regularはオフの設定だが,完全3-正則グラフになっている.(完全と言っても有限木なので終端ノードの出次数は0だ)Full regularにすると何が変わるのだろう?⇒ADLファイルはダブルクリックで開けるようになっていたはずだが,エラーになる.「隣接リストのインポート」でも同じ.

image

ダブルクリックしたときには,このパネルは出ないが,「入力文字列の形式が正しくありません」というメッセージは同じだ.ダブルクリックの場合はエラーパネルが立て続けに出て止まらなくなるが,この場合は「続行」ボタンで初期画面に戻った.⇒出力ファイルがADLになっていない.通常のCSVファイルとしてインポートすることで問題なく読み込めた.⇒おそらく,Full regularという機能は未サポートなのではないだろうか?CSVファイルとして開くとFull regularオフのADLファイルとまったく同一の内容が表示された.

このCSVファイルは通常のゼルコバの木のエクスポート形式なので,ADLでインポートしようとすると中身が空になってしまうため「入力文字列の形式が正しくありません」になってしまうのだろう.このメッセージは「このファイルは無効です」とか,「このファイルの内容は空です」のようなものでなくてはならないところだが,とりあえず,想定外エラーということのようだ.Full regularオフで出力したCSVファイルの拡張子をADLに変更したものはダブルクリックで問題なく開けた.つまり,ADLファイル(隣接リストファイル)のIOは動作している.



ログを読み直して作業の中断地点を確認

povo1.0でテザリングするのはやはり,かなりきつい.フレッツ光を使うという手があるかもしれない.フレッツ光なら月額3~4千円で間に合う可能性がある.スマホをpovo2.0に切り替えれば基本料金はゼロになるから,ほぼフレッツの料金だけということになるので,なんとか予算額以内に収まる可能性がある.現在はほとんど外に出ていないし,出るときでもスマホを置いて出かけているので,とりあえずのところそれほど支障もないような気がする.以前はウォーキング中にYouTubeを聞き流ししていたのだが,最近はそのような使い方をほとんどしていない.

とは言え,そのような使い方を今後一切しないという訳でもないので,その場合はそのつどトッピングを購入しなくてはならなくなる.それもかなりきびしいような気がする.USBテザリングを使うともう少し動作はましになるような感じだが,そうすると今度は他のマシンとのインタフェースに支障が生じる.USBテザリングとWiFiによるアクセスポイントの併用はもしかするとできる可能性はある.まぁ,ともかく,もう少し,様子を見ることにしよう.

現在ノート(Dospara)とタブレット2機の計3台を使っているが,そのどれもが終末ホスピスに入っている.いずれも電源投入時の立ち上がりに覚束ないところがあり,いつご臨終となるのかはらはらしている状況だ.2 in 1のミニノート(BlackHawk)はキーボードを外してタブレットとして使っているが,しばしば画面(内蔵モニタ)が崩れて流れてしまう.外付けモニターには出力できるのでハード的にはまだ活きているようだが… 薄型ノート(VAIO2)はバッテリが膨張して背中の辺りが大きく膨らんでいる.使っていないノートなどはまだ他にもあるが,CPUパワーが足りないので予備機としては心もとない.

さて,そろそろ仕事に入ることにしよう.どこから始めたらよいか?現状の問題を洗い出して個別対処というのでもよいが,まず,ログを読み直してどこから作業中断になっているのかを確認しておいた方がよい.現在外部公開しているCollatz Tree Generatorのバージョンを確認しておこう.テント村トップの固定ページではV1.1.5となっている.まず,これを基準点と考えなくてはならない.この版には「Build Collatz Tree」と「Get branch position」という2つのタブがある.最初のタブは①ルートノード番号,②枝数,③木高を指定して正則コラッツ木を出力するようになっている.2番目のタブには,①Verify, ②Get the sequence,③Get the number,④Truncated treeのボタン4つ.

この使い方を飲み込むまでは結構大変そうだ.製作者のわたし自身ほとんど使いこなせない.一応 VAIO2上では動作していることは確認できた.「Collatz Tree Generator」自身が壊れていると考えた大きな理由は,開発機でこの版を動かしたとき,画面が崩れてしまうという問題が出ていたからだ.画面のレイアウトが崩れてTest countの入力ボックスをメール送信ボタンが覆うような配置になっている.この問題は以前から確認されていたはずだが,開発機ではテストを行わないという手順になっていたので忘却していたのだろう.この問題の解決はかなり難しいような気がする.機種ごとにレイアウトを微調整するようなことまではできないと考えられるからだ.おそらく対処するとしても,何か「逃げ」を打つようなことしかできないのではないかと思う.ともかく,障害としてリストアップしておこう.

▲開発機でCollatz Tree Generatorを起動して,2番目のタブでTest Countの入力ボックスの上にメール送信ボタンが被ってしまう

Collatz Tree Generatorのリリース版のバージョンはV1.1.5だが,最新版はV3.0.3になっている.ということはこの中間にV2.0というのがなくてはならないはずだが,どこに置いてあるのだろう?バックアップはすべてどこかにあるはずだが,整理しておく必要がある.⇒すっかり忘れていたが,2022/05/06「二兎を追う者は一兎をも得ず」にこんなことが書いてあった.

ここに来てにわかにもうひとつのミレニアム懸賞金問題が急浮上してきた.例の「数学・物理etc 談話室」で「ケーニヒスベルクの橋の問題」が話題となり,そこでまた大きな進展があったためだ.もう少し詰めないとものになるかどうかは分からないが,感触としては十分な手応えがある.「二兎を追う者は一兎をも得ず」と言われるが,「一石二鳥」ということわざもある.

なんのことを言っているのかさっぱり分からないが,リンクに飛ぶと

(6’)任意の連結な無向グラフ上の奇次数頂点の集合をOとすると,|O|は偶数であるから,Oを2つのパートO1, O2に分けて,(o1, o2)のような奇次数頂点の「ペア」を組んだとき,このようなすべてのノード対(o1, o2)に付き,o1とo2を結ぶ他の奇次数頂点を含まない初等的経路が存在する.つまり,互いに素であるような(共通点を含まない)奇次数頂点ペアを結ぶ経路のセットが存在する

のような命題を提示した上で,「(6’)が成立するとかなりおもしろいと思われるのですが,今のところ確信はありません.「3正則グラフのハミルトン閉路問題はNP完全である」とどこかで聞いたような記憶があるのですが,もしそれが本当なら,(6’)の成立はNP=Pを証明したことになるかもしれません.」としている.多分,このことを言っているのだろう.いまは,そこまで突っ込む余裕はないが,ヒマができたらもう一度調べてみる価値はあるだろう.

コラッツ木生成ツールの出力ファイルにADLという拡張子を持ったものがある.この拡張子が何を意味しているのかさえ忘れてしまった.「極小反例サンプル抽出」というのを行おうとしているようなのだが,「極小サンプル」とは何かすらも覚えていない.この時期にはゼルコバの木のデバッグも並行して実行している.「スタックオーバーフロー」などの障害も発生しているが,解決しているのだろうか?コラッツ木生成ツールが生成したCSVファイルをインポートしたとき,一部ノードが消失してしまうような現象が出ていたが,この辺りの問題なのではないだろうか?開発環境としてはVS2019を使っているが,VS2017の修復インストールなどのこともやっている.

2022/05/03のタイトルは「あきらめてここで打ち切るか,何か対策を考えるか?それが問題だ」となっている.どうも,ここで「あきらめて打ち切り」の状態で終わっていたのではないだろうか?ここでは,12243点というゼルコバの木のスケールを超えたサンプルを扱っているのだが… 障害の原因はメモリ不足にあるように思われるのだが… Windows 10とWindows 7という開発環境の違いも影響しているようだ.「極小反例サンプルの抽出」ではUNDO機能を使って何かやっているようだが,それもよくわからない.2022/04/28「LNK1248: イメージ サイズが最大許容サイズ (80000000) を超えています」には,

先祖ノード(とその配偶者)だけは例外的に結婚枠の中に入っていないが,これはいま考えると敗因だったような気もする.⇒おそらく,この「コラッツ特注版」の挑戦が完結した時点でここに戻ることになると思う.「コラッツ特注版」は「単純な木」であり,「結婚木」も「単純な木」と考えられるから,「系統並び替え」を「もっとも単純なトポロジーソート」として再編成できるはずだ.

ともある.「ここに戻る」というときの「ここ」が何を指しているのかもよくわからないが,「先祖ノードを結婚枠内に収容すること」を意味しているのだろうか?コラッツ木生成ツールのタブにはA面,B面という名前が付いている.B面は3機能(コラッツ数列,アドレス変換,幹線木)+検証テストという構成だ.「極小反例サンプル抽出の自動化」という技法が何を意味しているのかまだよくわからないが,2022/04/26「極小反例を探す長いジャーニーが終わった」では,「応用が効く」としているので,なんらかのデバッグ技法になっているのだろう.

UNDOに関してもかなりの修正が入っている.2022/04/16は「Windows 11をダウングレードしてWindows 10に戻す」となっている.開発機にはWindows 11をインストールできたようだが,動作不良が起きたため元に戻している.Windows 11への移行はどこかの時点で実行しなくてはならないかもしれない…

2022/04/16の記事に「極小反例サンプル抽出の自動化」の目的と方法が書いてある.ループカウントオーバーなどの障害が発生したとき,その障害を再現できる最小構成のサンプルを抽出するという課題だ.実装がどうなっているのかはわからないが,多分コンパイルオプションとして作り込んでいるのではないかと思う.⇒VBの「包括自動テスト」に組み込んで,メニューから起動するようになっている.⇒「検索文字列.TXTが見つかりませんでした」というエラーに関しての記事がある.

ADLという拡張子は「隣接リスト専用」として設置されたもので,タブ区切りのCSVファイルだが,中身は隣接リストという特殊フォーマットだ.ADLはActivities of Daily Livingで「日常生活動作」という意味だという.まぁ,もちろん,元の意味は adjacency listということだったのだろう.ADLファイルはZELファイルと同様にダブルクリックで開けるようになっている.これは系図データではない「一般のグラフ」をゼルコバの木で扱えるということを意味している.

2022/04/11から「コラッツ木生成ツールから直接ゼルコバの木を起動する」ことができるようになっている.2022/04/06には「『拡張コラッツ問題』は一般には成立しない」という記述がある.これはコラッツ予想問題に直接関連する考察だ.今回の課題になっている「Kurmer Sultanの独創的解法」に関係があるかもしれない.

前稿(2022/04/06)には,2つの式が記載されている.

ノード番号:={長子ノード番号}.{兄弟順位}      (1)
長子ノード番号:={親ノード番号}.{長子識別子}    (2)

これら2式が正しければ,

ノードN:={地番1}.{地番2}.{地番3}…{地番k}

のようなアドレスコードが可能となり,すべての自然数はその内部にコラッツ木の(暗号化された)アドレスコードを持っているということになると予測される.

としている.これから,

拡張コラッツ問題:kを任意の奇数(定数)であるとする.任意の自然数Nについて,Nが偶数ならば2で割り,奇数であればk倍して1を加える操作を反復すると,かならず1に帰着する

という設問が提示される.ただし,①k=1の場合は自明,②k=3はコラッツ問題に相当,③k=5では成立しないところから,

そもそもk>3の場合に,「長子木」のようなものが構成可能であるかどうかは,まったく自明ではない.というか,おそらく,k>3の場合には「長子木」のようなものは存在していないのではないだろうか?逆に言えば,長子木のようなものが構成可能であるのは,k=3の場合に限定されるのではないだろうか?いずれにしても,「長子木とは何か?」ということが追求されなくてはならないだろう.

としている.コラッツ問題に関する考察に関してはおそらくここが我々の最終到達地点である.コラッツ生成木ツールの仕様は変遷しているが,完全木と仮想木のどちらが優位か?という問題で紛糾している.目標は,自然数Nをデコードして一般コラッツ木のアドレスコードに自動変換することである.2022/04/05では『「三本桜の復活」→「銀河系の再構築」』としているが,これは何だろう?⇒コラッツ木から3倍数を除去したものを完全木と呼んでいる.3倍数は終端ノードになるため,完全正則木を構成することができない.このため,アドレスコードが変則的なものにならざるを得ないので,これを除去した木を考えて完全木としているのだろう.

しかし,3倍数を除去することによって生じるコラッツ木上の空位とアドレスコードの対応は必ずしも自明ではない.仮想木の場合は仮想木上の位置とノード番号の関係は明確に定義されているのでむしろ対処し易いのではないか?と考えられたので急遽方向転換し,汎用アドレスコードを仮想木上で再定義することにした.

としている.Sultanはこの逆に3倍数を基準にすべてのノードをコラッツ木に配置するという戦略を取っており,我々と真逆の方法論になっているように思われる.この記事では「コラッツ木上で共通の親を持つノードを兄弟ノードとし,兄弟ノードのうち最右に位置するノードを長子ノードとする 長子ノードはコラッツ数と呼ばれることもある」としているが,Sultanは確か,非3倍数であるような(すべての)奇数をコラッツ数と呼んでいたような気がする.※

仮想コラッツ木はグラフの連結性を維持しながら,兄弟ノードを長子ノードに合併・縮約することによって得られる一般コラッツ木の簡約グラフである 仮想木上の(1を除く)すべてのノードは長子ノードである

これで見ると,「仮想木」というのは,「長子木」に他ならないように思われる(仮想木から1を除去したものという別定義もある).これに対し,「拡張コラッツ木」にはすべての自然数が含まれるようだ.「仮想木検定」というのがCollatz Tree Generator V2.0に与えられた名前であるように思われる.「コラッツ銀河高速道路系プロジェクト」というのがそれに該当する.この最終版はCollatzCoreTree 2022-02-22-1の一つ前のバージョンと思われる.CollatzCoreTreeというプロジェクトからバージョンをV3.0.1に切り上げている.「仮想木で汎用アドレスコードをサポートする」というのが,このプロジェクトの目標だ.「完全正則木」を考えているのは,「証明」に備えるためと考えられる.(長子木は完全正則木である)

※「コラッツ数」は2022/03/29には以下のように定義されていた.

『コラッツ木からすべての3倍数を除去したグラフをコラッツ完全木,コラッツ完全木上のノードをコラッツ数とする』

これはSultanの定義と完全に一致する.ようやく「コラッツ国の公用語は4進数である」というところまで来た.ノード番号を16進ではなく4進表記すると,

兄弟ノード番号=長子ノード番号+1の並び

のようになる.このとき,子ノード番号をNとして,3N+1を2進数表記してやると,

子ノードNの3N+1バイナリ表現=親ノードのバイナリ表現+0の並び

となるが,これを3進数表記したらどうなるか?というところに興味がある.その準備として「横書き」機能拡張が導入された.Core Treeというのは「コラッツ中核木」=3倍数を含まないコラッツ木である.

2022/03/25「非公開投稿」では,ロギング用のノートの配置をいろいろ試している.結局,「ロギング用のノートは左配置しかない」ということになったのだが,今回も多少の改善を試みて,下図のような配置に落ち着いた.最左のタブレットとモニターの中間にあるのがロギング用のタブレットだ.モニターにはタブレットの画面が表示されている.これまでで一番安定した配置になったような気がする.

IMG_20221218_220337

いや,これは基本的に2022/03/17の配置とまったく同じだ.