論理型プログラミング言語 Prologを触ってみました(『7つの言語 7つの世界』第4章)

7つの言語 7つの世界』(オーム社)の第4章で紹介されているPrologという言語を少しさわってみました。論理型プログラミング言語というものらしいです。
使用した処理系
GNU Prolog(日本語対応はしてない)
 Mac OS X Lionにインストールしてみたのですが、/opt/local/binにインストールされてしまったため、PATHはすぐには通っていない等々で初歩的なところで結構躓きましたが、以下を参考にしてなんとかその問題もクリアしました。
SWI-Prolog – Macで使うための準備 : Please Comment on My Code
 
.bashrcに書き込むか、一時的に通すだけでよいなら、直接、シェルに打ち込む。

export PATH=$PATH:/opt/local/bin

 処理系にGNU Prologを使用している場合は、起動するために「gprolog」と打つ。

| ?-

 こんな感じのものがでれば起動成功です。
  Prologのソースファイルの拡張子は慣習的に「.pl」なのだそうです。Perlと混同してしまいそうですが、こちらのほうが歴史が古いようです。テキストエディタで作成したplファイルを適当なところにおいて

| ?- ['/Users/code/test.pl'].

 な感じで [‘ ’]内にplファイルを置いたディレクトリを指定して読み込むと 

| ?- ['/Users/code/test.pl'].
compiling /Users/code/test.pl for byte code...
/Users/code/test.pl compiled, 4 lines read - 933 bytes written, 7 ms
yes

とコンパイルして読み込んでくれます。
  
 ここまで出来るようになるまでインストールから一時間はかかっったとです。情けなかと・・・。
 それはそれとしてProlog、なかなか面白い言語です。『7つの言語 7つの世界』のPrologの解説は半分も理解できませんでしたが、それでも面白かった。これまで私がかじってきたRubyやPerlのようなプログラミング言語は、あーだったらこうして、こーだったらあーしてみたいな命令を書いていたのかなと思うのですが、Prologはルールを書き込むという感じです。
 ・・て、ここで簡単なサンプルでも書いて、それを例示できればよかったのですが、今回はパス・・・・。挫折した・・・orz。
 
 自分でローテーションを組むプログラムを書いてみようかと
・月曜日から土曜日までの1日2人が入るローテーションを組む。
・ローテーションに入るのはTaro、Jiro、Hanakoの3人
・Taroは○曜日と○曜日と○曜日が都合がよく、Jiroは・・・・
 という感じで条件を決めて、一週間のローテーションがばっと決まるものを書いてみたかったのですが、リストもよく理解してない私なので、ハードルが高すぎて早々に躓いてしまいましたorz。出直してきます。とりあえず今回は『7つの言語 7つの世界』の次の章のScalaに進みます(進めるのか・・・?)。

オブジェクト指向を理解してない私がプロトタイプベースのオブジェクト指向言語のIOを触ってみました(『7つの言語 7つの世界』第3章)

7つの言語 7つの世界』(オーム社)を読みながら、IOという言語で少し遊んでいます。プロトタイプベースの言語なので、オブジェクトがクラスの代わりになるんだそうで、オブジェクトを複製してさらに別のオブジェクトを作成したり、インスタンスを生成したりします。
 
 IO言語については以下の解説をご覧ください(私には解説はムリぽ)。
io(公式サイト。ダウンロードもこちら)
Io (プログラミング言語) – Wikipedia
Rubyist Magazine – Rubyist のための他言語探訪 【第 3 回】 Io
 といいつつも、メモ程度には書いてみたいと思います(そのほうが書いた方が理解しやすいので)。

1.最初の儀式

 まずはということで、”Hello,World!”。

Io> "Hello, world!" println
Hello, world!

 

2.プロトタイプチェーン

 ルートレベルのオブジェクトはObjectオブジェクトです。このObjectオブジェクトからこんな感じでオブジェクトを複製します。

