※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。ついてassertやretractはヒープ領域内に新たに述語を追加したり、反対に削除したりする組み込み述語です。assert/1ヒープ領域に述語を追加します。類似の述語としてasserta,assertzがあり、それぞれassertaは同一名の述語があった場合に、その述語の先頭に、assertzはその述語の最後尾に追加されます。※assertについても、基本的に同一述語名の最後尾に追加が行われますが、何番目に追加が行われるかは保障されていません。そのため、確実に最後尾に述語を追加したい場合は、assertzを使用した方が確実です。yes解説1回目のa(1).ではまだ何の述語の定義もされていないため、失敗して終了しています。その後、assert(a(1))の実行により,ヒープ領域にa(1)という述語が定義されたため、2回目のa(1).が成功するようになっています。listingについてlistingとはヒープ領域に登録(consultやassert)されたプログラムを出力する組み込み述語です。具体的になにが行われているのかわかりません。そこで以降の例ではlistingを使用して、ヒープ領域の状態を確認しながら、動きを見てみましょう。何も表示されずに、終了しています。2回目のlistingでは直前に行われたassert(a(1)).によって、a(1)という述語がヒープ領域に登録されたため、a(1).という内容が出力されています。asserta/1ヒープ領域へ述語を追加しますが、assertと違って、同一述語名の先頭に登録されます。そのため、追加した述語を、既に登録済みの述語より優先的に処理したい場合などに、使用します。asserta事前に以下のコマンドを実行しておきます。事前に実行したassertでは述語は実行した順番でaという述語が登録されていますが、その後実行された、asserta(a(0))はa(1)という述語より前に登録されていることがわかります。assertの利用方法の一例assertにはフラグのような利用方法があります。以下にその一例を示します。aという述語で定義された内容を表示する。同一の述語が存在する場合は1度だけしか表示しないものとする。上記の例ではまず、出力対象のaという述語を定義しています。testという述語はaという述語を順番に呼び出し、aの述語の中の数字が出力されたことがあるかのチェック用の述語test2を呼び出し,その数字が出力されたことがなければ出力します。チェック用の述語のtest2では、1つ目の定義で出力済みか否かのフラグ用の述語b(X)の存在チェックを行います。b(X)が存在する(出力されたことがある)ならfailさせて、且つ、カットオペレータによってバックトラックも行わずにtest述語のwrite以降の処理を実行せず、次のaの述語を探して処理に移ります。2つ目の定義は述語b(X)が存在しなかった(出力されたことがなかった)場合の処理を記述されており、assertによって、現在の入力引数でbという述語を定義して(出力済みのフラグを立てて)、test述語のwrite以降の処理を実行します。実行してみましょう?-test.123yes上述のプログラムで、a(1)という述語は2つ登録されていますが、1は1度だけしか表示されないことが確認出来ました。retract/1引数で指定された述語とユニファイされた述語をヒープ領域から削除します。retract事前に以下のコマンド実行しておきます。?-assert(a(1)).?-assert(a(2)).?-assert(a(3)).ヒープ領域を確認?-listing.a(1).a(2).a(3).yesretractの実行?-retract(a(2)).yesヒープ領域の確認?-listing.a(1).a(3).解説retract(a(2))で指定された、a(2)の述語が削除されています。retractは指定した述語とユニファイ可能な述語が登録されていなければ、失敗します。retractとabolishとs_newヒープ領域に登録された述語を指定して削除する組み込み述語には、retractの他にabolishがあります。見つかった最初の述語を削除するのに対して、abolishは、abolish(X,Y)という形で記述し、Xで指定した述語名のYで指定したアリティ数に合う述語を全て削除するという違いがあります。s_newはヒープ領域を全てクリアします。事前に以下のコマンド実行しておきます。削除される述語は1つだけであるため、a(1)という述語を全て削除したい場合には注意が必要となり、そういった場合にまとめて削除してくれるabolishは便利です。上の例の場合なら、a(1)という述語を削除するつもりで使用したつもりが、a(2)という述語を削除したくない場合も削除されてしまうという問題があるため、やはり注意が必要となります。nonvar/1varとnonvarについてvarやnonvarは、入力引数が未代入の変数か否かを確認する、型チェック用の述語ですvar/1varは引数に変数が指定された場合に、その変数に値が代入されていない場合に限り、成功します。引数には変数以外にアトムやリストなども指定出来ますが、その場合はfailします。Xyes?-X='abc',var(X).no?-var(123).no?-var([a,b,c]).no解説1回目のvarではXに何も代入していないため、成功しています。2回目のvarでは直前にXに値が代入されているため、失敗しています。nonvar/1nonvarは引数に変数が指定され、その変数に値が代入されていない場合に限り、failします。引数には変数以外にアトムやリストなども指定出来ますが、その場合もやはり成功します。abcyes?-nonvar(123).yes?-nonvar([a,b,c]).yes解説1回目のnonvarではXに何も代入していないため、失敗しています。2回目のnonvarでは直前にXに値が代入されているため、成功しています。float/1integerとfloatについてintegerとfloatは、入力引数が整数か、浮動小数点数かを確認する、型チェック用の述語です。integer/1integerは入力引数が整数か、整数の代入された変数の場合のみ成功する述語です。引数にはアトムやリストなども指定出来ますが、その場合はfailします。123yes?-integer(1.23).no?-integer([a,b,c]).no?-integer('123').no?-integer(X).no解説1つ目の実行では引数が整数であるため、2つ目は整数が代入された変数であるため成功しています。3つ目も引数は数値ですか、浮動小数点数であるため、失敗しています。その他はそもそも引数がリストやアトム、未代入の変数であるため、それぞれ整数であるという条件に合致しないため失敗しています。floatfloatは入力引数が浮動小数点数か、浮動小数点数の代入された変数の場合のみ成功する述語です。引数にはアトムやリストなども指定出来ますが、その場合はfailします。1.23yes?-float(123).no?-float([a,b,c]).no?-float(X).no解説1つ目の実行では引数が浮動小数点数であるため、2つ目は浮動小数点数が代入された変数であるため成功しています。3つ目も引数は数値ですが、整数であるため、失敗しています。その他はそもそも引数がリストや未代入の変数であるため、それぞれ浮動小数点数であるという条件に合致しないため失敗しています。まとめ今回は以下の事を学習しました。プライバシーポリシー。