基準ノードの物理世代番号と系統ポテンシャル値が一致しないというエラー

▲ZTシステム構成図7.1.ZELの全体図を#33 baselist 基本世代枠でソートして,TRIBEBOX::SetPotentialで停止.基準ノードの物理世代番号と系統ポテンシャル値が一致しないというエラーが起きている.障害が起きているのは,始系列のTRIBEBOX #905 先祖=#716 coupling(0)[1] 優先=#748 baselist基本世代枠(0)で,系統ポテンシャル値は4,基準ノードの物理世代番号は3になっている.AFTERMARGSAMEGENEフェーズ「重婚グラフ検定の事後処理」の中でCheckTribeVerticalPositionを実行しているところだ.最古世代先祖ノードは始系列に属する #716 coupling(0),つまり,始系列は系統最古系列でもある.

基準ノード世代=-1 先祖ノード世代=-4で確かに世代差は3だ.つまり,基準ノードの物理世代番号3というのは数字的には正しい.そもそも,基準ノード世代=-1というのがおかしい.この値はNAMEBOX::listdata.Generationに格納された値で,系列内の相対世代番号を表す数字だが,基準となるのは「系列優先ノード」であり,始系列の場合は基準ノードに該当するものであるのだから,つねにゼロでなくてはならないと考えられる.かなりややこしい問題がある.

基準ノードのbaselistから先祖ノードへの経路は少なくとも2つある.距離(世代差)3の経路と距離4の経路だ.上流検定ではより小さい数値が適用されるので,先祖ノードの世代値は-4となり,下流検定で基準ノードの世代値に-1が設定されることになる.これをいじると,今度は世代差が出てきて世代計算の根底が崩れてしまうようになるので,この状態で収めることを考えよう.

InvestigateVSplitsで垂直スプリット

ZTシステム構成図7.1.ZELの全体図を#24 UNDOCHAINで開いて,TREEVIEW::InvestigateVSplitsの垂直スプリットエラーが発生する.⇒物理世代1~4でスプリットとされるが,画面で見た限りでは起きていないように見える.TREEVIEW::InvestigateVSplitsでダンプしてみると,mingene=0 maxgene=12 maxgene-mingene=12で描画要素はNAMEBOX #903 nodule(0)のindex=0を除き,index=6~12の間に分布している.実際の画面出力は8世代分しかないので,どこかで4世代分の齟齬が発生している.indexの値はgetFloorで得た物理世代番号ーmingeneだが,mingene=0なので実質物理世代番号で見ていることになる.つまり,物理世代番号が間違っていると推定される.

これは結局系列ポテンシャル値が不正ということになるので,それを設定している場所を調べてみよう.AFTERMARGSAMEGENEフェーズのCheckTribeVerticalPositionの中でGetPrimaryGapに従って設定されている.これは優先実ノードと仮ノードの相対的な世代差によって調整するものなので,始系列のPotential値が正しいということが前提となっている.TRIBEBOX::setpotentialにはシグネイチャの異なる3種があるので, ①callSetpotential,②Setpotential,③setpotentiaのようにリネームして識別するようにした.

callSetpotential→Setpotential→setpotentia

のような関係がある.callSetpotentialは現在の系列優先実仮ノードを引数にSetpotentialを呼び出し,SetpotentialはGetPotentialで得た値を引数にsetpotentiaを実行する.callSetpotentialは19箇所,Setpotentialは3箇所,setpotentialも3箇所から参照されている.始系列のPotential値を設定しているsetPotentialを見てみよう.

この系図には2つの系統がある.①#905 先祖=#739 UNDOCHAIN(0)系統,②#957 先祖=#903 nodule(0)系統.nodule(0)系統のポテンシャル値は一貫してゼロだが,UNDOCHAINのポテンシャルは0, 2, 5, 8, … のような変動を繰り返している.どうも,TRIBELIST:SetTribeMaxGeneにはかなり問題がありそうだ.

SetTribeMaxGeneを全面的に書き換えて,上記のような変動は解消した.現行では系列の世代枠リストは伸張の方向にしか変化しないようになっている.系統ポテンシャルに関係するのは,KeitoMaxだけだ.まず,KeitoMin,KeitoMaxのアクセス関数を作っておこう.SetTribeMaxGeneではKeitoMin,KeitoMaxを無条件で更新している.従って,硬直しているのはTRIBEBOX::minGenerationと推定される.

TRIBEBOX::minGenerationの書き換え関数setMinGeneは以下の3箇所から呼び出されている.①GoDownStream(void) (TRIBELIST),②InsertRing(MARGBOX * mbox) (TRIBEBOX),③adjustGenerationRange(int min, int max) (TRIBEBOX),④clean(void) (TRIBEBOX).④は初期化しているだけなので無関係.①は先祖ノードの世代を直接格納しているので問題ない.②では系列の世代枠が持つ結婚枠リングに結婚枠を登録する際に系列世代範囲が拡大した場合のみ更新している.

③adjustGenerationRangeでは(PHASE < BUILDGENELIST)の場合は無条件で書き換えを実施しているが,フェーズがBUILDGENELIST以上ではUpdateGeneListを実行した結果を転記している.UpdateGeneListでは世代枠リストが上下に伸張する方向でしか書き換えを実施していない.世代範囲が縮小した場合には空になった世代枠を削除して最小/最大世代番号を更新すればよいというだけだから,修正はそれほど難しくないと思われるが,現状のままでもそれほど不都合はないとも考えられる.問題は使われていない世代枠が存在する状態をスプリットと誤認する点にあると考えられるので,まず,これに対処することにしよう.

