ZTシステム構成図の作図方式を決定する

もう少しZTシステム構成図の入力を続けることにしよう.クラスとオブジェクトを婚姻させるという仕様に方式転換したので,修正が必要な箇所が残っている.これを点検するために,まず婚姻数をチェックしてあぶれが出ていないことを確認する.実装を持たない(抽象)クラス以外ではすべてのクラス(女性)は少なくとも結婚を1持たなくてはならない.実装を持たないクラスでは配偶者を持たない結婚枠を作り,その中に(必要なら)抽象メンバー(女性)を表示することにする.

いや,そういうことはできないと思う.クラスの単身婚の子どもはそのクラスの基本クラスでなくてはならない.従って,もしクラスの抽象メンバーを女性ノードとして表示するとすれば同じ箱の中に入れるしかない.これはやり過ぎだと思う.オブジェクト(男性)はすべていずれかのクラスに属するはずだから,本来なら必ずクラス配偶者を持つことになるが,図面が混み合ってしまう可能性があるので,別に実装がある場合にはとりあえず単身のまま残すことにする.

CARDLINKオブジェクトの場合,実装はCARDTABLE *PDBに格納されることになる.実際,CARDLINKがこれ以外の場所で生成されることはない.このカードリンクにPDBをポインタとしてアクセスするときの構文は

CARDLINK *CARD = (CARDLINK*)(*PDB)[k];

のようになっている.これはNODULEの基本機能に備わっているoperator[]によってアクセスしているものでnodule *&operator [](int x); のように定義されている.取り出される配列要素の型はnodule*なので使う側ではいちいちキャストする必要があるが,仮想的にはCARDTABLE PDBをCARDLINK*の配列とみなしてよい.

▲BASETABLE<CARDLINK, MAXPDB>の本人タブの氏名をダブルクリックして「検定続行不能エラー」が発生した.

image

処理は続行できるのでUNDOして反例サンプルを取ってみよう.いや,ダブルクリック自体はイベントとして保存されていないので現状のまま保存でよい.(ERR7)としておく.保存したあとの動作が悪い.CARDLINK::ScootParentPageで (PHASE <= INITIALSTATE) が発生して抜けられなくなってしまった.PHASE = INITIALSTATEになっている.⇒なんとか抜けてきた.多分このエラーは再現できるだろう.

▲TREEVIEW::GetViewSizeで(!_size->cx || !_size->cy) 描画領域空エラーで停止した.かなり不調だ.系図画面をクリックしても反応しない.ZTシステム構成図2.ZELを開いただけでまだ特に何もしていないと思われるのだが…ファイルを閉じるときにもTRIBEBOX:setTribeRealnodeで停止する.おかしい.どこか書き換えてしまったのだろうか?作業を中断して食事を終えて席に戻ったところなのだが…

▲ZTシステム構成図(ERR7).ZELを開こうとしてTRIBELIST::GoDownStreamで(marg && !marg->Invalid() && (!marg->margbox || !marg->margbox->ISSETTLED()))により停止,その後続行して以下を出してエラー終了.

image

「修復されました」を出した後もエラーが続き,新規カードを開いた.つまり,(ERR7).ZELは開けない.構成図2.zelは開ける.

どうも作図がかなり難しい.構成規則をもう少し厳密に定義する必要がある.

  1. +を婚姻関係,→を親子関係,【】を結婚枠とする
  2. 【クラス】→【下位クラス(基本クラス),クラス要素…】
    クラス要素とはクラス内で定義されたメンバー変数であり型名(クラス名)ではないが,女性形で表示する
  3. 【オブジェクト+オブジェクトのクラス】→【下位オブジェクト…】
  4. ただし,下位オブジェクトが描画されない場合は結婚関係を省略して【オブジェクト】を終端ノードする
  5. 下位オブジェクトがメンバーとして属するクラスがオブジェクトのクラスより下位にある場合:
    【下位オブジェクト】→【下位クラス要素】
  6. クラスにはクラス名は付けないが,クラス要素には所属:クラス名を付ける
  7. オブジェクトには所属:クラス名を付ける
  8. テンプレートクラスには肩書:テンプレート引数を付ける
  9. 要素構成木のルートcouplingはオブジェクトである
  10. オブジェクトとクラスの婚姻による子どもはオブジェクトである
  11. クラス継承木のルートはNODULEクラスである
  12. クラスないしクラス要素の親はクラスである
  13. クラスの子どもは基本クラス(長女)かないしクラス要素(次女以下)である
  14. 配列要素は配列の子どもである 配列要素と配列要素の型(クラス)の結婚によってその型の内部構成を展開できる

これで矛盾なく描画できるのではないだろうか?

▲配偶者のいない2つの結婚ページにそれぞれ子どもが1人づつ記入されているとき,登録では1ページに合併するはずだが,そのような動作になっていない.BASETABLEにARRAY<bnum>とlookupをそれぞれ登録されているが2ページのままだ.

オブジェクトPDBはオブジェクトanod[]とlookupを構成要素として持っている.これとCARDLINKをどのように結びつければよいか?BASETABLEはテンプレートクラスで引数として<CARDLINK, bnum>を渡されている.これとCARDLINKを結婚させた子どもをCARDLINKのインスタンスとすればよいのではないか?あるいは,anodとCARDLINKを結婚させてCARDLINKのインスタンスとするか?

【配列】+【クラス】→【クラス型の配列要素】

でもよいのではないか?⇒便宜的にそうしておくことにしよう.いずれにしても,CARDLINK型のオブジェクトはCARDLINKと結婚しなくてはならないのだから,配列の下位オブジェクトとして配列要素を産出し,それとCARDLINKを結婚させるというのが順当だろう.

▲おかしい.子ども並び替えパネルが出てこない.⇒別モニターに出ていた.

おそらく一番厄介なPDBとMDBのところが一応終わった.まず,クラス部分図を出してみよう.

image

孤立ノードが6つある.うち2つはBASETABLEのテンプレートのインスタンスで不用になっているので削除できるが,それら以外が孤立してしまった理由が分からない.かなり荒っぽい修正をやっているので多少の補修が生じるのはやむを得ない…残り4つはいずれもクラス木的には終端ノードなので接続は容易だが,特にCARDLINKが孤立しているのが解せない.TREEVIEWのところは接続が間違っているので後から直すことにする.TRIBEBOXも配偶者がBobjectというのは間違いだ.クラス同士の婚姻はここでは定義されていない.Bobjectと言っても男性形だ.

▲部分図から親族図に切り替えようとしてPAIRBOX::CalcPairBoxでASSERT_NEVER (nocommon) エラーになった.⇒再現できる.この状態で保存しておこう.(ERR8)とする.このファイルを開いた場合にも同じエラーが出る.

BASETABLEにならって,NLISTのテンプレートも整理しておこう.NLISTは2つの引数を持ったテンプレートクラスだが,たとえば,NLIST<SIMPLEEDGE, ‘E’> のようなクラスは独立には存在しない.

▲NLISTの母をEDGELISTに付け替えて,CARDLINK::ScootParentPageで停止した. (!OnImportEnd && !APPENDFILE && !PrimaryMergeCard && !OnDeleteCard) 同一親ページの重複を検出.

クラス木は一応図式的には整った.

image

一応すべてのノードの接続関係をチェックしておこう.クラスノードは全部で43個ある.クラスノードは基本クラスとは単身婚で接続するという規則になっている.これに反しているのは結構ありそうだ.ただし,付け替えてもクラス木のトポロジーには変化はない.⇒失敗した.途中で並び替えしてしまったのでどこまでチェックしたか分からなくなってしまった.あと少しだったのに…

▲先祖並び替えで先祖ノードを複数選択して移動できると便利なのだが…ないし,ドラッグ移動して並び替えが実行できるとさらによい.

Bobjectの主要派生クラスであるNAMEBOXが落ちている.これなら木に見えるだろう.

image

さて,要素木の方はどうなっているだろう?現状はこんな風になっている.

image

孤立カードが7点出ている.完全に孤立しているカード5点はおそらくゴミと思われる.

▲カードが削除されたとき,別のカードにジャンプする動作はあまりうれしくない.むしろ単純にその場所で再描画してもらった方がよいのだが…⇒カードが操作されたときにはトポロジーが変化するのでどうしても系統並び替えを実施する必要がある.また,再描画のときの基準点を選択されたカードに置いているため,カード操作のたびに選択カードの位置に戻ってしまう.この動作でよい場合もあるとしても,予期していない動作になる場合が多い.むしろ,基準点(不動点)をたとえば現在の画面中心位置などに置くことが考えられる.かなり大きな方式変更になる可能性があるが,編集ストレス軽減のためには必要な修正だ.

仕掛りの部分に関しては接続関係はおおむねできているようだ.いや,まだおかしな点がある.PDBが3つも親を持っている.PDBの本籍はTOPOLOGYのはずだが,linktableとnamesort+NAMESORTの子どもになっている.確かにどちらからも参照されている.参照の場合はクラス配偶者を持たないとしておこう.

▲pagesetup→treeviewとcoupling→treeviewの2つのtreeviewを合併するとtreeviewがcouplingからpagesetupに移動してしまう.couplingは基準ノードなのに消去されてしまうというのは望ましくない.この図面は一系列なので系列優先ノードには関わりはないが,基準ノードの子ども枠内のノードは保護されるべきだろう.いや,treeviewはtribelistの子ども枠の中にいる.⇒treeviewの血統軸線図にすればcouplingの直下に配置される.とりあえず現状ではそれ以上の対応策はない.

まだBobjectの実装が入っていない.また,TREEVIEWの内部コンポーネントのリンクも途切れている.TREEVIW自身がBobjectなのでtreeviewの位置で実装したはずなのだが…TREEVIEWのBobjctの部分が配偶者なしになっていた.

▲所属グループの親ページからtreeview+TREEVIEWを除去して,PAIRBOX::repairCommonEndPointでDEBUG_NEVER (CheckSamePoint())が起きる.

ゼルコバの木システム構成図の仕様変更

相当数のバグが検出されているが,一番悪質なのは部分図の登録/削除画面での操作だ.かなり惨めな状態になっている.一覧表には選択されたカードだけを表示するというオプションは存在しないが,部分図を使えばそれができる.カードを(属性に従って)個別にカラー表示したり,隠蔽したりすることも部分図の拡張機能として考えられる.(個別に隠蔽することは現在も可能だ)部分図はもっともっと活用されなくてはならないので,部分図のロジックはもっと鍛える必要がある.

システム構成図の下半分はほぼ仕上がったとみてよい.きれいな(と言えるかどうかは別として)倒立した木になっている.上半分の部分図を正立した木として表示することができれば,一応システム構成図としては完成したことになる.どういう図柄になるのか?楽しみだ.

▲GENEBOXの父にbaselistを登録しようとしてMakePairListClean中PAIRBOX::getLocationで停止した.その後の操作でも同様エラーが生じる.GENEBOXとbaselistの間には下記のような関係がある.

image

つまり,母であるGENELISTはGENEBOXの異母兄弟となっている.多分上のエラーはこのような状況を反映したものではないかと推定されるが,図面からこの関係を読み取ることは難しい.このエラーは描画のたびに発生すると考えられるので一時的に停止しておくことにする.⇒今日はバックアップを取らずに始めてしまった.仕方ない.いまからでも取っておこう.サンプルは構成図7とした.

▲構成図7を開き,上図の部分図を再現しようとしてSIMPLEGRAPH:TightenHasseDiagramで「孤立ノードが存在する」エラーが発生した.このサンプルは障害サンプルフォルダにコピーしておく.

▲部分図から親族図に戻ったとき,選択されたカードが画面内に入っていない.⇒全体図→部分図→親族図のように遷移したものと思われる.全体図では選択カードは見えている.

おかしい.BASETABLE<CARDLINK, MAXPDB>はクラス(女性)だが,父がCARDTABLEになっている.CARDTABLEは女性のはずだ.⇒確かにそうなっている.いくらレインボーカラーと言ってもこれは流石にまずいのではないか?しかし,同性婚→養子縁組なら起こり得る事象だ.本来ゼルコバの木では異性婚しか認めていなかったが,現在は緩和して同性関係を許容するようになってはいるが,父母の性別はチェックしていなかったのだろうか?anodも父BASETABLEを持っている.

▲カード履歴の動作がおかしい.一度も訪問していないcouplingが中間に入ってしまう.選択状態は全体図・親族図・部分図共通であったはずだが…⇒図面種別を切り替えたとき強制的に基準ノードが選択されているのではないか?⇒図面種別の切り替えでは再描画のため系統並び替えが必ず実行される.カード履歴では系統並び替えの基準ノードを履歴として記録している.(系統並び替え履歴はカード移動履歴に含まれる)

▲UNDOで戻ったときにも「孤立ノードが存在する」が発生した.ここからREDOでも同じエラーになるので状況が再現できているということだけは言える.つまり,UNDO/REDOは概ね動作している.

▲UNDO/REDOでは図面種別の切り替えまでは再現されるが,人名カードの表示は変わらない.⇒仕様的にはやむを得ないとは思われるが…UNDO/REDOはDLLに送ったコマンドが保存されているだけで,カードの切り替えなどには関知しない…これは仕様である.

▲女性カードが父となっているのは子どもカード生成ないしリンク時の動作が誤っていた可能性が高い.クラスノードを親とするほとんどのノードにこの誤りが起きている.

▲部分図でtoplistの父がDATALISTだったのを母に移動して登録したら,新しい女性カードのDATALISTが生成された.これはまずいのではないか?⇒多分DATALISTはtoplistの子どもだったのだろう.このようなケースでは自動的に新規カードを生成する.これが意図しない動作だった場合にはカード合併で修正すればよい.このようなことが起こるのは実際にはレアケースだと思う.

◎現行では系図画面では右クリックしてもメニューは出ない.これは系図画面を出しているのがアプリではなく,バックグラウンドで動作するDLLであるためだが,DLLの持っている情報だけでも出せるものはあるのではないだろうか?系図画面で右クリックメニューが出ればかなり使い易くなると思う.ただし,カード削除一つ取っても単独では実行できない.VBでカード削除パネルを出すなどの動作が必要になる.DLLからVBにコマンドを発出する機構があれば,それも可能となるのだが…

toplistの母氏名にDATALISTを記入するとグリーンになるのは,実在するDATALISTカードを押さえているためと考えられるのに,実動作では新規カードが生成されるというのはどこかに誤りがあるためと考えられる.おそらく,このカードDATALISTが部分図画面上にないことが誤動作の原因になっているのではなかと考えられる.⇒実際,全体図に移ってから登録を実行すると正しいDATALISTにリンクされている.

