描画領域サイズオーバーの問題が片付いた

VAIO2に(一昨日)仕掛けてあった渋沢一族の完全木テストの結果がダンプされていたので記録しておこう.所要時間1時間57分となっているが,時計の針は少なくとも一周しているので26時間掛かっている.

包括テストI 完全木テストを完了しました.
ご協力ありがとうございました.

C:\Users\babalabo\Desktop\渋沢一族8.ZEL
サンプル点数: 829 経過時間:01:56:51 検定図面数: 7461面
計算時間:12.52 秒/面 99.81 ms/点 延べ点数: 935925点

描画領域サイズオーバーの問題が片付いた.かなりあちこち調整する必要があった.主な点を挙げてみると,

  1. ZoomListTool_SelectedIndexChanged SendKeys.Send(“{ENTER}”)を廃止し,SendKeys.Send(“{BACKSPACE}”)を実行する
  2. MDIForm_KeyDown Keys.EnterではSetZoomRateを実行し,Keys.BackではResetZoomRateを実行する
  3. SetZoomRate Zelkova1.ZoomSetを引数ZOOM_RESETで呼び出す
  4. ResetZoomRate Zelkova1.ZoomSetを引数ZOOM_NOMSGで呼び出す
  5. CZelkovaCtrl3::ZoomSet CtrlZoomSetの戻り値がERR_ZOOMOVERRANGEのときはActionCenteringを実行する
  6. CtrlZoomSet 引数がZOOM_RESETのときは,TreeView->OVERSIZEをリセット,ZOOM_NOMSGでは保持してZoomSetを実行する
  7. TREEVIEW::CheckDispSizeOver OVERSIZEがオンのときは,「この図面は~以上には拡大できません」の表示を抑制する
  8. TREEVIEW::LimitSizeOver 描画領域サイズオーバーが発生した場合には,OVERSIZEをオンにする
  9. TREEVIEW::Zoom OVERSIZEならERR_ZOOMOVERRANGEを返す
  10. TREEVIEW::ZoomIn,ZoomOut ZoomSetを呼び出す前にOVERSIZEをリセットする

要点は,①エラーコードERR_ZOOMOVERRANGEがアプリ側まで伝達されるように経路を整備(渡せないところではTREEVIEW::OVERSIZEを使う),②警告パネルが重複表示されるのを抑制,③ズーム倍率リストのテキスト変更でリターンキーが押された場合,④ズーム倍率リストのインデックスが変更された場合の動作を(外形的に)統一する.⑤エラーが発生した場合にズームタイマーを確実に止めるなど.コンボボックスのSelectedIndexChangedイベントをキャンセルできないという不都合に対処するために,キーイベントを送ってイベントハンドラで遅延処理するという仕掛けを作り込んだのは2017年頃のようだ.デバッグモードではこの操作が止めてあったため気付かなかった.

系図画面ないし一覧画面上での選択動作にいろいろと不具合がある.選択操作と部分図操作は切っても切れない関係があるので,正しく動いてくれないと甚だ都合が悪い.特に一覧画面上の動作が悪い.まず,最初に一覧画面上に表示されているレコード数をチェックできるようにしておこう.⇒ModeNameChangeの末尾で以下を実行するようにした.

CardTable.Text = TitleName + “ 《” + ModeName + “》” + “ ” + Str(CardTable.CardGridView.Rows.Count) + “点”

これでほとんどカバーできるようだ.数字も合っている.選択されているカードの数も出しておこう.CardGridView_SelectionChangedでModeNameChangeを実行するようにして同期が取れるようになった.

一覧画面上での選択操作は系図画面上の選択されたカードと同期している.また,カード画面に表示される主選択カードも同期している.問題は,系図画面上での操作が一覧画面に反映しないという点だ.カードが1点だけの場合は一覧画面にも反映される.また,選択解除も同期しているが,複数選択になるとまったくダメだ.

しかし,「まったくダメ」という訳でもない.入る場合と入らない場合がある.しかし,ほとんど入るという場合がない.親族図で複数選択して部分図に移動すると一覧画面でも複数選択になる場合がある.ただし,このとき部分図は無選択状態になっている.また,何かの拍子で選択が反転して「訳が分からない状態」になる場合もある.⇒渋沢一族ではサンプルが大き過ぎる.親族呼称図を使うことにしよう.

▲系図画面設定の動作がおかしい.結婚マークを表示する→ 人名枠線を表示するとして結婚点が下枠の高さに表示されてしまう.⇒ただし,この事象は再現しない.また,結婚マークを表示するをオン・オフしても画面に反映されない.

GetHasseDiagramの論理を見直し

岩崎彌次郎系列を選択して部分図に切り替えようとして,SIMPLEGRAPH:GetHasseDiagramで停止した.この関数を呼び出すときの引数seedが空になっている.⇒SIMPLENODE::AddOyakoEdaで枝が生成されていない.⇒「系列分解図の場合は始系列のみ処理する@20171125」となっている.これはかなりまずい.クラスタ図は婚姻と親子関係だけで構成されるので,「系列」は無関係のはずだ.

いや,そういう訳にもゆかない.確定世代番号を得ることがクラスタ図の目的だが,系列間の結婚によってそれが歪められてしまう.かなり厄介な話になってきた.系列分解図の場合は重婚クラスタ検定はパスするというのが現実的であるような気がするが,この問題は棚上げして,部分図の場合はつねに系列分解図オフとすることで逃げることにしよう.

渋沢一族が5つのブロックに分解している事情を解明する手がかりとして,岡部長景の傍系親族図と渋沢栄一の傍系親族図の接点となっている尾高豊作@22の傍系親族図を取ってみた.246人を収容するかなり大きな親族図だ.尾高豊作は尾高 惇忠(藍香)の子どもの尾高次郎と大内ふみの間の子で,尾高家は渋沢一族の中でも渋沢家に次ぐ大きな氏族だ.尾高豊作の配偶者の岡部豊子は岡部長景とは異母兄弟に当たる.

尾高豊作の娘尾高泰子からすると,岡部長発は直系血族,岡部長景は傍系血族に当たるから現行アルゴリズムでもトレース可能なはずなのだが… クラスタ図の枝は親子関係だが,婚姻関係は1個の節点(クラスタ)として集約されているので,尾高豊作→ 岡部長景のパスが検出できないということは考え辛い.SIMPLEGRAPH::GetHasseDiagramの論理を見直してみよう.

確かに,現行では到達できないパスが発生するのは避けられないように思われる.現行アルゴリズムは以下のようなフローになっている.

  1. 起点から上流/下流検定を実施する
  2. すべての先祖ノードから下流検定を実施する
  3. すべての末裔ノードから上流検定を実施する

この論理では傍系に到達できない可能性がある.書き直してみよう.先祖ノードからの下流検定と末裔ノードからの上流検定を一体化して,下流検定→ 上流検定→ 下流検定を反復する必要がある.⇒解決した.

MARGBOX::CheckMargBoxChangedで@20渋沢市郎右衛門の先祖リンク不良が反復発生するのはなぜか?⇒該当する結婚枠が複数存在するためだ.⇒ダンプを抑制した.

現行では重婚クラスタ検定の入口で多重カードをカウントし,多重カードゼロの場合は重婚クラスタ図を生成しないようになっているが,つねに生成するようにすべきではないか?⇒多重カードゼロのサンプルは比較的単純なものが多いのでクラスタ検定を実施してもそれほど負荷が掛かる訳ではないのでやった方がよいと思う.やらなくても弊害はほとんどないとは思われるが,やっておいた方が安全だ.

画面サイズオーバーの問題が出ているので調べておこう.

系列分解図で栄一の系列を選択→新規部分図で部分図に切り替えようとして,TREEVIEW:CheckDispSizeOverのエラーになった.系列分解図でズーム倍率46%のとき,尾高磯五郎系列のカードを拡張選択して部分図:新規部分図で「現在の選択範囲を部分図に設定」した後,「部分図モードに切り替えますか?」→「はい」を押して,TREEVIEW:Zoom→ SetOuterFrameでエラーが発生する.OuterFrameには系図外枠が入っているが,幅が上限の32000を超えている.

しかし,選択された部分図の領域はそれほど大きなものではないので,全体図の領域と間違えているものと思われる.「部分図に設定」しただけでは描画領域は確保されず,部分図モードに切り替えて系統並び替えが実行されて初めて部分図の領域が確定するので,ZoomSetが掛かるタイミングが早過ぎる.ズーム倍率は描画に先立って切り替えておく必要があるが,適用される領域が間違っている(まだ計算されていない).

TREEVIEW::CheckDispSizeOverはGetTitlePositionから呼び出されているが,GetTitlePositionの呼び元は2つある.①CallGetTitlePositionと②SetOuterFrameだ.前者はという外部関数から呼び出されているが,後者はLButtonUp, SetDispParm, SetTitleBox, UpdateDiagram, Zoomなどいろいろなところから呼び出されている.