TREEVIEW::InvestigateVSplitsでは最初にmingeneとmaxgeneを現物オブジェクトから取り出している.この中でnodule(0)が唯一物理世代番号0となっているため,これに引きずられて0~12というレンジになってしまっている.これを避けるためにはどうしても最古世代系列を世代枠リストの先頭に配置しなくてはならない.このようなことになってしまうのは,世代計算で物理世代番号を使っているためと考えられる.当初は系統内でのみ通用する常用世代番号を使っていたはずだが,「重婚クラスタ検定」の導入により「確定世代番号」が適用できるようになったため,物理世代番号で処理するようになったものと思われる.物理世代番号を使うようになったもう一つの理由がある.ノード対を管理している基本世代枠リストが物理世代番号で管理されているためだ.

系統最古世代ないし,系統最古世代先祖ノードが確定できれば現行論理をあまり変えずに何とか対処できるのではないか?いや,どちらにしても世代枠リストで前詰めしないことにはどうにもならないのではないか?⇒画面上は問題なく描画できているのだから,問題をスプリット検定の問題として限定すべきではないか?考えられる方策としては検定を系統単位に分解することが考えられる.

TRIBELIST:HeapTribeBoxesで系統ポテンシャル値を再設定している.ここで系統最古世代先祖ノードの物理世代番号がゼロとなるように系統ポテンシャルを設定することで解決した.ただし,TRIBEBOX:setPotentialでKeitoMinと設定値が一致しないというエラーが出る.⇒「系統最古世代先祖ノードの物理世代番号がゼロ」というのが系統ポテンシャルの本来の定義なので,TRIBEBOX::SetPotentialをその趣旨で書き換えてみよう.⇒問題なさそうだ.

KeitoMinという値は,系統ポテンシャルを決定するときしか使われていないので廃止できるのではないか?というのは,系列世代枠リストは系列内の世代のみを扱い,基本世代枠リストは系統より広域な全域世代枠を扱っているからだ.一度バックアップを取ってから試してみることにしよう.⇒うまくいったようだ.

▲ZTシステム構成図7.1.ZELの全体図を#33 baselist 基本世代枠でソートして,TRIBEBOX::SetPotentialで停止した.基準ノードの物理世代番号と系統ポテンシャル値が一致しないというエラーだ.

checkBrotherOrderで微細な移動を実行

源氏物語全系譜6.1.ZELの直系血族図 #318 右大弁(桐壷)で三極検定レッドラインオーバーが起きた.これはかなり信じ難い動作だ.右大弁(桐壷)は親なく子なく妻もなしなので,直系血族図には本人カード1枚しか残らないはずだ.それがエラーになるとは何かが「狂って」いる.REDLINE値がゼロになっている.現在この変数には「結婚数」が設定されている.⇒1よりも小さい値にならないよう修正した.

同上の傍系親族図を#5 紫の上(若紫)で開いて,TRIBEBOX:StackTribeGeneで停止した.completeの状態にある系列枠の検査でCheckMaximalSegment不合格になっている.この検査では「インター系列シンメトリ婚の場合は他系列での移動が配置に影響する場合がある」ため除外されている.障害が起きているのは,TRIBEBOX #1548 先祖=#1231 一院(0)[6] 優先=#1673 朱雀院(1)→#1347 源氏宮(0)で,主系列は主系列#1540:先帝だ.

StackTribeGeneではsetcompleteでCheckMaximalSegmentの検査を通している.セグメントは3つに分離している.①#1231 一院(0)とその結婚枠#1055:#1231 一院(0)+→#1648 桐壷院(1),②#1685 八宮の母女御(1),③それ以外だ.八宮の母女御は何も特別な属性を持っていないが,たとえば,BTW解除などのことが起きているのではないか?⇒そういう状況ではないが,結婚点不一致が起きている可能性がある.⇒八宮の母女御の子ども枠はTYWになっているため結婚点一致できない.承香殿女御 (桐壷院の)→四宮 (桐壷院の)もTYWになっている.麗景殿女御 (桐壷院の)まではセグメント[4]になっている.また,②つのTYW枠も[4]になっている.

八宮の母女御だけが[6]という理由が分からない.⇒TRIBELIST::CheckMargBoxChangedの中で何らかの変異が起きている.おそらく,微細な調整で無視されているようなものだろう.

MARGBOX::checkBrotherOrderで移動量-1の移動が実行されている.この移動は誤差の範囲なので戻り値では返されていない.微細な移動は実行しないか,ないし実行して結果を報告するかの2択しかない.「微細な移動は実行しない」というのがもっとも確実だが,おそらく描画はやや精度を欠くものになる可能性は避けられない.実行した場合には最悪処理が発散ないし循環してしまう可能性がある.とりあえず,実行するという方向で修正してみよう.⇒少なくともこの反例に関してはこの修正で収まった.これでしばらく様子を見ることにしよう.

image

八宮の母女御の子ども枠はTWY解除されて直下に収まっている.承香殿女御のTYWは残っている.

ZT BASICで源氏物語全系譜6.1.ZELの完全木テストが通った.

image

この続きはVAIO2でやることにしよう.⇒早速エラーが出た.ZTシステム構成図7.ZELの全体図:#24 UNDOCHAINで垂直スプリットが発生している.ただし,開発環境では再現しない.サンプルは同じZTシステム構成図7.ZELだが,VAIOにあるのはカード数が1少ない.それだけでここまでの差が出るのかどうか?開発機では別のエラーが出た.

ZTシステム構成図7.ZELの法定親族図:#7 topologyでMPLCループレッドラインオーバーが発生した.⇒昨日の修正を戻して解消した.やはり,「checkBrotherOrderで微細な移動を実行する」というのは無理がある.以下のように仕様変更することにした.

  1. checkBrotherOrderで計算誤差範囲の移動が発生した場合:
    移動は実行するが,crushはインクリメントしない
  2. 移動を実行した場合には,対象系列をincompleteとする

NAMEBOX::originateでは変位が計算誤差を超える場合には,CancelStackを実行して系列枠をincompleteにしている.これをつねにCancelStackを実行するようにした場合には収束しなくなる可能性が出てくるので現状のままとする.この意味ではcheckBrotherOrderでも微細な移動はすべて無視するものとし,StackTribeGeneではCheckMaximalSegmentで停止しないようにするというのが一番合理的であるような気もする.⇒そのように対処した.