一応システム構成図の上半分の要素包含図ができた.couplingをルートとする完全な木になっている.

image

もう一方の下半分クラス継承図も再掲してみよう.こちらはNODULEをルートとする倒立した木だ.

image

この2つを合体させたらどうなるか?こんな感じになった.

image

あまりわかり易い図とは言えないかもしれないが,システム全体の構成を一応網羅的に表現しているものと言って差し支えない.ある意味で「何だこんなものか」と思われる向きもおられるだろう.出口検査で出しているダンプを見ると

★出口検査 重婚同類循環=3 系列数=1 非連結=0 多重カード=1 避けられない多重=1 SYM=0 TYW=0 ZTYW=0 ROUND=3 表示数=4 基準ノード=CARDLINK:#338 @33baselist[0]

となっているが,多重カード1というのは明らかに間違っている.少なくともMDBとPDBは多重カードだ.tribelistも多重だし,NLISTも多重だ.当然避けられない多重1とは思われない.重婚同類循環が3もあれば多重が多発するのは避けられないだろう.図面が間違っているのか?計数が間違っているのか?図面もカウントも間違っている可能性もある.サンプルはゼルコバの木モジュール構成図8.ZELとして保存した.

この図面にはミスが相当含まれていると思われるが,欠落もかなり残っているのではないかという気がする.メモリ管理をやっているブロックがそっくり欠けている.タイトル設定に関するクラスも抜けていた.システム機能のうちnoduleで直接サポートしている部分は完全に隠蔽されている.それでも全体を把握するのには多少は役に立つだろう.さて,そろそろ本線に戻らなくてはならない.どこからこんな脇道に紛れ込んだのだろう?描画セグメントを管理するDrawingObjectの本体をどこに配置するのが適切か?という疑問から始まったような気もするが…

▲treeviewの出現は2つあるが,2番目の出現は配偶者であるはずなのに頭に垂線が入っているのはおかしい.これではTREEVIEWの子どものように見える.treeviewの親はcouplingとtribelistだからそこから入ってくるのならわかるが…treeviewの親はtreeviewの最初の仮ノードで受けているから,ここでは親からの連結線は入らないというのが正しい.

image

この図面の煩雑さから得られる教訓は「結婚枠には任意のカードを登録できるようにするべきだった」という反省だ.この点に関しては設計時かなり悩んだが,問題になったのは「先祖ノードを結婚枠に入れるべきか否か」という点だった.と言うのは「婚姻関係とは本人と配偶者と子どもからなる関係であり,これら当事者のうちの少なくとも2つの関係が成立する場合を結婚とする」と定義していたためだ.しかし,だとすれば少なくとも配偶者が存在すれば結婚は成立する.結婚が成立しているのならそれを表象する結婚枠は表示されるべきなのではないか?

image

これはおそらく結婚枠というオブジェクトを実装する中で結婚枠=子ども枠という考え方が固まっていったためではないかと思われる.実際子ども枠の中に存在するのは本来子ども(兄弟)のみであり,配偶者はある種の転入者と考えられていた.人は父と母を持たなければこの世に生存するを得ない.つまり,人に取って父と母は唯一無二の絶対的な存在である.親が無二であることから子ども枠(結婚枠)は親の結婚枠からリンクされることによって(グラフ理論的にも)結婚木を構成する.

当初設計の時点で方針転換していれば,「先祖ノードだけの結婚枠」というのが実装されていた可能性もあるが,そのときは「先祖ノードはかなり特殊な存在であり,結婚枠を持たないのは不自然ではない」という見方をしていたため実装を見送った.しかし,これを拡張して,「結婚枠の中には誰が入ってもよい」としたらどういうことになっていただろう?多分構図の自由度は格段に増したものと思われる.

結婚枠≒FAMILYと考えてよいが,「結婚枠の中には誰が入ってもよい」と再定義したときの「結婚枠」はむしろ「家庭」というより「世帯」ないし「家」という考え方に近いものになる.実際わたしが子どものころ家は相当貧しかったが,孤児(長兄の同級生)を一人預かっていたことがある.むしろこれはよりリアルな生態を表現できる可能性がある.親子関係がなくても結婚枠の中に入れられるようにすると,一般のダイアグラムを描くのにはかなり好都合だ.現行の構成規則を維持しながら,ここまで拡張することは不可能ではないように思われるのだが…

▲この図には確かにかなりの欠陥があるような気がする.下図ではnoduleが選択されているが,多重出現している.これは回避可能な多重であり,本来解決されるべきものだ.なぜこの状態で残ってしまったのか理由はよく分からないが精査する必要がある.

image

▲tajugraph2の子ども氏名欄をクリックしただけで,以下のようなパネルが出る.まったく意味不明だ.他のテキストボックスをクリックした後は収まった.登録されていない名前なら黙って新規カードを作ればよいし,空白氏名のカードを生成することは禁止されている(カード画面の本人タブで氏名を空欄にしてもよい).

image

不用カードを1枚削除した他は何もしていなかったと思う.ダブルクリックで新規カードを生成するという動作はあったかもしれないが…

▲一覧表で所属欄が見えなくなってしまった.また,列幅ゼロの列は可視に切り替えても見えない.⇒原因は分かった.横スクロールすれば見えるようになる.

image

▲NAMEBOX::IsPossibleBTWLeftHandでASSERT_NEVER (rightwife->IsLeftHandBox())により停止した.treeviewの父母ページで母氏名をCOUPLINGとして登録しようとしたところ.UNDOで戻して(ERR4)で保存.kakeizuでも起こる.

▲TRIBEBOX::SetMinorTribeで(primary->getrelation() == REL_SPOUSE)により停止した.starttribeから子どものTRIBEBOXを削除して配偶者に付け替えようとしたところ.UNDOで戻して(ERR5)で保存した.topUndo,UndoCurptrなどでも起こる.

ここまでのところをZTシステム構成図1として保存.longtable RecordListとBASETABLE<CARDLINK, MAXPDB> が孤立ノードになっている.前者はlongtableの配偶者,後者はBASETABLEの子どもとしておこう.いや,その逆だ.BASETABLE<CARDLINK, MAXPDB>がダブってしまった.後からできた方は削除しておこう.

▲一覧表で行クリックするたびに画面を更新しているようだ.

▲couplingの結婚ページで配偶者COUPLINGのページが2あるなかで最初のページが空のままになっている.(ERR6)で保存しておく.⇒読み直しても空白ページは残っている.⇒これはエラーではない.COUPLINGという同一名の配偶者を2人持っていただけだ.

これまではオブジェクトOのクラスCをオブジェクトの子どもとして配置し,その箱の中にクラスメンバーMを格納するというやり方をしてきた.この方式ではクラス名CはクラスメンバーMの入った箱のラベルという感じになる.クラス木の方はこれでうまく作れるが,構成要素木を作ろうとするとかなり無理な形になってくる.クラス間に多段の派生関係がある場合下位オブジェクトMは一つ上のクラスCupperの子どもになっているので,オブジェクトOはCupperと婚姻関係を結ぶことになるが,CupperはオブジェクトOの子孫でもあるので矛盾が生じる.描画は可能だが,クラスCupperの位置にオブジェクトOの仮ノードが配置され不可避的な多重カードが発生してしまう.

以前に試みたことのあるクラスオブジェクトOとクラスCを婚姻させるという方式を復活させてみたところ,うまくゆくことが分かった.なぜこれがうまくゆくのかという理由は下記のような解釈として与えられる.

「システム構成図は構成要素の包含関係図であると同時にクラス関係継承図でもあることを意図して作図される.構成要素は実体(男性)だが,クラス(女性)は抽象でその中のメンバーもまた抽象である.これを調和させるためにクラスとオブジェクトの婚姻という関係を導入する.クラスという抽象はオブジェクトという実体と婚姻することによりメンバーオブジェクトという実体を産出するという構成だ.」

システム構成図の構成規則は二転三転しているが,多分この方式の方が自然な木を構成し易いのではないかと思う.実際,大分形が変わってきた.これまでよりずっといい感じだ.

image

tamo2さんからもう一つのVAIOが届く

やっと動いた.VB→プロパティ→参照タブでパスの見つからないCOMが2つ上の方に隠れていた.これでやっと参照を操作できるようになった.やれやれ…しばらくデバッグ環境でZTを走らせてモジュール構成図の入力を続けることにする.

▲ウィンドウのドッキングでウィンドウ境界に隙間ができてしまう.これは生成されている実際のウィンドウと理論値に差があるためと考えられる.ウィンドウサイズが変わってしまうのと類似した現象だ.

上半分のモジュール構成図と下半分のクラス継承図をすり合わせるために,以下のような方式を考えた.①オブジェクトを男性,クラスはすべて女性とする.②クラスメンバーはオブジェクトとして扱い,一つの結婚枠の中でクラスを長女とし,メンバーを男子兄弟とする.多分これですべてが解決するのではないかと思う.やってみよう.以前の案はクラスを配偶者として配置するというものだったが,図式的に見てこちらの方が構成し易いのではないかと思う.このようなクラス名とメンバーが表示された結婚枠をクラス枠と呼んでおこう.

あるオブジェクトOがクラスCに属する場合にはOはCを子どもとして持つ.クラスAがクラスBの派生クラスである場合には,BはAの子どもとなる.⇒確かに理屈ではこれでよいのだが,実際動作としてはゼルコバの木では多重を解消することを最大のポイントとしているため,思ったような図式にならない.また,STOPのたびにブレークが掛かるので作業の妨げになる.やはりテストにはリリース版を起こした方がよい.

▲名前を付けて保存したあと,終了して再起動するとリネーム後のファイルが立ち上がってくる.これはリネームした後で編集対象のファイルが変わっていると考えられるので,その時点でタイトルバーの表示を変えるべきだろう.⇒しばらくすると変わるようだ…

tamo2さんからもう一つのVAIOが届いた.普通は受け取りのサインが必要なところ,今日の配達員は「要らない」と言って置いていった.

image

中を開けるとお米が入っていたので,ああ,今度はお米を送ってくださったのだな~と思ったら,その下にノートが入っていた.超薄手のスマートな 2 in 1でキーボードと本体は無線でつながっていて,本体と離れていてもキーボードが使える.(というか,使用時には本体とドッキングするようにはなっていない.サブ機に使っているタブレットはキーボードを持っているが,装着しているときしか使えない).これもVAIOなの?と思えるほどまるきり別ものだが,それを同じVAIOと呼び続けるところにSONYの美学を感じる.

一時は泣きが入るほど追い込まれていたが,ようやくリリース版がビルドできたので安定版として確保しておこう.⇒「すべてのドキュメントを閉じる」を実行しようとしただけでVSがアボートしてしまった.最近のVSはクラッシュする代わりに一度アボートしてまた立ち上がってくる.バージョン番号を変えるとあちこち変更が必要になってくるが所内版の場合はそこまで厳密管理しないで,これまで通りLicenseCode.h を書き換えるだけにしておく.ZelkovaTreeSetup.2.2.0.011-64.msi,パッケージは20201025-KGWZMZCとした.

■部分図を使えばカードを個別に隠蔽することはできる.

▲検索ボックスでテキストを全選択してDELキーで「削除する対象カードを選択してください」が出る.OKでテキストはそのまま残っている.BSで一文字づつ消すことはできる.

Bobject::saveparentの位置を上に上げて,親参照パス操作の区分に移動する.また,getsaveparentというアクセス関数を作った.treeviewオブジェクトはcouplingとpagesetupから参照されている.(本来はcouplingが所有しているのだが…)

image

couplig→treeviewは連結線を引き回して描画されているが,pagesetup→treeviewをリンクすると下図のようにpagesetupはtreeviewのボックスから飛び出してしまう.

image

この場合もtreeviewと同じように,pagesetupを下げなくても(抽出枠を作らなくても)描画できそうな気はするのだが…一般に婚姻による理由以外では下流の子どもとの連結のために抽出枠を作る必要はないように思われるのだが…

▲カード一覧表の表示範囲はもっと広げてよい.たとえば不可視カードなど.選択されたカードというのも表示できればよいのだが… カード一覧表には表示されているカードの点数を(タイトルバーに)表示してほしい.多分部分図に落とせば一覧表に表示され,カウントも取れるとは思うが…⇒選択範囲を部分図として一時的に登録してカード一覧表→一覧表表示範囲→部分図に含まれるカードの操作はそれほど手間の掛かるものではない.部分図を使い倒すというのも一つの方向性だ.

大分まとまって来た.

image

まだ主要コンポーネントのNAMEBOX, MARGBOX, TRIBEBOXやその上のCARDLINKやMARGLINKなどは登場していないが,それらが出揃えば大方仕上がった図になる.一度バックアップを取っておこう.

▲結婚枠間にもう少しギャプがあった方がよい.⇒ただし,そうすると結婚枠内の人名間ギャップも(場合によっては)拡がることになる…

▲氏名同定のあいまい探索は確かに便利ではあるが,危険でもある.該当が1件の場合登録で無条件で確定するが,そのときに名前を補充している.少なくとも名前を補充した場合には,一度保留して「再登録」を待つべきだろう.氏名が厳密一致していないときはイエロー表示でもよいのではないか?⇒あいまい探索は機能としては残した方がよい.

▲子ども12人を登録して子ども数が11のままになっている.

▲カード検索パネルが出てこない.昨日は出ていたような気がするのだが…⇒通常は正常動作している.マルチスクリーンで作業していたことが影響しているのではないか?

▲一覧表でカードを選択してDELで削除パネルが出ない.メニューからは実行できる.

198点まで入力した.うちクラス要素が47個ある.クラス要素だけを部分グラフにするとまだ全然ツリーになっていない.クラス要素だけで逆向きのツリーにならなくてはならないのだが…しかし,この線が入るといきなり見難くなると思われるので,一度バックアップしておこう.現状はこんな感じになっている.

image

クラス要素部分図が細切れになっている理由は中間に一般ノードが入るためもあるのではないか?現状はこんな感じだ.

image

終端はnoduleクラスだが,クラスの大部分は基本クラスがnoduleなので,現在の設定では間に合わない.父母ページ数を大幅に増やさなくてはならない.30個くらいあれば間に合うだろう.MAXPARENTS=32としてみた.⇒起動してすぐ異常終了してしまう.メモリ不足だろうか?nodule::Sansyoで参照カウント負が起きている.TREEVIEW→Bobjectのコンストラクタでcleanを実行しているところだ.以前関数参照木グラフを作っているときにMAXPARENTS=12で動かしたことがある.⇒MAXPARENTS=12でも同じエラーになった.