TREEVIEW::ZoomSetにはapplyという引数があって,Zoomを実行するか否かを選択できるようになっている.これをオフにして呼び出せばよいのではないか?TREEVIEW::ZoomSetは,CtrlZoomSet, MakeLeastWindow, ZoomIn, ZoomOutから呼び出されている.今の場合は,CtrlZoomSetからの呼び出しだが,この関数ではモードがZOOM_RESETとZOOM_KINDREDの場合にのみ,ZoomSetを呼び出している.ZOOM_KINDREDは今の場合のような「図面種別の切り替えに伴うズーム倍率の変更」だからapplyオフでよい.ZOOM_RESETはVBのSetZoomRateで呼び出されるケースだが,これもオフでよいのではないかと思う.⇒これでこの問題は一応片付いたのではないかと思う.

しかし,今度はTRIBELIST::ShiftDirectAbsoluteでエラーが出るようになってしまった.先祖ノードのシフトを実行して,確定世代番号と人名枠の物理世代番号の不一致が起きている.下図は尾高磯五郎系列の「一部」を部分図としたもので,4系統に分離している.

image

関係の一部がカットされたために系列がバラバラになるのはやむを得ないというより,当然だが,出力がかなりおかしい.それぞれ独立系統なので先祖ノードが物理世代ゼロに配置されるのは当然だが,下流系との間にギャップが出来てしまっている.各カードに表示された確定世代番号を見ると,画面上の垂直位置と一致しているので,確定世代番号に従っていると言える.カード数は全76点だ.

GetHasseDiagramで距離数を確定世代番号に変換するところで失敗しているのだろう.系統ごとに基準点が異なるので一括して処理したのでは正しい値にならない.どうすればよいか?SIMPLEGRAPH:GetHasseDiagramの中で系統ごとに処理が閉じるようにしなくてはならないだろう.この修正は結構クリティカルなので,一度バックアップを取って最近の修正をフィックスしてから着手することにしよう.

  1. RetrieveGhostではCHAOTICSTATEまではノーマル処理する@20210301 1件
  2. CHAOTICSTATEまではつねにノーマル処理する@20210302 12箇所
  3. NOMULTICARDを廃止する@20210303 12箇所
  4. 仮修正 1箇所,暫定 2箇所,#if 0 4箇所

SIMPLENODEにはすでに使われなくなったdownwardとupwardという2つの変数があるのでこれらを廃止して,代わりにstrain(系統)という変数を導入することにする.⇒実装した.動作している.

image

渋沢一族の系列分解図は横幅が上限を超えてしまうため,「92.2%以上には拡大できない」が,その動作があまりよくない.ズーム倍率リストで100%以上を指定しても拡大されないが,警告も出ない上,画面が崩れる場合がある.倍率表示は100%,200%などになっている.ズームトグルボタンで100%に戻そうとすると初めてメッセージが出て92%に自動調整されるが,画面は左端に移動してしまう.ズームインボタンで拡大しようとしたときの動作はトグルボタンの場合と同じだ.⇒ズームリストツールを操作したときのコマンドが,ZOOM_RESETだ.

しかし,ズームトグルの場合のように自動調整は実行されず,メッセージも出ない.ざっと見た限りではトグルとリストツールで動作には差異がないように見える.どちらもTREEVIEW::Zoomを呼び出しているだけだ.VB側の動作もZView.Zelkova1.ZoomSetを実行した後,UpdateZoomRateしているだけだ.どこかで書き戻されているようだ.⇒これは結構難しい.ズーム倍率リストのSelectedIndexChangedイベントの中でテキストを書き換えても上書きされてしまう.ComboBoxではe.Cancelのような方法が使えない.

渋沢一族のクラスタ図が5つに分離している

開発機とVAIO2で並行して渋沢一族の完全木テストを実行していたのだが,開発機の方はスリープから立ち上がれずに電源の再投入になってしまったため結果は分からない.VAIO2の方は遅々として進んでおらず,まだ全体図をやっている.開発機はZT Acvanced,VAIO2はZT Basicだが,どちらも遅い.開発機ではREFERENCECONTROLを止めた状態で走らせているが,それでも一面当たり15秒くらい掛かっている.

リリース版でテストするということも考えられるが,現行ではSTOP文をほとんどDEBUG_NEVERマクロに置き換えているので,リリースモードでは細かいエラーはほとんど捕捉できないのではないかと思う.開発ステージ的にはすでに「致命的ではないエラーはすべて無視」という段階に入っているのかもしれないが…

▲VAIO2で実行中の渋沢一族の完全木テストで例外が発生している.

例外がスローされました: ‘System.ArgumentOutOfRangeException’ (System.Windows.Forms.dll の中)

親族図:すべてのカード 基準ノード=#759 佐藤菊子だ.エラーを無視して続行は可能.ZT Basicをリビルドしてテストしてみたが,再現できない.このエラーはVBで出しているものと思われが,スリープ中のアプリを起こしたときに何か画面上の操作が入ったのではないだろうか?

「RetrieveGhostではCHAOTICSTATEまではノーマル処理する@20210301」というオプションを拡張して,「CHAOTICSTATEまではつねにノーマル処理する」としてみよう.

渋沢一族で部分図(中の家)を選択してNAMEBOX:RestoreExtractBoxで停止した.PartialMapCommand実行後の系統並び替え→ EraseTreeViewで系列枠不在が発生している.NAMEBOXのデストラクタに入ってきた時点ですでに系列枠への参照を失っている.TREEVIEW::EraseTreeViewでは無差別に描画要素を削除しているので,NAMEBOXより先にTRIBEBOXが削除されているのだろう.⇒フェーズがCHAOTICSTATE以下では系列枠不在を無視するようにした.

▲渋沢一族は完全に連結だと思っていたが,GetHasseDiagramのダンプで見ると,5つの系統に分離している.①渋沢 栄一@1,②岡部 長景@191,③吉阪 俊蔵@770,④正田 建次郎@624,⑤末松 謙澄@793だ.本当にそうなっているのかどうか確認する必要がある.⇒一見した限りではすべてのノードはどこかしらで連結しているように見える.

ゼルコバの木には「系統」という概念ないしオブジェクトは存在しないので,「系統を色別表示」などのことは直ちにはできないが,始系列は色別表示できるのでそれを見れば判定できるだろう.明らかに始系列は1個しかない.つまり,系図図面は連結でなくてはならない.ということは,重婚クラスタ分解に穴があるということを意味する.

渋沢一族の系列分解図を取ろうとして,TRIBELIST::MakeUpTreeで停止した.非始系列で系列優先実ノードを持たない系列がある.⇒いや,これはノーマルな状態だ.系列分解図ではすべての系列が優先実ノードを持たない状態になっている.つまり,始系列と非始系列を区別する意味がない.MakeUpTreeにはこのようなブロックが複数あるのですべて停止した.また,TribeRelocationで実行される

EstablishMajorTribeChainも系列分解図では不用なのでパスするようにした.これでようやく系列分解図が出力できるようになった.渋沢一族8には系列が107個入っている.つまり,先祖ノードが少なくとも107人登録されている.上記5系統の代表ノードから先祖ノードを探すと,

  1. 渋沢 栄一@1 → 渋沢 市郎右衛門@20
  2. 岡部 長景@191 → 岩崎 彌次郎@343
  3. 吉阪 俊蔵@770 → 箕作 秋坪@387
  4. 正田 建次郎@624 → 正田 貞一郎@625
  5. 末松 謙澄@793 → 伊藤 助左衛門@661

とりあえず,これらの系列の部分図を作ってみよう.

▲系列分解図で栄一の系列を選択→新規部分図で部分図に切り替えようとして,TREEVIEW::CheckDispSizeOverのエラーになった.系図外枠が35025x1489になっている.上限は32000x32000なので明らかにオーバーしている.「この図面は 91.4% 以上には拡大できません.」という警告が出されている.しかし,部分図画面で100%に切り替えても特に問題は発生しない.500%まで拡大することもできる.どうも,部分図と全体図を取り違えているのではないだろうか?

渋沢市郎右衛門系列には165名収容されている.

▲岩崎彌次郎系列を選択して部分図に切り替えようとして,SIMPLEGRAPH::GetHasseDiagramで停止した.この関数を呼び出すときの引数seedが空になっている.tajugraph2の節点リストが空になっている.⇒エラーを無視して描画できたが,内容がかなりおかしい.

image

これは明らかに系列分解図としての出力だ.確かに現在の親族図の設定では「系列分解図」となっているが,それが部分図まで影響するというのは想定外だ.「特殊レイアウト」で「系列分解図」をオフにすれば図面は正常に戻るが,その代わり,全体図でも系列分解図オフとなり,図面が変化してしまう.全体図・親族図・部分図のそれぞれで図面モードを持つというのもかなり厄介だが,そうするしかないのではないだろうか?まぁ,これは後で考えることにしよう.

