「右枝ノードが結婚枠を親参照していない」

源氏物語全系譜6.1.ZELの法定親族図を基準ノード=#74 薫で開いて,NAMEBOX::DoublyBlessedOne→ MARGBOX::CheckLongTailからNAMEBOX::makeLongTailを実行して,結婚枠の右枝が結婚枠を親参照していないというエラーになる.この不良はNAMEBOX:BundleStringの中で発生している.この関数は「LDR束線分移動後束芯を一致させる」ためのもので,問題のノード#21950 浮舟(2)はLDRだ.#21929 中姫君(1)と#21950 浮舟(2)が束ねられている.LDR束に束ねられた線分はすべて先頭LDRを親参照するようになっている.これはLDR束全体が一体化したものとして操作される必要があるためだ.

つまり,このノードは結婚枠に含まれる描画要素ではあるが,実態はすでに外部にあると考えなくてはならない.従って,これはエラーではなくノーマルな状態として扱われるべきだろう.これを判定する基準は,「そのノードがLDR束線分に属し,LDR束先頭線分が別の結婚枠を参照している場合」ということになる. しかし,MARGBOX:CheckMarchainで「右枝ノードが結婚枠を親参照していない」という不良が検出されるときには,このノードはすでにLDRではなく,通常の「消去された仮ノード」に戻ってしまっている.

LDRでなくなったとき,ないし,LDR束から離脱した時点で親参照の付け替えがなされなくてはならないと考えられる.LDR束線分属性はBUNDLEDSTRING,LDR属性はELDERWIFEだが,BUNDLEDSTRINGの解除の方が先行するものと思われるので,その時点を特定してみよう.NAMEBOX::PairBoxGeneChangeで実仮世代差ゼロとなり,NAMEBOX::TailSheddingを受ける時点でリセットされている.BUNDLEDSTRINGをリセットしている場所は7箇所ある.個別対応するのも難しいので,resetghostbitsの中で一括処理するようにしてみよう.⇒対処した.

源氏の完全木テストが完了した.

image

フルスペック版の36分39秒に比べるとかなり遅い.完全参照リスト管理を外せばそこそこの数字が出る.

image

▲「IsPrimeboxOrNotを有効化」オプションをONにしたバージョンで源氏物語全系譜6.1.ZELの法定親族図を開いて,TRIBEBOX:DecideTribeで「系列タイプ決定不能」が発生する.障害系列はTRIBEBOX #1566 先祖=#1339 伊予介(0)[16] 優先=#1799 軒端の荻(1)→#1449 蔵人の少将(夕顔)(0)で主系列は#1634:蔵人の少将(夕顔)だ.しかし,これはあまり上等な選択とは言えない.蔵人の少将には親も子もなく,軒端の荻との結婚があるだけだ.この不良は「基準ノードの配偶者の外部婚を排斥」オプションをOFFにすれば解消する.しかし,情況は思っていたよりずっと深刻だ.

image

衛門督 (箒木)系列と伊予介系列は位置的にはほぼ接触しているが,始系列につながる連結線をまったく持っていない.これはかなりまずい事態だ.それでも非連結=0となっているのはなぜだろう?どうも根底から見直しが必要となるような形勢になってきた.連結/非連結は「始系列に至る実仮優先ノード経路が存在する場合を連結,そうでない場合を非連結とする」と定義されている.

ゴミ箱,UNDO,グラフ検証系を止めたベーシックZTの動作

リサイクルシステム,UNDOシステム,グラフ検証系を止めたZTベーシックの動作をチェックしているところだが,アプリ終了でnodl_floatのエラーが出ている.今回は「完全参照リスト管理」を搭載した状態でチェックしているところが前回と異なる点だ.参照リストは親オブジェクトが削除されても存続するという仕様になっていることがこの不良の原因と考えられる.~NODULEを修正して,ゴミ箱が未サポートのときには,増設スロットを含むすべてのスロットの下位オブジェクトを削除するようにしてこのエラーは解消したが,こんどは,CallSetCouplingPtrでCOUPLINGを削除した後,rootnodeをクリアするところで無限ループするようになってしまった.

rootnodeにはnullpointオブジェクトが入っている.このオブジェクトは地べたに置かれた根付きのオブジェクトだ.newで生成されたものではないという属性NOTAUTODELETEを持っているため削除できない.このオブジェクトのアドレスを格納しているrootnodeは昨日nodl_floatを修正して,すでに親ノードが死亡しているときには書き込みを行わないとしたため,空にできない状態になっている.ゴミ箱を使っていないときにはオブジェクトの削除=メモリからのパージを意味するから,死亡しているオブジェクトへの書き込みにはリスクがあるが,今の場合書き込むのはオブジェクトではなくリンクを格納しているアンカーなのでその場合だけは例外として処理されなくてはならない.⇒対処した.

これでrootnodeは始末できたが,こんどは_getblock_で「フリーメモリゼロ」というダンプが出るようになった.Nリングに残留オブジェクトが大量発生している.すべてfreeblockオブジェクトだ.なぜだろう?freeblockはCOUPLING:EraseFamilyTreeでfreeblock:ReleaseFreeBlockを使って完全に解放しているはずなのだが…

_getblock_では(!totalblock || !topblock)のとき,「フリーメモリゼロ」というエラーを返している.どうもまた何かメモリ管理に関する齟齬が発生しているようだ.⇒カウントの問題ではない.nodl_floatでIsAliveでないときは処理しないとしているためだ.⇒いや,違う.親ノードがIsAliveでないときは書き込みしない,ただし,対象ノードがNOTAUTODELETEであるときは,無条件で書き込むように修正した.これで「フリーメモリゼロ」も解消し,rootnodeも始末できた.