どうもどこか壊してしまったのではないかという気がする.Dドライブが早くも容量不足に陥ってしまった.10個くらいバックアップを取っただけで満杯だ.と言っても1個で2.4GBもあるので…⇒作業開始前にバックアップした20201025-KGWZMZCは問題なく動いている.WinMergeで比較してみたが,修正を行った箇所以外にはゴミの混入は見られない.修正は以下の3点だ.

  1. Bobject::saveparentのクラス内での位置を上げてprivate領域に移した
  2. saveparentにアクセスするための関数getsaveparentsを導入した
  3. MAXPARENTSを4から8に引き上げた

もしかするとDドライブの容量不足がこの時点ですでに発生していた可能性も考えられる.ファイル転送が終わったら,もう一度修正版をテストしてみよう.どうもバッファ不足が発生していたのではないかという気がする.CARDBASEのサイズはMAXPARENTSによって増減するが,MAXPARENTS=8の状態でsizeof(CARDBASE)は2560にもなっている.現状MAXSTRBUF=2048だが,この値は sizeof(CARDBASE)=1240x2を基準に設定されている.いや,データベースの書き込み時に使うバッファサイズはランタイムに計算している.

下記のエラーが実行時に毎回出る.そのたびにVSを再起動しているが,かなりおかしい.VSを単独で走らせているだけなのにEXEが使えないというのはどういうことだろう?EXEを使っているのはVSだけだ…

image

▲結婚枠データの保存でMAXMARRIAGEでループしている.

image

いずれにしてもこのパッケージは放棄するしかないかもしれない.もう一度バックアップから入れ直してみよう.MAXSTRBUFは4096に増量した.⇒作り直してみたが,やはりMAXPARENTSを32まで増やすと同じような状況になる.どこか分からないが,何かしらまずいことが起きているように思われる.データサイズを大きくしているので,どこかで脚が出ているのに違いない.しかし,アプリのエラーならまず捕捉できないということはないと思われるのだが…MAX=8なら問題ない.あるいは,システムから与えられたヒープを使い切っているということも考えられる.MAX=16でも障害が生じる.

◎VAIOが2台も入ってきたので,分散処理が組めるのではないだろうか?ただし,incredibuildは有償だったはずだ.⇒2万円くらいだ.買えない値段ではない.いや,違う.それは「Acceleration Solutions」の価格で端末にインストールする「Agent」は4コアでも87,000円だ.

MAX=12なら動く.⇒「EXEを開始できない」というエラーは出るが,VSを再起動してやればMAX=32でも動作する.原因はまったく不明だが,もう少し動かしてみよう.noduleの親の登録数が13を超えてから,noduleを子どもとして登録しようとすると氏名欄が赤色表示され,別カードとして新規登録されてしまう.カード合併してやれば父母数を増やすことができる.VBでブレークポイントが効かない.⇒リリース版でテストしていた.⇒NAME_PAGEOVERが発生している.⇒MAXPARENTSがVBでは12になっている!VBではヘッダファイルを読めないのでInportExport.hで記述した内容を転記しなくてはならない!

▲VBとC++で定数が一致していることを確認する.

大体できた!ゼルコバの木システム構成図の下半身だ.

image

とりあえず,ゼルコバの木ではこれ以上にはならない.

▲クラス部分図を全選択→反転してTREEVIEW::selectAllで (topology->ActiveList->count) という理由で停止した.

▲クラス部分図で全選択→反転→部分図登録で作った部分図に女性カードのCOUPLINGが入っていた.

▲部分図をリネームして登録したのに部分図が3つになってしまった.そのうちの一つを削除して部分図の選択メニューが壊れてしまった.

image

▲ここまでのところを構成図6で保存した.このファイルを開き直そうとして,nodule::Sansyoで停止した.previous->Refcount()–;を実行していて例外が発生している.previousが無効になっている模様だ.対象オブジェクトはPARTIALNAME.枝番号は2.このスロットはlongtable *SavePartialListと思われる.この障害はPARTIALNAMEのデストラクタの中でCleanSlotを実行中に発生している.アプリアボート後,再起動してこのファイルを開いたところ,一部不具合がありましたが,修復しましたが出た.部分図は1個だけ残っている.

▲要素包含図で全選択したのに一覧画面ではごく一部のカードしか選択されていない.今度は動くようになった.

男性ノードの要素部分図はまだバラバラで木になっていない.

image

ゼルコバの木システム構成図を入力する

ランニングテストを兼ねて「ゼルコバの木システム構成図」を作っているところだが,いろいろと不具合が検出されている.これらのデバッグないし改善は後回しにして,もう少しデータ入力を続けることにしよう.ゼルコバの木システム構成図の上半分は①COUPLING(系図システムオブジェクト)を頂点とするコンポーネント(実体を持ったオブジェクト)の包含関係図,下半分は②NODULEクラスを基底クラスとするクラスの継承関係図になるということが分かった.当面は両者を無理やり結びつけるのではなく,2つの独立した図面として描画してみるというところから始めてみたい.①はすでに半分まで出来上がっているので,あとは基本クラスを要素として追加するだけだ.

図面①ではオブジェクトの接続関係を実親子関係とし,参照関係を養親子関係として表記することにする.これはメモリ上に配置されたオブジェクトはそのオブジェクトが所属する親オブジェクトを一つだけ持っているという実態に即したものだ.下位オブジェクトへのポインタを格納するスロットにはオブジェクトへのリンクが格納されている.これは接続の場合も参照の場合も同じ.異なるのは子オブジェクトには親オブジェクトへのリンクがあるという点だけだ.「ルート以外のすべての節点が親節点を一つだけ持つ閉路を持たない有向グラフは木になる」のでこの図面は階層的な木を構成する.

スロットに格納されるリンクには二つの場合がある.単体のオブジェクトを参照する場合と,リストのようなオブジェクトの複合体を参照する場合だ.これを図示できないと全体の構図を把握することができないので何らかの工夫が必要になる.ここでは名前の後ろに※を付けることで「集合オブジェクト(一般にはリスト,つまり単純な順序集合)」であることを示すようにしてみよう.また,複数のスロットを使って複数の「集合オブジェクト」を操作しているような場合には,その機能を日本語で表示するノードを説明的に挿入するということにする.

また,ゼルコバの木では性別をカラー表示できるので要素オブジェクトを男性,要素クラスを女性としておこう.要素クラス(基本クラス)はオブジェクトの中に実体があるので実子関係になるものと思われる.しかし,この図面ではたとえばnoduleクラスというのは基本クラスとしてどこにでも出てくるのでそれを同一ノードとみなしたときにはゼルコバの木はそれを強引に描画しようとして相当無理な図面になってしまうことが考えられるので,とりあえず,同一名の別オブジェクトとして登録しておくことにする.

▲kakeizuの子どもにnoduleを入力して登録→すでにcouplingの子どもとしてnoduleを登録してあるので2つのnoduleを同一ノードとして図示→kakeizuの子ども欄でnoduleをnodule1にリネームして登録で下のパネルが出た.

image

このパネルを複数回出したあと正常動作に戻ったが,noduleはフロート状態になり,couplingは子どもを失った状態になった.この後couplingの子どもにnodule(女性)を追加して登録では新たなカードが生成された.本来ならフロート状態のnoduleとリンクされなくてはならないところだが,kakeizuの子ども欄はイエローになっていた.これは複数の候補があることを示すものだが,状況からしておかしい.UNDOで戻ってもう一度確認してみよう.ヒントには

image

とあるが,半ば意味不明だ.これは,氏名入力欄に名前を入力したときの同定カード探索では「あいまい検索」していることが原因だ.ダブルクリックするとカード巡回パネルが出て子ども氏名欄はショッキングピンクに変わる.これで確定選択ボタンを押せば,このカードが登録されるということになるので操作的にはこれでよいと思われる.

image

ヒントの「ダブルクリックして子どものカードに移動」はよいとして,次の「未入力の場合は新規カードを作成」は意味不明だ.確かに子ども氏名欄が未入力の場合はダブルクリックで新規カードを作成するという動作になっているが,記入されている氏名欄の上で出されるヒントとしては不適切だ.⇒いくつか改善項目が考えられる.①あいまい氏名(イエロー表示)が残っている場合には登録時に注意を促すプロンプトを表示すべきではないか?できるだけパネルの表示頻度を減らしたいという意図と思われるが…②ヒントの用語はですます調の方がよい.

言い切りだとコマンドのように聞こえる.たとえば,「子どもの名前を入力して既存カードにリンク」ではユーザはどこからどこまで自分でやればよいのか分からない.「子どもの名前を入力して既存カードにリンクします」なら,(ここでは)操作の主たる目的が「既存カードにリンクすること」だということが(何となく)わかる.このヒントは「一般の場合」のヒントで氏名入力中のヒントにはなっていない.氏名欄の状態によって表示内容を変える方が望ましい.色については①のプロンプトで説明できるかもしれないが…

couplingにnoduleを再登録するときも子ども欄はイエローになったが,ダブルクリックして確定選択でフロート状態のカードにリンクできた.

▲マルチスクリーンで作業しているとき,削除パネルなどが別のモニターに出るのはよくない.現在のスクリーンに表示すべきだ.⇒コマンドを受け付けたウィンドウがどのスクリーンにあるかを特定する必要がある.ただし,パネルは前回表示した場所に開くという原則もある.

考えてみるとゼルコバの木のオブジェクトはすべてnoduleの派生クラスなので個別にnoduleを子どもとして持たせる必要はないのではないか?その方が図面もわかり易い.ほとんどのクラスはnoduleから直接派生している.noduleの孫クラスというのはかなり少ないと思う.Bobjectはその一つだが,何か他にあるだろうか?BASETABLEにはCARDTABLEとMARGTABLEという2つの派生クラスがある.Bobjectの派生クラスはNAMEBOXを初めとしていろいろある.

▲PARTIALMAPがクラス名とCARDCOMMANDのコマンド識別子として使われているが避けた方がよい.⇒いや,間違えた.クラス名はPARTIALNAMEだ.⇒単なるミスタイプと思われる.

▲人名カードでテキストボックスをダブルクリックしてテキストを全選択状態にしようとして戻ってしまう.

あるオブジェクトの基本クラスをそのオブジェクトの下位要素として配置するのはよいとしても,同じクラスに属する複数のオブジェクトが存在する場合にはどこかにクラスの代表ノードが存在しないとあまりに冗長になってしまう.これを避けるため,所属クラスを配偶者ノードとして表示することを考えてみる.これが通用すればクラスノードは一箇所に一度だけ出現するので図面をかなりコンパクトにできる.

たとえば,クラスSIMPLEGRAPHにはnodelist, edgelist, complistの子どもがあり,子どものいない配偶者としてgraph1, graph2, graph3, tajugraph1, tajugraph2, tajugraph3, tempgraph, copygraph, keisengraphがあるという具合だ.子どもたちは単身婚のこどもとしてクラスノードの直下に配置する.⇒いや,これもあまり素敵とは言えない.むしろそのオブジェクトの下に配置した方がましな気がする.複数のオブジェクトと養子縁組すればよいのではないか?

ゼルコバの木では循環が発生するような矛盾した直系血族間の結婚を配偶者同定探索対象からあらかじめ弾いているようで,graph1の配偶者SIMPLEGRAPHをカットして,子ども欄に貼り付けてもボックスはグリーンにならず,登録で新しいカードを生成する.

▲複数のグラフオブジェクトの配偶者SIMPLEGRAPHを子どもに移す付け替えをやっていて下記のエラーになった.tajugraph2の操作を行っているところでエラーが起きた.

image

UNDOで戻したものを反例サンプル(ERR2)として保全しておく.⇒残念ながら再現しない.いや,次のtajugraph3で出た.前回出なかったのは女性→男性に変更していなかったためと思われる.⇒ひなアイコンをクリックしたタイミングでパネルが出ている.登録は実行できる.

▲SIMPLEGRAHPHの父母ページで4ページ目に移動するとエラーパネルが出る.登録ページ数は4.

image

このサンプルを(ERR3)で保存しておく.SIMPLEGRAPHは親を8人持ち,そのすべてを上の操作で登録したつもりだったが,4人しか入っていない.⇒4ページ目で出るのではなく,4ページのあとの空白ページに移動しようとしてエラーになっている.父母ページ数の上限が4になっていたのだろうか?確かに4になっている.MAXPARENTS=8に変更してビルドしたものを再インストールしてみる.

▲リリース版をビルドしたが,OCXが認識されない.VB→参照の追加で該当バージョンのOCXへの参照を追加しようとすると,

image

のようなパネルが出る.VB→プロパティ→参照にはOCXは何も登録されていない.ツールボックスには残っていた.ツールボックスに残っているOCXを削除し,ツール→ツールボックスアイテムの選択からOCXを選択しOKでも同様のエラー↓になる.

image

他に参照を操作できる場所は存在しない…今度はツールボックスへの追加で以下のようなエラーになった.

image

どうも何かが決定的にこじれてしまったような感じがする.もはやこうなったら,Visual Studioを再インストールするか,Windows 10を再インストールするか,あるいは,モジュール名をすべて付け替えるか?の三択しかないような気がする.なぜこんなことになってしまうのか?まったく理解に苦しむ.昨日まではVSを2つ立ち上げてそれぞれを個別に同時実行できていたのが,急に一つも動かなくなるというのはどういうことなのか?誰か説明してほしい…リリース版はともかくデバッグ版まで走らないというのは考え難い.⇒バックアップに戻ってビルドし直した.ビルドは通ったが,実行時エラーになった.

image

HRESULT = 0x80040111は前にも出たことがあると思うが,どう対処したのだろう?クリーンビルドしたら却って悪化した.ビルドが通らなくなってしまった.多分このあとは同じだろう.デバッグモードでビルドできないのだから,セットアップの問題ではない.OCXの参照の問題であることは確かだが,何が障壁になっているのかその辺りの見当がつかない.テスト版に切り替えて動作を見てみよう.⇒ダメだ!再開始スタート版の前まで戻ってみたが状況はまったく変わらない.このようなときには大概奥の手が効いたものだが,それが効かないというのが致命的だ.もやは打つ手なしという感じになっている.

リリース版のOCXをregsvr32で登録しようとしてみたが,下記エラーになった.HRESULT = 0x80040200

image

