見出し画像

SWI-prologとAZ-prologの比較

prologには方言が多い。ISO述語ならば統一されているかと思いきや、そうでもないようだ。少々、両者を比較してみる。

atom_concat/3 (アリティはアトムを想定。なので数値は不可のはずだがSWIではくっついてしまう。まあ、よいことなのかもしれないが)

Welcome to SWI-Prolog (threaded, 64 bits, version 8.4.2)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- atom_concat(aa,11,A).
A = aa11.

参照:他者blog

AZ-prologの場合

AZ-Prolog Version 9.83 (Linux/x64) GCC 9.3.0
Copyright (C) SOFNEC CO., LTD. 1987-2022/02/13
| ?-atom_concat(aa,11,A).
Illegal argument supplied	 ---- Backtrace
atom_concat(aa,11,A_9) ?-
| ?-atom_concat(aa,'11',A).
A	= aa11
yes

ちなみに、AZ-prologの古いバージョン (ver 9.6xあたり)だと、atom_concat(A,ban,'02ban'). とするとAが2になってしまう。本来 「02」のようにアトムとして取り出さなければならない。9.8xシリーズではこのバグは修正されている(本人がいうのだから)。

| ?-atom_concat(A,ban,'02ban').
A	= '02'
yes

current_prolog_flag/2 はAZ-prologのほうはほとんどない(unknowのみ)。SWI (GNU-prolog)のほうは例えば以下のようにたくさんある(詳しくはマニュアルをみてください)。

http://www.gprolog.org/manual/html_node/gprolog046.htmlから抜粋

バージョン確認はISOではないので述語自体も異なる。

?- version.
Welcome to SWI-Prolog (threaded, 64 bits, version 8.4.2)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
AZ-Prolog Version 9.83 (Linux/x64) GCC 9.3.0
Copyright (C) SOFNEC CO., LTD. 1987-2022/02/13
| ?-s_version(A,B,C,D).
A	= 983,
B	= 'LINUX',
C	= 'JAPAN',
D	= x64
yes

atom_length/2 アトム長を返す。SWIは[]は0,AZは2となる。そして、アトムかどうか確認するとSWIはfalse, AZはtrue。 SWIでは、is_list([]) はtrue, AZでは、list([]) は no。

SWI-Prolog
?- atom([]).
false.

?- atom_length([],N).
N = 0.
AZ-Prolog
| ?-atom([]).
yes
| ?-atom_length([],N).
N       = 2
yes
GNU Prolog 1.4.5 (64 bits)
Compiled Feb 23 2020, 20:14:50 with gcc
By Daniel Diaz
Copyright (C) 1999-2020 Daniel Diaz
| ?- atom_length([],N).

N = 2

yes
| ?- atom([]).

yes
| ?- write_canonical([a]).
'.'(a,[])

| ?- atom_concat(aa,11,A).
uncaught exception: error(type_error(atom,11),atom_concat/3)
| ?- atom_concat(aa,'11',A).

A = aa11


| ?- current_prolog_flag(prolog_version,A).

A = '1.4.5'

term_to_atom/2(SWI)      term_atom/2(AZ)     write_to_atom(Atom,Term) (GNU prolog) termとatomを相互に変換
atom_number/2 (SWI)    というアトムを数値に変換する述語 はAZ-Prologにはないので term_atom/2 (AZ)を使う。アリティの順序が逆なので注意。

SWI-Prolog
?- atom_number('123',N).
N = 123.

?- atom_number('02',N).
N = 2.

?- term_to_atom(T,'456').
T = 456.


AZ-Prolog
| ?-term_atom(T,'123').
T       = 123
yes
| ?-term_atom(T,'02').
T       = 2
yes
| ?-number_codes(1,A),atom_codes(Atom,A).
A       = [49],
Atom      = '1'

cputime/0 (SWI) はprolog実行時間、cputime/0 (AZ)は1970年1月1日から現時点までの秒数