源氏物語全系譜6.1.ZELの傍系血族図 基準ノード=#51 若宮(匂宮の)でPAIRBOX::RepairCommonEndPointのエラーが出た.端点共有で始点不一致というエラーがPAIRBOX:#42220:#21900 明石の上(1)→#12444(0)と#42320:#22054 源氏宮(1)→#12988(0)で起きている.⇒これは起こり得るエラーだろう.この端点共有には3つのノード対が関係している.①明石の上,②源氏宮,③承香殿女御だが,元々は①承香殿女御,②源氏宮のようになっていた.明石の上と承香殿の始点の誤差は許容範囲内,承香殿と源氏宮の誤差も許容範囲内だが,明石の上と源氏宮では許容範囲を超えてしまう.

端点共有リストをノード対区間の大きさでソートしてやればおそらくこのようなエラーは(ある程度まで)回避できるのではないかと思われるが,必ずしも確実なものではない.許容範囲を倍にしてやればエラー自体は(ある程度)回避できるかもしれない… こちらの方が簡単だが,むしろ傷が深くなる可能性もある.基準となる始点座標を「固定」しない限りこのような変動は避けられない.

とりあえず,ソートしてみることにする.MoveSamePointではSwapBundledPairを実行しているが,この関数を「最大区間の付け替えを実施」するだけでなく,ソートまで実行するようにすればよい.この関数はPAIRBOX::MoveSamePoint,PAIRLIST::RepairPairBox,NAMEBOX::makePairBoxで使われている.⇒対処した.⇒最終的には上の3つのノード対の端点共有は崩れて分解してしまう.

▲同上サンプルの法定親族図を#74 薫でソートしてMARGBOX:CheckMarchainで停止した.結婚チェーン不整合が起きている.NAMEBOX::BuildMarChain→ CheckMarchainで不良が検出されている.NAMEBOX:#11679 八宮(0)の結婚チェーンで,要素は2つ.MARGBOX:#10223:#11679 八宮(0)+→#11951 大姫君(0)とMARGBOX:#8623:#11679 八宮(0)+#13583 浮舟の母(0)→ だ.前者は可視,後者は不可視でBTWの右手結婚枠.

「右枝ノードが結婚枠を親参照していない」というエラーが起きている.障害ノードはMARGBOX:#8623でYRにはNAMEBOX:#21950 浮舟(2)が入っている.浮舟(2)はこの結婚枠の最初の子どもなので当然結婚枠を親参照しているべきところだが… どこかで外れてしまっているのだろうか?⇒どうも最初から失敗しているようだ.

ネカフェでウクライナ・クライシスを観る

昨日の夕刻,ネカフェでVAIO2にVisual Studioをインストールしようと思って自転車で出かけた.ヨーカ堂の交差点を右に曲がってまっすぐ南に向かう.そこからは緩い勾配がだらだらと続き,ペダルを踏む力も段々と弱くなって最後自転車を降りてしまった.この道は街外れのスカイアルミの前を東西に走る道路に突き当たって止まる.この道になければその右側を通っている別の道か左側の道のどちらかしかないのだが,両方を試していたらへばってしまいそうなので,広い駐車場脇のテイクアウトショップの明かりに引かれ中に入って道を尋ねた.「ネカフェですか?この辺りにはなかったと思いますよ」と言われてすごすご帰りかけたらもう一人の店員が,「この交差点を左に進んで次の交差点で左に曲がると左にあります」と教えてくれた.(外でまごまごしていたら,出てきてもう一度今度は手ぶりで教えてくれた)

ネカフェの受付で会員カードの提示を求められたが,財布の中には入っていない.何か身分証明書のようなものはありますか?と言われて探したらマイナンバーカードが入っていた.喫煙席というのはすでになくなっていたが,別途入口の辺りに喫煙コーナーのようなものが設置してある.VS 2017 Communityは途中までダウンロードしてあったが,追加してVS 2019もインストールすることにした.

ダウンロードしている間手持ち無沙汰なので時間つぶしに「無料動画」というのを視聴してみることにした.「ウクライナ・クライシス」という比較的最近のネタを主題にした戦争物(ウクライナには友人もいる).インストールは一時間程度で完了したが,2時間近くの長い映画を最後まで見てしまった.(ネカフェで1000円掛けて一本の映画を見るのなら深谷シネマの1200円は高くないかも…)

Visual Studio 2017では従来のセットアッププロジェクトをサポートしていない.これを実行するにはMicrosoft Visual Studio Installer Projectを拡張機能としてインストールする必要がある.⇒このくらいはできるだろうと思ったが,Windows復元ポイントを作成していますというところでフリーズしてしまった.ネットには接続している… 中断したら,今度はVS 2017が起動できなくなってしまった.VS Installerを再実行する必要があるという.⇒「再開」で717MBを新たにダウンロードし始めた.150KB/秒くらいでダウンロードしている.終わるだろうか?スピードは段々落ちているので止まってしまうかもしれない.どうもやはりダメのようだ.30KB台まで落ちている…

▲DEFINETRASHCAN(リサイクル),DEFINEUNDOSYSTEM(UNDO),SUPPORTSIMPLEGRAPH(グラフ検証系)を停止したバージョンを走らせてアプリ起動→終了~NODEREFLIST→~DATALIST→… Dispose→ nodl_floatから(*moto)[edan] = NULLで停止した.edan=REFERIST=-2が入っている.親オブジェクトのmotoはすでに削除されている.⇒IsAliveであるかどうかをチェックするようにした.⇒今度は別のエラーが出るようになった.NODEREFLISTの親ノードスロットにデタラメな値が入っている.

UQモバイル月額1980円3GBのプランSから2980円10GBのプランRに切り替えた