レジストリが壊れているとしたらWindowsを再インストールするしかないかもしれない…regsvr32でレジストリの登録解除ができる.Zelkova for Test 2.0をアンインストールするためZelkovaForTestから/uを実行してみたが,HRESULT=0x80040201エラーになった.regsvr32 /uを実行するには管理者権限が必要だが,管理者権限で実行してもまだエラーになる.

image

打ち間違えていないはずなのだが,ZELKOVAとZELKOVAFORTESTの両方で実行してみたがどちらも効かなかった.どちらもdebugフォルダにはOCXが生成されている.CCleanerを導入してレジストリのクリーンアップもやってみたが効果はなかった.VB→プロジェクト→参照の追加→COMではZelkovaZ3.ocxが3つレジストリ登録された状態になっている.Zelkova For Test 2.1, 2.2, 3.0だ.⇒ようやく一つ消せた.あとは3.0を消すだけだ.PowerShellを使い,C:\Windows\Syswow64に移動してregsvr32を実行して成功できた.これもうまく行った.

OCXがレジストリ登録時と同じフォルダにあることが必須条件であるのかないのかは分からないが,念のため登録時のバイナリがある場所で登録解除した.あれ,おかしい.まだゼルコバの系図エンジン for TEST 2.1というのが残っている.消したつもりだったが…⇒失敗した.テスト版を作っている.今度はうまくゆくと思ったが,まだ参照追加できない.⇒パワーシェルからレジストリ登録して成功しているのに参照追加できない.どうも完全にいかれてしまったようだ.こうなると最後の手段としてはモジュール名の付け替えしかないように思われる.

絶対世代番号に関わる整理が完了した

Visual Studioは一つのマシンで複数のインスタンスを同時実行することができるが,これらが同一のOCXを参照している場合などにはうまくゆかない.この不都合を回避するためにコンパイルオプションでOCXのuuidとversionを切り替えるようにして並列実行を可能とすることができるようになった.修正前のバージョンと修正後のバージョンを同時実行して,1本のファイルを開くまでの間に200万回くらい呼び出されるような呼び出し頻度の高い汎用関数の呼び出し回数が両者で厳密に一致することが確認されたので,修正の正当性は高度に保証された.このオプションは今後大いに役立ってくれるだろう.

一つ気になっている点としてMARGBOX::nodegeneは不用なのではないかと推測しているのだが…不用なロジックは可能な限り排除しておきたい.MARGBOX::nodegeneが不用と考える根拠は,書き込まれてはいるが,読み出されていないように思われるからだ.単純にMARGBOX::nodegeneを隠蔽してコンパイルエラーを見ることにしよう.まず,最初にMARGBOX::getnodegeneを止めてみた.コンパイルエラーは発生していないが,SIMPLEGRAPH::TightenHasseDiagramのループでMINMOVが不定値になってしまう.つまり,動作が変化している.どういうことだろう?

NAMEBOX::nodegeneでは確かに修正ミスを冒していたが,その原因はNAMEBOXの場合には多少あいまいな点があったためだ.MARGBOXの場合は誤りようがないように思われるのだが…⇒原因は分かった.サンプルが源氏に切り替わっていた.源氏には「避けられない多重」が6個もあるので多重グラフ検定を打ち切ってループの外に出る必要がある.ここで停止するのは意図的にそうしているのだから問題ない.これで懸案の一つは片付いた.ここでバックアップを取っておこう.

これで次に進めるのではないだろうか?ゼルコバの木では人名枠の配置を大きく垂直検定と水平検定に区分している.重婚同類グラフ検定は前者を担当し,メインループで後者を処理していると言ってよい.ただし,例外的にメインループの中で垂直方向の操作を行うことも一部認められている.さて,ぼちぼちと始めることにしよう.連結線の途切れをチェックするための検査を系線グラフ検定,そのために使うグラフを系線接続関係グラフと呼んでおこう.

系線グラフの節点は線分端点の座標,枝は座標の対であるとする.系線グラフが一旦構築されると,今度はそれを描画に用いることもできるようになるが,系線には色や太さなどの属性を持たせなくてはならないのでその辺りはまた後日ということにしておこう.既存のグラフはすべてTOPOLOGY(系図解析木クラス)が管理している.この方がわかり易い上に安全なのでこの方式を踏襲することにする.グラフの本体は人名テーブルや結婚テーブルを保持しているLINKTABLEが所有する.グラフ処理の一般的手順は以下の通り.

  1. グラフの生成 TOPOLOGY::initialize→new
  2. グラフを初期化 TOPOLOGY::ResetExperiment→initialize
  3. ノードリストを生成 ノードリストは枝リスト生成時に自動生成される
  4. 枝リストを生成 両端点を指定して枝を生成 SIMPLEGRAPH::add
  5. 連結リストを生成 DecompConnectedComponent
  6. グラフ処理 ...
  7. 参照カウントの調整 TakeRemainSansyo
  8. グラフを廃棄 delete

描画オブジェクトを扱うクラスとしてDrawingObjectクラスを新設する.DrawingObjectのインスタンスはTreeViewが管理する.座標値は内部ではCPointとして表現されているので,任意長のCPointテーブルを扱えるようにする必要がある.固定サイズのlongテーブルを扱うlongtableというクラスはあるが,これではカバーできない.線描画関数には座標対と線の属性が渡される.DrawingObjectクラスの中に座標対と属性を保持するテーブルを持つということも考えられる.これがあれば,DrawingObjectが単独で系線の描画を実行できるようになる.これは描画を高速化する効果があるだろう.まず,DrawingObject.h, DrawingObject.cppという2つのファイルを作ってみよう.

TREEVIEWはTRIBELISTの下にあり,TOPOLOGYはTRIBELISTの上にある.いや,少し違うのではないか?最上層はCOUPLINGであり,その下にKAKEIZU, FAMILYTREE, TREEVIEW, PAGESETUPがある.参照と接続を区別しなくてはならない.KAKEIZUは系図データベース,FAMILYTREEは系図木構築,TREEVIEWは系図画面出力,PAGESETUPは印刷出力に関係する.FAMILYTREEの下にはUNDOSYSTEM,TOPOLOGY,LINKTABLE,NAMESORT,PARTIALNAME,COUPLINGがある.最後のCOUPLINGは追加読み込み用スロットだ.

開発機にインストールされているゼルコバの木を起動したらエラーになってしまった.再開発スタート版というバージョンをインストールしておこう.インストールされている版はZelkova-Tree 2021となっている.この版をアンインストールしようとしたら,「WindowsにZelkova-Tree 2021を設定しています 必要な情報を集めています」でハングしてしまった.かなりまずいのではないか?

image

キャンセルボタンを押しても終了しない.再起動しかないようだ.再起動したら以下のパネルが出た.

image

11178c24.msiなんてどこから来たのだろう?放置しておいたら,別のパネルが出た.

image

Administratorではないかもしれないが,管理者権限を持ったユーザとしてログインしているのだが…OKでようやくすべて閉じた.ともかく再起動しておこう.⇒多分このトラブルは一つ上のパネルが下に隠れているのに気付かなかったというケアレスミスだろう.今度は簡単にアンインストールできた.⇒とりあえず問題なく起動できた.しばらくゼルコバの木を使っていなかったので準備運動を兼ねて,ゼルコバの木プログラムのモジュール構成図を作ってみることにする.

▲子ども並び替えでドラッグ移動が効かない.カーソルキー操作はできる.⇒これは操作の仕様が変わっているのに説明文が改訂されていないためではないか?ドラッグはできないが,その代わり上下のスピンボタンが表示されている.⇒説明文を改訂する

▲人名枠氏名欄の左側に説明文を出したい.できれば任意配置できるとさらによい.表示項目の範囲を広げて取捨選択できるようにしたい.

▲pagesetupはTREEVIEWを参照しているだけなのに,子ども欄に記入したらCOUPLING→TREEVIEWの親子関係が切れてしまった.確かにこの方が便利な場合もあるが…画面設定→カード画面設定→既定で養子チェックオンというのがあるが,これで親子関係の自動切断動作を回避できるのだろうか?⇒確かにそうなっている.これはこれで便利ではあるが,養子チェックをいちいち外すのは厄介だ.むしろ,実子関係がすでに存在している場合には実親を切り替えるのではなく,養子関係で接続するという方がよい.この操作法をオプションとして提供し,①対象ノードがすでに外部に実子関係を持っているときは養子関係で接続,②対象ノードを実子として登録する場合にはそのノードがすでに実子関係を持っている場合にはその関係を切断するの中から選択できるようにするとさらによい.養子チェックは氏名を入力したあとでないと入力できない仕様になっているが,これでは上のような誤動作を避けることができない.空行を敢えて入力不可とする必要はないのではないか?裏技として,一文字入力して消すと使えるようにはなるが…そこのところは,これでも間に合わないことはないとして…⇒実子関係を切断する前に警告パネルを出すというのが実際的かもしれない.

▲「画面設定」メニューは「設定」とした方がよい.

▲人名カード画面の子ども氏名欄でホイールでスクロールしたときのスクロール量が大き過ぎる.ページスクロールの動作になっているようだが,次行に書き込めない.最小限一行分のダブリが必要だ.

▲子どもが親を2つ以上持っているとき,必ずしも実親の直下に配置されることにはならないが,その方がバランスがよい場合もある.直下に配置することを指定できてもよいような気がする(できない場合があるかもしれないが).しかし,実親を基準ノードでソートしているのに直下に来ないというのはかなりおかしい.⇒ある意味でそれを実現しているのが,「血統軸線図」と言えないこともないが…

▲血統軸線図で下図になるのはおかしいのではないか?UndoChainが軸線上に来ない理由がわからない.⇒これはバグと言ってよいと思う.

image

作りかけのゼルコバの木プログラムのモジュール構成図.ほんの気まぐれで作り始めたのだが,どうもかなり大きなものになりそうだ.実際のところゼルコバの木ではすべてのオブジェクトは1本の木を構成しているので,これを最後までやるとかなり大きなものになることは間違いない.途中でtreeviewという名前のカードが2つできてしまったので,カード合併を実行したところで「親子連結線の途切れ」が出現した.

image

しばらく動かしていなかったので多少とまどいはあったが,少し動かしていると慣れてきて,「ストレスなく入力できる」というキャッチフレーズも(上記の実子関係が切断されてしまうという点を除けば)あながち誇張と言うほどのものではない.UNDOで合併前の状態まで戻れることを確認しておこう.UNDO/REDOは動作しているようだが,REDOでそのまま続けてREDOしていたら,エラーパネルが出て止まらなくなってしまった.操作する直前にバックアップを取っているのでデータは失われないが,UNDOの不良動作を再現できるかどうかは分からない.

image

どこかでループしているもののように思われる.タスクマネージャで落とすしかなさそうだ.このアプリはZelkova Tree 2019(32ビット)(2)という名前で登録されている.デスクトップ上には大量の反例サンプルが発生しているが,すべて同内容なので一つを残して削除しておこう.これらのファイルを開くと以下のパネルが出る.

image

反例サンプルを開くと余分の白紙カードが生成されている.

image

オリジナルは66点なのに対し,反例サンプルは67点なので白紙カードと枚数が合わないが,オリジナルから消えているカードが2枚あるので一応帳尻は合っている.もう少しデータ入力を続けよう.

▲検索ボックスに名前を入力して虫眼鏡をクリックしてもジャンプしない.⇒無選択状態ならジャンプできる.これはかなりおかしい.確かに選択状態を変化させずにジャンプしたい場合はあるかもしれないが…無選択状態のときはそのカードにジャンプしてそのカードが選択された状態になる.人名カードはカード選択と同期しているから,ジャンプしたときカード選択が移るのはやむを得ないと思われるが,無動作というのはまずいと思う.⇒つねにジャンプでよいのではないか?

▲純血統図では養親子関係のノードは無色カードとして表示されているが,むしろ非表示の方が用途があるのではないだろうか?実際,いま作成しているモジュール構成図では「接続関係」が「実子関係」,「参照関係」が「養子関係」に対応すると考えるとうまく表現できるのだが,「構成図」の場合には純粋な(参照関係の系線を省いた)木としての表現が見たいので,「養親子関係は非表示」とした方がフィットする.

image

coulingを基準ノードとして親族図→直系血族図を描画しても思ったような図が出てこない.treeviewには親が3つあるが,実親は頂点のcouplingなのでこの図面ではcoupligの直下にあることを期待しているのだが,tribelistの下に配置されている.これは図面範囲を直系血族図としたとき,図面に配置される人名ノードの範囲は直系血族になっているが,表示されているカード間の関係はすべて温存されているために起こっている.確かに,この図面では表示されているカードの関係情報はすべて網羅されているが,ユーザが期待しているのは別のことなのではないだろうか?それができれば,登録時にはすべての情報を登録しても,表示するときには単純な木として表示することができるようになるのだが…純血統図では(養親系を除く)と表示されている.これを文字通り理解すれば,(養親系の関係は表示しない)となるはずであり,その方がわかり易いような気がする.このオプションの動作をそのように変更すれば,他のところをいじらなくても要求されているような図式を出力することが可能になると思われるのだが…

■カード番号の左右のスピンボタンで移動するとき,飛び番になることがある.これはスピンボタンの動作が一覧表の順序になっているためで,不良ではない.

ともかく,入力を続けることにしよう.

▲カードに個別に色を付けることができるというオプションもあっていいと思う.また,個別に「関係を非表示する」ことができるとさらによい.⇒カードに任意の属性を与え,それを色別表示することが考えられる.⇒部分図という概念があるが援用できないだろうか?ある部分図に属すること=ある属性を持つことという解釈だ.

▲カード一覧表でいくつかの列を非表示にしたあと,一覧表セル幅→均等分割するとまたもとの全列表示状態に戻ってしまう.これはうれしくない.⇒表示領域は現在のウィンドウの横幅とし,現在表示されている列で均等分割するというのがよいのではないか?

この図面は人名枠左に説明を表示できるようになってから,その部分の日本語テキストを補充することを考えているので,今回の入力では実親関係データだけを入力するということにしてみよう.あるいは,全データを入力しておいて,その派生版として複数親を持つノードだけ修正したバージョンを作ることも考えられる.複数の親を持つノードはそれほど多くないので原本としてまずすべてのデータを入力しておこう.

▲#33 baselistの子ども氏名欄に「NLIST <GENEBOX, ‘g’>」と入力→登録でエラーが発生した.この欄にはNLISTという名前が登録されていたが,それを上書きして登録でエラーになった.

image