岩崎彌次郎系列を系列分解図で切り取るとき,矩形領域選択しているはずだが,余分なカードが付いて来てしまっている.栄一系列の先祖ノードの渋沢市郎右衛門だ.もう一度取り直ししてみよう.今度は渋沢市郎右衛門は含まれていない.シフトキーを押していればこのようなことも起こり得るかもしれないが…

岩崎彌次郎系列は23点だ.

image

箕作秋坪系列は43点.

image

正田貞一郎系列は12点.これには,正田建次郎の子ども3人は含まれていない.この三人は平山信系列の平山多美の預かりになっている.

image

伊藤助左衛門系列は25名収容だ.

image

これで5つの系列は取り終わった.後はこれらの接点を探すだけだ.いや,それは別に難しいことではない.全体図を系列分解すればすぐに分かる.たとえば,岩崎彌次郎系列の場合,系列分解図で彌次郎系列のすべてのカードを選択し,外部系列で選択状態になっているカードを見つければよい.岩崎弥太郎の娘岩崎磯路@347は木内重四郎系列に入っている.岩崎弥太郎の孫娘加藤悦子の配偶者岡部長景と弥太郎の弟弥之助の孫娘岩崎妙子の配偶者岡部長章はともに,岡部長発の孫だ.弥之助の孫の岩崎英二郎の配偶者北原篁子は北原白秋の三人の配偶者の一人佐藤菊子との間にできた子ども,などなど… しかし,これでは埒が明かないので,岡部長景の傍系親族図を取ってみよう.

image

岡部長景の傍系親族図は40点だ.これも部分図として登録しておこう.

EraseTreeView中,NAMEBOX::RestoreExtractBoxで停止した.(PHASE > INITIALIZING && !tywbox->IsExtractOrTooYoung()) という理由だ.tywboxのownerはすでに空になっている.⇒NAMEBOX::RestoreYoungWifeと同等の修正を入れた.

吉阪俊蔵の傍系親族図は37点

image

正田建次郎の傍系親族図は27点.

image

末松謙澄の傍系親族図は30点

image

渋沢栄一の傍系親族図も取っておこう.全239点だ.

image

岡部長景の傍系親族図と渋沢栄一の傍系親族図の接点が見つかった.尾高豊作@22だ.手順は以下の通り.

  1. 一覧表表示範囲を「系図画面上のカード」に設定
  2. 岡部長景の傍系親族図を部分図で開き,全選択する
  3. 渋沢栄一の傍系親族図を部分図で開く
  4. 一覧表をスクロールして選択状態になっているカードを見つける

吉阪俊蔵の傍系親族図と渋沢栄一の傍系親族図には接点はない.

▲カード選択の動作がおかしい.部分図で全選択状態のまま選択が落ちない.選択と非選択が反転しているように思われる.部分図に切り替えて全選択した場合の動作もおかしい…

正田建次郎の傍系親族図と栄一の傍系親族図にも接点はない.末松謙澄の傍系親族図も同様.

▲全体図で表示を更新すると選択が落ちてしまう.⇒「選択を反転」→「選択を反転」で選択状態を復元することはできる.

吉阪俊蔵の親族図と栄一の親族図には直接の接点はないが,下図のように他系列との接点は存在する.

image

吉阪俊蔵の親族図と正田建次郎の親族図には接点がある.共通カードとして,坪井正道@390,坪井信子@391,坪井直道@392がある.この三人は坪井誠太郎+平山百合の子で,平山と正田は正田建次郎+平山多美で繋がっている.吉阪俊蔵の配偶者箕作花子は箕作佳吉の娘,箕作佳吉の姉箕作直子の子が坪井誠太郎だ.また,吉阪俊蔵の子吉阪隆正は箕作佳吉の弟箕作元八の孫娘甲野富久子と結婚している.

image

伊藤博文の傍系親族図を部分図で開いて全選択→ 末松謙澄の傍系親族図を部分図→ 選択を反転でTREEVIEW::selectAllのエラーが出た.(!selectedcard || !selectedname)のとき,(topology->ActiveList->count)が起きている.

CHAOTICSTATEまではノーマル処理する

軟体動物3.zelを開き,①マキガイとニマイガイを合体,②カタツムリとイカとタコを合体させて,RetrieveGhostのエラー「すでに廃棄中のノード対」が発生する.もう少し簡単な手順があるかもしれないが,少なくともこの方法で確実に再現できる.障害はCOUPLING:TopologicalSort冒頭のEraseTreeViewで起きている.フェーズはCHAOTICSTATEに入っているので,エラーを無視してもよいのかもしれないが,どういうフローになっているのか調べておこう.

UNDOありでゴミ箱なしというエディションだ.カタツムリとタコのカード合併でこれらが保持するノード対がClearPairBoxでパージされる.その後,系統並び替え→EraseTreeViewですべての描画要素が削除され,NAMEBOX #357 カタツムリ(0)が削除されている.このとき,PAIRBOX #406:#376 カタツムリ(1)→#357(0)がRetrieveGhostの対象となる.PAIRBOX #406はClearPairBoxですでにRetrieveGhostで処理されている.RetrieveGhostではこのノード対にdisableのマークを付けた後,(PHASE<=CLEARTABLE)という理由でゼロ復帰している.

RetrieveGhostはかなり複雑で大きな処理なので不用な摩擦を避けるために離脱することにしているものと思われるが,削除しようとしているノード対を放置したまま復帰というのは明らかにまずい.ゼルコバの木では基本的に「混沌とした状態」というのを認めないというのが方針であり,目標でもあるので,できる限りのことは実行すべきであると思う.フェーズはINITIALIZED=CHAOTICSTATEにあるので,この段階では処理を省略できないとしてみよう.また,仮に離脱する場合でも少なくともPAIRBOXを破棄してから離脱すべきだろう.最初にPAIRBOXを破棄してから離脱するようにしてみよう.⇒これでエラーは解消した.

CHAOTICSTATEまではノーマル処理するとしてみよう.ここまでできると「完全にクリーンなシステム」までは後一歩というところに達する.RetrieveGhostというのはこの種の処理としては最大で,それがこなせるとなればほとんどの場合はクリアできると考えられるからだ.⇒問題なく動作した.CHAOTICSTATE=INITIALIZEDの前には,INITIALIZING→ INITIALSTATE→ GROUNDZEROしかない.

これらのフェーズはアプリ起動時と終了時にしか通過しない完全な「初期状態」ないし「初期化中フェーズ」と考えられるので,システム的な整合性が崩れるのはある程度までは避けられない.ゴミ箱を復活させてUNDOシステムとの整合性をチェックしておこう.⇒問題なさそうだ.かなりよい動きになってきたので,リリース版を作り直しておくことにする.⇒源氏物語全系譜6.1.ZELが完了した.実行環境は開発機,デバッグモード,エディションはZT BASIC.

image

ZT BASICで渋沢一族を開いてみた.描画までに8.1秒掛かっている.多重カードが2件ある.①#224 穂積万亀子と②#691 井上光貞だ.穂積万亀子は穂積八束+浅野総一郎の娘浅野松の子で,栄一の子星野 辰雄の妻だ.万亀子の2つのカードはとんでもなく離れている上,世代差もあるので,多重になるのも仕方ないという感じはするが,「重婚クラスタ循環」は発生していないので,不可避の多重という訳ではない.

井上光貞は桂太郎の孫で,井上三郎+千代子の子であり,北白川宮能久親王の孫の二荒明子の配偶者だ.井上光貞のカード2枚は比較的近接しているので消去できそうにも見えるのだが… リリース版(ZT ADVANCED)ではどちらも解決して,多重ゼロになっている.これが,ZT BASICとZT ADVANCEDの力の差と見てよいのではないだろうか?井上光貞の場合はこんな↓感じだ.

image

穂積万亀子の場合は左に伸びる親子連結線が限りなく長いので追い切れないが,連結線を選択できるようになればそれも改善されるだろう.

image

従って,ZT BASICに求められるのは,これ以上の機能向上ではなく,障害で停止しないような安全な運用が可能であることにあると言ってよいと思う.渋沢一族の完全木テストを試してみよう.⇒早速障害が出た.ただし,これは開発機ではなく,リリース版の障害だ.

image

渋沢一族8.zelをただ開いただけでは発生しない.デスクトップ上に反例サンプルが複数できている.これらを開くとエラーが起きる.