最近は包括テストを割と頻繁にやっているので,tamo2さんから送られてきたVAIO2をテスト専用機に仕立ててみようと思ったのだが,Visual Studio 2017をダウンロードできなかった.現在使っているUQモバイルはMAX3Gという契約だが,VS 2017をフルインストールしようと思ったら,50GB以上の容量がなくてはならない.必要最小限までカットしてダウンロードサイズを7GBくらいまで切り詰めてみたが,ダウンロードを開始して間もなく,UQモバイルから「上限オーバー」の通知が届いた.その後は秒速30~0KBまで落ちて来たので布団を被って寝てしまったが,朝起きてみるとほとんど前日と変わらない状態で停止していた.

すでにWIMAX2+は解約してしまったので代替手段がない.UQモバイルは最終的には10GBで2980円という契約に切り替えるつもりだが,直ちには間に合わない.後はネカフェに行ってダウンロードするか,どこか公共WiFiを探すかしかない.確か,つい最近新装オープンしたばかりの市役所にはWiFiがあると聞いているのでそこに行くことも考えられるが,緊急事態宣言の渦中であまり人の集まるようなところには行きたくない.UQモバイルの契約変更を検討してみることにしよう.

月額1980円3GBのスマホプランSから月額2980円10GBのプランRに切り替えた.プランRの利点は容量を使い切ってもMAX1Mbpsが保証されるという点だ.もっともそれがどの程度実効性があるかは分からないが… 契約変更はネットで簡単に終わったが,回線は来月1日にならないと切り替わらない.それまで待ってもよいが,しばらく外出していないので,今日はネカフェに行ってみようかと思う.

リリース版を開発機にインストールした.これまでの版では走らせるたびにデスクトップ上に反例サンプルの山を築いてしまうので閉口していたのだが,ようやく多少まともな版が動くようになった.源氏の完全木テストが完了している.前回と同様デバッグモードだが,前回が34分37秒だから,大分遅くなっている.

image

12分というのは無視できない数字だ.余分なダンプなどをカットしてむしろ多少なりとも速くなるのではないかと思っていたのだが… 何が影響しているのだろう?今は,まだ時間効率を追求するときではないのでまぁ,こんなものだろうということにしておこう.VAIO2にZTをインストールして走らせてみたが,どうも画面のイメージがしっくりこない.メニュー項目の文字サイズがやけに大きくてぼやけている.逆に系図画面上のカードの文字は虫メガネが必要なくらい小さい.逆にカード画面の文字はバカでかく見える.

image

原因はわかった.VAIOの画面を外付けモニターにクローンで表示しているためだ.拡張スクリーンにすればノーマルな解像度で表示できる.

image

これなら申し分ない.PAIRBOX::CalcPairBoxを廃止して,もう一度完全木テストを実施してみた.

image

今度は前回と同等の数字になった.CalcPairBoxの廃止は,端点共有の先頭ノード対をつねに最大区間とするという変更と関わりがある.以前はCalcPairBoxで端点共有の包括矩形領域を計算してそれを先頭ノード対の包括矩形領域に書き込むようにしていたが,その計算が不要となった.

NOCOMMONPAIRノード対は端点共有束で唯一でなくてはならない

源氏物語全系譜6.1.ZELの直系血族図 #114 先帝でPAIRBOX:SwapBundledPairのエラー,「NOCOMMONPAIRノード対は端点共有束で唯一でなくてはならない」というルールの違反が起きている.PAIRBOX:#23978:#20650 冷泉院(2)→#20622(1)とPAIRBOX:#26892:#26825 冷泉院(3)→#20622(1)が競合している.どちらもNOCOMMONPAIRで端点共有の中では両存できないことになっている.ノード対の仮ノードが前者は実親子関係,後者は養親子関係であるという点からも共存できないとされるのだが…

PAIRBOX:MoveSamePointではCheckCommonEndPointで端点共有を見つけているのだが,おそらくルールが甘いのだろう.CheckCommonEndPointではsearchCommonPairで候補を見つけた後,共有種別不一致と始点共有の親子関係のチェックを実施している.⇒判定が悪いのではなく,ロジックが悪い.端点共有候補がリジェクトされた場合もリセットされないため,ループから出るときその値が残ってしまっている.⇒修正した.

image

CheckCommonEndPointのロジックをsearchCommonPairに移植した.この論理はCheckCommonEndPointの追加条件ではなく,searchCommonPair自身が判定できなくてはならない.親子関係による実子太線,養子細線の別は,細線の方が長ければ判別できるので,その条件も加味してより詳細化した.これでノード対の端点共有論理は完全にsearchCommonPair一本に統括できたのではないかと思う.

同上サンプルの全体図:#1 光源氏でPAIRBOX:#60400:#23602 蛍兵部卿宮の前の北の方(1)→#13153(0)の端点共有が解決できない.⇒searchCommonPairでは共有種別を返していない.⇒対処した.

同上サンプルの傍系血族図:#42 朱雀院でMakePairListClean中,PAIRBOX:MoveChannelToで停止した.この関数は対象ノード対が直列リスト上にあることを仮定しているが,端点共有ノード対が引っかかった.⇒障害ノードはPAIRBOX #38053:#21312 雲井の雁(1)→ #12405(0)で,PAIRBOX:#38039:#21295 玉鬘(1)→ #10977(0)に繋がっている.CheckPairEndPoint→ CheckInverseCycle→ PAIRBOX::RepairVerticalInverseで起きている.