VAIOのZTシステム構成図7.zelを7.1.zelにリネームして開発機にコピーした.このサンプルを開くと開発機でもエラーを再現できる.

▲ZTシステム構成図7.1.ZELの全体図を#24 UNDOCHAINで開いて,TREEVIEW::InvestigateVSplitsの垂直スプリットエラーが発生する.しかし,実際にはスプリットは発生していないように見えるので,事実誤認が疑われる.

image

PAIRBOXのsectionとsetSectionを廃止

PAIRBOXの関数setSectionと変数sectionを廃止した.これらの値はダイナミックに変化するので値がつねに正当であることを保証できない.

ZTシステム構成図7の全体図を#92 Bobjectで開いて,NAMEBOX:makePairBoxで(common && common->CheckSamePoint())で停止した.⇒これはエラーではない.まだ端点共有していないためsamepointがCOMMON_NOCOMMONになっているというだけだ.⇒commonが端点共有束でない場合を検査から除外した.

ZT BASICによるZTシステム構成図7.ZELの完全木テストが完了した.前回より若干遅くなっている.

image

使用していない変数などを削除した.①PAIRBOX:setSectionを廃止,②NAMEBOX:shiftedonceを廃止,③TRIBEBOX:brokenを廃止,④Boject:nobori,kudari,unequalを廃止など.

源氏物語全系譜6.1.ZELの全体図を#123 左大臣の女御で開いて,三極検定ループカウントオーバーが発生した.障害はTRIBEBOX #1542 先祖=#1231 一院(0)[2] 優先=#1754 冷泉院(4)→#1230 冷泉院(0)で起きている.⇒三極検定レッドラインオーバーが発生した場合には,「レッドラインでZTYW/TYW婚を1個づつ停止しながら続行する@20210218」ようにした.ZTYW婚は当初14個あったものが,12個まで削減されるとループから脱出できた.ただし,TribeRelocationのSYMMETRICGEOMETRYフェーズでCheckZeroPositionにより5個削減され,最終的には7個だけが生き延びている.

▲同上サンプルの直系血族図 #318 右大弁(桐壷)で三極検定レッドラインオーバーが起きた.

VAIOにOpen Live Writerを導入した

VAIOにOpen Live Writerをインストールしてサイトにアクセスできるようにした.また,VAIO2では途中で止まっていたVisual Studio Community 2017のインストールを再開した.どちらもネットアクセスにはスマホのテザリングを使っている.上限は10GBだが,まだ9.87GB残っているので余裕だ.月が変われば最大15GB/月まで高速で使えるようになる.VAIOは常時ネットに接続しているので,ネットアクセス用のサブ機,VAIO2は通常はLAN接続してテスト機として使えるだろう.大きいパッケージがスムースにダウンロードできるというのはありがたい.ただし,LANが遅い.開発用フォルダを転送するのに10分以上掛かる.最近の修正をフィックスしておこう.

  1. 軸線グラフではreferを使わない@20210212 2箇所
  2. CheckVerticalPosition中は系列ポテンシャルの変更不可@20210212 3箇所
  3. CheckNormalizedSectionで危険対同士の衝突は無視@20210213 1箇所
  4. goodsonが上位ノードの枠内で結婚点一致ならマージを廃止@20210214 → 廃止
  5. MoveLowerMargTreeではTYW枠は移動しない@20210215 1箇所
  6. 仮修正 11箇所,暫定 2箇所,if 0 3箇所,#if 1 1箇所
  7. OBSOLETE 10箇所

源氏物語全系譜6.1.ZELのZ木家系図を#74薫で開いて,MakeUpTree中にTRIBEBOX::GetRealnodeで実ノード不在エラーが起きる.これは,GetAlternativePrimeNodeで失敗していることを意味する.障害が起きているのはTRIBEBOX #1546 先祖=#1335 先帝(0)[4] 優先=源氏宮で,源氏宮の仮ノードは2つしかない.(0)は先帝系列,(1)は一院系列だが,先帝系列のtorder=3に対し,一院系列のtorderが4であるため不成立となっている.系列順位は①摂政太政大臣,②二条太政大臣,③先帝,④一院のようになっている.

torderの設定基準を基準ノードの重みではなく,先祖ノードの重みに変えてみた.⇒これで系列順位は,①摂政太政大臣,②一院,③二条太政大臣,④先帝のように変わり,#1614 源氏宮(1)→#1347 源氏宮(0) で主系列#1542:一院に接続できるようになった.多分これが正解なのではないかと思う.

image

同上サンプルの全体図を#9 冷泉院で開いて,上記と同じ場所で実ノード不在が発生する.障害が起きているのはTRIBEBOX #1552 先祖=#1397 常陸介(0)[7] 優先=常陸介で,系列順位は5位.優先ノードの常陸介の仮ノードは2つで,(0)は常陸介系列,(1)は大臣(橋姫)系列だ.大臣(橋姫)系列の順位は6位なので,現行ルールでは常陸介系列の主系列となることはできない.

TRIBEBOX::DecidePrimaryNodeではGetAlternativePrimeNodeで代替となる優先仮ノードを提案しているが,それが棄却された後,もう一度深堀りして代替案を見つけている.最終的にはこれで解決しているように思われるので,TRIBEBOX::GetRealnodeでは「主系列実ノード決定不能」の理由で停止しないようにした.

ZTシステム構成図7.ZELの全体図を#201 noduleで開いて,系列優先ノード決定不能が発生し,StackOverflowになる.TRIBELIST:SortTribeListByWeightで系列順位の基準を昨日の修正「系列優先ノードの重みに従ってソートする@20210216」に戻してやれば動作する.どう対処すればよいか?障害が起きているのはTRIBEBOX #906 先祖=#837 CARDTABLE(0)[3] 優先=BASETABLEだ.これはかなりおかしい.この系列は始系列のはずだ.しかし,系列種別はPRIME_PARENTになっている.いや,違う.この系列は始系列ではない.