BUG21-03-01 21-37-57.ZELを開いて,結婚参照番号不整合というエラーが起きる.また,CARDLINK::CheckCardLinkでvsprintf_sのエラーも起きている.このエラーは「父母ページ数の調整」をダンプしようとして起きている.⇒最終的には描画まで進んだが,中身はごく一部を除いて完全にバラバラになってしまっている.反例サンプルは全部で9つある.これらがどのタイミングで生成されたのか分からないが,その手順が分からないとバグを追跡できない.リリース版と同じ構成でビルドし直すところから始めるしかない.

新規ファイルの状態から,渋沢一族8.zelを開こうとして,nodule:Connectでエラーが起きる.TRASHCAN::ReuseWasteでオブジェクトを再利用するために,nodl_floatしようとしているところだ.Connect関数は付け替えをするときに,そのスロットの先住者を上書きする動作になっているためエラーが起きている.昨日の修正でnodule:nodl_floatを書き直しているが,ミスっていた.

接続元がIsAliveのときはスロットを開けるようにしているが,そうでない場合には放置している.これは「死亡しているノードは仮想関数SLOTが使えない@20210111」という理由だが,ゴミ箱に入っているノードはDELETED == DEADになっているため処理されないことになる.DEFINETRASHCANの場合にはつねにスロットを空けるようにした.

渋沢一族は完全に連結だと思っていたが,GetHasseDiagramのダンプで見ると,5つの系統に分離している.①渋沢 栄一@1,②岡部 長景@191,③吉阪 俊蔵@770,④正田 建次郎@624,⑤末松 謙澄@793だ.本当にそうなっているのかどうか確認する必要がある.

渋沢一族をリリース版で開いたときの状況は多重カードの位置を確認することが目的だったので,基本的には系統並び替えその他のデータ操作は一切行っていないつもりなのだが,実際には障害が発生しているのだから,何かしらのデータ操作を行っていたと考えるしかない.何をやるとこのようなことが起こるのか?ともかく少し動かしてみよう.⇒いや,障害が発生していたのはリリース版ではなく開発機のZT BASICではなかったのか?リリース版では多重が発生していないから,ほとんど操作らしい操作をやった記憶がない.

しかし,開発機でデバッグ中には反例サンプルは生成されないのだから,机上に反例が残っているとしたら,アプリで生成されたと考えるしかないだろう.開発機上でリリースモードでテストしていたという可能性はないだろうか?完全木テストを開始しようとした時点で問題が起き始めたのだから,完全木テストをやってみればよいのではないか?上のような派手な障害なら必ず引っかかるはずだ.

参照番号200近くまで走らせたが,エラーは発生していない.当初のエラーの原因はおそらくnodl_floatの書き換えミスだったのではないかと思う.しかも,それを開発機上でリリースモードで走らせていたのだろう.開発実機のデバッグモードで渋沢一族の1面を描画するのに約8~10秒近く掛かっている.これでは一晩掛かっても終わらないのでVAIO2に移すことにした.VAIO2ではさらに遅く倍速1面で20秒くらい掛かっているが,仕方ない.やらせておくことにしよう.

開発実機で標準版をデバッグモードで走らせて,渋沢一族を開き,完全テストに入ったところでRestoreYoungWifeで停止した.(PHASE > INITIALIZING && !tywbox->IsExtractOrTooYoung())という理由だ.完全木テストに入る前に参照番号でテーブルの並び替えを実行している.その処理が完了した後の系統並び替えでエラーが起きている.

系統並び替え冒頭のEraseTreeViewを実行しているところで,NAMEBOXのデストラクタからRetrieveGhost→ RestoreYoungWifeの呼び出しが掛かっている.フェーズはCHAOTICSTATE = INITIALIZEDでINITIALIZINGよりも大きいために停止している.上記で「CHAOTICSTATEまではノーマル処理」としたためだ.

問題のTYW枠はMARGBOX #130718:+→#37005 井上博邦(0)でこの結婚枠のTOOYOUNGWIFE属性が落ちてしまっているという点だ.⇒NAMEBOX::Dispose→ clearmarchainでMARGBOX:ReleaseMargBox→ ResetTooYoungWifeが実行されている.つまり,この結婚枠のオーナーとともに殉死しているということだろう.⇒結婚枠のオーナーが空ないし削除処理中の場合は停止しないようにした.

ゼルコバの木普及版 Zelkova Tree Basic

ゼルコバの木の普及版として公開を予定しているZekova Tree Basic バージョンの実現可能性が高くなった.テクニカルな問題はほぼクリアできたような気がする.ZT BASIC はゼルコバの木標準版(Zelkova Tree Advanced)から以下の機能を外したものだ.

  1. ゴミ箱(リサイクルシステム)
  2. UNDO/REDO 機能
  3. 抽象グラフ検証系(重婚クラスタ検定,端点共有ノード対の循環検査)
  4. 完全参照リスト管理

記録ページやカード写真イメージなどは普及版でもサポートされる.一般の個人ユーザが作成する50~100人程度の比較的単純なツリー構造の系図であれば,上記のような高度の機能を用いなくても十分作成できるだろう.ゼルコバの木を使うと100人程度の系図なら一週間程度で完成してしまうし,一旦作成してしまうと大概のユーザはそこで飽きてしまうので,高価な専用ソフトを購入しても宝の持ち腐れになってしまう.ゼルコバの木普及版の予価は2千円くらいを予定しているが,このくらいなら捨てる気持ちで支出できるのではないだろうか?

データ保存機能を持たないビューアはこれまで通り無償配布してゆきたいが,そうなるとどのバージョンのビューアを公開するかという問題が出てくる.ZT Advancedのビューアが無償で使えるということになると,普及版(ZT Basic)で作成した系図を高機能版のビューアで見るという使い方ができるようになり,誰も標準版を買う人がいなくなってしまうのではないか?普及版でビューアを出すならもちろんそういう問題は発生しないが,それも少しせこいような気もする… 場合によっては,ビューアの配布もユーザ会会員限定とすることも考えられる…

普及版では「部分図」という機能も不用かもしれない.部分図を止めるにはVB側で関係するコマンドを「不能」状態にするだけでも済むが,「部分図機能」に関わるモジュールをブロックとして切り出しておくことはシステム構成上意味がある.普及版から余分な機能を削ぎ落とすとしたら,①ファイル:追加読み込み,②一覧表のインポート/エクスポート,③親族図:軸線図法,④親族図:純血統図,⑤テーマの選択/登録なども対象になる可能性はある.というか,③はグラフ検証系を使っているので,もともと普及版には含まれていないと思う.

ともかく,完成させないことには始まらない.

▲カード写真を削除したとき,系図画面が更新されていない

▲「7」キーで「HOME」キーを代用するときの問題

▲軟体動物3.zelを閉じて,ZTシステム構成図7.ZELを開こうとして,freeblock::_releaseall_で停止.軟体動物3.zelではカード合併などの操作を行っている.テストバージョンは,UNDOサポート,ゴミ箱未サポート.軟体動物3.zelを開いて,閉じるだけで再現する.nodule:operator deleteでPHASE≦CHAOTICSTATEの場合はすべて削除としてある程度処理できるようになったが,totalblockが10個まで減少したところで,「**mptr** が 0xDDDDDDDD」という例外が発生した.

▲軟体動物3.zelを使ってカード合併のテスト中,RetrieveGhostで「すでに廃棄中のノード対」というエラーが出た.UNDO/REDO中には発生しない.マキガイとニマイガイを合体し,カタツムリとイカとタコを合体させて,カード数全20枚のところ,17枚になっている.

ニマイガイとマキガイをカード合併した図

UNDOシステムを搭載していないZT BASIC版で源氏物語全系譜6.1.ZELの全体図を#235 常陸介の前の北の方で開き,浮舟の母の配偶者欄で「常陸介」→「7777常陸介」のように変更して「登録」すると,系統並び替え中TOPOLOGY::MakeActiveListでエラーが発生する.treeview->validcardとActiveList->countのカウントが一致していない.「7777常陸介」という新しいカードが生成されているので,有効なカード数は318から1増えて319になっているはずだが,ActiveList->countは318のままになっている.treeview->validcardはSetKinshipから得ているが,TOPOLOGY::validcardnumとも同期している.validcardnumはTOPOLOGY::HideNameboxでカウントされている.

ActiveListはTOPOLOGY::MakeActiveListで生成されているが,ここではPDB()->lookup->tableを使ってカードにアクセスしている.lookup->countが318のままになっている.CARDTABLE::makelinkでは以前はMakingLookUpを実行していたが,@2018-02-1に 廃止された.同様に廃止された箇所が2箇所ある.MakingLookUpはルックアップテーブルを1から作り直す関数で,カードテーブルへのリンクの挿入と削除に際しては実行される必要がある.UNDOBASE:UndoProcessとCommandEndではつねにMakingLookUpが実行される.

