🤠

Goで論理プログラミング

2022/12/23に公開

どうも、Go信者のgureguです。今年初めて論理プログラミングをやってみて世界が変わりました。Go言語で論理プログラミングが出来るライブラリを紹介しようと思います。

ぼくのかんがえたさいきょのくみあわせ

課題: Go言語で書かれたソフトを拡張機能のようにカスタマイズしたい

Go言語の特徴としては

  • 制止的
  • コンパイル式
  • 手続き型
  • 標準ライブラリが優れている
  • プラグインと言った拡張機能みたいな書き方は基本的に出来ない

Prologの特徴は

  • 動的
  • インタプリタ式
  • 論理プログラミング
  • 標準ライブラリ(ISO述語)は最低限の機能しかない
  • プラグインとかスクリプトとしての使い方は簡単に出来る

この正反対の言語2つを組み合わせたら最強になります。それぞれのメリデメをカバーが出来ます。

ichiban/prolog

ichiban/prologはYutaka IchibangaseさんによるGoで実装されたPrologのインタプリタです。Pure Goなので外部依存はなくて、非常に簡単に使えるPrologです。

メリット

  • ISO標準(Scryer Prolog, Trealla Prologなどと互換性が良い)
  • 外部依存がない
  • Goで述語が実装できて、簡単に「ネイティブ述語(関数)」を追加出来ます。
  • database/sqlっぽいAPIで簡単にクエリの結果が扱えます
  • キャッチコピーが面白い「The only reasonable scripting engine for Go.」(ナイスダジャレ)
  • コードが綺麗で読みやすい
  • Goのfsパッケージで好きなファイルシステムが使えます
  • MITライセンス

デメリット

  • まだv1.0に至ってなくて、APIが変わるかも
  • モジュールや変数属性は未対応
  • 最適化の余地はたくさんありそう(clause indexingとか)
  • 組み込まれている述語やライブラリが比較的に少ない

「GoとPrologを合わせてみたい!」とい人はまずichiban/prologを使ってみると良いと思います。もっと複雑なことをやりたい人や、更にスピードを求める場合は他を使うと良いかもしれません。

trealla-prolog/go

trealla-prolog/goはAndrew DavisonさんによるCで書かれたPrologをWASM経由で使うGoのライブラリです。Goのライブラリは私がメンテしています。

メリット

  • ISO標準
  • 速い(インデックスが効きます)
  • Goで述語を実装出来ます
  • ichiban/prologのAPIをパクったので似た使い方が出来ます
  • モジュールや変数属性が使えます
  • 便利なライブラリがたくさん組み込まれています
  • trealla-jsというJS版もあるのでフロンエンドで同じPrologのコードを共有できます
  • MITライセンス

デメリット

  • まだv1.0に至っていなくて(ry
  • WASMランタイムに依存しているため、外部依存があります
    • 現在Windowsで動かない様子
    • wasmerのshared libraryが必要でデプロイが若干面倒くさい
  • ファイルシステムが使いたい場合はOSの本物のFSを使うことになります
  • CLP(FD)やCLP(Z)といった制約プログラミングのライブラリはまだ使えない

ichiban/prologに限界を感じた場合に使うと良いと思います。例えば、複雑なモジュールをたくさん使いたい時とかですね。また、フロントエンド向けのライブラリもあるので、フロントエンドとバックエンドで同じPrologのコードを共有できます

guregu/pengine

guregu/pengineは私によるSWI-Prologと連携出来るPenginesのライブラリです。PenginesとはProlog Enginesの略で、SWI-PrologのRPCプロトコルです。このライブラリで簡単にSWIへ問い合わせが出来るが、SWIのサーバへ接続する必要があります。guregu/pengineの内部でichiban/prologを使っていて、ichiban/prologで使えるpengine_rpc/3の述語も提供しています[1]

メリット

  • SWIのライブラリとかモジュールをそのまま利用出来ます
  • CLP(FD)など、制約プログラミングのライブラリが使えます
  • 速いが、ネットワークのオーバーヘッドが入ります
  • ichiban/prologと連携が出来て、二刀流が可能です
  • BSDライセンス

デメリット

  • SWIのサーバに依存することになります
  • Penginesのドキュメントが少ない
  • RPCのオーバーヘッドがあります
  • Goで述語が書けない
  • SWIはISO標準じゃない(他のPrologと互換性はあまり良くない)

既にSWIを使っている人やどうしてもCLP(FD)を使いたい人におすすめします。Goで述語が書けないのでPrologで頑張ってください、という書き方になります。

結論

  1. まずichiban/prologを使ってみると良い
  2. ichiban/prologに限界を感じた場合や、フロントエンドとコードを共有したい場合はtrealla-prolog/goを使うと良い
  3. それでも物足りない場合やすでにSWI Prologを使っている場合はguregu/pengine

ちなみにmangleというDatalogっぽい(?)ライブラリは最近出たので、私がまだ触っていないGo×論理のライブラリもあります。

GoとProlog、最強の組み合わせを使ってみましょう!

脚注
  1. 若干古いのでichiban/prologの新しいAPIへアップデートする必要があります ↩︎

Discussion