系列順位を決定する基準は系列分解の手順に従うというのが本来の方式だ.系列優先ノードの重みないし,先祖ノードの重みをこの目的に使うのは不当である.系列順位はTribeDecompositionで決定している.⇒MakeUpTreeの中で実行している系列枠リストの並び替えを廃止.

同上サンプルを#87 NAMESORTでソートしてPAIRBOX:RepairCommonEndPointで停止した.CheckPairBoxのエラーが起きている.エラーを無視して描画は可能.「最大区間ノード対の逆転」が起きている.障害ノードはPAIRBOX #1887:#964 nodule(6)→ #956(1).「最大区間ノード対の逆転」が修復されていない.⇒SwapBundledPairが効いていない.

SwapBundledPairは動作しているが,まだ別のエラーが残っているのに中間で復帰しているためだ.SwapBundledPairを実行した時点でCheckSamePointで再検査するようにした.⇒CheckSamePointは純検査関数であるのに,setInclusiveを使っているのは問題がある.この関数はノード対の相対矩形領域を更新している.⇒CheckSamePointの中ではオブジェクトへの書き込みを行わないように修正した.

ZT BASICの完全木テストが通った

ZTシステム構成図7.ZELの全体図を#57 BASETABLEでソートして三極検定レッドラインオーバーが発生する.結婚枠枠の衝突が起きている模様だ.系列枠TRIBEBOX #912 先祖=#769 COUPLING(0)[6] 優先=#983 nodule(8)の衝突が止まらない.衝突は複数世代に渡るかなり複合的なもののように見える.

  1. gene=1 move=612  #1456 <>  #712
  2. gene=1 move=612  #678 <> #656
  3. gene=0 move=306  #655 <> #652
  4. gene=-1 move=465  #1463 <> #676
  5. gene=-1 move=306  #676 <> #702
  6. gene=-2 move=1096  #629 <> #634
  7. gene=-2 move=97  #633 <> #635
  8. ————————————————–
  9. gene=0 move=97  #655 <> #652
  10. gene=-1 move=179  #1452 <> #1468
  11. gene=-1 move=97  #676 <> #702
  12. gene=-2 move=1262  #633 <> #635
  13. gene=-4 move=15  #697 <> #660
  14. —————————————————–
  15. gene=1 move=612  #1456 <> #712
  16. gene=1 move=612  #678 <> #656
  17. gene=0 move=306   #655 <> #652
  18. ......

1周期が2ラウンドに渡る12個の衝突を含む長いサイクルが繰り返されている.この衝突サイクルを解析するのは至難の業だ(衝突以外の因子もからんでいる).しかし,おかしいのはレッドラインオーバーで一旦ブレークすると,その後は衝突は完全に影を潜めてしまうという点だ.何がどう変化しているのか?

障害が起きているのはMainExperimentのステージ【7.2】完全木検定:すべての系列を完全系列として正準化するで実行されるMakePairListCleanだ.⇒REDLINEの上限を現行の40から60に引き上げて解決した.REDLINEは概ね系図の世代数に依拠した数字だが,この処理は系列枠単位なので系列サイズによっても左右される.

同上サンプルを#87 NAMESORTでソートして,ノード対と実ノードの世代不一致で停止した.NAMEBOX::MakeUpPairBoxでは「makePairBoxで新規に生成されたノード対を構成」しているが,その中でTRIBEBOX::hasPhysicalConnectionにより,「実ノードを切り替え」が起きている.この関数の中でなぜ敢えてNAMEBOX:ChangeTribeRealnodeを実行しているのか,趣旨がよくわからない.

ChangeTribeRealnodeというのは,「系列優先実ノードを付け替える」ための関数,MakeUpPairBoxは新規に生成されたノード対のパラメータを整備するための関数だ.⇒この関数の中でIsPrimaryGhostでない場合はゼロ復帰しているので,呼び出していること自体は誤りではないが,ここでやるべきことではないような気がする.⇒「ここではChangeTribeRealnodeを実行しない@20210216」としておく.

#88 PARTIALNAMEで三極検定レッドラインオーバーが起きた.⇒まだ上限数が不足している.REDLINE値として「有効な結婚数」を適用するようにして解決した.

#91 TREEVIEWで系列優先実ノード不在が発生する.エラーを無視して実行すると,TRIBEBOX::IsMinorOfで主系列参照チェーンのループが起きる.TRIBEBOX #942 先祖=#821 NODELIST(0)の系列優先ノードが決定できない.TRIBEBOX #924 先祖=#769 COUPLING(0)[12]とNODELIST系列がどちらもNLIST< LISTNODE,CID>を優先ノードとしているためだ.

NLISTは2つしか仮ノードを持っていないので線形順序を与えることができない.⇒系列枠リストの順序に従い,前方系列しか主系列を選択できないという制限を与えて解決した.系列枠リストをソートするために,TRIBELIST::SortTribeListとは別にSortTribeListByWeightという関数を作り,系列優先仮ノードの重み(基準ノードからの距離)に従ってソートするようにした.

同上サンプルを開いてPAIRBOX::CancelCommonPairで停止する.(plist == bottomlist)というエラー.CancelCommonPairは端点共有を解除するための関数で「対象ノード対を現在のノード対リストから取り出し,最下段チャンネルに仮移動する」操作を行う.「現チャンネルが最下段の場合には最上段チャンネルに移動」に修正した.

同上サンプルを#84 FAMILYTREEでソートして,MPLCループレッドラインオーバーが発生した.TRIBEBOX #902 先祖=#784 FAMILYTREE(0)[1] 優先=#784 FAMILYTREE(0) 始系列でCheckMargBoxChangedが起き,以下のシーケンスを反復している.

  1. 不可視ノード移動x9件
  2. ————————————————
  3. 兄弟順位の逆転 #626
  4. 不可視枠の移動 move=-3100
  5. ————————————————
  6. goodsonを設定 goodson=#722

