LoginSignup
2
3

More than 5 years have passed since last update.

Prologでfor-loop

Last updated at Posted at 2015-03-29

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を回す毎に新たな述語が増えてしまうのはちょっと・・・。
このへんのリスト処理については汎用的な述語を作っておくと便利かもしれませんね。

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3