この関数では「始点終点が同一座標で逆転」が起きたときの処理を実施している.「逆転循環検定」は端点共有とまったく関わりがないと考えられるので,MoveChannelToに変わるノード対単体の移動ができる関数を用意する必要がある.MoveChannelToの中で使っているTakeoutを小文字のtakeoutに変えればよいと思われるので,引数で判別できるようにしてみよう.⇒対処した.

同上サンプルの傍系血族図 基準ノード=#57 女三宮でPAIRBOX:RepairCommonEndPointの出口検査で停止した.PAIRBOX #39234:#21555 蛍兵部卿宮の前の北の方(1)→#13153(0) の「共有端点不一致」が解決していない.CheckSamePointの判定のロジックが悪いのではないか?現行では対象ノードが端点共有代表ノード対の場合に限って検査しているが,その逆ではないか?つまり,代表ノード対を基準にして他のメンバーが間違っているかいないかを決めるべきではないのか?⇒書き直してみよう.⇒うまくいったようだ.

同上サンプルの傍系親族図 基準ノード=#135 致仕太政大臣の北の方でNAMEBOX::IsPossibleBTWLeftHandのエラーで停止した (rightwife->IsLeftHandBox())というエラーが起きている.BTW(Between Two Women)の右手結婚枠配偶者が左手結婚枠本人というエラーだ.エラーを無視して描画は可能.障害ノードはNAMEBOX #21314 冷泉院(1).冷泉院は結婚を7つ持っている.子どもは3人で弘徽殿女御との子ども女一宮と冷泉院の御息所との子ども女二宮,若宮だけだ.この図面は致仕太政大臣の傍系親族図なので,表示されているのは冷泉院+弘徽殿女御→女一宮だけのようだ.⇒いや,違う.

image

表示されている結婚枠は3つ,弘徽殿女御,冷泉院の御息所,秋好中宮の3箇所だ.冷泉院の仮ノード(人名枠)は5つ出ているが,うち,可視ノードは弘徽殿女御のところに出ている(0)と上図右端の光源氏の下の2つだけだ.桐壷院の下の養子ノードは消去された仮ノードになっていて,残り2つがBTWに関係している.⇒この図面は他にもいろいろ問題があるが,保留して先に進もう.ここでは「右手配偶者が左手本人で停止しない@20210108」としておく.

▲HOMEキーが利かなくなっている.

同上サンプルの法定親族図:#110 弘徽殿大后を開いてNAMEBOX:makePairBoxで停止した.ノード対冷泉院(3)→#101539147(1)で「共有端点不一致」が発生している.makePairBoxは新規ノード対を生成する関数だが,この時点で端点共有可能であれば端点共有を実施している.makePairBoxが呼び出される前にこの端点共有は指定されていて,それを決定しているのはAvailableChannelだ.

この関数は内部でSearchSamePointPairを呼び出している.SearchSamePointPairはNAMEBOX::IsBindablePair→ getCommonPairで判定している.NAMEBOX::IsBindablePairは複数箇所から呼び出されている.判定基準をすべての箇所で統一する必要がある.Bobject:getCommonPairTypeという関数を作ってNAMEBOX::IsBindablePairから呼び出すようにした.この論理はPAIRLIST::searchCommonPairから切り出してきたものだ.

しかし,これだけではエラーは止まらない.今度はノード対生成後に,端点共有エラーが発生するようになった.元々あったノード対の連結線の方向が逆向きに変化している.これは仮ノード消去によってトポロジーにドラスティックな変化が生じたためと考えられる.⇒この変化はNAMEBOX::EraseGhostNodeの中でEraseGhostを実行することによって生じているので,端点共有サーチを実施する前にEraseGhostを実行するように書き換えた.⇒これで一応解決したが,searchCommonPairもこの関数を使うように書き換える必要がある.

傍系血族図 基準ノード=#75 葵の上でソートしてPAIRBOX:SwapBundledPairで「NOCOMMONPAIRノード対は端点共有束で唯一でなくてはならない」というエラーで停止した.⇒このエラーはNAMEBOX::makePairBoxで発生している.実際には複数のNOCOMMONPAIRが発生していた訳ではないが,その点を修正しても「最大区間でないnocommonを別チャンネルに移動」が発生する.これは,端点共有を探すときにはまだ,ノード対実ノードのNOCOMMONENDPT属性がセットされていないためだ.これを避けるためにgetCommonPairTypeに渡す引数でNoCommonGoodSonをチェックするようにした.

傍系親族図 基準ノード=#133 麗景殿女御(朱雀院の)でソートしてPAIRBOX::CheckSamePointで停止した.対象ノードが直列リスト上にないというエラーだ.障害ノードはPAIRBOX:#36478:#21473 冷泉院(3)→#21310(1)で右始点共有となってはいるが,所属しているノード対はこれだけだ.これは結局,samepointが間違った値を持っているということを意味する.この不良は「非共有対でsamepoint」としてCheckPairBoxで検出されているが,CheckSamePointに伝達されていない.このようなパラメータ不良が発生したときは,CheckSamePointを呼び出さずにCheckPairBoxでエラー復帰するようにした.

takeoutでノード対を削除して端点共有が解消した場合には,samepointをリセットしておくべきだ.⇒一応そのような論理は整備されているのだが… 何か穴があるのだろうか?⇒ノード対の移動関数には,takeout, Takeoutの他,MoveChannelTo,MoveSamePointがある.PAIRLIST::dataCountDownにも所要の修正を入れた.⇒いや,ここに入れても効果ないのではないだろうか?dataCountDownは事前処理であり,この時点では接続関係に変化はないはずだ.

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

image