UNDOで元の状態に戻せる.この状態で一度保存しておこう.(ERR1)とした.UNDOではエラーは発生しなかった.UNDOの種が切れるとメニューは不能状態になるのでそれ以上のUNDOはできない.CTRL+Yを押しても反応しない.とすると,上のエラーはかなり特殊ケースだったのかもしれない.⇒このエラーはゼルコバの木モジュール構成図(ERR1).ZELで再現できる.⇒上書き入力だけでなく,baselistの子どもNLISTを抹消登録だけで再現する.他のノードでも起きる場合がある.extraslot2の子どもCOUPLINGを削除しても同じエラーになった.1人だけの子どもを削除しようとしたときに発生するようだ.エラーパネルが出なくなった後は,エラーなしでUNDO/REDOできる.⇒この障害は子どもが一人だけになったときには確実に発生する.⇒このエラーは子どものカードで親を抹消したときにも発生する.

▲UNDOメニューがすでに不能状態になっているときにCTRL+Zを押してエラーになった.

image

どうもメニューではリミットが検出されているのに,CTRL+Z/Yのキーが入ってしまうことがあるような気がする.OKで次のパネルが出た.

image

これを2, 3回反復してパネルは消えた.メニューではUNDO/REDOのどちらも使える状態になっている.ただし,CTRL+Zを押しても画面上には変化が現れない.CTRL+Yではエラーが出た.スクリーンショットは取らなかったが,「配偶者不在」のようなパネルもあった.そのあと,CTRL+Yで以下が出た.

image

どうもUNDOシステムが壊れてしまったようだ.CTRL+Yを押すたびに上のパネルが出る.一度終了してもう一度始めることにする.クローズボタンで警告なしにアプリが閉じてしまった.最後の状態がなんであれ,ファイルを修正しているのだから,保存しますか?が出なければおかしい.⇒「配偶者データがありません」のあとは正常に動作する.

VS2017を再起動→ソリューションを開いて,変なパネルが出た.

image

確かにVS2017を2つ開いてしまっている.キャンセルしてアプリを落としておこう.どうも細部はまだ完成にはほど遠い状況だが,入力を続けよう.下図まで入力して気付いたのだが,この図には2つの因子が混在している.一つはcouplingを頂点とするオブジェクトの実体的な包含関係,もう一つは実体を持たないクラスの親子関係だ.

image

上の図の赤枠はインスタンス(オブジェクト)で実体として存在するもの,白枠はクラスで実体を持っていないか,あるいは実体を統括した表象とでも言うべきものだ.この図ではコンポーネント(名前を持った実体)はすでにすべて描画されている.しかし,このシステムがそんなに単純なものであるはずがない.それはなぜかと言えばこれ以外にも名前を持たない無数のオブジェクトが存在しているためだ.言ってみれば上図は「骨格図」であり,すべてのサンプルの共通部分と言えるが,それに付随して無数のオブジェクトがさまざまなトポロジーによってリンクされている.そのような実態を一枚の図で描画することは不可能に近いが,上の図にはまだ決定的に不足している部分がある.

それはあるコンポーネントが保持する下位要素にはそのコンポーネントの基本クラスの要素がすべて含まれているという点だ.上図で白枠で表示されている部分はこのような下位要素の一部を展開したものと言える.従って,もし,この図が完成されたとすれば,頂点にはcouplingがあり,真ん中から下の白い領域にも最下層の頂点としてNODULEが来るという構成になるはずだ.これは図式的に見ると「束(lattice)」と呼ばれているものにかなり似ている(意味はまったく違うが…).

image

現状のゼルコバの木を使ってこの意味での「完全な構成図」を描くというのは不可能に近いという気もするが,ゼルコバの木のような複雑なシステムをもし仮に一枚の図式で示すことができるとしたら,それはかなりすごいのではないかと思う.原理的にはそれほど難しくないし,もしそのような図面が手元にあればプログラムのデザインや実装のときに大いに重宝するのではないかと思う.

ゼルコバの木を使ってゼルコバの木システムを図式化するという試みは以前も(途中まで)やったことがある.このときの対象は「関数の呼び出し関係」つまり,「関数木」を作ろうとしていた.Visual Studioには「呼び出し階層」というツールがあってある程度このような関係を図式化できるようになっているが,あまり使い勝手がよいものではない…「ゼルコバの木システム構成図」がどんなものになるかというイメージがつかめたところでまた明日ということにしよう.

■以前は実親は親ページの先頭に配置されていたはずだが,現行ではどのページでも実親として設定できるようになっている.

▲これから手直しというのも大変だが,先祖ノードに結婚枠を与えなかったというのは敗因であったような気がする.結婚枠は背景色のべた塗りしかできないが,枠線というものがあってもよかった気がする.

下図は実親子関係だけを抽出した派生バージョンだが,システム構成図としてはこれが正しい.上半分のピンクは完全な木になっている.

image

この図にはシステムの大きな構成要素である描画オブジェクトリストのようなものは出てこない.なぜか?描画リストはBobjectの4つのスロットを使った三元木として構成されている.TREEVIEWクラスの基本クラスはBobjectだが,上の図のtreeviewにはそれが含まれていない.Bobjectはほとんど抽象クラスだが※,その派生クラスは当然オブジェクトとしての実体がある.上の図ではそれが見えてこない.⇒たとえば代表的な描画オブジェクトクラスとしてNAMEBOXとMARGBOXの場合を考えると,NAMEBOXはCARLINKに保持されている.CARDLINKのnamboxスロットにはNAMEBOXのリストがリンクされる.MARGBOXも同様MARGLINKのmargboxスロットにリンクされる.

※BobjectやNODULEを「抽象クラス」として再定義してみるがよい.

MARGLINKとMARGBOXは一対一に対応するが,CARDLINKとNAMEBOXは一対多の関係になる.CARDLINK自体は上の図で言えばPDBという名前のCARDTABLEに格納されているし,MARGLINKはMDBというMARGTABLEに格納される.従って,上の図をもう少し詳細化すれば基本的にはシステム全図を(一枚の図面として)描くことが可能になると考えられる.(原理的にはゼルコバの木でもそれを描画可能だが,見易い図面にはならないだろう)

デバッグ用のツールなどどこにあるのか上の図からは見えない※.⇒デバッグ用のツールというオブジェクトは存在しない.デバッグ用ツールはほとんどすべてさまざまなクラスの関数で,それを適宜コードに挿入して使っているに過ぎない.たとえば,ShowUnderWearというのはマクロで,例外を発生してあるエラートラップにジャンプしているだけだ.関数の依存関係は関数木として表現できる.ゼルコバの木はアラン・ケイのオブジェクト志向とは真逆の発想だけど,誰か世界中に一人くらいそれを継承しようなんて突飛な人はいないものだろうか…たとえ人間国宝になれたとしても,継承者がいなければ何の意味もない.

※いや,たとえば現在取り組んでいる「抽象グラフ検証系」などはオブジェクトとしての実体がある.現行ではこれらはTOPOLOGYのスロットに格納されているから,詳細化すれば図面にも出てくる.

tamo2さんへの応答

早朝tamo2さんからメールが入っていた.babalabos@outlook.jp アカウントはわたしの公式アカウトとして「テント村」に表示してあるものだが,これはマイクロソフトアカウントでもあるのでほとんどチェックしていなかった.今回Thunderbirdを整理したついでにサブ機でも受信できるようにしたので受け取れたが,危うくのところだった.現在の作業に関わるテクニカルな内容なのでログ上に転記しておくことにする.

tamo2氏からのメール本文:

VAIOのWindows7、Windows8 及びエイサーのWindows7の機種についてはWindows10にアップデートすればゼルコバの木がインストール可能でした。但しWindows10をクリーンインストールしたら、インストール不可能。私が考えるにはVAIOのPCには古い .net 2.0 VisualStadioが温存されているのでは推測してます。以前にWindows10 の機種でゼルコバの木をインストールしようとして.net2.0をインストールして下さいのエラーなった記憶があります。又エイサーのタブレットでWindows10にインストールしていたがSSDの容量少なくVisualStadioをアンインストールしたら動かなくなった。

こちらからの返信:(tamo2氏から送られてきた VAIO にはゼルコバの木ベータ2がインストールされている)

tamo2 さま

お世話になります.

tamo2さんの推理のポイントは .NET 2.0の有無というところですね!?大いに考えられます.

>VAIOのWindows7、Windows8 及びエイサーのWindows7の機種については Windows10にアップデートすればゼルコバの木がインストール可能でした。

Windows 10以前は.NETはオプションだったが,10以降は必須になったためというご理解ですね?

>但しWindows10をクリーンインストールしたら、インストール不可能。

この現象は他のユーザからも報告があります.→新しいバージョンのWindows 10にはもはや .NET 2.0は常備されていないためというお考えですね.

>私が考えるにはVAIOのPCには古い .net 2.0 Visual Studioが温存されているのでは推測してます。

お送り頂いたVAIOで新規ユーザ名でゼルコバの木を実行しようとするとエラーになります.アンインストールすればインストールできる可能性はありますが,アンインストールしてしまうと折角の「ゼルコバの木ベータが根付いている64ビット機」が失われてしまう可能性があるので,いまのところペンディングしています.ただし,インストールが失敗したときの代替手段として,「EXEを直接実行することは可能」ということが分かりましたので,思い切ってやってみようと思います.

>以前にWindows10 の機種でゼルコバの木をインストールしようとして .net2.0をインストールして下さいのエラーなった記憶があります。

.NET 2.0をインストールしてくださいというメッセージは.NETがすでにインストールされているPCでも起こることがあります.これは環境設定で.NETが無効化されている場合に起きますが,「Windowsの機能」というところで有効化できます.検索ボックスなどで「Windows Features」と入力してエンターキーを押すとWindowsの機能パネルが開きます.また,それと反対に,すでに .NET 2.0以上がインストールされているPCにダウンロードしてインストールしようとすると,このPCにはすでに上位バージョンがインストールされていますと言って弾かれます.

>又エイサーのタブレットでWindows10にインストールしていたがSSDの容量少なく Visual Studioをアンインストールしたら動かなくなった。

VAIOにはVisual Studioはインストールされていないように見えますが,Visual Studio 8のパッケージがProgram Files (x86)に入ってますね.Visual Studio にはそのときの .NETのバージョンが入っているはずなので,それをアンインストールしたため動かなくなるということは考えられます.今朝目を覚ましたら画面に隠れて以下のようなパネルが出ているのを見つけました.どのタイミングで出たものかよくわかりませんが,おそらくインストール画面を閉じたあとに出されていたのではないかと思います.

image

まだ試していませんが,→の行をクリックするとオンライン・ヘルプにジャンプするのでしょう.「互換性の設定」という話はどこかで聞いたことがあるので,うまくゆけばインストール時のトラブルがすべて解決できる可能性があります(多分そううまくはゆかないだろうとは思いますが…)以下について調べてみたいと思います.

  1. VAIOに新規ユーザとしてログインしてゼルコバの木をアンインストール→これでOwnerがゼルコバの木を使えなくなるとすればマイクロソフトの「落ち度」と考えられる しかし,新規ユーザとしてゼルコバの木を起動したときの動作から考えると,「すべてのユーザ」を指定していても実際には個別ユーザごとにインストールしていて共有しているのはmsiインストーラだけということも考えられる(実際の動きはそういう感じになってます)
  2. VAIOの新規ユーザでゼルコバの木ベータをインストール→成功した場合,保説の蓋然性が高くなる
  3. VAIOに.NET 2.0がインストールされているかどうかを調べる(昔はコントロールパネル→プラグラムと機能でインストールされている.NETのバージョンがずらずらと出てきたのですが…)
  4. すでに上位バージョンがインストールされているPCに.NET 2.0(ないし下位バージョンの.NET)をインストールする方法を調べる C++のディストリビューションをインストールするという手があるかもしれない
  5. 「プログラム互換性アシスタント」の動作と「互換性の設定」について調べる 可能ならばそれを使ってインストールを試す
  6. 他の機種でも「EXEを実行して直接起動」が動作するかどうかを確認する
  7. ゼルコバの木の直近バージョンで古いサンプルが開けることを確認する(EXEから起動したゼルコバの木ベータで*.QDBを含む2012年以前の古いファイルが開けることは確認済み)

ゼルコバの木ベータで.NET 2.0が必要になるというのはゼルコバの木の根っこがVB6(Visual Basic 6)にあるためとも考えられます.VB6の機能はいまでも使っていますが,コード的には変換されているので .NET 2.0は不要ということになったのではないかと思います.貴重な情報のご提供ありがとうございました.大変参考になりました.

馬場 英治

早速にも上記項目のチェックに入りたいところだが,仕掛りになっている本線が思わぬところで難渋しているので,そちらを先に片付けてしまいたい.修正は32箇所で完全に特定できている.コードは何度も読み直してどこにもミスはないと思っているのだが,思ったように動いてくれない.Visual Studioのコンパイラが誤動作しているのではないかとさえ考えてしまうような状況なので,もはや「本格的なデバッグ」に入るしかないのではないかと判断しているのだが…さて,今日中にこのトラップから脱出できるだろうか?

ありゃ,おかしい.tamo2さんへの返信で添付したはずの画像がメールに入っていない.入れ忘れたのだろうか?画像はVAIOのスクリーンショットだが,Mouse Without Borders で受け渡ししたあと消してしまったのでどこにも残っていない…あ,パネルはまだ閉じていなかった.以下のようなメッセージ※だ.

※この画像はメール本文の位置に移動した

setnodegeneの呼び出しでは「NODULE:nodegeneを廃止する@20201021」がオンのときとオフのときの相違はあるが,すべてTESTABSOLUTEGENERATIONのブロック内のコードで,現在テスト中の環境では「NODULE:nodegeneを廃止」がオンのときもオフのときもTESTABSOLUTEGENERATIONブロック内のコードは実行されないようになっているので,動作に変化がある可能性はないはずなのだが…TribeRelocationの【5】重婚同類グラフ検定の中でSTOPCARDSHIFTがオンになっている.つまり,絶対番号不一致が解決していない.これは実質的に検定が失敗したことを意味している. 異世代多重カウントオーバーが発生している.現行ではこのループカウントは最大でも1しか認められていない.オリジナル版ではこの事象は起きていない.

オリジナルの場合,当初はmultigenes=28, multicount=50だが,重婚同類検定後はいずれもゼロになっている.修正版でも当初は28, 50だが,最初のループで13, 13に減少したあと変化が止まってしまうため,強制終了しているようだ.オリジナル版と修正版を並行してテストできるようにVS2017のインスタンスをもう一つ立ち上げることにしよう.⇒ダメだ.開発パッケージはコピーを用意したが,OCXを参照できない.以下のようなエラーになる.