兄弟順位の逆転補正を停止すれば描画できる.兄弟順位逆転が起きているのはMARGBOX #626:#784 FAMILYTREE(0)+#716 familytree(0)→#725 BaseLink(0)だ.障害ノードはprevious=#721 linktable(0)とperson=#722 namesort(0)だ.

familytreeの子ども枠は幅広く,namesort(0)は+3100と-3099の間を往復運動している.namesortが子ども枠の中央付近に来るとgoodsonが交互に変化してシーソーになってしまうため運動が反復して停止しない.MARGBOX:checkBrotherOrderでは対象ノードがgoodsonであるときはつねにゼロ復帰するようにして解決した.

同上サンプルを#87 NAMESORTでソートしてTRIBEBOX:hasPhysicalConnectionで停止した.(!realnode->getghostbits(PRIMGHOST | ELDERWIFE)) で優先仮ノードがREALGHOST属性を持つのに実ノードが(PRIMGHOST | ELDERWIFE)ではないことが検出されている.⇒ここでは停止しないでダンプするだけとする.

image

重婚クラスタ図の出力がおかしい

重婚グラフ(多重グラフ2)の出力がおかしい.グラフをダンプすると節点数48,枝数54となっているが,エクスポートしたグラフ(重婚クラスタ図)をインポートして表示してみると,ノードが2つ足りない.#1848のcouplingと#1774のpagesetupだ.枝数54には#1846 noduleと#1848 couplingの自己ループ枝が含まれている.また,#1848 couplingy→ #1774 pagesetup,#1848 coupling→ #1768 familytreeの枝もある.#1774 pagesetupから出る枝は存在しない.婚姻グラフ(多重グラフ1)の連結成分数は48なので,重婚グラフの節点数と一致する.⇒SIMPLEGRAPH:ExportGraphで自己ループ枝は出力しないようにしてみたが,状態は変わらない.

TREEVIEW::sendUpdateDataではcouplingもpagesetupも作られている.ただし,LINKTABLE::ImportEndではカードテーブルPDBに登録されたカード数は46になっている.カード参照番号#3のpagesetupはlinktableで上書きされている.また,#27のcouplingは配列要素で上書きされてしまっている.ExportGraphではカード参照番号として成分番号を使っている.これが重複しているということなのだろうか?グラフ2をエクスポートする前に,sortComponentListでグラフ1の連結成分リストをソートしているが,成分番号の付け替えを実施していないのだろうか?⇒いや,やっているはずだ.⇒SIMPLEGRAPH:sortComponentListに論理ミスがあった.

image

これで正しい重婚クラスタ図を描画することができるようになったが,「先祖ノード絶対世代番号不一致」は相変わらず収まっていない.AdjustTribeGenerationをShiftDirectAbsoluteの実行に先駆けて実施すると,14あった世代差は2~6程度まで縮まる.最終的にループを抜けるときには1まで軽減される.AdjustTribeGenerationでは冒頭でSetAbsolutePotentialを実行している.これは「絶対世代番号系と物理世代番号系を一致させる」とあるので,この段階で問題は解決していなくてはならない.⇒あれこれ試してみたがうまくゆかない.一度バックアップに戻って出直そう.これまでの修正は以下の2点だ.

  1. SIMPLEGRAPH::ExportGraphで自己ループ枝を出力しない
  2. SIMPLEGRAPH::sortComponentListに論理ミス

ZT BASICでZTシステム構成図7.ZELの全体図を#1 couplingで開いて,TRIBEBOX::hasPhysicalConnectionで停止した.系列優先仮ノードがREALGHOSTを持つとき,(realnode->getrealnode() != primenod)という理由だ.⇒hasPhysicalConnectionを整理して,「系列優先仮ノードが実ノードで逆参照されていない場合」でも系列タイプがPRIME_INVERTでない場合は停止しないようにした.また,優先仮ノードが実ノードで別のノードから参照されている場合には,ChangeTribeRealnodeを試みるようにした.この事例では最終的には落ち着くところに落ち着いている.

同上サンプルを#2 kakeizuでソートしてMakePairListCleanでエラーが発生した.ループカウントオーバーが起きている.「兄弟順位の逆転」と「TYW枠の移動」が反復実行されている.前者ではNAMEBOX #747 tribelist(0)が149移動,TYW枠の移動はそれに見合う形で-149移動している.TYW枠の移動によって,兄弟順位の逆転が発生していると見てよい.兄弟順位の逆転はprevious=#747 tribelist(0) person=#984 TRIBELIST(1)で起きている.障害の起きているTYW枠はMARGBOX #1633:#747 tribelist(0)+→#983 treeview(3)だ.

TYW枠の移動量はRightContactMargTreeで求めている.この関数は6箇所で使われているが,NAMEBOX::GetRightContactでは,前方ノードとの接触距離をGetContactDistanceで測定している.MARGBOX::checkBrotherOrderではGetRightContactで同様の検査を実施している.NAMEBOX::IsLefMovePossibleでは「本人の第一配偶者が右移動不可の場合に限定」される.

MoveTooYoungWifeでは結婚点一致以外の除外条件はない.MARGBOX::CheckZeroPositionではZTYW婚が結婚点一致位置に移動可能かどうかを検査するためにRightContactMargTreeを使っている.GetRightContactでは内部でGetContactDistanceを使っているので,実質同等である.

ただし,MoveTooYoungWifeでは結婚枠を直接移動しているので,上位人名ノードには関わりがないはずであり,そうでないとしたら親参照パス不良ということになるのではないか?いや,むしろ人名ノードを移動するとき,TYWを共連れにしていることが問題なのではないか?本人ノード自体はRelativeで相対移動しているが,MoveLowerMargTreeで下流系を連れて移動している.⇒直下のTYW婚は移動しないようにした.

▲同上サンプルを#57 BASETABLEでソートして三極検定レッドラインオーバーになった.