所要時間を以前のレコードと比較したいのだが… 2020/03/12に「源氏4の完全木テストとパックマン全点をPCで並行して走らせておいたのだが,完全木テストの方は5726面:12時間12分21秒で完了していた.」というのがあった.2020年3月なら多分開発環境はいまと同じではないかと思うのだが… 5726面で12時間も掛かっている.今回の検定図面数は2862面で約半分だが,30分そこそこで完了している.体感的には「昔より遅くなった」ような気がしていたのだが… 1台のマシンで2つのテストを並列実行するというのは少し負荷が大き過ぎるような気もするが,それを差し引いてもかなり大きな落差がある.

いや,違う.上の引用は2012/03/12投稿の記事だ.確かにこの頃ならそんなものだったかもしれない.CPUも速くなっているし,この頃はおそらくまたリサイクルシステムも導入されていなかったはずだ.確かに,源氏の完全木テストが30分くらいで終わるというのはこれまで見たことがないような気がする.もう少し整理したらリリース版を起こしてみることにしよう.リリース版は多分これよりずっと速いと思う.

端点共有ノード対が削除されて共有ノード対が単体に戻ったときにsamepointをリセットするために,PAIRLIST::deleteElementを新設した.これで上記傍系親族図 #133 麗景殿女御で出ていた問題は完全にクリアできた.Bobject::getCommonPairTypeという関数を作ってあるので,PAIRLIST::searchCommonPairでこの関数を使うようにする必要がある.⇒対処した.これで端点共有に関する修正は基本的に閉じたのではないかと思う.リリース版を起こしてみよう.

RepairCommonEndPoint「右端点共有で種別不一致」

源氏物語全系譜6.1.ZELの全体図を#12 桐壷の更衣の母でソートして,PAIRBOX::MoveChannelTo→ PAIRLIST::Takeoutで停止した.この関数では対象ノード対が直列リスト上にあることを仮定している.⇒「共有端点不一致」で「端点共有解除」していなかった.

バックアップも取ったので,ここで修正をフィックスしておこう.

  1. CheckSamePointの戻り値仕様変更@20210106 3箇所
  2. CheckSamePointとCheckPairBoxを統一@20210106 4箇所
  3. CalcPairBoxからSwapBundledPairを切り出す@20210107 4箇所

同上サンプルを#97 若君(紅梅の)でソートして,NAMEBOX:makePairBox→ CheckPairBoxで停止した.「最大区間ノード対の逆転」が起きている.ここでは新規ノード対を生成して端点共有束の末尾に直接接続している.PAIRBOX::SwapBundledPairを実行して最大区間ノード対を差し替えるようにした.

同上サンプルを#106 六条御息所でソートして,TOPOLOGY:CheckPairEndPointでループカウントオーバーが発生した.PAIRBOX #59496:#22720 玉鬘(1)→#10977(0)とPAIRBOX #59510:#22766 雲井の雁(1)→#12405(0)が関係する端点共有だ.玉鬘のノード対が「危険対」になっていて,共有解除と共有設定が反復されている.⇒searchCommonPairでCRITICALPAIRを弾くようにした.

同上サンプルを#110 弘徽殿大后でソートして,COUPLING:TopologicalSort→ TREEVIEW::EraseTreeViewを実行中,PAIRLISTのcancelでデータ数不一致が発生した.detacount=0でデータが残留している.弘徽殿大后の前は,#109 二条太政大臣だ.この事象は#109 二条太政大臣で開いて→終了でも再現できる.この障害はTribeRelocationの出口ではすでに発生している.

障害が起きているのはPAIRLIST #29168だ.MoveSamePointの実行によって生じている.MoveSamePointでは移転元リストと移転先リストが異なるときだけカウントアップする論理になっていた.しかし,これは誤っている.移転元ではつねにカウントダウンしているので,移転元と移転先が同じ場合でもカウントアップは必要だ.

同上サンプルを#123 左大臣の女御でソートして,PAIRBOX:RepairCommonEndPointの出口検査で停止した.「右端点共有で種別不一致」というのが起きている.障害ノードはPAIRBOX #60318:#23480 蛍兵部卿宮の前の北の方(1)→#13153(0)とPAIRBOX #60343:#23492 致仕太政大臣の北の方(1)→#13170(0)だ.samepointにはCOMMON_LEFTEND 左終点共有が入っている.しかし,その前には「左端点共有で種別不一致|端点共有で始点不一致」というのも起きている.確かに,この時点ではそうなっているようだ.

この事例はいろいろと問題がある.共有解除する前の状態は蛍兵部卿宮の前の北の方と致仕太政大臣の北の方の他にPAIRBOX:#57882:#22568 冷泉院(4)→#11028(0)も加わっている.おそらく,この三者は最初から三つ巴の状態になっていたのではないかと思われる.

従来論理では端点共有の接続種別の判定をNAMEBOX::IsBindablePairで実施しているが,この関数の解釈は間違っている.現行のsearchCommonPairの解釈と合わせる必要がある.PAIRBOX:getCommonPairという関数を作って論理の共通化を図った.これで完全に問題は解決した.致仕太政大臣の北の方と蛍兵部卿宮の前の北の方はどういうフローになっているのか分からないが,最終的には端点共有で収まっている.ただし,蛍兵部卿宮の前の北の方と朧月夜はなぜか共有にならない.これは別途調べる必要がある.

▲同上サンプルの直系血族図 基準ノード=#114 先帝でPAIRBOX:SwapBundledPairのエラー,「NOCOMMONPAIRノード対は端点共有束で唯一でなくてはならない」というルールの違反が起きている.

image

藤壷の宮から冷泉院に連結線が2本入っている.1本は桐壷院+藤壷の宮,もう1本は光源氏+藤壷の宮だ.冷泉院は光の実子で桐壷院とは事実上義理の関係にあるため,2本の連結線の太さで書き分けている.もし,これがどちらも養親子関係であったとすれば,長さが同じでNOCOMMONのノード対が2つ存在することになる.

