2015/04/02 Update
・Mac OS X に対応しました
・AZ-Prolog用Eclipse Pluginが利用可能となりました
改修内容
【制約変数の構造とFrozenGoal惹起タイミングの変更 】
Ver7では変数のユニフィケーションごとにFrozenGoalの惹起を行っていたがVer8において
ヘッドユニフィケーションが全て成功したあとにFrozenGoalの惹起を行うように変更した。
<Version7.x>
?- freeze(X,write(frozen_goal_invoked)),[1,2,3]=[X,2,4].
frozen_goal_invoked
no
a(1,2).
?- freeze(X,write(frozen_goal_invoked)),a(X,3).
frozen_goal_invoked
no
<Version8.x>
?- freeze(X,write(frozen_goal_invoked)),[1,2,3]=[X,2,4].
no
?- freeze(X,write(frozen_goal_invoked)),a(X,3).
no
【虚変数の取り扱い】
プログラム中の虚変数に名前がついていても、コンサルト(アサート)時は虚変数(“_”)にする。(SWIと同一仕様)これにより、変数名スペルミスを防ぐことが可能。
?-assert(a(A,B)),listing.
a(_,_).
yes
【TopLevelの結果表示をwriteqに変更】
<例>
Version 8.08まで
| a('X').
| ?- a(X).
X = X
Version 8.09
| ?- a(X).
X = 'X'
【組込述語の追加】
1) chdir/1 カレントディレクトリを引数で指定されたディレクトリに変更します。
AZ-Prolog version 8.10 (Win64/x64)
Copyright (C) SOFNEC CO., LTD. 1987-2015/01/13
| ?-get_install_base_dir(X),atom_append(X,'\sample\other',Y),chdir(Y).
X = 'C:\AZ-Prolog.810',
Y = 'C:\AZ-Prolog.810\sample\other'
yes
【DEBUGGERの大幅改修】
1) SPYの機能拡張
従来の「述語名」、「述語名/アリティ」に加え
「述語名/アリティ/節順位」「述語名/アリティ/節順位/ゴール順位」のSPY(BreakPoint)も可能にした。
| ?-listing.
a(1) :- true, write(a1), nl.
a(2) :- true, write(a2), nl. <== a/1第2節の第2ゴール、write(a2)がTryされるところでトレースを開始したい
a(3) :- true, write(a3), nl.
yes
| ?-spy a/1/2/2.
yes
||?-a(X),fail.
a1
[2] 1 Try : write(a2) ? w <== "w"コマンドで現在位置確認
a/1/2/2 <== トレース開始点が a/1/2/2であることが確認できる
[2] 1 Try : write(a2) ? p <== "p"コマンドで呼び出し祖先を確認
1: write(a2)
0: a(2) :-
true,
*> write(a2), <== 親節のこの位置(a/1/2/1)をTry中
nl.
Goal: ?- a(2),fail.
[2] 1 Try : write(a2) ?
2)leash/1,leash2/1 の改良
従来のビット対応設定に加え、局面頭文字による設定を追加。
?- leash1(rfpt). <== retry,fail,pop,try の意味 2'111001 と同義
3)leash2(2) モードでのトレース表現の改良
各局面表示の直後にWコマンドの内容を表示。
4) Trace中の項の表示をwriteqに変更
5) Trace コマンドの変更
(1)Trace中のBreakの振る舞い
従来、SPY,Callcountのクリアをしていたが、これを廃止。
(2) Parent表示の改良
・スタック深さ番号を正規化(従来と逆順)下記の 3: 2: 1:
・祖先節の表示でTry中のゴールに"*>"を追加
[4] 3 Try : select([4,3,2,1],S_70,D_72) ? p <== "p"コマンドで先祖である節をすべて表示します
3: select([4,3,2,1],S_70,D_72)
2: put([4,3,2,1],[],L_8) :- <== select/3の親はput/3です
*> select([4,3,2,1],S_70,D_72), <== ここをTry中
safe([],S_70,S_70),
put(D_72,[S_70],L_8).
1: queen(4,L_8) :- <== put/3の親はqueen/2です
generate(4,[4,3,2,1]),
*> put([4,3,2,1],[],L_8). <== ここをTry中
0: q(4) :- <== queen/2の親はq/1です
e_register(0,0,0),
*> queen(4,L_8), <== ここをTry中
e_register(0,N1_10,N1_10+1),
M_12 is N1_10+1,
write(No.),
write(M_12),
nl,
disp(L_8,4),
fail.
Goal: ?- q(4). <== q/1を呼び出したトップレベルのゴールです
[4] 3 Try : select([4,3,2,1],S_70,D_72) ?
6) Trace コマンドの追加
(1)Trace コマンドに d (Dump Stack)を追加
D dump stack |
スタックの最底部から最上部までのゴールを全て木構造で表示します。 ”[シリアルナンバー] スタックの深さ: ゴール” の形式で表示され、”>*”が現在のスタック位置を表します。 [シリアルナンバー] はトレース時の「インタプリテーションが始まってからの実際のゴールの積層数」と同じです。 ”スタックの深さ:”は逆順ですが、Pコマンドと同じ現在ゴールの直系列で「現在ゴールからトップゴールまでの先祖系列の深さ」です。 ”スタックの深さ:”がついていない行はオルタナティブの残っている兄弟ゴールおよびその子孫にあたります。 [シリアルナンバー] はバックトラックパス(番号の小さい方向に向かって順番にバックトラックする)でもあります。 |
---|
<例>
[14] 1 Try : e_register(0,N1_10,N1_10+1) ? d <== Dコマンド
[1] 0: q(4)
[2] ┣ queen(4,[2,4,1,3])
[3] ┃ ┗ put([4,3,2,1],[],[2,4,1,3])
[4] ┃ ┣ select([4,3,2,1],3,[4,2,1])
[5] ┃ ┃ ┗ select([3,2,1],3,[2,1])
[6] ┃ ┗ put([4,2,1],[3],[2,4,1,3])
[7] ┃ ┣ select([4,2,1],1,[4,2])
[8] ┃ ┃ ┗ select([2,1],1,[2])
[9] ┃ ┃ ┗ select([1],1,[])
[10] ┃ ┗ put([4,2],[1,3],[2,4,1,3])
[11] ┃ ┣ select([4,2],4,[2])
[12] ┃ ┗ put([2],[4,1,3],[2,4,1,3])
[13] ┃ ┗ select([2],2,[])
[14]>* 1: ┗ e_register(0,N1_10,N1_10+1) Try
[14] 1 Try : e_register(0,N1_10,N1_10+1) ?
(2)i(inspect) コマンド 制約変数の制約情報調査機能
|?-listing.
turukame(Turu,Kame,Foot,Head) :-
Turu in 0..Head,
Kame in 0..Head,
Foot#=Turu*2+Kame*4,
Head#=Turu+Kame.
yes
|?-trace.
yes
||?-turukame(X,Y,14,5).
[1] 0 Try : turukame(X_7,Y_9,14,5) ?
Match : turukame(X_7,Y_9,14,5) :-
X_7 in 0..5,
Y_9 in 0..5,
14#=X_7*2+Y_9*4,
5#=X_7+Y_9.
[2] 1 Try : X_7 in 0..5 ? i <== Iコマンド
Foot = 14 <== 定義節の変数:Foot は 14に束縛されています
Head = 5 <== 定義節の変数:Head は 5に束縛されています
[2] 1 Try : X_7 in 0..5 ?
<< BUILTIN CALL >>
[2] 1 Succ : _30 in 0..5
[2] 1 Try : Y_9 in 0..5 ? i <== Iコマンド
Turu = _30 { [0..5]::true } <== 定義節の変数:Turu は 0..5 に制約されています
Foot = 14
Head = 5
[2] 1 Try : Y_9 in 0..5 ?
<< BUILTIN CALL >>
[2] 1 Succ : _46 in 0..5
[2] 1 Try : 14#=_30*2+_46*4 ? i <== Iコマンド
Turu = _30 { [0..5]::true }
Kame = _46 { [0..5]::true }
Foot = 14
Head = 5
[2] 1 Try : 14#=_30*2+_46*4 ?
<< BUILTIN CALL >>
[2] 1 Succ : 14#=_30*2+_46*4
[2] 1 Try : 5#=_30+_46 ? i <== Iコマンド
Turu = _30 { [1,3,5]::$clp_area_propagation(7,[1,2],[_30,_46]),! } <== 制約が狭まりました
Kame = _46 { [1..3]::$clp_area_propagation(7,[1,2],[_30,_46]),! } <== 制約が狭まりました
Foot = 14
Head = 5
[2] 1 Try : 5#=_30+_46 ?
<>
[2] 1 Succ : 5#=3+2 <== この制約で値が求まりました
<< LAST CALL >>
[1] 0 Succ : turukame(3,2,14,5)
X = 3,
Y = 2
yes
(3)O(Step Return) コマンド
親スタックにマークを付け「Lコマンド」の処理を実行します。トレース中にステップを追わなくてもよい節に入り込んでしまったときに使います。
(4)w(where) コマンド Trace中のゴールの位置情報(述語名/アリティ/節順位/ゴール順位)を表示
| a:- b. % a/0/1 述語名=a,アリティ=0 ,第1節
| a:- c. % a/0/2 述語名=a,アリティ=0 ,第2節
||?-a.
[1] 0 Try :a ?
Match : a :-
b. ? w <== wコマンド
a/0/1 <== a/0 の第1節にマッチしました
[2] 1 Try :b ? w <== wコマンド
a/0/1/1 <== a/0 の第1節の1番目のゴール(b)をTryしています