image

どうすればよいか?OCXは多分,uuidとversionで識別しているはずなので,これを変えてみよう.⇒対処した.デバッグモードでテスト環境と開発環境で独立にアプリを走らせることができるようになった.ただし,どうしてもVBからOCXへの参照が通らないので奥の手(プロジェクトに新しいWindowsフォームを追加してテストツールから直接貼り込むという方法)を使って決めた.一つだけ問題がある.VBのプロジェクト→参照の追加→COMでバージョンの異なるOCXが独立に表示されるようにはなったが,一つのOCXをチェックすると同時に複数のコンポーネントにチェックが入ってしまう.これはおそらく同じ名前のモジュールを作っているためと思われるが,もう少し落ち着いてから対処する.

オリジナル版ではループを一度で抜けている.重婚同類グラフ検定の出口ではmulticountはまだ50のままだが,事後処理のTribeGhostNameで19まで減少し,BetweenTwoWomenで残りを一掃している.今回の修正は重婚同類グラフ検定でそれ以外の部分には影響はないはずなのだが,何かしら副作用が出ているのではないか?TribeGhostNameでは「系列枠の範囲内で消去可能な仮ノードを消去する」処理を実行している.ここでは天皇系列だけで仮ノードを60個消去している.

一方の修正版では50→23→7→13→7→13→7→13…を繰り返して結局13でブレークする.TribeGhostNameでは23点になり.次のBetweenTwoWomenで7まで減少するが,MakePairListCleanで13に戻って以下同じパターンを繰り返す.TribeGhostNameではEraseGhostNameで可視の人名ノードを対象に消去を試みている.これがうまく動作していないものと思われる.最初のループでTribeGhostNameは28個の仮ノードを消去している.オリジナルでは31個消去しているが,その差はそれほど大きくはない.

修正版ではTRIBEBOX::adjustGenerationRangeで「先祖ノードが系列世代範囲を逸脱」が起きている.オリジナルでは起きていない.この差異が大きいのではないか?問題が起きているのは蘇我倉麻呂系列と藤原不比等系列,つまり天皇系列以外はすべてということになる.この関数はmin=28, max=31で呼び出されている.なぜだろう?オリジナルではこの関数では天皇系列しか処理されていない.TRIBELIST::ShiftDirectAbsoluteの絶対世代番号不一致→カードシフトでsc=54までは歩調を揃えているが,そのあとから大幅に狂い始める.

これはTribeRelocationのステージ【5.1】絶対世代番号に基づいてカードシフトで重婚同類グラフ検定のメインの処理に当たる.オリジナルではsc=79まで停止しないが,修正版ではsc=58で停止する.この処理は多重グラフ1の連結リストをベースに実行されている.これはハッセ図ではなく,最初の多重グラフ1ができそこなっているのではないか?多重グラフ1はいわゆる重婚同類グラフで,子どもないし配偶者のいない単身者は対象から除外されている.まず,このグラフを比較してみよう.目視で追いかけるより,グラフをダンプしてそれをファイルに格納し,WinMergeで比較するというのが一番速いのではないか?

グラフ1のノードは人名カード,枝は配偶関係で,連結リストには重婚多重集合のリストが生成されている.グラフとしては完全に一致している.それではなぜ動作に差異が見られるのか?⇒どうもフローが少し違うのではないかという気がする.TRIBELIST::ShiftDirectAbsoluteでscount=58のとき停止しているが,オリジナルは五百城入彦皇子で停止し,修正版ではその次の仲哀天皇で停止している.COMPLIST:DumpComplistのscountは前者が59に対し,後者は61だ.両道入姫で絶対世代番号不一致→カードシフトが発生したときにオリジナルではNAMEBOX::ShiftGenerationで余分なダンプが出ている.

修正版ではAbsoluteGeneGapが真になったため復帰している.なるほど原因は分かった.やはり,一箇所手抜きしたところだ.この関数では!getnodegeneが未設定の間は偽で復帰するようになっていたが,現行の人名枠オブジェクトはnodegeneを持っていないため通常処理して真を返しているものと思われる.TestAbsoluteGenerationでは人名枠のnodegeneを設定しているが,この処理全体がコメントアウトされている.AbsoluteGeneGapを呼び出しているのはCardShiftDirectだけだ.CardShiftDirectを呼び出しているのはShiftDirectAbsoluteはこの位置から呼び出されるのが唯一の出現だ.

!解決した!TOPOLOGY::CountMultiCardが11回しか呼び出されていないということは超速で収束しているという意味だ.最も頻繁に呼び出されている関数の中からMARGBOX::GetUpperNodeを選んで実行カウントを数えてみよう.⇒ダンプの量が多過ぎて一晩では終わらないかもしれない.どこかにグローバル変数を作ってカウントした方がよいかもしれない.⇒いや,完了した.修正版の呼び出し回数は2,156,353回だ.200万回以上実行されている.オリヂナル版のカウントとも正確に一致する.これで2つのバージョンの互換性はほぼ確証できたと言えるだろう.(不一致の可能性は10^6分の1以下とみてよい)

結論的にはAbsoluteGeneGapという関数はまったく不用だったということになる.NAMEBOXだけでなく,MARGBOXのgenenodeも不用なのではないかと思っているのだがどうだろう?⇒これはまた明日ということにしておこう.現状で天皇家を描画するまでに4.7秒くらい掛かっている.渋沢で6秒だ.⇒渋沢でTightenHasseDiagramを実行中MINMOV不定で停止した.このサンプルは避けられない多重が6あるのでやむを得ないものと思われる.いや,渋沢ではなく源氏だった.

パソコンと一緒にお菓子が入ってましたよ~

WinMergeを使って全ソースファイルの比較検査を行ったところ,ミスがぼろぼろ出てきた.⇒修正を入れて,少なくとも旧版の部分は復元できた.あとはこれをデバッグするしかない.バックアップを取ってから始めることにしよう.修正箇所にはすべて「NODULE:nodegeneをBobjectに移管する@20201020」が入っているので,この部分だけ検査すればよいはずだ.まず,複数クラスに新たに追加した変数nodegeneをコンストラクタで初期化しておいた方がよい.対象クラスはCARDLINK, MARGBOX, COMPLISTだけだ.

tamo2さんからVAIO ノートパソコンが届いた.パソコンと一緒にお菓子まで!パッキングするときはお菓子を詰めましょう!

Version 1.9.9.99が走っていると聞いたのでてっきり32ビット機と思っていたが,64ビット機だった.ほとんど新品同様!RAM 8MB, HD 100Gもあるのでサブマシンとして使っているタブレットの2倍のキャパがある.このタブレットはときどき電源が入らなくなったり,かなり不安定なところがあるのでバックアップ機になりそうだ. ゼルコバの木ベータ2では新しいバージョンで作ったサンプルは読めないので,古いサンプルを探してみよう.2013年頃のサンプルならかなりあるのだが,Version 1.9.9.99をリリースしたのは2012年の3月だ.サイトのバックアップにはかなり古いものがあり,その中にもサンプルがある.

外付けHDのバックアップにあるZelkova Shootsフォルダにはアルファ版のサンプルまで入っている.tamo2さんはすでに1万件に近いデータを入力されているゼルコバの木の最強ユーザだが,ずっとVersion 1.9.9.99を使われているので,いよいよとなればZELファイルの入ったフォルダを一括コンバージョンできるようなツールが必要かもしれない.ちょっと厄介な問題が出てきた.これまではまったく意識されてこなかった点だが,どうもmsiインストーラでインストールされたプログラムはインストール元のmsiと紐付けされているのではないだろうか?

tamo2さんから送られてきたノートにはあらかじめゼルコバの木ベータ2がインストールされていて起動できることも確認してあるが,別のログインアカウントを作ってそこから開こうとすると,msiのファイルを探す動作になってしまう.ゼルコバの木ベータ2のアイコンは新しく作ったアカウントのデスクトップにもあって使える状態にはなっているのだが,起動できない.実行しようとすると以下のようなパネルが出る.

image

このmsiインストーラのコピーをデスクトップ上に置いて,「ソースを使用」ボックスに入力してOKを実行すると,

image

のようなメッセージが出て「致命的なエラー」で終わってしまう.もし,ここでこの新しいユーザがこのアプリをアンインストールした場合,元のユーザはどうなってしまうのだろう?常識的に考えれば元のユーザはこれまで通り使えなくてはおかしいということになると思われるのだが…アンインストールは簡単だが,それをやってもし元のユーザからも使えなくなると元も子もなくなってしまう.ともかく,別のマシンを使ってVer 1.9.9.99が任意の64ビット機にインストール可能であることを確認しておこう.このマシンには一度もインストールしたことがないので試してみることにしよう.⇒ダメだ.

image

どこが違うのだろう?tamo2氏のノートはCPUはIntel Core 13-3227U でOSはWindows 10 Home 2004 64ビットだ.OSのインストール日付は2020/08/09なのでつい最近インストールされているみたいだが…コメントを読み直してみると,Windows 8から10にアップデートしたとあるので,Windows 8の時期にインストールされたものと思われる.しかし,Windows XPでも64ビット版があるくらいなのだから,このWindows 8も64ビットOSだったのではないだろうか?だとしたら,プラットフォーム的にはそれほど隔たりはないはずなのだが…

いずれにしても,このマシンでいまこのアプリをアンインストールすると再インストールできなくなる可能性はかなり高いような気がする.もちろん,ゼルコバの木の新しいバージョンなら問題なくインストールできるはずだし,新しいバージョンのゼルコバの木は古いバージョンの系図ファイルも読むことができる.新しいユーザでアンインストールしても古いユーザはアプリにアクセスできるというのなら,新しいアカウントで再インストールを試すこともできるが,失敗するとゼルコバの木ベータが走る64ビットの貴重な参照マシンを失うことになりかねない.

インストール時に「すべてのユーザ」ではなく「このユーザのみ」としておけばこのような事態にはなっていなかったと思われるが,デフォルトで「すべてのユーザ」となっているのでそうするのが普通だろう.新しいユーザでアンインストールして古いユーザが使えなくなるとすれば,それはマイクロソフトの「過失」に当たるとは思われるが,インストールに関してはあらゆるところでトラブルが発生しているので,到底安心してお任せという訳にはゆかない…

このマシンにインストールされている版のバージョンが確定した.バージョンは1.9.9.99だが,このバージョン番号を持ったリリースはある事情から複数存在する.そのうち,この版は2012年3月26日にビルドされた版だ.これはインストーラのサイズ4,235,264バイトおよび,ライセンスコードのMNERKEGが一致することにより特定された.なるほど,だいぶ実情が分かってきた.このバージョンはネット上で公開されていたものと思われるので,「公開版」と呼ぶことにしよう.

これまでの所内テストではゼルコバの木ベータないし,32ビット環境で構築されたバージョンは64ビット環境では動かないものと決めつけてきたが,tamo2氏からお送り頂いた実証機によってそうではないということが確証できた.確かにVer1.9.9.99のリリース版は64ビット機にインストールできないが,実際には「実行可能」であることが明らかになった.つまり,インストールするのではなく,直接EXEのアイコンを叩いて起動してやれば何の問題もなく動作する.

結局,マイクロソフトはややこしい(飛び切りスマートな)ことをやりながら,動作するものを動作させないということをやってきただけということになる.妨害行為とまでは呼ばないが,事実上それに近いと言ってはばからない.その結果バカバカしいことでバカバカしいほどの時間の空費が発生しているのだから…ひどい話だね~

これで問題は一つ片付いた.つまり,32ビット版は64ビット機上で動くということが発見された.32ビット版が64ビット機にインストールできないのはやむを得ないとしても,それが「使える」ことが分かればかなり救われる.これで残る問題は「64ビット機で開発した版を32ビット機上で走らせることができるか?」という問題に絞り込まれた.原理的に言えば「動いて当然,動かなければおかしい」ということになるが,いまのところ32ビット機というのは手元にないので確認できない.

ようやく動き始めたが,多重が13件も出ている.1点だけ見てみよう.

image

上の2つのカードの位置(世代)を厳密に一致させなければ多重は解消しない.そのような箇所が13箇所もある.これだけ見ても天皇家系図を多重カードゼロで描画するのが如何に困難かご想像頂けると思う.

マイクロソフトが系図作成ソフトを販売!

マイクロソフトが系図作成ソフトを販売している!やられたかな?開発元はIW Technologies LLCという(怪しい)ところで多分2011年にはすでに発売されていたのではないかと推定される.販売価格580円!価格的にはゼルコバの木に勝ち目はないが,スクリーンショットで見ると下図のようなシンプルなものなので,まだ当分の間リードを保つことはできるだろう.お手頃価格なので当所の財政でも購入可能だが,評価はもう少し手が空いたときにやることにしよう.

image

いや,これは「マイクロソフトストア」で販売しているというだけでマイクロソフトが開発したものではない.この手の系図作成ソフトは掃いて捨てるほど存在する.昨日見たのはこれではなかったような気がする.Windows 10の新機能というポップアップから誘導されたところにあったと思う.⇒出てきた!この画面だ.

Family history and occasions

image

よく見るとこれらはすべて「テンプレート」だ.つまり,Excel, Word, PowerPointなどを使ってこれくらいのことができますというお手本.確かにこれは頭のよいやり方かもしれない.特別な系図作成ソフトを使わなくてもそれなりに見栄えのするコンパクトな系図図面が出力できるというのは結構需要がありそうだ.「Buy Microsoft 365」というボタンが表示されている.Microsoft 365はサブスクリプションで個人用でも年間1万3千円掛かる.確かにOfficeは有用なアプリなのでそのくらいの値打ちはあるかもしれない…こういう汎用性(なんでもできるという万能感)のあるソフトというのはわたしの好みだ.

Shirley(ミニノート)へのVisual Studio 2017のインストールは完了している.ツール→拡張機能と更新プログラムでMicrosoft Visual Studio Installer Projectsをインストールしてからソリューションを読み込んだところ,VBを除く3つのプロジェクトがすべて(利用不可)になってしまった.これはエンタープライズ版を立ち上げたときと同じ状況だ.32ビットCPU機のShirleyにVisual Studio 2017をインストールすること自体は成功しているので,64ビット機(のVS2017)で構成したプロジェクトは32ビット機(のVS2017)環境では動作しないということになる.32ビット環境でプロジェクトを構築し直せば多分使えるものができるのではないかと思われるが,手が掛かりそうなのでしばらくは置くことにして本線に戻ることにしよう.

