OCamlでPrologを作っている話

# GDIS Prolog というのを作ってます。

これは [ML Advent Calendar 2017](https://adventar.org/calendars/2142) の 16日目の記事です。

書きかけですいませんが、締め切りすぎた感あるので、とりあえず投稿しておきます。追って更新するかも知れないししないかもしれませんが、生暖かい目で見てもらえればと思います。なんでかというとまぁ、型理論にはProlog力も必要だろということで、 OCaml 製のProlog (GDIS Prolog [^12]) を作ってみています。最初はできるだけ小さく美しくを考えてたのですが結構複雑になってしまったのでなんだろうな。うーむです。λProlog [^4] がOCaml製のものがあります。λPrologはエジンバラ記法ではなく、ラムダ計算的な記法を使え、型検査もあります。MLユーザー的には結構好みな Prologかもしれません。ちょっとやる気ないので、文章がとてもいい加減です。すいません。
モチベーションは最初は気軽に小さいPrologを作ろうだったのですが、徐々に型システムの記述に使える言語にしたいと思い拡張し始め、Clover2 [^13] という言語のPPAパッケージを作る実験として PPA パッケージを作ったり、PrologのVSCode用デバッガほしい。っていうか作りたいとか思い始めて色々拡張してたら結構大きくなってしまったのでした。

## インストール方法

Ubuntu 17.04 で

```bash
sudo add-apt-repository ppa:h-sakurai/gdis-prolog
sudo apt-get update
sudo apt install gdispl
```

とすればインストールできます。

あるいはソースコードからのビルドは以下のコマンドでインストールしてください。

```bash
git clone https://github.com/hsk/gdis_prolog
cd gdis_prolog
apt install ocaml
make
sudo make install_
```

## Prologづくりの面白い所

パターンマッチ作ったり、単一化処理作ったりしたあと、述語を増やしてくところとか面白いです。オンメモリデータベースを作るのも楽しい。型システムの実装を短く書いて自分で作った処理系で動かせるのが楽しいです。言語をちょろっと作って遊べる。素晴らしい。実験に速度は必要ないし、型システム作るのに型システムは必要ないのでｗSchemeの処理系作る感じで、Prologの処理系を作ると結構仲間とワイワイ楽しくやれます。

## 標準とか

普段は SWI Prolog [^7] が今熱いので SWI Prologを使っています。なので、SWI Prolog下位互換性を持って作成しています。しかし、標準は別にありまして、ISO Prolog [^5] とかあります。エジンバラ記法が標準のようです。GNU Prolog [^6] が標準に一番近いようです。ライバルは O Prolog [^8] です。

## PPAの作り方とかリリース手順とか

PPAのパッケージ作って大変でした。 [^9] PPAの作り方は、忘れました。オイ

launch pad に登録するにはubuntu one のアカウントが必要とかで、アカウント作って、鍵作って登録して云々です。けっこう面倒くさいです。しかし、一度手順作ってしまえば楽です。淡々とやってけば出来ますｗ

dch -v 0.1.8 などと書いてバージョン設定して
make ppa_test でテストして
make ppa_up で更新できるようにしたのでそうしてます。

`ppa_test`では、サーバで動く登録プロセスをローカルで行えるのでこれやってテスト通れば、確率アップします。`change_log`のチェックが厳しいのでなれないと登録できません。特にバージョン名仁奈に書いたらいいのか分からんぞーって苦しみました。githubにアップしてリリースしたバイナリファイル作って置いとくとかしてます。opamとかなくてもバイナリインストールできるのが強みです。

本当のところは、リンク [^3] はったりすべきだけど面倒になってしまったのでお許しをｗ

ということで、ああだこうだしてインストールできます。

## 今後の予定

### マクロ対応

ある程度してあるのですが、ちゃんと動いてません。

### デバッガ作る

これが本命なのです。デバッガ作るためにマクロ展開をProlog化して逐次実行可能にしたりしてました。
OCamlでデバッガ作るところまではやった[^10]ので、できれば対応したいです。

### WAM

WAM は Prolog の VM のことで、かなり１命令あたりに行う仕事が多いのですが、C言語にコンパイルするなども可能で非常に完成度が高い抽象化された仕様なのでほとんどの高速化PrologはWAMを元に作られています。WAM 以上の成果というのはどうもあまりだせないようで、高速化するためには関数型言語を使ったほうが良いという流れがあります。Haskell製のWAM [^1] をOCamlに移植してみたりはした [^11] ので、これを元に作り直したほうが速いはずだし、コンパイルもできるはずだし、逐次実行するならデバッガも作りやすいはず。移植してわかったことは、、、面倒くさいってこと。

### 出力バッファ

Haskellのコンパイラの移植なので、リスト生成するようになっていたのですが、出力バッファにしたほうがきっと楽です。
だけど出力バッファ使いたいとなると、OPAMもパッケージに含まないといけなくなるのが嫌かなぁ。どうしようかなぁです。

### ドキュメントちゃんとしたい

言語作る時はちゃんと仕様を書くべきだと思うのです。小さい処理系ならちゃんと書けるはず。しかし、書けてないですな。がんばるります。ヘロヘロｗ

## コントリビューションのお願い

一人で作るのも楽しいのですが、一人の力には限界があります。よかったら、プルリクエストください。
特典は、もれなく、コントリビュータ一覧に名前を載せようと思いますｗ

## 参考文献

[^1]: A simple compiler from Prolog to WAM (Warren Abstract Machine) and a runtime for WAM. Haskell製のPrologコンパイラ https://github.com/acharal/wam
[^2]: GDIS Prolog https://github.com/hsk/gdis_prolog
[^3]: PPAの作り方のリンクを貼る
[^4]: λProlog http://www.lix.polytechnique.fr/~dale/lProlog/
[^5]: ISO Prolog https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwi1oJDG_ZLYAhUBfLwKHSS0CqMQFggtMAE&url=http%3A%2F%2Ffsl.cs.illinois.edu%2Fimages%2F9%2F9c%2FPrologStandard.pdf&usg=AOvVaw10bSPfN3ukLM_2D5mH7_RE
[^6]: GNU Prolog http://www.gprolog.org/
[^7]: SWI Prolog http://www.swi-prolog.org/
[^8]: O-Prolog https://qiita.com/sym_num/items/e6e35d3e1bff41f0efe5
[^9]: GDIS Prolog in launchpad https://launchpad.net/gdis-prolog
[^10]: VSCode拡張の簡単なアセンブラのデバッガをOCamlで作った話 https://qiita.com/h_sakurai/items/14aae761c27bfedac0a2
[^11]: The WAM in OCaml https://github.com/hsk/wamo
[^12]: GDIS Prolog https://github.com/hsk/gdis_prolog
[^13]: Clover2 https://github.com/ab25cq/clover2/