Prolog 写経記 その 91 for/1

(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.

Prologユーティリティライブラリ

Prologユーティリティライブラリ

お次は repeat/1 を写経します.

解説

for ループとしての for Count :- I1 (down)to I2 do Q を実現する.ここで,Count はカウンタの名前,I1I2 はそれぞれカウンタの初期値と最終値であり,QProlog のゴールの並びである.

ふむ.
カウントアップとカウントダウンの両方に対応しているらしい.
でもでも,カウントの刻みは指定できないのね.まぁいらないけど.

モード

for(+)

ふむ.

定義

では,こいつの定義を写経しませう.

:- op(900, fx, for).
:- op(850, xfx, to).
:- op(850, xfx, downto).
:- op(800, xfx, do).
:- op(750, xfx, ':=').
for _ := I1 to I2 do _ :-
	I1 > I2, !.
for Count := I1 to I2 do Q :-
	counter_set(Count, I1),
	repeat (Q, counter_inc(Count, I))
		until I = I2, !.
for _ := I1 downto I2 do _ :-
	I1 < I2, !.
for Count := I1 downto I2 do Q :-
	counter_set(Count, I1),
	repeat (Q, counter_dec(Count, I))
		until I = I2, !.

本そのままだと警告がでたので一部修正してます.
はじめの二つはカウントアップ,残りの二つはカウントダウンするためのものですね.
ほとんど同じなのでカウントアップだけ見れば十分っぽい.

for _ := I1 to I2 do _ :-
	I1 > I2, !.
for Count := I1 to I2 do Q :-
	counter_set(Count, I1),
	repeat (Q, counter_inc(Count, I)) until I = I2, !.

最初の節は停止条件なので,実質的には二つめの節だけ.
そこでは以前「5 章 カウンタ」で作成した述語を使って再帰しています.
パッと見たとき長くてビビりましたが意外と簡単♪

注記

for/1 を使用するには,カウンタ管理述語 (5 章参照) と repeat/1 がデータベース中になければならない.手続き的プログラミング言語と比べて,Count は現在の値をためておく変数ではなく,その下にカウンタの値が記録されているキーとしての役割を持つ.

ふむ.

では使用例を写経しませう.

4 ?- for loop_count := 512 downto 509 do
(counter_is(loop_count, I), write(I), tab(2)).
512 511 510 509 I = 509 Yes

ふむ.
これで「10 章 手続き的構造の導入」も終了.