ZTシステム構成図7.ZEL #15 selectedcardで水平スプリット

ZTシステム構成図7.ZELの全体図を#15 selectedcardで開いて,系統並び替えの出口検査で水平スプリットを検出.

この図面には6個のTYW婚が出現している.

  1. #2067:#2066 baselist基本世代枠(2)+→#773 baselist基本世代枠(0)
  2. #2131:#2130 topUndo(1)+→#767 topUndo(0)
  3. #2139:#2138 anod[](4)+→#1057 anod[](1)
  4. #2211:#2210 Bobject(3)+→#912 Bobject(0)
  5. #2219:#2218 Bobject(9)+→#1093 Bobject(1)
  6. #2311:#2310 nodule(24)+→#902 nodule(0)

スプリットの原因となっているのはbaselist基本世代枠だ.baselist基本世代枠は3つ仮ノードを持っている.(0) #773, (1) #1067, (2) #2066だ.(0)はtribelistの子ども,(2)はtopolgyの子ども,(1)がTYW本人ノードで配偶者GENELISTを持っている.うち,(2)はかけ離れた位置にある.(1)と(2)が同一セグメントと認定されるタイミングを調べてみよう.いや,違う.(1)は不可視でセグメント値を持っていない.消去された仮ノードだ.(2)はLDRで,(0)がTYW本人だ.(0)と(2)のセグメントブロックがマージされるタイミングでは下図のようになっている.

image

この操作自体には問題はない.問題はそれ以前に起きている.前方(画面右)の黒いブロックは144というセグメント値を持っている.その次の草色のブロックは29で,上記のタイミングでこのブロックは前方のブロック144と接触する位置まで移動しているが,その後方になる黒のブロックはいずれも144という値を持っている.つまり,すでにこの時点で誤りが発生している.

image

!解けた!ただし,この解はまだ,暫定的なものだ.MAXIMALGRAPH::mergeUpperSegmentで「goodsonが上位ノードの枠内にあり,結婚点が一致している場合は子ども枠上位ノードと接合」するという規則を一時的に止めることによって得られた結果だ.この修正が果たして一般的に通用するものであるかどうかは今のところ不明だ.⇒いや,これは外しても大丈夫なようだ.この条件に合致するものは相当あるが,なしでも問題なく解けている.この論理の問題点は対象結婚枠が「タイト」でなくても上位ノードと接合できるという点だ.

上記サンプルを#24 UNDOCHAINでソートして三極検定レッドラインオーバーが発生した.かなり無茶苦茶なひどい図面になっている.

image

SUWではなく,単純にブレークすれば正常な図面が出力される.

image

TRIBELIST::AdjustTribeGenerationで「先祖ノード絶対世代番号不一致」が大量発生している.⇒この問題は後から見ることにする.mergeUpperSegmentで上記の修正を元に戻せばエラーは解消するが,それでは元の木阿弥だ.UNDOCHAINのケースとselectedcardが両立するような解決案として,goodsonでマージする条件として対象結婚枠がIsElderWifeBoxではないという条件を付け加えた.これでどちらも通るようになった.

これが問題の完全解になっているとは思われないが,少なくともこれまでよりはましな解になっていることは確かだと思う.現行リリース版ではエラーが多発しているので,「バレンタイン・バージョン」と称する版を所内リリースした.

「先祖ノード絶対世代番号不一致」の問題に移ろう.この事象もよく分からないところがある.絶対世代番号と物理世代番号の間で14もの差が出ている.それだけでなく,エクスポートした重婚グラフもかなりおかしい.この図面は仕上がりで12世代だが,重婚グラフでは11世代しか出ていない.

image

そもそも先祖ノードが「配列要素」となっているのが意味不明.

image

ここには,couplingかないしCOUPLINGが来なくてはならないところなのだが… しかし,婚姻グラフ(多重グラフ1)の連結成分リストの出力は正しいように思われる.SIMPLEGRAPH:dumpComponentを書き直して,簡単なリストを出力する関数SIMPLEGRAPH::dumpComplistを作った.

SIMPLEGRAPH::dumpComplist 連結成分リスト sc=1 list=#1848 k COMPLIST 1848
   1 [0]coupling COUPLING
   2 [1]pagesetup PAGESETUP
   3 [1]familytree FAMILYTREE
   4 [2]topology TOPOLOGY
   5 [2]linktable
   6 [2]namesort NAMESORT
   7 [2]partialmap PARTIALNAME
   8 [2]undosys UNDOSYSTEM
   9 [2]extraslot2
  10 [3]SIMPLEGRAPH graph3 keisengraph graph2 graph1 tajugraph1 tajugraph2 tajugraph3 tempgraph copygraph
  11 [3]MARGTABLE MDB
  12 [3]UndoChain UNDOCHAIN UndoCurptr undochain
  13 [3]longtable RecordList
  14 [3]CARDTABLE PDB
  15 [3]tribelist TRIBELIST
  16 [4]complist
  17 [4]starttribe TRIBEBOX
  18 [4]treeview TREEVIEW
  19 [4]BASETABLE
  20 [4]undotop
  21 [4]baselist基本世代枠 GENELIST
  22 [4]nodelist NODELIST
  23 [4]anod[]配列
  24 [4]anod[]配列
  25 [4]edgelist
  26 [5]topUndo UNDONODE
  27 [5]配列要素 CARDLINK
  28 [5]EDGELIST
  29 [5]配列要素 MARGLINK
  30 [5]GENEBOX GENEBOX
  31 [5]COMPLIST
  32 [5]ARRAY
  33 [6]MARGBOX margbox
  34 [6]nlist
  35 [6]NAMEBOX nambox
  36 [6]anod[]
  37 [6]pairlist PAIRLIST
  38 [7]NLIST< LISTNODE,CID>
  39 [7]PAIRBOX PAIRBOX
  40 [8]LIST LIST
  41 [8]Bobject Bobject
  42 [9]所属グループ
  43 [9]衝突検定リング
  44 [9]圧縮検定リング
  45 [9]DATALIST DATALIST
  46 [9]描画Yリスト
  47 [9]親参照リスト
  48 [10]nodule

