More than 1 year has passed since last update.

Prologでfor-loopを回す方法を紹介します。
ついでにPythonとの比較も付けてみました。

利用したProlog処理系: AZ-Prolog 7.54

基礎編1: リストの要素を順に出力する

python
>>> my_list = [1, 2, 3, 4, 5]
>>> for x in my_list:
>>>     print x
... 
1
2
3
4
5

prolog
print_list([]).
print_list([Element|List]):-
    write(Element),nl,
    print_list(List).

?- print_list([1,2,3,4,5]).
1
2
3
4
5
yes

基礎編2: リストの中身を処理して別のリストに格納

例えば、リストの中身を2倍する場合。

python
>>> my_list = [1, 2, 3, 4, 5]
>>> new_list = []
>>> for x in my_list:
>>>     new_list.append(x * 2)
... 
>>> new_list
[2, 4, 6, 8, 10]

もしくはリスト内包表記で、

python
>>> new_list = [x * 2 for x in my_list]
prolog
twice_list(OldList,NewList):-
    twice_list(OldList,[],NewList).
twice_list([],NewListRev,NewList):-
    reverse(NewListRev,NewList).
twice_list([OldNum|OldList],TempList,NewList):-
    NewNum is OldNum * 2,
    twice_list(OldList,[NewNum|TempList],NewList).

?-OldList=[1,2,3,4,5],twice_list(OldList,NewList).
NewList = [2,4,6,8,10]
yes

もしくは差分リストを利用して、

prolog
twice_list2(OldList,NewList):-
    twice_list2(OldList,TempList-TempList,NewList).
twice_list2([],NewList-[],NewList).
twice_list2([OldNum|OldList],List-[NewNum|Tail],NewList):-
    NewNum is OldNum * 2,
    twice_list2(OldList,List-Tail,NewList).

?-OldList=[1,2,3,4,5],twice_list2(OldList,NewList).
NewList = [2,4,6,8,10]
yes

応用編: 条件をつけてfor-loopで処理する

例えば、偶数の時のみ2倍する場合。

python
>>> my_list = [1, 2, 3, 4, 5]
>>> new_list = [x * 2 if x % 2 == 0 else x for x in my_list]
>>> new_list
[1, 4, 3, 8, 5]
prolog
twice_even_number(OldList,NewList):-
    twice_even_number(OldList,TempList-TempList,NewList).
twice_even_number([],NewList-[],NewList).
twice_even_number([OldNum|OldList],List-[NewNum|Tail],NewList):-
    Rest is OldNum mod 2,
    Rest = 0,
    NewNum is OldNum * 2,
    twice_even_number(OldList,List-Tail,NewList).
twice_even_number([OldNum|OldList],List-[OldNum|Tail],NewList):-
    twice_even_number(OldList,List-Tail,NewList).

?-OldList=[1,2,3,4,5],twice_even_number(OldList,NewList).
NewList = [1,4,3,8,5]
yes

感想

Pythonのシンプルさを再実感しました。
Prologはfor-loopを回す毎に新たな述語が増えてしまうのはちょっと・・・。
このへんのリスト処理については汎用的な述語を作っておくと便利かもしれませんね。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.