天皇家で垂線がブツブツに切れているという問題がある.これほど「派手な不具合」が長期間見過ごされてきたということは考え辛いので,VS2017に移行したことによって発現した不良であると考えてよいのではないかと思っているが,真偽のほどはいまのところわからない.バージョンパネルやカード画面の下部が切れてしまうという事象もVS2017で初めて起きていると考えられるのでVisual Studioの生成するコードに何らかの変異が起きていると考える方が素直なのではないかと思う.

描画がこの程度に壊れていれば目視で確認することも容易だが,ごく一部の線分が切れていたりなどのことがあったとすれば見落としてしまうこともあり得る.正しく描画できているか否かの検査は目視で行うしかないが,テストサンプルは膨大でしかも包括テスト中はめまぐるしい速度で画面が更新されるのでその中で不良を目視で発見するというのはかなり難しい.ここから目視に頼るのではなく,論理的に不良を検出できるようにしておくべきだという教訓を得て,線分の接続関係をグラフの連結性の問題として抽象化するという方針を立てた.

作業は順調に進んでいるが,テスト環境を構築する前に昨日提示した2つの改善項目を片付けてしまうことにする.実際これらを片付けてしまわないと思わぬところで不測の事態が発生するリスクがあるので先行して解決しておかなくてはならない.課題は2つあるが,分節すると,①SIMPLENODEにリスト構成用のスロットを増設する,②LISTクラスを拡張して任意のスロットを用いたリストを構成できるようにする,③NODULE::nodegeneをSIMPLENODEに移管する,④nodegeneを参照しているタスクでは枝グラフ生成時に値を設定するのようになる.

このうち①,②,③は比較的簡単な話だが,④については少し考えておく必要がある.有限半集合を推移簡約表示したものというのがハッセ図の定義だが,ここで使っているハッセ図という用語はもう少し特殊なものだ.系図は親子関係を半順序関係とする有向非循環グラフと考えることができるから,それを推移的に簡約した配置を求めることが系図作成のための図法であると言ってもよい.ゼルコバの木では結婚枠ないし人名枠を「世代」によって階層表示しているので,平面描画可能なハッセ図を生成するためにはどうしても世代を考慮しなくてはならない.

重婚同類循環グラフ検定では重婚同類グラフ1, 2, 3という3つの枝グラフを使用している.ここでハッセ図と呼んでいるものは内部的には重婚同類グラフ2と呼ばれるものに等しい.この処理をアプリケーションから切り離して完全に抽象化するというのは難しいというより不可能と考えられるが,SIMPLEEDGEには類似概念としてgenerationというのを扱っているので,これがどういう動作になっているのかを見てみたい.generation→_generationと改名して出現箇所をチェックしてみる.

この値は,SIMPLEGRAPH::addで設定されているが,参照されている気配がない.おそらく「このパラメータは現在使われておりません」という状態になっているものと思われる.不用なものが入っているのは望ましくないので廃止しておこう.「SIMPLEEDGE_generationを廃止@20201020」を定義してコンパイルオプションで切り分けることにする.⇒廃止した.ここで一応バックアップを取っておこう.さて,nodegeneをSIMPLENODEに移すことができるかどうかを見ることにしよう.問題はこのパラメータをどこで設定しているか?にある.

この値は基本的にハッセ図を扱うところでしか参照されていないのではないかと思うのだが…⇒値はnodule::setnodegeneで設定されている.初期値0を与えているところを除外すると,以下の関数でsetnodegeneが呼び出されている.

  1. NAMEBOX::MakeExtractBox
  2. TOPOLOGY::TestInevitableMultiZeroのステージ【18】
  3. TRIBELIST::AdjustTribeGeneration
  4. SIMPLEGRAPH::TightenHasseDiagramのステージ【7】
  5. SIMPLEGRAPH::DownStreamHasse 3箇所
  6. SIMPLEGRAPH::UpStreamHasse
  7. TREEVIEW::UpdateDiagram

setnodegeneの逆関数getnodegeneの出現箇所を見てみると68箇所もある.ファイル単位ではInevitableMultiCard.cpp,Potential.cpp(検査用),SimpleGraph.cppの3本で基本的には枝グラフ処理の内部処理ないしその関連と考えられる.

TestInevitableMultiZeroとAdjustTribeGenerationはTRIBELISTのTribeRelocationの中で一回だけ実施される.前者はステージ【5】重婚同類グラフ検定,後者は【5.1】で実施されている.UpdateDiagramは描画フェーズの中でしか実行されないので,操作不要と思われる.SIMPLEGRAPHクラスの関数ではすでにグラフは生成済であるはずだから,内部の値を参照することは可能と考えられる.つまり,nodegeneはTribeRelocationの中で設定され,グラフ検定の内部で操作されているものと推定される.重婚同類グラフ検定の概略手順は,

  1. TOPOLOGY::TestInevitableMultiZero
  2. TOPOLOGY::VerticallyTightenHasseDiagram
  3. TRIBELIST::AdjustTribeGeneration

のようになっていると見てよい.MakeHasseDiagramは最初のTestInevitableMultiZeroの中で実行されているので,少なくともnodegeneのスコープは重婚同類グラフ検定中と見て間違いないと思われる.ただし,最後のAdjustTribeGenerationはグラフ検定によって決定されたnodegene(絶対世代番号)に従って構成要素の再配置を実施しているはずなので,この時期までは関係する枝グラフが存続していなくてはならないと考えられる.しかし,その修正を一時に導入するというのはリスクが高過ぎる.nodegeneが必要となるオブジェクトはCARDBOXとMARGBOXだけなのだから,むしろその上位クラスであるBobjectに預けるというのが順当なのではないだろうか?

HasseDiagramに関連する関数はSIMPLEGRAPHのクラスメンバーということになっているが,ここで扱っている図式は数学的に定義された純粋なハッセ図ではなくむしろその応用と考えるべきであり,その意味ではこれらの関数が応用クラスであるBobjectを参照しなくてはならないという構成の方がより論理的であるように思われる.つまり,SIMPLENODEにnodegeneを持たせるという仕様はSIMPLEGRAPHに不純な要素を持ち込むということに他ならない.これで方針は決まった.

tamo2さんからコメントが入っていた.i5のVAIOノートを送って下さるという.このパソコンではゼルコバの木ver.1.99999が走っているという.ありがたい!これがあれば鬼に金棒だ.さて,修正に取り掛かることにしよう.③と④は③’NODULE::nodegeneをBobjectに移管するということになる.この修正はキャストをちょこっと直すだけだから,すぐにでも終わる.「NODULE:nodegeneをBobjectに移管する@20201020」を定義した.

まずい.一つ勘違いしていた.CARDBOXではなくCARDLINKだ.CARDLINKの親はnoduleでBobjectではない.ではMARGBOXはどうなるのか?少し混乱があるような気がする.いずれにしてもCARLDINKとCARDBOXの対応は1対多だが,MARGBOXとMARGLINKの対応は1対1だから,このまま進めることにしよう.やや変則的になるが,CARDLINKとMARGBOXの両方にnodegeneを置いてみる.

少しややこしい話になってきた.COMPLISTでもnodegeneを使っている.なぜだろう?COMPLISTというのはグラフの連結成分リストで純グラフ理論的なオブジェクトであるはずなのだが…どこかで必要になるのだろうか?かなり面倒くさい話だが,現在のロジックを壊す訳にはゆかないので,COMPLISTにもnodegeneを持たせるしかない.これでは結局SIMPLEGRAPHの内部に外部要素を抱え込むことになってしまうのだが…NAMEBOXでもnodegeneが存在することを予定したコードがある.この論理は少しおかしいのでコメントアウトしておく.場所はNAMEBOX::AbsoluteGeneGapだ.

Dドライブの空き容量がゼロになってしまった.Eドライブにはまだ151GBの余裕があるので少し空けてみよう.バックアップフォルダはZELKOVA_2021とする.テストサンプルも相当大きいのでCドライブに移すことにしよう.⇒エクスプローラのドライブの残量表示バーがすべて青になった.Dドライブは37GBの空き,Cは64GB,Eが129GB,外付けのGが926GBとそれぞれ適当な空き領域を持っている.これだけあれば,しばらく遊べるだろう.

CARDLINKにはcleanという関数がないのだが,いいのだろうか?MARGBOXにはある…TESTABSOLUTEGENERATIONというオプションは一時的に止めておくことにする.⇒どうも訳が分からなくなってきた.nodelist の中にCOMPLISTが入っている.どういうことになっているのだろう?「予定が狂った」というのはこのことだ.nodelistには181個のノードが入っている.⇒ハッセ図を扱っている重婚同類グラフ2の節点はCOMPLISTだ.これはキャストをCARDLINKからCOMPLISTに変えれば対応できる.

どうもどこか壊してしまったようだ.SIMPLEGRAPH:TightenHasseDiagramのステージ【7】移動対象となる人名リンクの絶対世代番号を設定するで停止してしまう.(MINMOV == _INT_MAX)になっている.ループの中ではまともな値を取っているのにループ外にでて突然初期値の_INT_MAXに戻ってしまっている.マネージド デバッグ アシスタント ‘ContextSwitchDeadlock’ という障害まで起きている.確かにどこかでハングしているような気配はある.⇒一度開発機を再起動してみよう.

デバッグアシスタントでは止まらなくなったが,状況は変わらない.「SIMPLENODEsLINKを廃止@20201019」をオフにして動作を確認してみよう.⇒やはり同じだ.つまり,どこかを不用意に壊してしまったということのようだ.一度バックアップに戻るしかないが,バックアップが動作していることをまず確認する必要がある.⇒確かにこの版はまともに動いている.WinMergeをインストールして比較してみよう.

  1. nodule::getnodegeneとsetnodegeneがコンパイルオプションを付けずにまるごと削除されている⇒ただし,このコードはRingLink.cppに移されている.
  2. SimpleGraph.cppのSIMPLEGRAPH::TightenHasseDiagramでコンパイルオプションがネストしているところで記述を誤っている⇒ただし,このコードは検査用コドなので動作には関係しない
  3. ...

抽象グラフ検証系を汎用化する

大失敗!Shirley(ミニノート)にインストールしたVisual Studio が不調なので,一旦アンインストールした後,再インストールを一晩掛けて実施したが,無料版のVisual Studio Communityをインストールしたつもりで,Enterprise版をインストールしてしまった.Enterprise版は30万円もする上,既存プロジェクトが「利用不可」になってしまう.これをアンインストールするだけで1時間くらい掛かりそうだ.

親子連結線の途切れを自動検出するためグラフ理論を応用したツールを作成することを意図しているが,すでに実装済の抽象グラフ検証系の仕様を調べておこう.ゼルコバの木では以下のような検定グラフをグラフ検証系の応用として実装している.

  1. 逆転循環検出枝グラフ
  2. 血統軸線図用枝グラフ
  3. 系列木グラフ枝グラフ
  4. 重婚同類グラフ1
  5. 重婚同類グラフ2
  6. 重婚同類グラフ3

これらはすべてSIMPLEGRAPH(検定用枝グラフ)として実装されている.SIMPLEGRAPHは①NODELIST,②EDGELIST,③COMPLISTを管理している.NODELISTはグラフの頂点集合,EDGELISTは辺集合,③COMPLISTは連結成分集合を意味するものと思われる.SIMPLEGRAPHの特徴はグラフの頂点としてシステム上の任意のオブジェクト(NODULE)を参照できるという点だ.NODELISTはSIMPLENODEのリストでSIMPLENODEはnoduleを参照している.EDGELISTはSIMPLEEDGEのリストでSIMPLEEDGEは辺の端点を示す2つのSIMPLENODEを参照している.

構想しているグラフを親子関係グラフと呼ぶことにしよう.親子関係グラフの節点は線分の端点であり,枝は線分そのものと考えられる.線分を描画する関数には用途によって各種ある.これらの描画仮数を呼び出すタイミングでグラフが生成されなくてはならないが,これはかなり難しい.描画関数は単純にディスプレイに描画を実行するための外部関数であり,システム内のオブジェクトとはまったく無関係だ.現行ではSIMPLENODE::linkにはnoduleポインタを格納することになっているが,これをvoidポインタに変更可能かどうか調べてみよう.

検定用枝グラフは基本的に対象システムを上から俯瞰するようになっていて,対象システムにはいかなる副作用も与えないことになっているのだから,参照先オブジェクトは必ずしもNODULEでなくても動作しなくてはならないはずだ.⇒この修正は比較的簡単に行えるが一つ問題が出てきた.連結成分の検査に用いているCOMPLISTは対象オブジェクトを直接参照するリストになっている.リスト操作は一般にノードのSLOTZEROを用いて構成されているが,SIMPLENODEはそれ自体リストを構成しているので,SLOTZEROが使えないようになっているためではないかと推定される.しかし,この構成はやや問題があると言わなくてはならない.グラフ検証系が一般的に活用される段階では対象オブジェクトがSLOTZEROを使っている可能性は十分あり得るからだ.

class NODELIST : public NLIST<SIMPLENODE, ‘V’>

どうすればよいか?SIMPLENODEに連結成分リスト用のスロットを設けることが考えられる.既存のリングないしリグという構成が使えるのではないか?   デバッグ用増設スロットというものもある.

  1. WASHING –4 UNDOシステムでオブジェクトの再生に用いる特殊枝番
  2. SEIZEGROUND -3    アンカー接続:ポインタはメモリ上のセルに格納
  3. XPAND_ANCHOR -2    デバッグ用増設スロットを示すスロット番号
  4. EXTRA_ANCHOR -1    増設スロットを示すスロット番号

これらのスロット番号が負の値を取っているというところが不気味なところだ.実装者であるわたしでさえ想像つかない…親子関係グラフと夫婦関係グラフを合わせて結婚関係グラフと呼ぶことにしよう.系図木というのは究極のところ結婚木であり,婚姻関係図であると考えられる.結婚関係グラフがデバッグ時にのみ使われるものであるのなら,デバッグ用増設スロットを使うことも考えられるが,場合によっては拡張されたリリースバージョンでも使われるようになる可能性は十分考えられるので正規のスロットを定義しておいた方がよいように思われる.

