LoginSignup
0
0

Prologでグローバル変数を定義する

Posted at

概要

ドキュメントのグローバル変数の項目を読んだのでまとめる

使い方

値の設定

グローバル変数へ値を設定するには以下の述語を利用する。

  • b_setval : blocking set value
  • nb_setval : non-blocking set value
  • nb_linkval : non-blocking link value

b_setvalnb_setvalの違いは以下の通り。
b_setvalは更新中に他スレッドからのアクセスがブロックされる(スレッドセーフ)
nb_setvalは更新中に他スレッドからのアクセスを許可する

nb_linkvalnb_setvalとほぼ同じ挙動であるが、値のコピーを作成しない。
具体的には以下のコードからわかるが、nb_linkvalは値のコピーを作成しないので、N = worldのスコープから外れると中身を参照できなくなる。

demo_nb_linkval :-
        T = nice(N),
        (   N = world,
            nb_linkval(myvar1, T),  % 保存
            nb_setval(myvar2, T),   % 保存
            fail                    % 強制的に失敗させる
        ;   nb_getval(myvar1, V1),  % 失敗したのでこちらが実行される
            nb_getval(myvar2, V2),
            writeln(V1),            % nice(_27146) 引数の中身までは保存されない
            writeln(V2)             % nice(world)が保存される
        ).

値の取得

グローバル変数の値を取得するには以下の述語を利用する。

  • b_getval : blocking get value
  • nb_getval : non-blocking get value
  • nb_current : non-blocking current value

b_getvalnb_getvalの違いは値の設定と同様にBlockin/Non-Blockingの違いである。

b_getval, nb_getvalnb_currentの違いは以下の通り。
b_getval, nb_getvalは存在しない変数名を指定するとエラーになるが、nb_currentは失敗(false)する。

demo_getvalue :-
  b_setval(var1, 100),
  nb_getval(var1, X1),
  nb_current(var1, X2),
  writeln([X1, X2]),            % var1は存在するので両方とも取得可能
  (
    nb_current(var2, X3),       % var2は存在しないので失敗する
    writeln(X3)
    ; writeln('not found var2') % 失敗するのでこちらが実行される
  ),
  nb_getval(var2, X3).          % var2は存在しないのでエラーになる

値の削除

グローバル変数を削除する場合は以下の述語を利用する。
なおBlocking用の述語は用意されていないようである。

  • nb_delete : non-blocking delete

まとめ

最初はまとめるほどのことでも無いと思ったが、nb_linkvalnb_currentなどドキュメントを読んだだけでは挙動がわかりにくかったので、サンプルコードで挙動を確認しつつまとめてみました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0