Welcome to SWI-Prolog (threaded, 64 bits, version 8.4.2)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- X is cputime.
X = 0.109375.
AZ-Prolog Version 9.64 (Linux/x64) GCC 5.4.0
Copyright (C) SOFNEC CO., LTD. 1987-2017/07/12
| ?-X is cputime.
X       = 1699712459.90727
yes

算術関数では、log/1 (SWI, AZ 自然対数 eを底とする対数)、log10/1 (SWI, AZ 10を底とする対数)があり、AZ-Prologのみ log/2 ( AZ, log(E,N) Eを底とするNの対数)がある。

AZ-Prolog Version 9.64 (Linux/x64) GCC 5.4.0
Copyright (C) SOFNEC CO., LTD. 1987-2017/07/12
| ?-X is log(3.0,9.0).
X       = 2.0

randomはSWIでは述語 (random/1) として、AZの場合には算術関数(random/0)として(random_seed(N)で初期化が必要)0から1までの実数の乱数を発生させることができる。

SWI-Prolog
?- random(A).
A = 0.12222201549134765.
AZ-Prolog
| ?-random_seed(179).
yes
| ?-X is random.
X       = 0.565605990955979
yes


shell/1 (SWI)   system/1 (AZ)    OS のコマンド実行 
 関係子「'.'」を使った表現。SWIとAZでは大きく異なる(というかSWIがサポートしていないようだ)。(※サポートしてないのではなく、「'[|]'」という関係子の複合項で表現している)

SWI-Prolog
?- write('.'(a,[])).
ERROR: Type error: `dict' expected, found `a' (an atom)
ERROR: In:
ERROR:   [13] throw(error(type_error(dict,a),_21874))
ERROR:   [10] '<meta-call>'(user:user: ...) <foreign>
ERROR:    [9] toplevel_call(user:user: ...) at c:/program files/swipl/boot/toplevel.pl:1158
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
SWI-Prolog
?- display([a]).
'[|]'(a,[])
true.

?- diplay([a,b]).
Correct to: "display([a,b])"? yes
'[|]'(a,'[|]'(b,[]))
true.

?- write_canonical('[|]'(a,[])).
[a]
true.
AZ-Prolog Version 9.83 (Linux/x64) GCC 9.3.0
Copyright (C) SOFNEC CO., LTD. 1987-2022/02/13
| ?-write_canonical([a]).
[a]yes
| ?-write('.'(a,[])).
[a]yes

C言語のように出力したいとき、AZ-Prolog側だけの述語、AZ-Prologのマニュアルには sprintf/3 が載っていますが、現時点では c_sprintf/3 という述語も使えます(2023/11/18)。

AZ-Prolog Version 9.64 (Linux/x64) GCC 5.4.0
Copyright (C) SOFNEC CO., LTD. 1987-2017/07/12
| ?-c_sprintf(A,"%2.4f   %.5s¥n",[12.3456789,misosyouyukome]).
A       = '12.3457   misos¥n'
yes
| ?-c_sprintf(X,"Hello %s, year=%d\n",['world!',2023]).
X       = 'Hello world!, year=2023(\n)'
yes

すでに登録されている述語については、current_predicate/1 ( current_predicate(A/B) のように使う)が SWI, AZともにある。また、登録されているアトムについても、両者とも current_atom/1 でみることができる(特に、is 演算子で使われる算術関数などはこれで確認できる)。 AZ-Prologではこの他、 get_builtin/3 でも登録済の述語がわかる。

AZ-Prolog Version 9.64 (Linux/x64) GCC 5.4.0
Copyright (C) SOFNEC CO., LTD. 1987-2017/07/12
| ?-get_builtin(A).
no
| ?-get_builtin(A,B,C).
A       = halt,
B       = 0,
C       = 0;
A       = assert,
B       = 1,
C       = 1;
A       = assertz,
B       = 1,
C       = 2;
A       = assert,
B       = 2,
C       = 3;
A       = asserta,
B       = 1,
C       = 4;
A       = listing,
B       = 0,
C       = 5;
A       = listing,
B       = 1,
C       = 6;
A       = s_new,
B       = 0,
C       = 7


この記事が気に入ったらサポートをしてみませんか?