ここで定義した関数 Chains の説明

例として,trefoil の"ステート3"(="011";プリント参照)を考え,次のリスト

[Graphics:Images/index_gr_1.gif]

({\bf 各交点において}どの辺同士が繋ぎあわされるかを表しているリスト)を考えます. こうしたリストを入力として,関数 Chains が出力するものは,

[Graphics:Images/index_gr_8.gif]

です.つまり,この出力リストは, ステート3を構成する輪っか達がどの辺達からなるかを表しています. ステート3は2つの連結成分からなり,それらは,{1,2,4,5} という辺達が連なってできる輪っかと {3,6} という辺が連なってできる輪っかです.

このような出力をさせる関数はどうやって作りましょう? C 言語等で手慣れている(であろう)For ループを使ってみましょう. この関数 Chains は,C 言語などでもすぐに書き移せるように3重の For ループで書いてみました (もうちょっと良くはできますが,それなりに能率的なプログラムです).

まず Chains の「最初の For ループ」を 上の b1 に作用させたケースで見てみます. b1[[1]]={1,5} と共通部分を持つものを2番目の要素から順にチェックしていき,共通部分があれば,その要素を {1,5} に繋げていきます---繋げるには Mathematica の標準的な組み込み関数 AppendTo を使います(step1):

[Graphics:Images/index_gr_2.gif]
[Graphics:Images/index_gr_3.gif]

Length[Intersection[b1[[i]],b1[[j]]] > 0 とは,b1[[i]](今の場合,i=1 と代入していますから,b1[[i]]=b1[[1]]={1,5} です)と b1[[j]] に共通の番号があるということです.もしそうならば,リスト c に b1[[i]] および b1[[j]] の和集合を作り,それを新たにリスト c と置きます. {1.5} に6番目の要素 {1,4} が繋がったものが出力されました.b1 の2番目以降,仮に共通部分をもつ要素がなかったとすると d として {1,5} が出力されます. つぎにb1[[2]]={2,4} と同じ要素を含むものを b1 の3番目 b1[[3]] ={2,5} から順にチェックして {2,4} に繋げ,出てきた結果と step1 の出力を合わせたリストを出します(step2)・・・ この操作を順次合計 6 回行うのにもうひとつ For ループを用意して, 2重ループを作ります:

[Graphics:Images/index_gr_4.gif]
[Graphics:Images/index_gr_5.gif]
[Graphics:Images/index_gr_6.gif]

ここで,d は6回の step 各々の出力を合わせたリストであって, つぎの Union[Sort[d]] は重複を除外したものです. b2 の要素の数はかならず b1 \ の要素の数よりも小さくなることに注意しましょう(*). 次に,b1 の代わりにこの最後のリスト b2 に対して,上の2重ループを施すと,

[Graphics:Images/index_gr_7.gif]
[Graphics:Images/index_gr_8.gif]

{3,6} と {1,2,4,5} には共通の要素がありませんから, これが求めようとしていたリストに他なりません. 最後の b1 から b2 を作り,さらに b3 を作り,という操作は, 一般にはまだまだ続くので,この部分もループで書く書いてみましょう. 注意*より,bi から bi++ を作る操作は多くとも最初の入力リスト b1 の 要素の数以上にならないことが分かるので,このループは For 文で 書くことができます(もしくは While 文を用いる). 以上が関数 Chains です.

同じ働きをするが別の書き方ももちろんできるでしょう. 以下はそのひとつです.構造自体は随分とシンプル(ループはひとつだけ)になっています. しかし,重複した計算も含めてしまっているので総計算回数は数倍増えて,使うにはちょっと遅いです.

chain1[bb_] :=
Block[{n = Length[bb]}, Map[Union[Flatten[#, 1]] &,
Table[Switch[Length[Intersection[bb[[i]], bb[[j]]]], 0, {}, _,
Union[bb[[i]], bb[[j]]]], {i, n}, {j, n}]]];
Chains[bb_] := Module[{b}, b = bb; While[b =!= chain1[b], b = chain1[b]]; Union[b]];