素性構造型対応AZ-Prolog Ver.9をリリース致しました。ぜひ一度おためしください。 x

2014/12/19 Update

改修内容

【制約変数の構造と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
 
【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) Trace コマンドの追加
トレース中のコマンドに次の2つを追加。

(1)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しています


(2)i(inspect) コマンド 制約変数の制約情報調査機能

||?-X in 1..10,X in 5..20.
 [1] 0 Try   : X_17 in 1..10,X_17 in 5..20 ? 
 << BUILTIN CALL >>
 [1] 0 Try   : X_17 in 1..10 ? 
 << BUILTIN CALL >>
 [1] 0 Succ  : _27 in 1..10 ? i    <== "i" コマンド

        _27 { [1..10]::true }      <== 変数が 1..10 の値領域に束縛されたのが確認できる
         in 1..10
 [1] 0 Succ  : _27 in 1..10 ? 
 [1] 0 Try   : _27 in 5..20 ? 
 << BUILTIN CALL >>
 [1] 0 Succ  : _27 in 5..20 ? i    <== "i" コマンド

        _27 { [5..10]::true }      <== 5..20 により、変数が 5..10 の値領域になったのが確認できる
         in 5..20
 [1] 0 Succ  : _27 in 5..20 ?


3)Parent表示の改良
(1) スタック深さ番号を正規化(従来と逆順)下記の 3: 2: 1:
(2) 祖先節の表示で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) ?


4)leash/1,leash2/1 の改良
従来のビット対応設定に加え、局面頭文字による設定を追加。

?- leash1(rfpt).  <== retry,fail,pop,try の意味 2'111001 と同義

5)leash2(2) モードでのトレース表現の改良
各局面表示の直後にWコマンドの内容を表示。

6)Trace中のBreakの振る舞い
従来、SPY,Callcountのクリアをしていたが、これを廃止。

7) Trace中の項の表示をwriteqに変更

8) 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) ? 

【TopLevelの結果表示をwriteqに変更】

<例>

Version 8.08まで

| a('X').
| ?- a(X).
X	= X

Version 8.09

| ?- a(X).
X	= 'X'