ハッキングバカ

プログラミングに関するメモ

Clojure で論理プログラミング

環境 macOS 10.13.6
ClojureProlog 的な論理プログラミングをする場合は、GitHub - clojure/core.logic を使う。
とりあえず

$ lein new logic

project ファイルに書き加える。

; project.clj

(defproject logic "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/core.logic "0.8.11"]]
  :main logic.core)

依存関係を更新

$ lein deps

wikiっぽく例の一家でやってみる

; src/logic/core.clj

(ns logic.core
  (:require [clojure.core.logic.pldb :as pldb]
            [clojure.core.logic :as l]))

; 関係を定義
(pldb/db-rel parent p c)

; 事実を挙列
(def facts
  (pldb/db
    [parent 'namihei 'sazae]
    [parent 'fune 'sazae]
    [parent 'namihei 'katsuo]
    [parent 'fune 'katsuo]
    [parent 'namihei 'wakame]
    [parent 'fune 'wakame]
    [parent 'sazae 'tara]
    [parent 'masuo 'tara]))

(defn -main []
  (pldb/with-db facts
    (println "波平の子供:")
    (println (l/run* [q]
                     (parent 'namihei q)))
    (println "タラの親")
    (println (l/run* [q]
                     (parent q 'tara)))
    (println "フネの孫")
    (println (l/run* [q]
              (l/fresh [x]
                       (parent 'fune x)
                       (parent x q))))))

動かしてみる

$ lein run
波平の子供:
(sazae katsuo wakame)
タラの親
(masuo sazae)
フネの孫
(tara)

面白い。
もっといじってみよう。

参考:
core.logic/tests.clj at master · clojure/core.logic · GitHub
clojure - From defrel and facts to core.logic.pldb - Stack Overflow