MakingLookUpでテーブルの作り直しをしているのなら,個別にメンテナンスするより,系統並び替えで一度だけ更新するというのが早いのではないか?そうすれば,1箇所だけで済むようになるはずだ.それでもよいとは思われるが,現状を追認して,CARDTABLEとMARGTABLEのmakelink,FAMILYTREE::callSendCardで復活させることにする.削除の場合も必要になると思われるが,CARDTABLE:deletelinkの末尾で実行しているdecmaxrecnでMakingLookUpを実行するようにしたら,却ってエラーが出るようになってしまった.

image

これはVB側で出しているエラーだ.UpdateMaxCardはステータスバーを更新するための関数で,Z.RecordCountとZ.ActiveCountを比較している.Z.ActiveCountはおそらくActiveListのカウントに対応するものと思われるが,更新されていないため319になっている.Z.RecordCountはmaxRecordCountで取得された値で,lookupテーブルのカウントが入っている.MakingLookUpを実行しないようにすると,エラーは発生しないが,ステータスバーのカード数は319/319のまま更新されていない.つまり,誤った数字が表示されている.

問題は2つある.①MakingLookUpの実行後,Z.RecordCountとZ.ActiveCountで不一致が生じる,②系統並び替えを実行してActiveCountが更新されてもUpdateMaxCardが実行されない(ステータスバーが更新されない)⇒lookupテーブルはActiveListや部分図リスト構築のために使われているので,系統並び替えで一度だけ更新するというのでよいのではないか?まず,この修正を入れてみたい.バックアップを取ってからやることにしよう.

同上サンプルで常陸介を含む十数点のカードを選択→ 常陸介を削除で被参照カウントの残留が発生した.参照カウントが4残留している.参照はすべてMARGBOX[22]で「所属系列の先祖ノード人名リンクへの参照」が入っている.常陸介を単独削除しても同様事象が発生する.CARDLINK::DisposeではTRIBEBOX::CleanSansyoで先祖ノードからの参照をクリーンアップしているはずなのだが… これらの結婚枠はおそらくなんらかの事情で系列移籍が実行されたものではないかと思われる.所属系列の先祖と結婚枠が保持する先祖リンクが一致しない.

MARGBOX::CheckMargBoxChangedでこのような先祖リンクは積極的に解除するようにした.また,TRIBEBOX::CheckTribeでは「結婚リンクの先祖不在」を無視するようにした.実際,大半の結婚枠の先祖リンクは空になっている.⇒「7777常陸介」のカードが追加されたとき,一覧表が更新されていない.やはり,「系統並び替えで一度だけ更新」というのはダメのようだ.コマンド実行に対応するVB側の動作は「コマンド処理」のスコープで実行されなくてはならない.系統並び替えはそれと非同期に実行されるものなので,タイミング的に遅れてしまう.

元の論理に戻して,CARDTABLE::deletelinkとMARGTABLE:deletelinkでそれぞれMakingLookUpを実行するようにした.「UpdateMaxCard 不正なカード数」エラーが発生する件に関しては,maxcount < Z.ActiveCount に付け加えて Z.mSpanTreeNode() = 0 を見るようにした.これでエラーは回避できるようになった.

カード合併時には記録ページのマージが実行される.UNDOをサポートしていないシステムでこの辺りがどのような動作になっているのかが気になるところだ.⇒UNDOがサポートされていないシステムでは削除されたオブジェクトが復活するということはあり得ないから,特に何の問題も起きないと考えられる.2021年2月27日 のログではUNDOの問題が起きているが,この版の素性が問題だ.

UNDOをテストしているのだから,UNDOは実装されていたはずだが,ゴミ箱は外してあったのではないだろうか?多分,DEFINEUNDOSYSTEMだけがオンになっていたはずだ.ゴミ箱がなくても基本的にUNDOは動作する.Shadow付きのオブジェクトは削除されないからだ.しかし,写真や記録ページのようなfreeblockオブジェクトは削除されているはずだ.だとすれば明らかにUNDO/REDOで不具合が起きても不思議はない.まず,反例を確保する必要がある.

逆にZT Basicでは写真や記録ページをサポートしないという仕様も考えられるのだが… それも少しわびしい気持ちがする…

DEFINEUNDOSYSTEMをオン,それ以外のZT BASICでサポートされない(ゴミ箱を含む)機能をすべてオフにした版で軟体動物3.zelの動作を見てみたが,やはりUNDO/REDOはできない.ゴミ箱がある場合には,freeblockオブジェクトはゴミ箱に残っているので,それを参照するオブジェクトが復活した場合にも問題なく動作するが,メモリから完全にパージされてしまえばそれもできなくなる.しかし,ゴミ箱に入っているオブジェクトはリサイクルに回る可能性があるから,運が悪ければ同じようなエラーが起きる可能性はあると考えなくてはならない.

従って,UNDOをサポートしている場合には,ゴミ箱のあるなしに関わらず,freeblockオブジェクトをパージしないようにする必要があると考えられる.ゴミ箱に入らない場合にはフロート状態のオブジェクトとしてNリングに連結されるはずだ.freeblockオブジェクトにはカード記録ページやカード写真イメージの他に,データベースの作業域その他に用いるバッファ類やタイトル情報などがある.

多分タイトル情報はUNDOの対象になっていないはずだから,保護しなくてはならないfreeblockオブジェクトはMM_NOTEPAGEとMM_CARDIMAGEだけではないかと思われる.まず,これらのオブジェクトをパージしないという仕掛けを作ってみよう.⇒うまく行ったようだ.下図は,ニマイガイとマキガイをカード合併した図だ.

image

ニマイガイの下にマキガイの類が混載状態になっている.記録ページも両方のページを合体したものになっている.この動作はゴミ箱のあるなしに関わりなく,どちらでも動作するものになっている.これで一昨日出ていたバグは解決しているのではないかと思う.ま,まずい.UNDO/REDOの動作は確認したつもりだが,UNDOで戻ろうとしてエラーになった.ニマイガイの方はUNDOで戻ると記録ページも復元されているが,マキガイの方は写真も記録も消えてしまう.オブジェクト本体は残っているので,その限りではUNDOにはなっているが…

image

ビットマップはやや難しいところがあるので,記録ページのRTFの方を追いかけてみよう.⇒CARDLINK.CARDBASE.bitmapinfoとnotepageは空になっている..cBitmapには値は残っているがパージされた状態になっている.まず,ゴミ箱付きのときの動作を確認してみよう.UNDOはうまく行ったが,REDOがおかしい.処理の途中でバックアップタイマーの割り込みが入って,作業域のためのメモリ要求が出されて記録ページが使われそうになっている.

このオブジェクトのsnumは131だが,NODULE.sizeが179603240というとんでもない数字になっている.その他の部分は概ねまともなので,どこかで書き込みが発生している可能性がある.というか,ここで例外が発生しているので,このアドレス自体すでにパージされている可能性がある.再起動して,バックアップタイマーを止め,ファイルをクローズしようとしてTRASHCAN::throwCanで停止した.

delete wasteで例外が発生している.NODULE.sizeは215179560という値になっている.このオブジェクトのsnumは232だ.⇒クリーンビルドで作り直したら動作するようになった.しかし,2回目のUNDOでまた引っかかった.freeblock::_delmem_でdelete mblockを実行しようとして例外が発生した.やはり,sizeに大きな数が書き込まれている.CARDBASEのデストラクタではcBitmapをdeleteし,bitmapinfoとnotepageをfreeblock::_delmem_している.

これでは写真や記録を復元することなどできないのではないだろうか?むしろ,これまで動いていたとすればその方が不思議という感じもする… 古いバージョンでは~CARDBASEでビットマップの破棄などをやっていなかったのではないだろうか?⇒~CARDBASEを無動作で抜けるようにして動作するようになった.

Mouse Without Bordersでファイルを別マシンにドラッグ&ドロップできる!

源氏物語全系譜6.1.ZELの全体図を#5 紫の上(若紫)で開いて,NAMEBOX::IsPossibleBTWLeftHand Sc=884 左手本人が不可視で停止した.障害ノードは #15496 明石中宮(1)で消去された仮ノード.ゼロ復帰しないとしたらどのような動作になるのか確認しておこう.⇒「右手配偶者カードリンク不一致」でゼロ復帰している.右手結婚枠はMARGBOX #1098:#1225 明石中宮(0)+#1277 今上(0)→#1234 春宮(0)で,左手本人と右手本人が同一というシチュエーションだ.「左手本人が不可視」の検査を検査ルーチンの末尾に置いてみよう.

同上サンプルを#235 常陸介の前の北の方で開いてTRIBEBOX:hasPhysicalConnectionで停止した.(primenod->bigamist != realnode)というエラーが起きている.障害が起きているのは系列枠:snum=1544 primetype=3:婚姻関係 senzo=#424 一院 @10で,優先仮ノードはNAMEBOX #1382 浮舟の母(0).優先実ノードはNAMEBOX #1732 常陸介(1)だ.浮舟の母(0)はBTW右手配偶者,常陸介(1)はBTW左手本人だが,primenod->bigamistには浮舟の母(1)が入っている.これはかなりおかしい.