連結成分リスト 成分数=48 ノード数=86 世代数=11 min=0 max=10

世代数は11でこれは実際の系図出力より1少ない.この食い違いがどこで生じているのかを見ておこう.ノード数=86は実際のカード数188より大分少ないが,これは終端ノードを省いているためだ.これを追加したグラフを作ってもよいが,効率を落とすだけなので省くのが正解だと思う.世代数が1少ないというのも同じ理由だ.確かに省略されている分,間違い易い.

多重グラフ1の連結成分リストは完全に正しいと言ってよいだろう.重婚グラフは節点数が46で成分数48より2少ない.重婚グラフの節点は重婚クラスタであり,多重グラフ1の連結成分に他ならないのでこの食い違いは問題だ.落ちているのは,1 [0]coupling COUPLING と2 [1]pagesetup PAGESETUP のようだ.いずれにしても重婚グラフがまちがっているか,ないし,エクスポートでやり損なっているかのいずれかだ.

ZTシステム構成図7.ZELの軸線が通った

ZTシステム構成図7.ZELを#1 couplingで開いて,系統並び替え出口検査で垂直スプリットが検出される

従来論理のMakeHasseDiagramを廃止して,GetHasseDiagramと差し替えているが,TOPOLOGY::TestInevitableMultiZeroとVerticallyTightenHasseDiagramで実行していたSIMPLEGRAPH::sortComponentListを継承していなかった.GetHasseDiagramの実行後にSetAbsoluteGenerationとsortComponentListを実行することでスプリットは解消した.

同上サンプルで多重カード3件が残る.うち1件(COUPLING)は重婚クラスタ循環に起因する不可避の多重だが,残り2件(NLIST < LISTNODE,CID>とnodule)は同世代に多重カードが発生しているので,回避できなくてはならない.原因を調べてみよう.まず,noduleから見てゆこう.

noduleの仮ノードは(0)~(103)まである.ダミー枠を除いても17個ある.うち,(0)と(3)を除く15個はLDRだ.(0)は仮ノード消去の実ノードですべての親子連結線はここに集まっている.このノードはTOOYOUNGWIFE属性(TYW転換された抽出結婚枠とその本人)も持っている.(3)は軸線ノードだが,外部からは参照されていない.(16)は「LDRチェーン末尾に接続するTYW結婚枠を上位人名枠から参照」している.多重カードの削減はメインループのTOPOLOGY::ReduceMultiCardで実施しているが,実効性がない.これはおそらく(0)が結婚を持っているためだろう.

特に,単身婚の子どもを持っていることが効いているのではないか?血統軸線図の構築フェーズBUILDCENTERLINEは17で,GODOWNSTREAMの11より後に実行されるので軸線ノードが決定するときには結婚枠の割当はすでに決まってしまっている.しかし,軸線ノードの持つMOTHERLESSではない結婚枠をMargBoxTransferで移転したような技法を使えば,単身婚を軸線に移動させることはできるはずだ.⇒うまくいった.一発で2つとも多重が消えた!軸線も完全に通った.これが通れば,大概のサンプルはこなせるだろう…

image

上記サンプルを#8 linktableでソートして,TRIBELIST:MakePairListCleanで無限ループが発生した.MDB(2)→(1)とMDB(3)→(1)が競合している.どちらも危険対属性(CRITICALPAIR)でPAIRLIST::VerifyPairBoxで一方が別チャンネルに移動した後,RepairVerticalInverseで元のチャンネルに戻されている.⇒危険対の操作はCheckInverseCycleに任せて,CheckNormalizedSectionでは無視することにした.⇒解決.

▲同上サンプルを#15 selectedcardで開いて,系統並び替えの出口検査で水平スプリットが検出された.⇒確かにひどいスプリットが発生している.

image

障害が起きているのは始系列で,先祖ノードはCOUPLINGだ.⇒TRIBEBOX::CheckGeneSplitの検査は結婚枠単位だが,幅の広い結婚枠が3つあるため領域が被覆された状態になっている.BaseLink(0)の入っている枠は(-118, 12109),PDB(0)の枠は(676, 10024),pagesetup(0)は(-298, 9548)もある.この種の空洞はこの関数では検出できない.伸びた兄弟枠(ルーズな結婚枠)を詰めるのは水平セグメント検定の分担だ.何がそれを妨げているのだろう?⇒原因がTYW婚にあることは明らかだ.実際,TYW婚を完全禁止すれば問題なく描画できる.

image

TYW婚はシンメトリ婚と同様の「フロート婚」であり,どのような位置にも水平移動できるが,その状態を完全に捕捉するのは難しい.むしろ,水平セグメント検定の対象から除外してしまうということが考えられる.つまり,ほったらかしにするという方針だ.言い換えれば,既定の木構造の規制範囲外とする.逆に言えば,「衝突を起こさない限りどこにいてもよい」ということになる.フロート婚は一般に衝突を起こした場合には解体されることになっているので,これでも特に問題ないのではないか?ものは試しなのでやってみたいが,かなり大きい修正なのでバックアップを取ってから始めるのが妥当だろう.

MargBoxTransferで軸線枠を移動する

ZTシステム構成図7.ZELの全体図を#30 MDBで開いてMARGBOX:GetUpperNodeで停止する.「親ノード不在」が起きている.⇒TOPOLOGY::CallBuildShaftLineで軸線枠を設定する際に,結婚枠の親参照パスを付け替えて上位軸線ノードを参照するように修正してエラーは解消したが,絶対座標変換後のCheckAtypicalMarriage(非類型的結婚処理)でエラーになる.

