めざましテレビ
今日の早耳ムスメは長谷川潤ちゃん,お題は「六本木ヒルズ 注目のニューショップ!!」.
BANANA REPUBLIC 通称バナリパ.通称って... 通じるの? (キーワードになってる... 失礼しました)
ともあれ (JW),久しぶりの潤ちゃん,見るたびに表情が柔らかというか穏やかになってきてるような気がします.
昨年はゴージャスでカッコいいという印象でしたが,今やキュートさも併せ持っているようで素晴らしいです.
特にアースミュージック&エコロジー プレミアムストア (これには通称がないのか!?) にて JOE'S のジーンズとベロアジャケットをコーディネートした潤ちゃん最強.
っていうか,滅多に出演しない潤ちゃんなのに,新企画をやらなくていいの?
もしかしてもしかすると,新企画は直ちんだけでボツ?
あう,まさかやらせ発覚とか... んなわけないか.
Prolog 写経記 その 26 reverse/2
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
reverse/2
を写経します.解説
reverse(List1, List2)
はList1
の要素の順番を入れ替え,逆順のリストをList2
として返す.
ふむ.Java でいうと Collections#reverse(List)
ですね.
モード
reverse(+, ?)
ふむふむ.
定義
では,こいつの定義を写経しませう.
reverse(List1, List2) :- revconc(List1, [], List2). revconc([], L, L). revconc([X | L1], L2, L3) :- revconc(L1, [X | L2], L3).
ふむふむふむ.下請けを使ってますね.
本体は何もしていないに近いので,下請けを見てみませう.
1 番目の節は終了条件なので,まずは 2 番目の節ですが...
revconc([X | L1], L2, L3) :- revconc(L1, [X | L2], L3).
受け取ったリストの先頭の要素を取り除いて,残ったリストを逆順にしたリストの先頭にくっつける??
それで逆順になるのか? っていうか,逆順になった結果は L3
だけど,L3
はまるっきり具体化されていませんが?
そこで 1 番目の節.
revconc([], L, L).
ここで第 3 引数のリストが第 2 引数のリストに具体化されて,それが 2 番目の節の L3
に.
うーみゅ,これはまさか...
分かりにくいけど,これって差分リストみたいですね.
1 番目の節の終了条件って,差分リストで空リストを表す場合のお約束だし,元請けの reverse/2
が最初に revconc/3
を呼び出す際に空リストを渡しているのも差分リストでのお約束.
それなのに,なんで分かりにくいかというと引数の並びが逆なんですよね.
L2 - L3
という差分リストじゃなくて,L3 - L2
になっちゃってる.
ちょっといやーんなので書き直すと
reverse(List1, List2) :- revconc(List1, List2, []). revconc([], L, L). revconc([X | L1], L2, L3) :- revconc(L1, L2, [X | L3]).
この方が List2 - []
,L - L
,L2 - L3
という差分リストが見えやすい感じ.
そしてこれは「差分リスト その 1」でやった例とほとんど同じ.
っていうか,「差分リスト その 1」でやった例って,N から 1 のリスト (じゃなかったけど) を 1 から N のリストに並べ替えたようなものだから,同じようになって当然ですかそうですか.
ともあれ (JW),revconc/3
は再帰呼び出しで具体化されたリストの先頭に X
を追加するんじゃなくて,具体化されたリストを受け取ってその先頭に X
を付加して再帰呼び出しに渡すので,結果として元のリストの後にあったものが結果のリストの前の方に来る,と.revconc/3
の呼び出し方って revconc(+, -, +)
(オリジナルの場合は revconc(+, +, -)
だけど) なんですね.
注記
要素の順番は実際には述語
revconc/3
によって逆転される.この定義とconc/3
を比較してみよ.
ふむふむふむふむ.
conc/3
の定義は次の通り.
conc([], List, List). conc([X | L1], L2, [X | List]) :- conc(L1, L2, List).
こちらの [X | List]
は普通の使い方というか,再帰呼び出しで具体化されて返ってきたリスト List1
の先頭に X
を付加しています.戻っていく際にリストが伸びていくわけです.
revconc/3
が再帰呼び出しの際にリストが伸びていくのとは好対照.
っていうか,やることが逆なのだから対照的なのは当然ですね.
例
では使用例を写経しませう.
48 ?- reverse([dark, blue, car], R).
R = [car, blue, dark]
Yes
49 ?- reverse(, RevList).
RevList =
Yes
50 ?- reverse([3, 1, 7], [7, 1, 3]).
Yes
ふむふむふむふむふむ.
当然,引数の順序入れ替え版でも同じ結果です♪
出演予定 TV 番組
情報なしですぅ...