リング参照リンクという構成が実装されている.これは「環状リスト用の汎用双方向参照」をサポートするためのもので,描画オブジェクトクラスでは2種のリングが使われている.一つは結婚枠衝突検定用結婚枠リング,もう一つは極大グラフ検定用セグメントリングだ.このクラスにはスロットを3つないし4つ使ったグループ参照リストも組み込まれているが,これらは汎用的な処理とはなっていない.現行のリスト処理はLISTクラスを基本クラスとするものでNLISTはその派生型だが,これを任意のスロットを用いる形式に仕様変更するのもかなり厄介だ.

COMPLISTはNLISTの派生型なのでここではキャストを用いて逃げておくことにしよう.クラスCOMPLISTの他にSIMPLEGRAPHでもlinkがnoduleであることを仮定している以下のような操作がある.MakeHasseDiagram,TightenHasseDiagram,DownStreamHasse,UpStreamHasse,RemoveRedundantEdge.これらはすべてNODULE::nodegene(絶対世代番号)を参照しているものだが,NODULEクラスの汎用性を考えるとこのパラメータをNODULEのメンバーとしておくことには問題がある.

しかし,その前にlinkを汎用ポインタでアクセスできるようにするためには,まずこのリンクを固有データ域に移す必要がある.実際,この状態で走らせるとGENEBOX::CheckInverseCycleでSIMPLEGRAPHを初期化しただけで落ちてしまう.

SIMPLENODEsLINKを廃止する必要がある.「SIMPLENODEsLINKを廃止@20201019」を定義して切り分けるようにしておこう.TestSimpleGraphはコメントアウトした.「SIMPLENODEsLINKを廃止@20201019」の両面で動作することを確認した.アプリ終了時に64バイトのメモリリークが出ているが,これは既存コードでも同じであり,以前から存在する事象と考えられる.

これで一応オブジェクトを含め「なんでも」グラフ検定の対象とすることができるようになった.たとえば,描画関数で線分を描画するとき,端点情報をどこかに保管できるようにしておけば,それだけで検証用の枝グラフを生成することが可能だ.ただし,その先は少々難しい.

◎COMPLISTは対象オブジェクトのSLOTZEROを使って連結成分リストを構成しているが,SIMPLEGRAPHを完全に抽象化するためにはオブジェクトから完全に分離する必要がある.SIMPLENODEにリスト構成用スロットを一つ設けるのがよいのではないか?任意のスロット番号を指定してリストを構成するようにLISTクラスを拡張するのは新たに組み込みで特殊リスト操作を付け加えるよりはるかに簡単なのではないか?現行ではSIMPLENODE::linkからオブジェクト以外の場所を参照することができるようになっているので,地雷を踏む危険性がある.

◎SIMPLEGRAPHで使っているnodegene(絶対世代番号)をNODULEのメンバ変数とすることには問題がある(一般性がない).この値がハッセ図を生成するために不可欠であるというのなら,SIMPLENODEに持たせた方がよい.実際,SIMPLEEDGEはgenerationという値を持っている.枝を生成する時点でアプリからnodegeneを設定するSIMPLENODEの関数を呼び出すようにすればよいのではないか?

上記はSIMPLEGRAPHの抽象化レベルを高める上での必須項目である.

どうもはかばかしい進捗がない

どうもはかばかしい進捗がない.Shirley(VAIO 4インチミニノート)はむちゃくちゃ遅いし,Tamoz(3インチタブレット)はタッチペンを使わないと誤動作するくらい文字が小さい.Tamozはそこそこ動いてくれるが,唯一の32bitCPUマシンであるShirleyは泣きたくなるほど遅い.どこかで中古品を見つけてきたいくらいだがともかく辛抱して使うしかない.32bit/64bitというのが問題になっているが,一つ勘違いしていたことがある.32/64という区別はOSの場合とCPUの場合があるという点だ.つまり,32ビット機と言ってもOSが32ビットでCPU64ビットということがある.64ビット機というのは概ねOS64ビット,CPU62ビットと考えて間違いないと思われるが…

これまで確認した限りではVisual Studio 2017でビルドしたパッケージはCPU62ビット機では「ソリューションプラットフォーム」の設定如何に関わらず動作するが,CPU32ビット機では「ソリューションプラットフォーム」の設定如何に関わらず動作しないという状態になっているように思われる.この点を確認するためにはどうしてもCPU32ビット機というのが必要になってくるが,現状唯一のCPU32ビット機であるShirleyは遅過ぎてほとんど使いものにならないというレベルだ.タスクマネージャで不要と思われるバックグラウンドタスクをいくつか殺してみたが,あまり効果はなかった.姉貴の旦那が持っているノートを貸してもらうということも考えてみたが,このノートのOSは多分Windows 7のはずだが、CPUは64ビットである可能性が高い.

今後は32ビット機というときはCPU32ビットのPCを指すものとし,32ビットOSを意味する場合には明示的に示すことにする.(これは通常の用語と少し違うかもしれない…)ShirleyにはVS2017をインストールしてあるが,コンポーネントが不足しているため満足な動作になっていない.Visual Basicに関わるコンポーネントを改めてダウンロードしてインストールしてみたが,どうもまだ思わしくないところがある.Visual Studio 2017自体は32ビットアプリケーションなので32ビット機でも64ビット機でも同様に動作しなくてはならないはずなのだが…

image
Windows Formの追加で新しい項目の追加が開いてしまう

インストールを妨げる要因として,.NETのバージョンが合わない(必要なバージョンがインストールされていない)場合と,C++がインストールされていない場合がある.必要な.NETがインストールされていても「有効化」されていないと同じようなエラーになる.このような場合はMSからダウンロードしても「すでにインストールされています」と言って弾かれてしまう.ランタイムをMSサイトからダウンロードするsetup.exeも失敗することがある.

Windows 10タブレットは前から使っているが,2 in 1 ノートで通常はキーボード付きで使っているため,キーボードのないタブレット上でゼルコバの木がどのような挙動を示すかという点に関してはほとんど知らなかった.今回tamozさんのタブレット上でZTを起動して初めてかなり悲惨なことになっていることに気付いたが,この辺りはすでに相当昔にkamui氏から指摘されていたところだ.「タッチ操作」をサポートすることはもはや喫緊の課題になっている.

作戦タイムが必要だ.ここでは一旦開始点まで退却するしかないのではないだろうか?つまり,「当面はターゲットを64ビット Windows 10 搭載機に限定する」という当初方針だ.この条件ならインストール可能なバージョンはすでに確保されている.あとはリリース可能な程度までデバッグするだけだ.ここでこれ以上深入りしていたら持ち時間を使い切ってしまう可能性がある.実際,天皇家系図だけでも相当な不具合が生じているのでまずこれを片付けないことにはお話にならない.

ShirleyではVSを一度アンインストールしてもう一度今度はVisual Studio 2017をフルインストールしてみることにする.どのくらい時間が掛かるかわからないが,放置しておけばよいので作業の妨げにはならない.タブレットTamozは32ビットOS(CPU64ビット)だが,64ビットOSのメイン機とまったく同じ動作になっているので動作上の問題はない.「タッチ操作」は「次期課題」としておこう.

Semalt.com によるリファラスパムを遮断する方法

デスクトップ上にはこれまでのランニングテストで発生した障害ファイルが11本もある.まず,これを片付けておこう.⇒いや,特に問題なくすべて開ける.おそらくリリース版でSTOP文が残っているバージョンがあったのだろう.もうひとつ気になっているのは,ヘルプ画面の下の方が切れているという不良だ.

image

デザイン画面ではもちろんこんな風にはなっていない.このパネルは最前面に表示されるフロートパネルでサイズ変更はできないから,レイアウトの計算などは一切行っていないはずなのだが…MaximumSizeとMinimumSizeを固定したら,とりあえず画面が切れることはなくなった.ただし,デザイン画面とはレイアウトが微妙に異なる…高さはほぼ一致するが,横幅がかなり詰まっている.おそらくそのためではないかと思われるが,フォントが少しぼやけて見える※.Max, Minをデフォルトに戻した場合は縦横ともに均等に縮小する.どういうことだろう?

※これは画面を解像度の高い(ピクセルサイズの小さい)モニターから低いモニターにドラッグ移動して比較しているためではないか?

カード画面もデザインより縦横ともに詰まっている.ただし,横幅の方が少し縮み方は大きい.カード画面は可変サイズなので調整すればデザインとほぼ同等の見え方にはなる.ファイルを開き直したとき,系図画面は前回と同じサイズ・位置に表示されるが,カード画面は位置は同じでもサイズは標準のサイズに戻される.タイトル枠設定画面も可変サイズだが再起動時には標準サイズに戻される.手動で変更したサイズと標準サイズはボタンで切り替えできるので,仕様的にはこれでもよいのかもしれないが,使い勝手からは閉じたときの画面がそのまま表示された方がよいような気がする.

▲表示→タイトル枠表示で系図画面にタイトルの表示/非表示を切り替えるようになっているが,違和感がある.ここは表示→タイトル枠設定画面を表示ではないだろうか?この場合はタイトル枠設定タブがタイトル情報タブより先に来るべきだろう.

描画処理系では座標・サイズとも物理単位(ピクセル)で操作しているが,元々のプロトタイプでTwipという単位を使っていたため保存数値はTwipになっている.Twipは絶対単位で1Twip=1/20ポイント=1/1440インチ=0.01763888mm=17.6μmに当たる.絶対単位では画面上のサイズと印刷出力のサイズは厳密に一致するが,ピクセルの場合はアスペクト比というものがあるため調整が必要になるという点に配慮したものだ.しかし,事実上ピクセルで扱った方がずっとわかり易いので現在ではTwipなどの単位はほとんど廃れてしまっているのではないだろうか?

Twip⇔ピクセルの変換でこれほど大きな誤差が出るとは考え難いので何か別な理由を考える必要がある.フォームのサイズはGetWorkingAreaという関数から取得しているが,この関数が返す値は「ディスプレィの作業領域」とされているので,タイトルバーなどの領域が除外されているのではないだろうか?⇒フォームのWidthとHeightを直接取り出しても同じ結果だ.デザイン画面ではSizeは554×381だが,ヘルプ画面のLoad関数の入口ではこの値は411×282に変わっている.およそ0.74くらいに縮小している.これから推測すると,静的なデザイン画面と実行時の内部(System.Drawing)では座標単位が違うような気がする.

LoadWndPostにも多少疑問はあるが動作は変化しないので,オリジナルに戻しておこう.いまのところ対処策としてはMaxとMinを固定するという方法しかない.ただし,この方法ではカード画面のように実行時に変化する画面を扱えない.カード画面も画面下部が少し切れている.

image

カード画面のデザイン時のサイズは695×476,Max=任意, Min=527×238となっている.カード画面サイズという関数でサイズをランタイムに決定しているが,既定値は現在516×370となっている.修正履歴的に変化しているのに対応していないのではないだろうか?⇒どうもますますわからなくなってきた.695×476を既定値とすると,下図のように下部に広い空白が生じてしまう.

image

この図面は縮小されているので実際にはもっと大きい.⇒原因がわからないので,暫定的に高さを調整して516×382としておこう.バージョンパネルはもうちょっと縦が詰まってもよいので554×371とする.

▲タモリんちで人名枠線なしのとき人名下部の垂線が人名描画域に越境している.

系図画面設定パネルはとりあえず問題なさそうだが,タイトル枠設定画面はすこしだけ下が切れている.プロパティ画面その他のパネルもサイズ的な問題はなさそうだ.系図画面設定パネルとタイトル枠設定画面の違いはFormBoderStyleで,前者はFixedDialog,後者はSizeableとなっている.タイトル枠設定画面もSizeableとすれば多少の難はあるが,文字が切れたりすることはなくなる.⇒これから言えることは,画面をサイズ変更可に設定すると,システム側で何か余分なことをしてくれるということのようだ.何をしているのかわからないが,ありがた迷惑だ.

タイトル枠設定画面はタイトル設定画面サイズという関数でサイズを決定している.SetupTitleSizeには既定値の516×370が入っている.これは正確にカード画面と同寸だ.というか,①カード画面,②系図画面設定,③タイトル枠設定の3つの画面は完全に同寸というのが元々の設計なのだが…現状ではタイトル枠設定画面は516×373という数字になった.しかし,奇妙なことにこれらの横幅は同じ値を取っているのに不揃いな林檎たちになっている.

調整すれば完全に同一サイズに「見える」ようにすることは可能とは思われるが,これは後日ということにしよう.タブレットで「タッチ操作」を実装しようとするときにはいずれこの辺りをみっちりやるしかなくなるはずなので…一応これで一番気になるところは調整できたことにして,現状で目につく最大の瑕疵である切れ切れの垂線の問題に移ることにしよう.かなりひどいことになっている.

image

何が原因かよくわからないがブツブツに切れてしまっている.この図面では多重カードは発生していないので,少数の先祖ノードを除けばほとんどすべてのノードには親からの垂線が入って来なくてはならない.途中で線分が切れていることをプログラム的に検出することは可能だろうか?各線分がオブジェクトとして管理されていればそれもそれほど難しい話ではないが,ゼルコバの木では描画出力はすべて描画関数によってディスプレイに直接描画されているため,事後に検査するというのはかなり難しい.しかし,今後このようなことが二度と起きないようにするためにはなんらかの検査関数を作ってチェックする必要がある.

系図図面は人名枠と水平線および垂直線から構成されるが,人名枠を1個の垂線とみなせば,かなり単純な線分の集合とみなすことができる.従って,グラフG(V, E)としてV={線分の端点},E={線分}からなるグラフを考えることができる.Vの部分集合p={人名枠線分の端点}とし,pに属する2つの点pとp’が「親子関係」にあるとき,pからp’に至る経路があるかどうかを探索すればよい.座標計算には誤差があり得るので完全一致できない場合には近傍探索でもよいが,むしろ誤差が発生する原因を追求する端緒としても活用できる.同様のことは夫婦関係についても言える.原則的に夫婦は同じ世代に属すると考えられるが世代差が出る場合もあり得るので同じ手法で一般的に解いた方がよい.

グラフ理論的なアルゴリズム(抽象グラフ検証系)はこれまでにもある程度実装しているので多分それほど難しくはないのではないかと思う.これはあくまで部外の検査であり,リリース版ではそこまでやる必要はないが,描画図形をオブジェクトとして扱えるようになると,たとえば線分をくリックしたときそれに接続する経路の全長をハイライトしたりなどのことができるので,その方向性も考えておく必要がある.さらには線分をクリックして選択→削除で(親子・夫婦)関係を切断したり,人名枠を2つ選択して関係付けなどの直観的操作も実装可能になる.