この意味で「NOCOMMONPAIRノード対は端点共有束で唯一」というルールは必ずしも絶対とは言えないのだが,今の場合は,「始点共有で実親子関係⇔養親子関係が一致しない場合は共有不成立 実親子と養親子では連結線の太さが違うなど不具合が発生するため」というルールが適用されなくてはならないところなのだが…

CheckSamePointの戻値の仕様を変更する

「端点共有束全体を移動する@20210105」オプションをフィックスしてから進むことにしよう.7箇所ある.仮修正が19箇所.

源氏物語全系譜6.1.ZELの全体図を#3 桐壷の更衣でソートしてPAIRBOX::RepairCommonEndPointの出口でCheckSamePointエラーが出る.「端点共有で始点不一致」が起きている.障害はPAIRBOX:#234599:#199072 明石の尼君(1)→#188661(0)とPAIRBOX:#234457:#198879 先帝の后宮(1)→#188559(0)で起きている.両者の区間は前者が(-207, -117),後者が(4066, 3989)のようにかけ離れているので,最初の判定が間違っていたか,ないし関係するノードのいずれかが大きく移動しているものと思われる.

このエラーはTOPOLOGY::CheckPairEndPoint→ PAIRBOX:RepairCommonEndPointで起きている.RepairCommonEndPointの目的は「対象ノード対の端点共有状態を検査し再構成する」なので,それに失敗していると考えるしかない.RepairPairBoxで修復を試みているが,変化していない模様だ.

CheckSamePointの従来の仕様では,エラーがあるかないかを示すだけのブール値を返していたが,仕様を変更して障害の詳細な要因を返すようにした.これらのビット定数はコード内から日本語でアクセスすることができる.障害をダンプするときにも,数値だけでなく名前まで表示できるようにした.

  1. 無効なノード対 disable状態のノード対
  2. 長さゼロのノード対 長さゼロのノード対は無視する
  3. ノーマルなノード対 ノーマルなノード対(端点共有束を含む)
  4. 実仮ノード不在 ノードないし仮ノードが取得できない → 不良
  5. ノード対不一致  仮ノードの参照するノード対と現物が一致しない → 不良
  6. カードリンク不一致 仮ノードと実ノードで参照する人名リンクが一致しない → 不良
  7. NOCOMMON属性不整合 実ノードとノード対でNOCOMMON属性が整合しない → 不良
  8. 直列リスト上にない非共有対 非端点共有ノード対でBundledTopが間違った値を返している → 不良
  9. 非共有対でsamepoint 直列リスト上の非端点共有ノード対がsamepointの値を持っている → 不良
  10. 最大区間ノード対の逆転 端点共有リストの先頭ノード対が最大区間ノード対でない → 順位入れ替え
  11. 危険対を端点共有 始点終点が同一座標で逆転するノード対を端点共有 → 端点共有解除
  12. NOCOMMONGOODSON NOCOMMONGOODSONで端点共有代表でない → 端点共有解除
  13. NOCOMMONで非共有代表 実ノードがgoodsonであるノード対は最大区間でなくては共有不可 → 端点共有解除
  14. samepoint不良 端点共有ノード対のsamepointが代表ノード対と一致しないかゼロ → 端点共有解除
  15. 共有端点不一致 端点共有ノード対で座標不一致 → 端点共有解除
  16. 左端点共有で種別不一致 左端点共有でsamepointが一致しない → 端点共有解除
  17. 右端点共有で種別不一致 右端点共有でsamepointが一致しない → 端点共有解除
  18. 端点共有で始点不一致 始点共有で始点が一致していない → 端点共有解除
  19. 端点共有で終点不一致 終点共有で終点が一致していない → 端点共有解除
  20. 端点一致でsamepointゼロ 端点共有可能なノード対のsamepointがゼロ → 端点共有
  21. 端点共有でsamepointゼロ 端点共有束上のノード対でsamepointがゼロ → 端点共有
  22. 直列リストノード対の衝突 直列リスト(同一チャンネル)上のノード対区間で交叉している → チャンネル移動(連結)
  23. 端点共有解除 シンメトリ婚/危険対の端点共有を解除する → チャンネル移動(単体)

CheckSamePointで「端点一致でsamepointゼロ」というエラー

源氏物語全系譜6.1.ZELの全体図を#127 摂政太政大臣でソートしてPAIRBOX:repairCommonEndPointの出口でGENELIST:CheckPairBoxの不良ノード対エラーにより停止.CheckSamePointで「端点一致でsamepointゼロ」というエラーが起きている.問題のノード対はPAIRBOX:#49223:#23382 蛍兵部卿宮の前の北の方(1)→#13126 蛍兵部卿宮の前の北の方(0).

PAIRBOX:#49223:#23382 蛍兵部卿宮の前の北の方(1)→#13126(0)と#49237:#23394 致仕太政大臣の北の方(1)→#13143(0)が端点共有と認定されているが,CheckCommonEndPointでは端点共有なしを返している.つまり,CheckCommonEndPointとCheckSamePointの基準が異なる.⇒CheckSamePointのロジックから,PAIRLIST::searchCommonPairという関数を作り,CheckCommonEndPointから呼び出すようにした.

系統並び替えの出口検査でCheckPairListのエラーが検出される.サンプルは源氏物語全系譜6.1.ZELの全体図 #1 光源氏.CheckPairBoxCollisionで障害が発生している.ノード対の衝突が5件発生している.この障害はHeapTribeBoxesを実行することで発生している.たとえば,PAIRBOX:#55361:#23947 八宮の北の方の母(1)→#14452(0)とPAIRBOX:#55518:#24194 受領(1)→#15438(0)が衝突している.