Io> Thing := Object clone
==>  Thing_0x46ff60:
  type             = "Thing"

 これはOjectオブジェクトを複製して、Thingという変数に代入することで、Objectオブジェクトを複製したThingオブジェクトを作成している、という理解でよいのですかね。同じようにThingオブジェクトを複製して他のオブジェクトをつくることができます。

Io> CreativeWork := Thing clone
==>  CreativeWork_0x475980:
  type             = "CreativeWork"
Io> Blog := CreativeWork clone
==>  Blog_0x47b3d0:
  type             = "Blog"

 ここまでで、プロトタイプチェーンは以下のような感じになります。
Object > Thing > Creativework > Blog
 たとえば、Thingオブジェクト内に “description”というキーを持つプロパティを定義してみます(「スロット」というらしいです)。

Io> Thing description := "The most generic type of item. "
==> The most generic type of item.

 当然ですが、BlogオブジェクトはThingオブジェクトを継承したCreativeWorksオブジェクトを継承しているので、Blogオブジェクトで”description”をキーに持つスロットを定義していなければ、以下のようにThingオブジェクトで定義したスロットが引き継がれます。

Io> Blog description
==> The most generic type of item.

 
 当然、Blogオブジェクトでdescription”をキーに持つスロットを定義してやればそちらが優先されます。

Io> Blog description := "A blog"
==> A blog
Io> Blog description
==> A blog

3.インスタンス?

 これまで、Thing、CreativeWork、Blogという頭文字が大文字のオブジェクトばかり生成してきました。小文字にすると、インスタンスっぽいものを生成することができるようです(多分、インスタンスですよね・・)。といってもインスタンスもオブジェクトなので、大文字と小文字の違いは独自のtypeをもつか、もたないかぐらいの違いしかないようです。

Io> myBlog := Blog clone
==>  Blog_0x2b4290:
Io> myBlog type
==> Blog

 はぁ〜と思ったのが、頭小文字(インスタンス?)を複製して頭大文字のオブジェクトを生成することができるようで、「他の言語(Rubyぐらいしか知りませんが)だとどうだったか・・・・」とかいろいろと。

Io> MarchEntry := myBlog clone
==>  MarchEntry_0x4567e0:
  type             = "MarchEntry"
Io> MarchEntry type
==> MarchEntry
Io> MarchEntry description
==> A blog
Io> myBlog description := "更新頻度低め"
==> 更新頻度低め
Io> MarchEntry description
==> 更新頻度低め

 この場合、継承関係はこうなるのでしょうか。
Object > Thing > Creativework > Blog >myBlog > MarchEntry

4.シングルトン

 上で以下のようにBlogオブジェクトを生成しました。

Io> Blog := CreativeWork clone
==>  Blog_0x47b3d0:
  type             = "Blog"

 
 もう一度BlogオブジェクトをCreativeWorkオブジェクトから複製して生成すると同じオブジェクト名であっても、異なるオブジェクトが生成されます。

Io> Blog := CreativeWork clone
==>  Blog_0x48d3f0:
  type             = "Blog"

 
 しかし、以下のように一度生成したBlogオブジェクトをBlogオブジェクトを複製するときに代入すると、”Blog_0x48d3f0″という全く同じオブジェクトが生成されます(「シングルトンオブジェクト」というかしら?)。

Io> Blog clone := Blog
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"

 
 このシングルトンオブジェクトから生成したインスタンスは異なる名前を当てても同じオブジェクトになるようです。

Io> hisBlog := Blog clone
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"
Io> herBlog := Blog clone
==>  Blog_0x48d3f0:
  clone            = Blog_0x48d3f0
  type             = "Blog"
Io> hisBlog == herBlog
==> true

 
 プロトタイプベースのオブジェクト指向言語では、オブジェクトがクラスの役割を果たすというのはわかってきたような気もしないでもないですが、正直まだよく分からない部分が多いですね。少なくともクラスベースのRubyではどうだったかなという疑問はすぐに確認しておいたほうがよさそう。
 『7つの言語 7つの世界』でIOを取り上げた章の2/3を読んだところです。あと1/3がんばります。