リスト中に文字と数字が並ぶ際には上記の事を注意しなければいけません。
?- [X] = "(".
X = 40 ;
No
というように、リスト要素をマッチングして行くと思わぬところで単一化されてしまいます。これを除こうと思っても、実際に数値なのでnumber/1は使えません。但し[X]全体をマッチしてやればnumber/1はfalseとなります。
アトムの文字列表記が数値リスト(ASCII値となります)であることを利用して、シーザー暗号を作ってみましょう。変換部分はそのままです。
translate([], []).
translate([X|R], [X1|R1]) :-
plus(X, 3, X1),
translate(R, R1).
アトムとその文字列表記の変換にはatom_codes/2を利用します。他にもchar_code/2やnumber_codes/2などが仕様にあります。ちなみにこの述語の引数をどちらも変数にすると例外が発生しますから、暗号のエントリ述語はこんな風に書きました。
caesar(Flat, Unflat) :-
((nonvar(Flat),
atom_codes(Flat, C1));
(nonvar(Unflat),
atom_codes(Unflat, C2))),
translate(C1, C2),
atom_codes(Flat, C1),
atom_codes(Unflat, C2).
平文も暗号文も可逆入力ですが、なんだかちょっと冗長ですね :)
0 件のコメント:
コメントを投稿