※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。今回は、リスト処理を学習する際に、よく出現する述語のmemberappendlengthreverseについて学習します。member(X,T).?-member(a,[a,b,c]).yes?-member(d,[a,b,c]).no解説member述語は2つ定義します。一つ目の述語は、第一アリティと、第二アリティのリストの頭部が一致した場合、trueとし終了します。一致しなかった場合、2つ目の述語が実行され、第二アリティを頭部、尾部へ分解し第一アリティと、尾部を再度、自分自身へ渡します。※注:memberはAz-Prologには組み込み述語として定義されているので、実際に作成してみる際は、述語名を適宜変えてください。[a,b,c,d,e,f]yes解説append述語は2つ定義します。一つ目の述語は、第一アリティが空リストであれば、第二アリティを第三アリティとユニフィケーションします。空リストではなければ、第一アリティのリストの頭部を、第三アリティのリストの頭部へ追加その後、尾部を自分自身へ渡し、再帰処理を行います。※注:appendはAz-Prologには組み込み述語として定義されているので、実際に作成してみる際は、述語名を適宜変えてください。[];上記の例のように、ひとつの述語で複数の使い方ができるのがPrologの特徴です。一つ目の述語は、第一アリティが空リストの場合、0を第二アリティへユニフィケーションします。第一アリティが空リストでは無い場合、尾部をlengthへ渡し、再帰させ、そこでユニフィケーションされた第二アリティに1を足した値を、(自分自身の)第二アリティへユニフィケーションします。※注:lengthはAz-Prologには組み込み述語として定義されているので、実際に作成してみる際は、述語名を適宜変えてください。一つ目の述語は、例によって終了条件です。第一アリティが空リストでは無い場合、尾部をreverseへ渡し、再帰させ、そこでユニフィケーションされた第二アリティと、頭部をappend述語で結合し、そのリストを(自分自身の)第二アリティへユニフィケーションします。上記の定義以外に、以下の書き方も可能です。!.reverse2([H|T],Y,R):-reverse2(T,[H|Y],R).reverse2では、reverse2/2にてreverse2/3を定義し、計算の途中結果を格納する為に第二アリティを使用します。このように、処理の途中経過と単一化されるものを「累算器」と呼びます。累算器を使うことによって、二つのリストを連結するという処理が必要ではなくなりますので、効率がかなり改善されます※AZ-Prologに同封されている、[DEL_APP.PL]によるとreverseの定義では、計算量はO(n^2)オーダーとなり、reverse2ではO(n)オーダーで済むとのこと。N要素のリストを反転する述語のCall回数は、それぞれ次のようになる。N121030100revese36664965151revese2341232102※詳しくは上述のファイルを参照してください。プライバシーポリシー。