Prolog 写経記 その 9 list/1
今日は list/1
を写経します.
本来の順番だと flatten/2
になるのですが,その中で list/1
が使われているのでこちらを先に.
モード
list(?).
入出力どっちでも使えます.なぜ?
未定義の変数を与えると何が返ってくるのだろうか?
定義
では,こいつの定義を写経しませう.
list([]). list([_|_]).
簡単といえば簡単ですが,見た瞬間はちょっと違和感を覚えました.
二つの節を使わないと,リストかどうか判断できないんですね.
2 ?- [_] = []. No 3 ?- [_|_] = []. No 3 ?- [_] = [a]. Yes 4 ?- [_|_] = [a]. Yes 5 ?- [_] = [a, b]. No 6 ?- [_|_] = [a, b]. Yes
そうですか,空リストにマッチするのは空リストだけなのね.
注記
list
によるデータタイプの検査にはいくつかの注意が必要である.変数X
が具体化されていなければ,list(X)
が最初に呼ばれた時には空リスト[]
に,またバックトラックの時は[_|_]
に具体化される.list
が述語flatten/2
の定義中でどのように用いられているかを参照のこと.
うーみゅ...
悩ましすぎる.ちょっと意味不明.あとでお試ししませう.
例
では使用例を写経しませう.
7 ?- list(a). No 8 ?- list([]). Yes 9 ?- list([a, b, c, d]). Yes 10 ?- list([x|_]). Yes 11 ?- list([_, z|[]]). Yes 12 ?- list([]). Yes 13 ?- list(list). No
まぁいいでしょう.普通に使えてるっぽい.
そんなわけで (どんなわけで?),注記の記述を確認してみます.
14 ?- list(X).
X = ;
X = [_G290|_G291] ;
X = ;
X = [_G290|_G291] ;
No
な,なんだこりゃあ!!
確かに注記に書いてあるように,具体化されていない変数 X
は最初空リストとしてマッチしちゃってますね.
そして再試行すると [_|_]
に訳の分からないリストがマッチしちゃってます.
それがなぜか 2 回ずつ.なぜ 2 回? なぜ 1 回でも 3 回でもなく 2 回?
うーみゅ...
そんなわけで (どんなわけで?),flatten/2
の定義を参照...
するのは明日のお楽しみってことで.心より恥じる.