Prolog 写経記 その 86 numbervars/3
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
numbervars/3
を写経します.解説
numbervars(Term, N1, N2)
はTerm
中の変数を$var(N)
の形式の項に具体化する.N
はN1
からN2 - 1
の間の整数である.
うーみゅ...
何を言ってるのかよく分からないのですが...
これも標準述語なの?
ごそごそ.
おぉ,SWI-Prolog にもありますね...
そのマニュアルの例.
?- numbervars(foo(A, B, A), 0, End). A = '$VAR'(0) B = '$VAR'(1) End = 2
ふーん,解説とちょっと違って $var
じゃなくて $'VAR'
になってるけど,何をするのかは分かった.
でも,なんでこんなのが必要なのか分からない...
モード
numbervars(?, +, -)
ふむ.
第 3 引数を見れば変数がいくつあったか分かるわけね.
定義
では,こいつの定義を写経しませう.
numbervars2(Term, N1, N2) :- var(Term), !, Term = '$var'(N1), N2 is N1 + 1. numbervars2(Term, N1, N2) :- Term =.. [_ | Args], numberargs(Args, N1, N2), !. numberargs([], N, N). numberargs([X | Rest], N, M) :- numbervars2(X, N, N1), numberargs(Rest, N1, M).
標準の述語とかぶるので,名前は numbervars
にしちゃいました.
まずは本体の最初の節から.
numbervars2(Term, N1, N2) :- var(Term), !, Term = '$var'(N1), N2 is N1 + 1.
第 1 引数 Term
が変数なら,それを具体化してます.
その記述なんですが...
うーみゅ,'$var'(N1)
も一つの項なのか.ふーん.
そして第 3 引数を第 2 引数に 1 加えた値にしています.
次の節
numbervars2(Term, N1, N2) :- Term =.. [_ | Args], numberargs(Args, N1, N2), !.
これは第 1 引数 Term
が変数じゃなかった場合.
その場合 Term
は具体化された項なので,その引数のリストを Args
に具体化し,それを下請けの述語で処理します.
その下請けの述語.
numberargs([], N, N). numberargs([X | Rest], N, M) :- numbervars2(X, N, N1), numberargs(Rest, N1, M).
最初の節は停止条件.
次の節では,引数リストの最初の要素を取り出して本体である numbervars/3
に渡しています.つまり再帰.
そして残りのリストをこの述語自身の再帰呼び出しで処理します.
うーん,なんか分かったような分からないような.
一応,やってることは分かったからいいか.
注意
numbervars
は具体化されていない変数を含む項を出力する際に役立つ.このような項をnumberargs
によってあらかじめ処理しておくと,変数の参照が$var(N)
で書き換えられるため,見やすい出力となる.個々での定義は変数を例えば$var(N),$var(2),$var(3)
などのかわりに'A', 'B','C'
などほかの項に具体化するよう変更できる.
見やすい?
デバッグ出力用ですか?
そうか,その程度のものか.ちょっと安心♪
例
では使用例を写経しませう.
6 ?- numbervars2(append(X, List, [X | List]), 1, _),
write(append(X, List, [X | List])). |
ふむ.
それらしい出力になってますね.
では,X
を具体化しておくと?
8 ?- X = ebiyuri,
numbervars2(append(X, List, [X | List]), 1, _), |
write(append(X, List, [X | List])). |
ふむ.
さらに List
も具体化しておくと?
9 ?- X = ebiyuri,
List = [cancam], | |
numbervars2(append(X, List, [X | List]), 1, _), |
write(append(X, List, [X | List])). |
ふむ.