昨日の仮修正は一旦破棄してバックアップに戻ろう.何が問題なのか?一番の問題は先帝系列で明石中宮が展開されていないという点だろう.明石中宮は※3系列で外部との接点を持つ唯一のノードなので,このノード以外に系列優先ノードとなり得るカードは存在しない.このノードがリジェクトされているのは,対向する有効な実ノードが存在しないためだ.対向する有効な実ノードとは,すなわち先帝系列で展開されるべき明石中宮の人名枠に他ならない.なぜそういう流れになっているのか,追跡してみよう.
明石中宮の義母である紫の上の父式部卿宮は結婚を3つ持っている.単身婚,式部卿宮の北の方,紫の上の母だ.この式部卿宮+紫の上の母の結婚が展開されていない.この結婚枠の所属系列が未定であるためだ.これはMARGBOX::IsPrimeboxOrNoに「基準ノードの配偶者が外部に有配偶者婚を持っている場合には,その結婚は基準ノードの配偶者の配偶者側で展開される@20190128」というルールがあるためだ.このサンプルの基準ノードは#229 式部卿宮の北の方で,式部卿宮はその配偶者に当たるため,弾かれている.この規則を暫定的に止めて描画できた!
確かにかなり難しい図面であるかもしれない… しかし,このような反例があるために,このルールを破棄ないし緩和するというのはよい方向であるとは思えない.IsPrimeboxOrNoという関数はある結婚を夫と妻のどちらのポジションで展開するか?という疑問に応えるための関数で,基本にはどちらを選択しても描画は可能となっているという前提がある.この前提が崩れたのは,「基準ノードの配偶者が外部に有配偶者婚を持っている場合には,その結婚は基準ノードの配偶者の配偶者側で展開される」というルールが厳し過ぎるためというよりは,むしろ「もっと優先度の高いルールが存在する」ということだろう.
つまり,その結婚がある位置で展開されないと描画不能となるようなものが存在するということではないのか?しかし,それをルール化するのは容易くはない.系列枠リストの最初の7系列を表示してみた.
- #915 先祖=#701 式部卿宮の北の方(0) 優先=#701 式部卿宮の北の方(0) 始系列 type=始系列
- #917 先祖=#509 先帝(0) 優先=#1093 式部卿宮(1)→#701 式部卿宮の北の方(0) →主系列#915:式部卿宮の北の方 type=BTW左接続関係
- #919 先祖=#557 ※6(0) 優先=#1101 先帝の后宮(1)→#511 先帝の后宮(0) →主系列#917:先帝 type=婚姻関係
- #921 先祖=#405 ※3(0) 優先=#1102 明石中宮(1)→#339 明石中宮(0) →主系列#917:先帝 type=親元関係
- #923 先祖=#603 中務宮(0) 優先=#1104 明石の尼君(1)→#521 明石の尼君(0) →主系列#921:※3 type=婚姻関係
- #925 先祖=#637 右大臣(明石)(0) 優先=#1110 今上(1)→#339 明石中宮(0) →主系列#917:先帝 type=BTW左接続関係
- #927 先祖=#589 按察の大納言(若紫)(0) 優先=#1112 紫の上の母(1)→#535 紫の上の母(0) →主系列#917:先帝 type=婚姻関係
1番目の式部卿宮の北の方系列は始系列だから,無条件で描画される.2番目の先帝系列の優先仮ノードは式部卿宮であり,実ノードは基準ノードの配偶者だから,この系列自体には何の問題もない.もちろん,式部卿宮+紫の上の母の結婚を他系列に譲ったとしても,問題なく描画できる.問題は※3系列の優先ノード候補が明石中宮しかないという点にある.ここで躓くのは,式部卿宮+紫の上の母の結婚の移転先が,※3系列より系列順位的に後方にあるという点にある.このようなことは予想されていなかったので,この場で対処することは不可能だ.
解決策としては,上記で実行したように何らかの条件を提示してこの結婚が紫の上の母側ではなく,式部卿宮側で展開する必要があるということを示す必要がある.これを決定するためには少なくとも次のことが言えなくてはならない.
- 系列優先ノード候補を一つしか持たない系列Kが存在する
- この優先ノードの実ノードを(子どもとして)含む結婚はこの系列Kに先行して展開されなくてはならない
- この結婚を系列Kより後方の系列に移籍してはならない
判定1.もあまり簡単ではないが,2., 3. も分かり易いものではない.通常始系列に含まれる結婚は最初に展開され,基準ノードの配偶者の系列はそれに準ずると考えられるから,通常の手順であれば,この結婚が「後方」に移動することは避けられない.仮にこの手順に入るまでに,すでに系列枠リストは生成され,系列順位が決定しているとしよう.また,系列優先ノードも選定済みであるとする.実際,現行論理ではそうなっていると言ってよいと思われる.とすれば,上の条件文は以下のように書き換えることが可能かもしれない.
「IsPrimeboxOrNoの検査対象の結婚に系列優先ノード(候補)が(子どもとして)含まれる場合は本人位置で展開する」
例外としては,その配偶者の系列が「系列優先ノードの系列」より先行する系列である場合は移動を認めるとしてもよい.以上をまとめると,
「IsPrimeboxOrNoの検査対象の結婚に系列優先ノード候補が子どもとして含まれる場合は本人位置で展開する ただし,配偶者系列が系列優先ノード候補系列より上位にあるときはその限りではない」
となる.しかし,これは絵に描いた餅で終わる可能性もある.まだ,この時点では結婚枠はおろか,人名枠でさえどの系列に属するかは確定していないと考えられるからだ.系列枠はすでに生成済みであるとすれば,系列枠のPrimaryには系列優先ノードが入っているはずだから,系列枠リストを走査すれば確認することは可能だが,ややコスト高になる.CARDLINK自体にその情報(優先ノード候補であるという情報)が入っていれば探索コストはかなり削減できるのだが…
CARDLINKには先祖ノードへのリンクを格納するancestryというスロットがあるが,これは必ずしも所属系列とは一致しない.CARDLINKはNAMEBOXのリストを持っているので,このリストをチェックすることはできる.しかし,たとえば,式部卿宮+紫の上の母の結婚を検査するタイミングでは明石中宮のNAMEBOXはまだ一つも展開されていないのではないだろうか?実装してみよう.
いや,問題はもう一段難しい.IsPrimeboxOrNoの対象結婚枠は式部卿宮+紫の上の母だが,明石中宮はこの結婚枠には入っていない.
式部卿宮+紫の上の母→紫の上→明石中宮
という関係だ.そこまでここで追求するのは無理なのではないか?というより,もし,それをやるとすれば系列優先ノードから先祖ノードまでの経路上に存在するすべての結婚が検査対象となってしまう.実際,そこまでやらないと解決にはならないのではないかと思う.かなり厄介な話に発展してしまった.つまり,あるノードを系列優先ノードとして予約するためにはそのノードから先祖ノードまでのすべての結婚枠を予約する必要があるということになる.⇒この方向はかなり険しいが,もしそれしか道がないのだとしたらそうするしかない.
もう一つ別のより簡便な方式も考えられる.現行の論理で一度GoDownStreamを通した後,MakeUpTreeで再挑戦の機会を与えるという方式だ.これなら,確定できる系列はすべて連結完了しているはずだから,系列順位とは無関係に接続点を探すことができる.
現行方式でまさにそれをやっているのではないだろうか?TRIBEBOX:GetAlternativePrimeNodeという関数はそれを行うために用意されたのではないのか?であるとすれば,この関数をより洗練させればよいというだけの話になる.それは実現可能な話ではないかと思う.大分回り道してしまったが,ようやくスタート地点まで戻ってきた.
一応GetAlternativePrimeNodeで(不十分ながら)接続先を見つけることはできるようになったが,TRIBEBOX::DecidePrimaryNodeが通らない.この関数は自分自身を再帰的に呼び出しているので無限ループに陥ってしまう.結局まだ問題は解決していないということのようだ.GetRealnodeでは「空でない可視の人名枠オブジェクト」を求めているため,按察の大納言系列の#1112 明石中宮(1)が弾かれてしまっている.しかし,所属系列枠が決まっているのに不可視というのはどういうことだろう?⇒GoDownStreamで所属系列を設定するタイミングで可視化してみたが,状況は変わらない.
どこかで落とされているようだ.CARDLINK::NameBoxを実行すると初期化される.しかし,この動作はかなりおかしい.対象となっているのは明石中宮ではなく,北山の尼君だ.
CARDLINK::NameBox→ NAMEBOX::makeProxy→ initializeで生成された北山の尼君の仮ノードを隠蔽リストにつなぎ込んでいる.この措置は「挿入」として実施されるため,挿入位置のノードが操作されて対象ノードの後ろに移動し,このとき不可視設定されている.隠蔽リストは原則として不可視となっているため,このような動作になっているのだろう.GoDownStreamでは人名枠などの描画要素は生成されてはいるが,まだ可視のYリストには登録されず,MAKEUPTREEで初めて繋ぎ込まれるという動作になっている.このため,MAKEUPTREEで実施しているGetAlternativePrimeNodeは再チャレンジになっていない.
見てきたように,従来手順では優先ノードが決定できない系列が発生することは避けられない.これを予防するための措置を導入することは不可能ではないが,高度に難解なものになることは避けられず,時間・空間効率に及ぼす影響も無視できない.この意味では系列木の生成を段階化して,後段で最終解決するというのは現実的であると思われる.中間段階に当たるGODOWNSTREAMでは描画要素はすべて隠蔽リスト上にあり,かつ隠蔽リスト上にあるノードはつねに不可視とするというルールになっており,これを直ちに変更するというのも現実的ではない.
TRIBEBOX::GetRealnodeはMAKEUPTREEに入ってから適用される関数だが,MAKEUPTREEが完了するまでは描画要素がすべてYリストに繋がって可視化した状態にならないため,この関数で認める系列優先実ノードの条件を緩和するしかない.実際問題として,人名リンクが有効であるような人名枠は基本的に合法と考えられるから,ここでは可視/不可視を問わないことにする.これで描画まで進むことができた.ただし,一つだけ問題がある.
TRIBEBOX::GetAlternativePrimeNodeの中段,(T2 == major)のとき(marglink)で停止する.TRIBEBOX::GetAlternativePrimeNodeで系列枠#927 先祖:#588 按察の大納言 (若紫)の優先ノードを探すメインループを抜けたところで誤動作している.婚姻関係では見つけられず,逆婚姻関係を探して見つけているが,相手方が空であるために間違った分岐に進んでいる.相手方を見つける論理は以下のように単純なものだが,単身婚の場合があるということが見落とされていた.
if (wife == marg2->OTTO) partner = marg2->TUMA;
else partner = marg2->OTTO;
逆婚姻関係の場合には従系列で配偶者となっているのだから,主系列では本人となる可能性が高いと考えられるが,実際にどちらに割り当てられるかは必ずしも分明ではない.ある結婚の夫と妻のどちらを本人としどちらを配偶者とするかということは,その結婚枠をどの系列ないし,どの「家」に配置するかを決定することに等しい.その最終決定を行っているのがMAKEUPTREEフェーズなので,このプロセスが完了するまでは確定的なことは言えない.しかし,系列優先ノードの決定はそれらが確定する以前になされなくてはならないという矛盾がある.
系列優先仮ノード→実ノードという関係はある意味でかなりルーズな関係であり,必要なことは,①2つの系列関係が接点を持つこと,②同世代の2つの人名ノードの配置によって系列枠の垂直位置関係を決定すること,の2つが満たされれば十分であると考えられる.従って,その関係を決定するためにはそのノードが本人ノードであるか配偶者であるかまでは問う必要がないと(基本的には)考えられる.この立場からすれば,婚姻関係の実ノードはつねに(従系列における)本人ノード,逆婚姻関係の場合は(従系列における)配偶者ノードとしてよいのではないか?このルールなら単身婚の場合も問題なく処理できる(はずだ).
一応これでできたようだ.最初の図と今回の図では微妙に細部が異なる.最初の図では紫の上の母が夫の式部卿宮との接触距離まで接近しているのに対し,後の図ではかなり開いたものになっている.これは「基準ノードの配偶者が外部に有配偶者婚を持っている場合には,その結婚は基準ノードの配偶者の配偶者側で展開される」というルールを文字通り実現したもので,基準ノードの式部卿宮の北の方の眼からすれば,この方がずっと好ましいことは間違いないだろう.明石中宮も2番目の図ではかなり遠いところに配置されているが,式部卿宮の北の方の距離感からすれば,こんな感じなのではないだろうか?
このサンプルではTRIBEBOX::GetAlternativePrimeNodeの出動が必要となるケースは1件しか起きていない.それも,※3系列の明石中宮ではなく,按察の大納言(若紫)系列の優先ノードが紫の上の母から式部卿宮に切り替わるという動きだ.これはかなり予想外の結末だが,この障害の真因が,MARGBOX::IsPrimeboxOrNoで式部卿宮+紫の上の母の結婚を紫の上の母系列で展開するように決定したことにあることからすれば,当然の成り行きとも言える.この修正は,結婚枠展開の自由度を残したという点では「※3系列の明石中宮」にこだわるというアプローチより優れていると言ってよいと思う.
※3系列はどうなったかと言えば,明石中宮を優先ノードとして,按察の大納言系列の従系列になっている.しかし,この方式が「完璧」であると言えるかと言えば,多少の不安は残る.系列の従属関係が当初の線形順序を崩しているため,場合によっては,本来連結でなければならない系統図が複数のブロックに分離してしまう可能性はゼロではない.系列優先ノードの選択というのは,かなり難易度の高い部分だったような気もするが,ようやくある水準に達したのではないかという気もする.