無向グラフのDOTにgvprでrank付きサブグラフを加える #1

話題のメインがライフゲームと関係なさそうなのでタイトルを変えた。
ライフゲームの記事の#20ではdotコマンドを使ってレンダリングしようとした。
その時は手書きでDOTファイルを書いたのだが、あのサイズでもそれは面倒だった。
これをメッシュ生成プログラムgen_mesh.gの出力に、
gvprプログラムで自動的にrank属性を加えるようにしてみる。
DOTにおける

...snip
  { rank = same; "0,3"; "1,3"; "2,3"; }
...snip

のように定義されるrank属性はサブグラフに与える属性である。
subgraphというキーワードが明示されてはいないが、
{ ... }で囲まれているものが一つのサブグラフとなる。
したがって#20のようなグラフを作るなら、
各ノードについて"x,y"形式のname属性を見て、
同じyの値を持つノードを同じサブグラフに属させればいい。

insert_rank.g
N {
  graph_t g = subg($G, yOf(name));
  g.rank = 'same';
  subnode(g, $);
}

サブグラフの名前をyの値そのものにして、その値を名前のyに持つノードをそのサブグラフに含める。

gvpr -f gen_mesh.g -a 3,4 | gvpr -cf insert_rank.g | dot -T png -o 3x4.png


上下がひっくり返ってしまった。insert_rank.gの出力を見ると、

graph {
        subgraph 0 {
                graph [rank=same];
                "0,0";
                "1,0";
                "2,0";
        }
        subgraph 1 {
...snip
        }
        subgraph 2 {
...snip
        }
        subgraph 3 {
...snip
        }
        "0,0" -- "1,0";
...snip

のようにy=0のサブグラフが先に定義されている。定義の順序は重要なので修正しないといけない。
とはいえ、この場合に限れば、

gvpr -f gen_mesh.g -a 3,4 | gvpr -cf insert_rank.g | dot -Grankdir=BT -T png -o 3x4.png


のような解決策もないわけではない。
rankの方向性を-Grankdir=BTにしてアップサイドダウンケーキの焼き上がり。