確かにMARGBOX #1150:#1777 浮舟の母(1)+#1778 常陸介(2)→#1398 蔵人右近将監(0)というBTWは成立している.逆に常陸介(1)が左手本人となるBTWは見当たらない.いや,#1778 常陸介(2)が右手配偶者となるBTWは発生している.このとき,#1732 常陸介(1)は左手本人になっている.とすれば,間違っているのはむしろ浮舟の母(0)がBTW右手配偶者ということになるのではないだろうか?いや,このBTWも存在している.#1382 浮舟の母(0)が右手配偶者,#1777 浮舟の母(1)が左手本人だ.このときの右手枠はMARGBOX #1082:#1270 八宮(0)+#1382 浮舟の母(0)→#1291 浮舟(0)だ.

この結婚枠は後から,もう一度BTWになっている.どこかで解除されているのだろうか?浮舟の母(1)はMARGBOX #1150:#1777 浮舟の母(1)+#1778 常陸介(2)→#1398 蔵人右近将監(0)のときには右手本人になっている.つまり,浮舟の母(1)は左手本人だが,右手本人でもある.何が問題となっているのだろう?右手本人と左手本人は複数のBTWに関係し得るが,右手配偶者の関わるBTWは一つしかないと考えられる.実際,浮舟の母(0)が右手配偶者となる結婚は#1082:#1270 八宮(0)+#1382 浮舟の母(0)であり,常陸介とは直接関わりはない.

優先仮ノードの浮舟の母(0)は右手配偶者で一院系列,その左手本人である浮舟の母(1)は大臣(橋姫)系列で同時に右手本人,その右手配偶者の常陸介(2)の左手本人が優先実ノードの常陸介(1)で,所属系列は常陸介の前の北の方だ.浮舟の母(0)のbigamistつまり左手本人は浮舟の母(1),浮舟の母(1)の右手配偶者の常陸介(2)のbigamistが優先実ノードの常陸介(1)になる.系列接続種別は婚姻関係となっているが,現行ルールではこのようなルーズな接続を認めている.ただし,それを正当化するのは難しい.今の場合で言えば

  • 優先仮ノードがBTW右手配偶者で,その左手本人が優先実ノードでない場合でも,もし,その左手本人が同時に右手本人であるとすれば,
  • その右手配偶者の左手本人が系列優先実ノードであれば正当と言える

のような感じになる.右手配偶者が同時に左手本人ないし,右手本人となる場合はあるだろうか?右手配偶者は原則として消去されているはずであり,逆に左手本人ないし右手本人は可視でなくてはならないと考えられるから,右手配偶者・左手本人ないし右手配偶者・右手本人ということはあり得ないと考えてよいはずだ.従って,優先仮ノードが右手配偶者で,その左手本人が優先実ノードでない場合には,左手本人が同時に右手本人である可能性を考えるのは妥当であるように思われる.

優先仮ノードが右手配偶者で優先実ノードが右手配偶者というケースはあり得るだろうか?一般には優先仮ノードは不可視,優先実ノード可視がノーマルな状態と考えられるので,実ノードが右手配偶者となるケースは除外してよいように思われる.従って,上の例外規則を適用すればある程度まではカバーできるのではないかと思われる.多少ややこしいが,実装してみよう.⇒動作している.

▲上記サンプルの画面で浮舟の母のカード画面上の子ども氏名欄で浮舟をダブルクリックしてTOPOLOGY::MakeActiveListのエラーが出た.(treeview->validcard != ActiveList->count)というエラーだ.validcard=319に対し,ActiveList->count=318になっている.氏名欄のダブルクリックで系統並び替えが発生するというのもおかしい.⇒再現しないが,ダブルクリックで新規カードを発行した後,UNDOで戻ると同じエラーが出る.浮舟の母の配偶者氏名欄に「7777常陸介」というのが入っているので,どこかで誤操作した可能性がある.

確かに,浮舟の母の配偶者氏名欄を「7777常陸介」のように書き換えて「登録」すると似たような事象が起きる.この後,UNDOしても元の状態には戻らない.これはUNDOの不備に依るものと思われるが,カウント不一致と合わせて別の機会に調べることにする.⇒この操作を行った後,ファイルを一旦閉じてもう一度開こうとしてハングする.freeblock::_releaseall_で失敗しているようだ.これはUNDOの不良と関係あるように思われる.⇒この版(ZT BASIC)ではUNDOをサポートしていないのにUNDOボタンが作動するというのがそもそも問題だ.

源氏物語全系譜6.1.ZELの直系親族図を#3 桐壷の更衣で開いて,「無効カードの仮ノード取り出し」エラーが起きた.⇒TRIBEBOX:GetAlternativePrimeNodeで無効カードを弾いていない.⇒対処した.

同上Z木家系図を#5 紫の上(若紫)で開いて,出口検査のTRIBELIST::CheckTribeListで,TRIBEBOX::CheckTribeのエラーが発生した.結婚リンク無効/結婚リンクの先祖不在が発生している.10系列でこのようなエラーが発生している.⇒GetAlternativePrimeNodeで無効結婚リンクを弾いていない.⇒対処した.

源氏物語全系譜6.1.ZELの完全木テストが完了した.Basicエディションを開発機上でテストした.

image

この後は舞台をVAIO2に移してテストすることにする.Mouse Without BordersではLAN上の別のマシーンにドラッグ&ドロップでファイルをコピーできる.これはすごい!他のマシンのデスクトップ上にドラッグするとMouseWithoutBordersという名前のフォルダを作ってそこに放り込んでくれる.…残念ながら,フォルダごとコピーすることはできない.「ZELKOVA 2021-02-26-1 – Folder is not supported, zip it first!」ZIPで圧縮しないとダメだと言われてしまった.⇒それでも,ZIPして解凍の方がLAN上(WiFi)でファイル転送より速い.最近の修正をフィックスしておこう.

  1. 系列のSPOUSESENZO属性を廃止する@20210224 25箇所
  2. 仮修正 1箇所,#if 0 5箇所,#if 1 3箇所

上記の「7777常陸介」という問題を調べておこう.最初に「カード登録」で(treeview->validcard != ActiveList->count)のエラーが発生するが,その後のUNDOの問題を先に見ておこう.VB側ではZ.mUndoStatusの値を読み取ってそれを表示しているだけだ.mZelkova::mUndoStatusではCallGetUndoStatで状態を取り出している.⇒CallGetUndoStatでUNDO未サポートの場合は,引数のUNDOSTAT *undoの内容をゼロクリアして返すようにした.

以前,Ctrl+ZでUNDOが誤動作していたので,チェックしておこう.Ctrl+Zが押されると,CardUndoRedoが引数FALSEで呼び出される.Ctrl+Yが押されるとCardUndoRedoが引数TRUEで呼び出される.この関数では状態に関わりなくZ.mUndoRedoを呼び出しているが,状態を判定してから実行するように改めておこう.⇒対処した.併せて,UNDOSTATの定数を整備した.

▲上記サンプルでUNDO/REDOの操作を実行していて,freeblock:_delmem_で例外が発生した.freeblock *mblockの値がおかしい.REDOを実行中で,delete unode->addressで削除操作を実行しようとしたところだ.unode->addressに入っているオブジェクトは正常であるように見える.障害は~CARDLINK→ ~CARDBASEで起きている.記録ページを解放しようとしているところだ.

削除しようとしているカードは@176の常陸介でこの人名リンクのcardbase.notepageの内容がおかしいようだ.カード合併などもやっているので,その影響があるかもしれない.オリジナルのZELファイルでは常陸介の記録ページは白紙になっている.というか,UNDOシステムはゴミ箱が整備されていないと正しく動作しないのではないだろうか?カードの削除や追加などは一応動作しているようではあるが…

freeblockにはShadowというのがないのでストレートに削除されている可能性がある.この問題は別途調べることにしたいが,再現できるだろうか?以下の手順を試してみたが,再現できなかった.

  1. 浮舟の母の配偶者欄で7777常陸介を登録→ 7777常陸介の新規カード
  2. 浮舟の母の配偶者欄で7777常陸介→常陸介→登録→ 常陸介新規カード
  3. 常陸介の新規カードとオリジナルの常陸介をカード合併
  4. 常陸介と7777常陸介をカード合併
  5. UNDO→UNDO→UNDO→UNDO→REDO→…

7777常陸介というカードが発生した原因は数字キーの7をHOMEのつもりで押していたためだ.テキストボックスにフォーカスがない場合には「7」キーでHOMEキーを代用できるのだが… 間違い易いかもしれない… この辺りも少し調べる必要がある.(treeview->validcard != ActiveList->count)のエラーが起きるのはUNDOシステムを実装していない場合に限られるようだ.