これは当然あり得ない.受領はまるきり離れた別系統のノードだ.これは,HeapTribeBoxesの中で独立系列をMoveRectRightで前詰めしているために起きている.ノード対管理は全域的に実施されているため,別系統のノード対とも数字的には衝突が起きる可能性はある.区間計算で用いている数字は,あらかじめ計算されてノード対の矩形領域に格納されているものが使われているためだ.

HeapTribeBoxesの実行後に再計算するか,ないし直接値を計算するしかない.衝突はPAIRLIST::VerifyPairBox→ CheckNormalizedSectionで検出されているので,この関数では値を直接計算するようにしておこう.⇒だいぶ正確に動作するようになってきたようだ.

同上サンプルを#2 桐壷院でソートして,CheckCommonEndPointで停止した.PAIRLIST::searchCommonPairとCheckCommonEndPointの判定が相反している.⇒searchCommonPairでは計算誤差を見ているのに対し,CheckCommonEndPointでは厳密値を適用しているためだ.⇒対処した.これでエラーは解消したが,別のエラーが発生している.

同上サンプルを開いて,PAIRBOX::MoveSamePointで停止する.この関数は対象ノード,移動先ノードともに直列リスト上のノードと仮定している.⇒searchCommonPairで端点共有の中まで探していた.

同上サンプルを#12 桐壷の更衣の母でソートして,TRIBELIST:MakePairListCleanでループカウントオーバーになった.PAIRBOX:#53758:#23537 致仕太政大臣の北の方(1)→#13143(0)の補修を反復しているようだ.衝突の相手方は毎回変化している.どうも補修が循環してしまっているように思われる.⇒#156006 ノード対:四宮(桐壷院の)(1)→(0)が割り込んで,致仕太政大臣の北の方を共有端点から追い出しているようだ.判定ではAfordableChannelが使われている.⇒checkNormalizedSectionで正規化していない区間を使っていた.

同上サンプルの#13 春宮でTOPOLOGY::CheckPairListのループカウントオーバーが起きた.PAIRBOX::CalcPairBoxで最大区間ノード対の逆転を解決が反復されている.PAIRBOX:#54628:#23016 致仕太政大臣の北の方(1)→#13143(0)とPAIRBOX:#54614:#23004 蛍兵部卿宮の前の北の方(1)→#13126(0)の入れ替えが実施されている.蛍兵部卿宮の前の北の方は同じチャンネルの葵の上のノード対と衝突して一旦チャンネルを追い出され,その後もう一度端点共有でこのチャンネルに戻るという動作を繰り返している.

端点共有ノード対とそうでないノード対の衝突では非共有ノード対側で処理するようにしてエラーは一応解消したが,端点共有同士の衝突という可能性もあり,むしろ,端点共有ノード対を移動する場合は端点共有束全体を移動するようにすべきだろう.チャンネル移動はPAIRBOX::MoveChannelToで実施している.

あらたまの年も新たに去年の月

image

今年はいよいよどっからもカレンダーが来ない… まぁ,いっか.コロナ時代だ!一旦ここまでの修正をフィックスしてから作業に掛かることにしよう.仕掛りのオプションには以下がある.

  1. DecidePrimaryNodeを書き換え@20201226 1箇所
  2. mergeUpperSegmentで移動禁止@20201227 1箇所
  3. 最大区間ノード対を端点共有の先頭に置く@20210101 25箇所

源氏物語全系譜6.1.ZELの全体図を#18 左兵衛督で開いて,PAIRBOX::CheckPairBoxで不良ノード対エラーで停止.「最大区間ノード対の逆転」が起きている.PAIRBOX:#84668:#23457 弘徽殿大后(1)→#12718 (0) と#50680:#23481 致仕太政大臣の北の方(1)→#13143(0)だ.NAMEBOX::makePairBoxではノード対を生成するだけで,端点共有の調整までは実施していない.ただし,端点共有はチェックされていて,端点共有束には追加されている.PAIRBOX:CalcPairBoxではNOCOMMONの場合には調整しているが,すべての場合をカバーしていない.ここで調整しておくべきだろう.

源氏物語全系譜6.1.ZELの傍系血族図を#5 紫の上(若紫)でソートしてLIST::nextで(PHASE > INITIALSTATE)という理由で停止した.系統並び替えでTribeRelocation→MakePairListCleanを実行しているところだ.PAIRLIST::SearchSamePointPairの中で起きている.この関数は「端点を共有するノード対を探す」ためのものだが,探しているノード対リストに属していないノード対をピックアップしてきたように思われる.IsBindablePairの中で書き換わっているのではないだろうか?

IsBindablePairの中でPAIRBOX::CalcPairBoxが実行され,「最大区間ノード対の逆転を解決」によってリストが再編されている.このため,直列リスト上にあったPAIRBOX:#35362:#21617 雲井の雁(1)→#12378(0)が端点共有リストの下位に移ってしまっている.IsBindablePairの中でPAIRBOX::CalcPairBoxが実行されること自体問題だが,最大区間先頭の調整が遅れていることも問題だ.いや,この動作はPAIRLIST::RepairPairBoxGenerationの中で起きているので,状態がある程度流動的になるのは避けられないのではないか?

IsBindablePairの中でCalcPairBoxを実行しないことでこのエラーは解消したが,雲井の雁と玉鬘の端点共有が崩れてしまっている.なぜか?⇒明石中宮と雲井の雁が同一チャンネルに入ったため,玉鬘が加わる余地がなくなったためと考えられる.(最終出力では明石中宮と雲井の雁は同一チャンネルにはなっていない… )最適解を求めるとすれば,玉鬘と雲井の雁の端点共有を成立させた上で,明石中宮は別チャンネルに移るというのが正解と思われるが,そこまでの動作にはなっていない.これで見ると,最優先すべき条件は端点共有であるということが分かる.

