Prolog 写経記 その 19 list_to_atom/2
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
lengths
の次は list/2
です.でもでも,なんだか見覚えが...
おぉ!!
やはり「その 9」で写経済みでしたよ.危ない危ない.
そんなわけで (どんなわけで?),今日は
list_to_atom/2
を写経します.解説
list_to_atom(Atoms, Name)
はアトムのリストAtom
からアトムName
を作り出す.
うーみゅ,一瞬意味が分かりませんでしたが...
つまり,[a, b, c]
というリストから abc
というアトムを作ってくれる訳ね.ふーん.
モード
lsit_to_atom(+, ?)
ふむ.
定義
では,こいつの定義を写経しませう.
list_to_atom(Atoms, Name) :- ascii(Atoms, List), name(Name, List). ascii([Atom], List) :- !, name(Atom, List). ascii([Atom | Atoms], List) :- name(Atom, L), conc(L, Rest, List), !, ascii(Atoms, Rest).
お,下請け君がいますね.
3度も使われている述語 name/2
は組み込み述語.なんでも,第1引数で受け取ったアトムを文字にばらしてそのリストを第2引数に具体化してくれたりその逆をしてくれたりするらしい.
2 ?- name(a, L). L = [97] Yes 3 ?- name(abc, L). L = [97, 98, 99] Yes
ふむ.
んで,下請け述語 ascii/2
の最初の節
ascii([Atom], List) :- !, name(Atom, List).
これは再帰の終了条件で,第 1 引数のリストに要素 (アトム) が一つしかなければ,name/2
でそのアトムをリストにします.
そしてもう一つの節.
ascii([Atom | Atoms], List) :- name(Atom, L), conc(L, Rest, List), !, ascii(Atoms, Rest).
ふむ.
第 1 引数で渡されたリストの最初の要素 (アトム) をリストにしたものと,残りの要素 (アトム) からなるリストを文字のリストにしたものを連結しています.
そして本体.
list_to_atom(Atoms, Name) :- ascii(Atoms, List), name(Name, List).
第 1 引数で渡されたアトムのリストをフラットな文字のリストにして,name/2
でそれをアトムにする,と.
ふむ.本体と下請けでは,同じ name/2
を使っているものの使い方の向きが逆なんですね.
例
では使用例を写経しませう.
4 ?- list_to_atom([john, ate, three, eggs, for, breakfast], A). A = johnatethreeeggsforbreakfast Yes 5 ?- list_to_atom([a, 1], a1). Yes 6 ?- list_to_atom([colour(blue), colour(red)], X). ERROR: name/2: Type error: `atom' expected, found `colour(blue)'
失敗って...
冷たく「No」って返ってくるんじゃなくて,こういう失敗ですか.
っていうか,写経本の例だと「No」って返ってくるだけになってるなぁ.
この辺りは処理系によって違うということでしょうか.
ところで,この list_to_atom/2
はリストの連結に conc/2
を使っています.
そんなわけで (どんなわけで?),これを差分リストを使うように直してみませう.
...
と思ったのですが,name/2
が普通のリストを返してくるから,どうやってもこいつを差分リストとして扱うためには要素数分たどるしかないような気のせいが.うーみゅ...
なんか,効率的になりそうな気がしないのでやめ.心より恥じる.