Prolog 写経記 その 61 counter_set/2
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
そんなわけで (どんなわけで?),今日からは「5章 カウンタ」へ進みます.
まずは
counter_set/2
を写経します.Prolog の変数は述語 (の節) に閉じたスコープを持つ,いわばローカル変数のみで,しかも一度値が具体化されると破壊的代入はできないわけですが,この章ではグローバル変数のようなスコープを持ち,値を増減することのできるカウンタを実装するようです.
なんかいやな感じ...
昨日の random/2
同様,えぐい方法を使う... んだろうなぁ.
解説
counter_set(Count, I)
はカウンタCount
の値を望む数I
にセットする.
ふむ.
モード
counter_set(+, +).
ふむ.
定義
では,こいつの定義を写経しませう.
counter_set(Count, I) :- integer(I), counter_remove(Count), recorda(counter, counter(Count, I), _), !. counter_remove(Count) :- recorded(counter, counter(Count, _), Ref), !, erase(Ref). counter_remove(_).
下請けの述語 counter_remove/1
を使っています.
まずは本体から.
第 2 引数が整数かチェックした後,下請け述語 counter_remove/1
でカウンタをリセットして,recorda/3
でカウンタの値を設定しています.
この recorda/3
,ISO 標準には含まれていないらしく,「Programming in Prolog (isbn:3540006788)」や「Prolog Programming for Artificial Intelligence (isbn:0201403757)」には解説されていません.
でもでも,SWI-Prolog はこれをサポートしていて,ドキュメントにも説明がありました.
- recorda(+Key, +Term, -Reference)
- Assert Term in the recorded database under key Key. Key is an integer, atom or term. Reference is unified with a unique reference to the record (see erase/1).
要するに第 1 引数をキーとして第 2 引数で指定された項を Prolog データベースに登録してくれるわけですね.
下請けの counter_remove/1
は二つの節を持ち,最初の節では recorded/3
と erase/1
を使っています.
recorded/3
は,第 1 引数で指定されたキーに対応する項 (recorda/3
で Prolog データベースに登録されたもの) とその「参照」を返します.
erase/1
は「参照」で示されたキーと項のマッピングを Prolog データベースから取り除いてくれます.
二つめの節はキーがまだ登録されていなかった場合でも述語が成功するようにするためのものですね.
counter_set/2
では,キーとして counter
というアトムを使っています.
counter_set/2
の第 1 引数で指定されたカウンタの名前は Prolog データベースのキーそのものとしては使っておらず,登録される述語の引数として使われています.
例
では使用例を写経しませう.
counter_dec
とcounter_inc
参照.
...
counter_dec
と counter_inc
に続く...