VAIO2でZTシステム構成図7.ZELの完全木テストが完了している.

image

このサンプルは開発環境では7.1.ZELの名前になっているので,リネームしておこう.ZTシステム構成図7.ZELをVAIO2にコピーしてテスト開始したところ,早速エラーが出た.

▲ZTシステム構成図7.ZEL 親族図:すべてのカード 基準ノード=#11 extraslot2を開いて,TRIBEBOX::DecidePrimaryNodeで停止した.系列優先仮ノードが空になっている.

源氏物語6.1.zelの完全木テストが完了 実行環境は開発機,エディションはZT Basic

源氏物語6.1.zelの完全木テストが完了している.実行環境は開発機,エディションはZT Basic.

image

この後のテストはVAIOで実行することにして,ZT Advanced(標準版)に戻ることにしよう.最近の修正をフィックスしてから始めることにする.

  1. GENELIST:BASELISTを廃止する@20210224 5箇所
  2. GENELIST:domainを廃止する@20210224 10箇所
  3. 暫定 1箇所,#if 0 8箇所,#if 1 2箇所

どうも,やり損なってしまったようだ.TRIBEBOX::SetPotentialでエラーが出るようになった.このエラーは確認されているが,現在の環境では起きていないはずだ.もう一度作り直すしかない.「現状でフィックス」しているのだから,変化しているとすればどこかでやり損なっていると見るしかない.⇒原因はわかった.MARGBOX::getFloorとNAMEBOX::getFloorだ.#if 1でグラフ検証系オンの動作を実行するようになっていたのを修正で復元している.⇒元の論理の方が正しい.

ZT Basicは一応動くようになっているので,ZT Advancedのテストに掛かろう.源氏物語全系譜6.1.ZELの全体図を#1 光源氏で開くと,ShiftDirectAbsoluteで(card->getnodegene() – nbox->getFloor())というエラーが出ているが,エラーを無視して描画は可能なので,一旦置いて,ZTシステム構成図7.1.ZELで出ているバグのシューティングを急ぐことにする.⇒おかしい.ZTシステム構成図7.1.ZELが開けなくなってしまった.nodule::setNringでエラーが出ている.考え辛い.⇒リサイクルシステムに動作不良があるようだ.DEFINETRASHCANを一旦止めて動作するようになった.この障害は後で見ることにする.

標準版:ZTシステム構成図7.1.ZELの全体図を#24 UNDOCHAINでソートしてadjustGenerationRangeで停止.(tribelist->ZentaiMin != baselist->MinGeneration)が起きている.⇒このエラーはすでに解消しているが,系統並び替えの出口で垂直スプリットが検出される.

image

確かに物理世代13でスプリットになっているようだ.どうもあちこち具合が悪い.リリース版の動作もおかしい.サンプルを開いてスプリットになるのは仕方ないとしても,その後のファイルが開けない.新規ファイルさえオープンできない.強制的に新規ファイルを開いた後,CSVをインポートしようとしてハングしてしまう.お手上げだ.UNDOシステムのエラーまで出ている.ZT Basicでは源氏物語6.1.zelの完全木を通しているはずだが,VAIO2でエラーが出ているので,先にこちらを見ることにする.開発環境でも再現できる.

源氏物語全系譜6.1.ZELの全体図を#5 紫の上(若紫)で開いて,TRIBEBOX::originateで停止する. (getcritical(SPOUSESENZO)) エラーだ.HORIZONTALORDERフェーズのHorizontalArangement→ MoveRectRightHorizontallyで起きている.処理はすでにMainExperimentに入っている.SPOUSESENZOというのは,「BTW左手本人が系列先祖でかつ系列優先ノードの特殊BTWに関わる系列と左手本人およびその結婚枠」ということを意味する.つまり,「BTW左手本人が系列先祖でかつ系列優先ノード」であるような特殊な系列だ.

前回テストと今回の動作が異なるのは,前回のテストではMARGBOX:IsPrimeboxOrNotがつねにFALSEを返すような設定になっていたためと思われる.障害の起きている系列はTRIBEBOX #1612 先祖=#1321 源典侍(0)[29] 優先=#1321 源典侍(0)→#1749 光源氏(3) →主系列#1548:一院で,先祖ノードでかつ系列優先ノードのげ(0)がBTW左手本人になっている.BTW左手本人は可視ノードだから,このような条件が成立したからと言って特に不都合はないように思われる.しかし,その後のTRIBELIST::CheckAllBondedTribeでループカウントオーバーが発生してSUWになる.なぜだろう?

TRIBEBOX::CheckDirectSubTribeで「接触系列を親参照していない」という不良が起きて,「直属系列接続不良」という状態になっている.系列枠のbondageが空になっている.SPOUSESENZOはBONDEDTRIBE | MAGARIHOSEIとともに,IsBondedTribeの中に入っているのでbondageは主系列を指していなくてはならない.checkIfBondedTribeが空を返しているためだ.この関数ではIfContactParentBlockで上位系列との接触を検査している.

SPOUSESENZO属性を完全に廃止することにする.⇒バックアップに戻って作り直した.源氏物語6.1を開発環境でもう一度テストしてみる.エディションはZT Basicだ.

源氏物語全系譜6.1.ZELの全体図を#70 浮舟で開いて,NAMEBOX:ChangeTribeRealnodeで停止.「優先仮ノードが配偶者で逆婚姻関係でない接続」というエラーが起きている.#81 弘徽殿女御でも起きる.NAMEBOX::DoublyBlessedOneで「系列優先実ノードが右手配偶者の場合右手本人に切り替える」という措置を行っているところだ.DecideTribeTypeはPRIME_BTWLEFTを返している.これは「BTW左接続関係:両手に花左手本人→右手本人」だから正しい.ここではDecideTribeTypeの値をsetprimetypeするだけでよいのではないか?

ただし,今の場合,配偶者が左手本人になっているが,これでよいのだろうか?「右手配偶者が左手本人で停止@20210108」というオプションもあるが,そのノードが可視である限りは配偶者が左手本人となることは可能なのではないだろうか?今の場合,系列優先仮ノードはNAMEBOX #1820 薫(3)で可視の配偶者,BTWの相手方はNAMEBOX #1294 女二宮(今上の)(0)だ.薫(3)の系列はTRIBEBOX #1602 先祖=#1443 小宰相の君(0)で,女二宮(今上の)(0)は一院系列だ.

この図面には薫は2箇所に登場する.浮舟の配偶者,および小宰相の君の配偶者だが,このレイアウトにはやや疑問がある.

image

薫は一院系列に女三宮の子どもとしてのポジションがあるのに,なぜ小宰相の君の配偶者などになっているのか?⇒理由はわかった.「基準ノードの配偶者の外部婚を排斥」というオプションが効いているからだ.これは「基準ノードの配偶者の外部婚は配偶者の配偶者側で展開する」ための例外規則で,基準ノードの配偶者の外部婚を基準ノードから遠ざけるための方策だ.このルールが妥当なものであるかどうかはもう少し見なくてはならない.⇒このオプションを外したら,薫のカードは3枚になったが,もう少し自然な図柄になった.

image

女二宮+薫はBTWでカード消去できるはずだが,なぜそうなっていないのかは,後で見ることにする.以下の2つの障害の原因も「基準ノードの配偶者の外部婚を排斥」にあるようだ.

▲同上サンプルの#100 源典侍でNAMEBOX::IsPossibleBTWLeftHandで「右手配偶者が左手本人」というエラーが起きている.⇒このオプションは「左手本人が右手配偶者で停止@20210108」に改名した.現行では「停止する」だけでBTW不成立としているが,BTW成立という動作も可能だ.その方が多重カード削減の効果はありそうだ.

▲同上サンプルの#221 源氏宮の母でCARDLINK::getnameboxのエラーが出た.配偶者不在でGP例外が起きている.

複数の障害が発生しているが

複数の障害が発生しているが,まずBASIC版で起きている不具合から見てゆくことにしよう.

BASIC版:源氏6.1.zelの全体図を#9 冷泉院で開いて,TRIBEBOX:SetPotentialで停止.(primary->getFloor() != pot)が起きている.このエラーはTribeRelocation出口で実行されるHeapTribeBoxesで起きている.障害が起きているのはTRIBEBOX #1540 先祖=#1231 一院(0)[1] 優先=#1628 冷泉院(1) 始系列で,基準ノードの物理世代番号5に対し,系統ポテンシャル値は4になっている.⇒基準ノードの相対世代番号(listdata.Generation)が1になっている.どこかでシフトされているのではないか?⇒いや,それ以前の問題だ.