上記サンプルの全体図 #30 MDBでTOPOLOGY:CheckAtypicalMarriageの「stave異常値」エラーが起きる.これは結婚連結線の割当てに失敗したことを意味する.障害が起きているのは,NAMEBOX #772 MDB(0),NAMEBOX #1261 MDB(2)とNAMEBOX #1229 MARGTABLE(1)だ.MDBは親を4組持っている.①topology+TOPOLOGY,②linktable,③namesort+NAMESORT,namesortだ.軸線はnamesortになっているが,topologyという選択もあったはずだ.

この図面では多重が2件発生している.MDBとMARGTABLEだ.topology→MDBは子どもがいないので消去できるはずなのだが,多重になっている.MARGTABLEには親はいない.単身婚の子どもBASETABLEとMDBとの結婚の子どもがいる.これらの子どもはMDB(2)の下にいるが,MARGTABLEとMDB(2)は連結されていない.MDB(0)というカードが可視で残ってしまっていることが混乱の原因なのではないかという気がする.

CallBuildShaftLineでは軸線枠の移動が5件発生している.①MARGBOX #689:#798 COUPLING(0)+#1212 coupling(1)→#747 pagesetup(0),②MARGBOX #655:#745 familytree(0)+#1218 FAMILYTREE(1)→#754 BaseLink(0),③mbox=MARGBOX #704:#772 MDB(0)+#1229 MARGTABLE(1)→#908 anod[]配列(0),④MARGBOX #683:#867 配列要素(0)+#1230 MARGLINK(1)→#1231 nodule(3),⑤MARGBOX #715:#880 margbox(0)+#1232 MARGBOX(1)→#882 owner(0).

これらはすべて有配偶者婚だが,stave異常値に関係しているのは,③のMDB(0)+MARGTABLE(1)のように思われる.出力図面で見ると,結婚枠は移動しているが,MARGTABLE(1)の隣接位置に残ったままになっている.明らかに結婚の移動と同時に配偶者も移動する必要がある.MARGBOX::MargBoxTransferという関数があるので,これを使ってみよう.⇒解決した.

image

ただし,この図面にはまだいくつか疑問が残っている.まず,重婚同類1,重婚1というダンプが出ているが,それらしきものが見当たらない.⇒いや,あった.COUPLINGだ.COUPLING はクラス名だが,クラス名はクラスの(代表)インスタンスと婚姻関係を結ぶことになっている.COUPLINGの孫にextraslot2というCOUPLINGのインスタンスがあるためだ.従って,この図面では多重は不可避であり,重婚同類1というのは正しい.

MDBはオブジェクトであり,すべてのオブジェクトはnoduleないしNODULEから派生しているはずなのに,軸線が届いていないのはなぜか?実際,上図でも右下コーナーに2枚のカードがブルー表示されている.これは養親子系血族であることを示しているのだが… 軸線の選び方が悪いのか,あるいは単なるデータの不備か?軸線の終端ノードの_goodson は子どもがいないのでここで止まるのは仕方ないが,別の経路があったのではないか?

MDBの孫の配列要素はnoduleという子どもを持っているが,最長鎖の長さでは同じになってしまうために選択されなかったのだろう.noduleは「クラス」なので,親はすべてクラスかないしクラス+オブジェクトだ.MDBの軸線の下流系はすべてオブジェクトばかりでnoduleに接続していない.MDBの軸線上のノードは先祖ノードのCOUPLINGを除くとすべてオブジェクトだ.先祖ノードをcouplingに取れば首尾一貫するのだが… 多分父系/母系を指定できるようになればある程度選択可能になるとは思われる…

上記サンプルを#1 couplingでソートしてMARGBOX:setownerで停止した.結婚枠とownerの世代が整合しないというエラーだ.⇒軸線グラフ検定は重婚クラスタ検定より前に実施されるため,まだ絶対世代番号は確定していない.この段階では世代の不整合は見過ごしてもよいのではないだろうか?⇒エラーを無視して描画は可能.MARGBOX::setownerで出る「結婚枠世代不一致」以外にも,「兄弟世代番号不一致」がMARGBOX:checkVerticalPositionで多数発生する.

checkVerticalPositionでは検査の直前に結婚枠と兄弟ノードの世代番号を一致させる処理を実行しているのだが… このエラーの原因はネストした処理の中で系列ポテンシャルが更新されているためだ.本来CheckVerticalPosition中は「系列優先実仮ノード世代差の補正はここでは行なわない」としているのだが,穴が空いているところが(複数箇所)あった.

「CheckVerticalPosition中は系列ポテンシャルの変更不可@20210212」としてエラーは解消した.MARGBOX:CheckVerticalPositionの出口ではSAMEGENEMARRIAGEフェーズでのみTRIBEBOX::adjustGenerationRangeを実行しないとしていたが,これに加えてAFTERMARGSAMEGENEフェーズの場合も同様に抑制するようにした.

image

一応描画はできるようになったが,2つ問題がある.①画面下部で垂直スプリットが発生している,②軸線が通っていない.まず,①の問題から見てゆくことにしよう.絶対世代番号はLIST[8]→ DATALIST[9]→ nodule[10]となっているが,実際にはLIST[8]→ [9]→ DATALIST[10]→ [11]→ [12]→ nodule(3)[13]のように伸びてしまっている.

noduleは(0)と(3)で多重になっているが,世代的には(0)の方が正しい.LISTとDATALISTには同名で♂型と♀型の2種があるので混乱するが,リネームしないでこのまま進めよう.まず,DATALIST♂がなぜシフトされているのかを見ておこう.重婚クラスタ図を出力すると,下図を得る.

image

これは重婚グラフと呼ばれるもので,ShiftDirectAbsoluteでは婚姻グラフの連結成分リストを基準に世代割当てを実施している.上図で各カードの右肩に付いている数字は,グラフ節点の「距離数」と「絶対世代番号」だ.距離数はすでに正規化しているので,世代番号と一致している.この値は,婚姻グラフの連結成分リストの要素(重婚クラスタ)にも転記されているはずだ.というか,重婚グラフの節点は婚姻グラフの連結成分に他ならないので,当然この値が設定されていると考えてよい.