Prolog 覚書
Rev.10を表示中。最新版はこちら。
SWI-Prolog 組込み関数
SWI-Prologのホーム : http://www.swi-prolog.org/文字列操作
アトムの連結
連結?- concat_atom(['A', 'B', 'C'], ' and ', X). X = 'A and B and C'分割
?- concat_atom(L, ',', 'a,b,c,d,e'). L = [a, b, c, d, e]
文字コード・アトムの変換
コードからアトム?- char_code(C,65). C = 'A'アトムからコード
?- char_code('a',N). N = 97
文字の種類
アルファベット?- char_type('A', alpha). Yes ?- char_type("A", alpha). Yes ?- char_type(65, alpha). Yes ?- char_type('1', alpha). No2文字以上指定するとエラーになる。以下、種類を調べて(訳して)みました。
種類を表すアトム |
一致条件 |
---|---|
alpha |
アルファベット |
alnum | アルファベット or 数字 |
csym |
アルファベット or 数字 or アンダースコア(_) |
csymf |
アルファベット or アンダースコア(_) |
ascii |
アスキー文字(0-127) |
white |
スペース or タブ |
digit |
数字 |
digit(N) |
数字のN |
xdigit(N) |
Nの16進表記 |
lower |
小文字 |
lower(Upper) |
Upperを小文字にしたもの、Upperは大文字 |
to_lower(Upper) |
Upperを小文字にしたもの、Upperは大文字でも小文字でもよい |
upper(Lower) |
Lowerを大文字にしたもの、Lowerは小文字 |
to_upper(Lower) |
Lowerを大文字にしたもの、Lowerは大文字でも小文字でもよい |
space |
レイアウト文字(タブ、Vタブ、改行、など) |
end_of_file |
-1 |
end_of_line |
行の終わり ASCII:10..13 |
newline |
改行文字(10) |
period |
ピリオド(「!」、「.」、「?」) |
quote |
クォーテーション(ダブル「"」、シングル「'」、バック「`」) |
paren(Close) |
閉じ括弧 Close に対応する開き括弧(「(」、「[」、「{」) |
まず、注意すべきことは、アルファベットは[A-Za-z]でない事。ウムラウトつきの文字やら何やら出てくる。次のようにして調べてみるとよい。(環境によって違うかもしれないが、alnum, csym, csymf, lower, upperも)
:- findall(X, char_type(X, alpha), L), write(L).確実に[A-Za-z]とするなら次のようにすればよい。
alpha_ascii(X) :- char_type(X, alpha), char_type(X, ascii).その他、digit, xdigit は数値と文字との変換に使える。
リスト操作
2つのリストを連結
連結?- append([1,2,3],[4,5,6],X). X = [1, 2, 3, 4, 5, 6]後ろ部分を得る
?- append([1,2,3],X,[1,2,3,4,5]). X = [4, 5]前部分を得る
?- append(X,[3,4,5],[1,2,3,4,5]). X = [1, 2]
リスト要素を選択
選択?- select(X,[1,2,3],Y). X = 1, Y = [2, 3] ; X = 2, Y = [1, 3] ; X = 3, Y = [1, 2] ; No任意の場所への挿入として使える
?- select(4,X,[1,2,3]). X = [4, 1, 2, 3] ; X = [1, 4, 2, 3] ; X = [1, 2, 4, 3] ; X = [1, 2, 3, 4] ; Nomemberと同じ使い方
?- select(4,[1,2,3,4],_). Yes
リスト反転
?- reverse(X,[1,2,3]). X = [3, 2, 1]
最後の要素
?- last([1,2,3],X). X = 3
一致する要素を削除
?- delete([1,3,2,3],3,X). X = [1, 2]
重複なしリスト
重複なしリスト = 集合(set)?- list_to_set([4,5,6,1,2,3,1,2,3,4,5,6], L). L = [4, 5, 6, 1, 2, 3]順序付きの集合(ord_set)
?- list_to_ord_set([4,5,6,1,2,3,1,2,3,4,5,6], L). L = [1, 2, 3, 4, 5, 6]
入出力
書式付出力
C言語のprintfのようなもの.エスケープは,バックスラッシュでなくチルダ.タブの文字数を '~t~10|' のように決めれる,さらに,*で動的に決定できる.
format('~t~*|Hello, World!~n', [4]).出力
Hello, World!
繰り返しとか
for文のようなことをするbetween(1, N, X), write(X), X is N.文の最後に,XがNになるまでバックトラックで繰り返される.
繰り返しの値で,リストを作成
?- findall(X, between(1, 9, X), L). L = [1, 2, 3, 4, 5, 6, 7, 8, 9]これは,次のコマンドと同じ.
?- numlist(1, 9, L). L = [1, 2, 3, 4, 5, 6, 7, 8, 9]リストの各項目に演算を施す.
?- maplist(plus(5), [1, 2, 3], L). L = [6, 7, 8]この時, plus/3を使用し,plus(5, [1, 2,3]の要素,Lの要素)が呼ばれる.
リストの項目を1つ1行に表示
?- maplist(writeln, [1, 2, 3, 4, 5]). 1 2 3 4 5findallは、見つかったもののリストを生成するが、繰り返しのたびに行動を起こす場合 forall が使える
?- forall(between(1, 5, X), writeln(X)). 1 2 3 4 5さらに条件部を括弧で括って次のように出来る。
?- forall((between(1, 10, X), X mod 3 =:= 0), writeln(X)). 3 6 9
その他
式の評価
SWI-Prologで,いわゆるeval関数のような事をしたい場合.term_to_atom/2 が使える.?- term_to_atom(T,'1+2+3'), X is T. T = 1+2+3, X = 6もちろん,関数でもよい.
?- term_to_atom(T,'writeln(\'Hello, World!\')'), T. Hello, World! T = writeln('Hello, World!')