▲源氏物語全系譜6.1.ZELの全体図を#127 摂政太政大臣でソートしてPAIRBOX:repairCommonEndPointの出口でGENELIST:CheckPairBoxの不良ノード対エラーにより停止.CheckSamePointで「端点一致でsamepointゼロ」というエラーが起きている.問題のノード対はPAIRBOX:#49223:#23382 蛍兵部卿宮の前の北の方(1)→#13126 蛍兵部卿宮の前の北の方(0).

ノード対の「端点共有で始点不一致」エラー

多重カードを削減する基本的な方法は二つのカードを連結線で接続して片方のカードを削除することだ.このような連結線のうち,親から出て子どもに入るように見える親子連結線の水平部分をノード対と呼んでいる.これはノード対の両端に同一人名のカード(一方は可視,他方は不可視)が接続していることによる.ノード対の処理はZTシステムのコンポーネントの中でももっとも基本的なパートとなっている.

これらの水平連結線を交叉しない範囲でできるだけ簡潔に描画するというのはかなり難しい課題で,達成目標はベストエフォート(できる限り)ということになっているのだが,どうもあまりできがよくないので見直す必要が出てきた.おおまかな方針を決定し,すでに実装も進んでいるので,バグを潰しながら整理してゆくことにする.

NAMEBOX::makePairBoxでCheckSamePointの「端点共有で始点不一致」エラー.障害ノード対は#1226:#1099 雲井の雁(1)→#587 雲井の雁(0)と#1225:#1098 玉鬘(1)→#419 玉鬘(0)だ.⇒解決済

源氏物語全系譜6.1.ZELの傍系血族図の基準ノードを#13 春宮から#1光源氏に変えて,系統並び替えの冒頭でノード対リストのcancelを実行中,PAIRBOXの削除で参照カウントが負になった.⇒系統並び替えしなくても,アプリ終了だけで再現できる.⇒完全参照リスト管理をオンにしてテストしてみよう.⇒nodule::CheckSansyoで被参照カウント不一致が多発している.#34442 ノード対:蛍兵部卿宮の前の北の方(1)→(0)で参照元ノードリスト不記載,#34134 ノード対:玉鬘(1)→(0)でも同じエラーが発生している.これらは起動時にすでに発生している.LIST::bottomlistへの書き込みだ.PAIRLIST:swapで直接書き込んでいるためだろう.Bottomlist関数を使うようにした.

同上サンプルの全体図:#5 紫の上(若紫)でソートしてMakePairListCleanでループカウントオーバーになった.「最大区間ノード対の逆転」がPAIRBOX:#1492439:#1462069 致仕太政大臣の北の方(1)→#2449 (0)で起きている.親族図:傍系血族図 基準ノード=#5 紫の上(若紫)を開くと,NAMEBOX::makePairBoxでCheckPairBoxのエラーで停止する.⇒エラーを無視して描画は可能.全体図は問題なく開けた.紫の上の全体図を開いて,基準ノードを変えずに反復ソートしたら,3回目でMakePairListCleanの障害が出た.これは初期化が不完全ということを意味している.かなりまずい.

まず,先に最大区間ノード対の逆転がなぜ止まらないのかを見ておこう.PAIRBOX 蛍兵部卿宮の前の北の方(1)→(0)と競合しているが,これを端点共有と認定しているところが誤りだ.(3434, 3293)と(3434, 3293)で向きが逆になっている.⇒PAIRLIST::takeoutで共有解除,PAIRBOX::RepairCommonEndPointとPAIRBOX::MoveSamePointで共有を設定している.CheckCommonEndPointが間違った値を返している.⇒比較対象の矩形領域を正規化していなかった.

これで問題は解決したが,系統並び替えを反復すると動作が変化するというのはとてもまずいので,シューティングしておかなくてはならない.正規化すれば正しく動作するのだから,正規化しなくても動いているというのは,「たまたま」動いていただけと解釈するしかない.しかし,何がどうなっているとそのような動作になるのかを解析するのは難しい.類似のバグがまだ潜んでいる可能性はある.複数のバグが競合して動いたり動かなかったりということもありそうだ.⇒系統並び替えの冒頭で描画要素を完全にクリーンアップすることでソートを反復しても動作には変化が見られないようになった.

その上でCheckCommonEndPointの修正(比較対象矩形領域の正規化)を行うと,連結線のもつれはほぼ完全に消えた.これまでは端点共有と通常ノード対の区間交叉がかなり見られたが,一見したところ見当たらなくなった.EraseTreeViewで行っている描画要素のクリーンアップは多少時間コストは掛かるが,これを実行しておけば間違いはない.

類似した関数にInitTreeViewというのがあり,修正履歴では「InitCoupling>InitTreeViewを廃止@20201208 余分な処理になっている → FIXED@20201209」となっているので,多分使わなくてよいのではないかと思う.この関数は,現在,①FAMILYTREE:callSendCard,②FAMILYTREE::getNewCardで使われている.

「InitTreeViewをCOUPLINGのコンストラクタに移動@20170731」というコメントもあるが,COUPLING()では「ここではTREEVIEWの初期化は実行しない@20170804」となっている.⇒タイトル枠を初期化しているのが気になるが,各種フラグのリセットなどをやっているので,実行しておいた方がよいと思う.

▲源氏物語全系譜6.1.ZELの全体図を#18 左兵衛督でソートしてNAMEBOX::makePairBox→ PAIRBOX::CheckPairBoxエラーが出た.