TRIBELIST::GoDownStreamで基準ノードの冷泉院が冷泉院の御息所の配偶者として展開されている.GoDownStreamが縦型探索になっているということにも関わりはあるが,それより問題は,MARGBOX:IsPrimeboxOrNotの動作を「IsPrimeboxOrNotを有効化」オフで止めているという点にある.この一点だけでも,このオプションが不可欠であることは分かる.関連するオプションとして,「系列接続に関わる結婚の優先展開」や「基準ノードの配偶者の外部婚を排斥」もオンに戻しておこう.DEBUGオプションの「右手配偶者が左手本人で停止しない@20210108」もオンとしておくのが安全だろう.⇒逆論理にしてオンに設定し,デフォルトオンのVERIFYに移した.

これでエラーは解消したが,グラフ検証系オフのときには,基準ノード/優先ノードの相対世代番号をゼロに正規化するという処理が入るはずなので,その辺りの動作を確認しておく必要がある.どこかで系列優先仮ノードが冷泉院(0)から(1)に切り替わっている.冷泉院の仮ノードは4つ出ている.

  1. #1230 冷泉院(0) 先祖=一院 関係=配偶者
  2. #1628 冷泉院(1) 先祖=一院 関係=配偶者
  3. #1629 冷泉院(2) 先祖=一院 関係=実子
  4. #1648 冷泉院(3) 先祖=一院 関係=養子

MakeUpTreeでは実子の(2)が基準ノードとして選択されているが,その後,SelectBaseBoxで配偶者の(0)に切り替わっている.この選択は誤っている.配偶者(0)はBTWが成立して不可視となり,再度SelectBaseBoxが呼び出されて(1)に切り替わる.このノードでSetPotentialのエラーが発生する.⇒このエラーを取るのはかなり難しい.SelectBaseBoxで可視で非配偶者の仮ノードがすでに選択されていない場合には再選択しないように修正してエラーは解消した.これで一応解決したということにしておこう.

ZT BASICで源氏物語全系譜6.1.ZELの全体図を#3 桐壷の更衣で開いて,TRIBEBOX::adjustGenerationRangeで停止した.(tribelist()->ZentaiMax != baselist->MaxGeneration)エラーが起きている.NormalizeRelativeGeneration→ SetTribeMaxGeneでTRIBELIST:ZentaiMinとZentaiMaxは更新しているが,baselist->MinGenerationとMaxGenerationとは同期していない.

このエラーが起きているのは,TRIBELIST::buildgenelist 世代枠リスト構築済みフラグが立っているためだ.SetTribeMaxGeneでUpdateGeneListを実行しようとすると,今度はdomain不在エラーが発生する.おそらく,domainはBUILDGENELISTフェーズでBuildGeneListを実行することで設定されているものと思われるが,baselistの生成時に設定するべきではないのだろうか?

GENELISTは2つリンクを持っているが,どちらもべた参照だ.あまり芳しくない設計だが… 特に世代枠リストの中に基本世代枠リストへのリンクを持つというのは不適当だ.まず,これを廃止できるかどうかを見てみよう.⇒簡単に廃止できた.基本世代枠リストの所在を尋ねるのなら,その所有者に尋ねるのが順当だ.domainも廃止してしまおう.その代わりにDomain関数を使えばよい.Domainは『参照』を返す関数になっているが,書き込み不要なのでリンクを返すだけでよい.GENELIST::InitializeGeneListも丸ごと廃止できる.

SetTribeMaxGeneでUpdateGeneListを実行するようにしているが,エラーが起きる.MinGeneration,MaxGenerationはすでに設定されているが,まだ世代枠が生成されていないため,動作不良が起きる.⇒この関数の中で調整することも不可能ではないが,世代枠リストはGoDownStreamとMakeUpTreeが完了した後にBUILDGENELISTで別途構成するようになっているので,buildgenelistフラグが立つのを待つというのでよいのではないか?⇒対処した.

系列相対世代番号を正規化するための関数

昨日の修正を一旦白紙に戻してバックアップから出直すことにする.TRIBEBOX::setPotentialが最初に掛かってくるのは,TribeRelocationのAFTERMARGSAMEGENEで実行されるCheckTribeVerticalPositionだ.グラフ検証系が作動しているときにはSAMEGENEMARRIAGEで重婚クラスタ図が生成され,絶対世代番号が確定している.それと同等のことをグラフ検証系なしでやるとすれば,各ノードが保持している相対世代番号Generationを正規化するということではないだろうか?

TRIBELIST::NormalizeRelativeGenerationという関数を作って,TribeRelocationの冒頭で実行するようにした.この関数では「優先仮ノードの世代番号をゼロになるように系列内世代番号をシフト」して,「系列世代枠リストの最小/最大世代番号を更新」する.これで,「ZTシステム構成図7.1.ZELの全体図を#33 baselist 基本世代枠でソートして,TRIBEBOX::SetPotentialで停止」という問題は解決した.

ZTシステム構成図7.1.ZELの全体図を#24 UNDOCHAINでソートして,TRIBEBOX::InsertRingで停止した.世代枠不在が起きている.NormalizeRelativeGeneration実行後,StackTribeGeneを実施しているループの中で起きている.NormalizeRelativeGenerationの中で何らかの手当てをする必要がある.#57 BASETABLE,#58 ARRAY,#82 SIMPLEGRAPHなどでも発生する.

障害ノードはMARGBOX #690:#795 longtable(0)+#755 RecordList(0)→で,世代番号は[1].所属系列はTRIBEBOX #913 先祖=#795 longtable(0)だ.系列世代枠リストのMinGeneration=-1, MaxGeneration=0で要素数は2.この関数はStackTribeGeneの冒頭MakeGringから呼び出されているが,その直後に実行されるGenerationBoundaryの中でsetPotentialを実行しているので,呼び出しが早過ぎる.また,GenerationBoundaryの中でもMakeGringを実行しているので,ここで実行する必要はないと考えられる.⇒対処した.

同上サンプルの直系血族図を#15 selectedcardでソートして,GENELIST::GetGeneBoxで停止した.引数の物理世代番号が負になっている.AFTERMARGSAMEGENEフェーズのTribeGhostNameで起きている.NAMEBOX::getPairlistは引数のindex=0で呼び出されているが,対象人名枠のNAMEBOX #719 treeview(0)の物理世代番号が-1になっている.所属は始系列のTRIBEBOX #905 先祖=#716 coupling(0)[1] 優先=#730 selectedcard(0).

最古世代先祖ノードはNAMEBOX #716 coupling(0)で物理世代番号は-3になっている.最古世代先祖は始系列に属している.この関数が呼び出されるまで,一度もTRIBEBOX::setPotentialが呼び出されていない.⇒NormalizeRelativeGenerationの中ですべての系列の系統ポテンシャルを設定するようにした.

image

同上サンプルの直系親族図を#2 kakeizuでソートしてGenerationBoundaryで停止した.#202 NODULEでも起きる.また,Z木家系図 基準ノード=#2 kakeizu,.#202 NODULEでも起きている.障害ノードはTRIBEBOX #907 先祖=#771 COUPLING(0)で,(!getGeneBox(minGeneration) || !getGeneBox(maxGeneration))という理由で停止している.minGeneration=-1, maxGeneration=0.

この2つの値はTRIBEBOXのプロパティで系列世代枠リストのMinGenerationとMaxGenerationに相当するものと思われるが,NormalizeRelativeGenerationの中では設定されていない.これらは,TRIBEBOX::setMinGene,setMaxGeneで設定されている.⇒NormalizeRelativeGenerationの中で更新するようにした.

ZTシステム構成図7.1.ZELの完全木テストが完了した.

image

悪くない数字だ.最近の修正をフックスしておこう.

  1. MoveLowerMargTreeではTYW枠は移動しない@20210215 1箇所
  2. PAIRBOX:setSectionを廃止する@20210218 7箇所
  3. NAMEBOX:shiftedonceを廃止する@20210218 5箇所
  4. TRIBEBOX:brokenを廃止する@20210218 11箇所
  5. Boject:nobori,kudari,unequalを廃止@20210218 8箇所
  6. checkBrotherOrderで微細な移動を実行する@20210219→ 廃止
  7. KeitoMin,KeitoMaxを廃止する@20210220 11箇所
  8. 仮修正 6箇所,OBSOLETE 2箇所

この後のテストはVAIO2で行うことにする.ここで標準版をビルドして別アプリ用にリリースしておこう.

▲標準版:ZTシステム構成図7.1.ZELの全体図を#24 UNDOCHAINでソートしてTRIBEBOX::adjustGenerationRangeで停止.(tribelist->ZentaiMin != baselist->MinGeneration)が起きている.

▲標準版:TRIBEBOX::SetPotentialで(primary->getFloor() != start->getPotential()) が発生する.

▲BASIC版:源氏6.1.zelの全体図を#9 冷泉院でソートして,TRIBEBOX::SetPotentialで停止.(primary->getFloor() != pot)が起きている.