Clara Rule based expert system (data exchange with external parties)

Continuing from the previous article, let’s talk about clara-rulues, an expert system in Clojure. In Clara, the defquery and query functions are used to output the results of reasoning to the outside world. A sample is shown below

ns test01.rules
  (:require [clara.rules :refer :all]))

(defrecord Stage [status txt])

(defrule rule1
  [Stage (= status "start" )]
  =>
  (insert! (->Stage  " step1" "this is start"))
  (println "this is start"))

(defrule rule2
  [Stage (= status "step1")]
  =>
  (insert! (->Stage  "next step" "this is next"))
  (println "this is next"))

(defrule rule3
  [Stage (= status "next step")]
  =>
  (insert! (->Stage  "last step" "this is last"))
  (println "this is last"))


(defquery get-ans []
  [?a <- Stage]) (defn show-ans [session] (query session get-ans)) (defn ask-ans [q] (println "pre:" q) (-> (mk-session 'test01.rules)
      (insert (->Stage q nil))
      (fire-rules)
      (show-ans)))

(defn get-ans-from-rules [res]
  (-> (:params res)
      (ask-ans)
      (first)
      (:?a)
      :txt
      )) 

Set Stage as the state record, and specify three rules to be applied to them, rule1, rule2, and rule3, using the defrule function. Set up a function to get the results of these rules with the defquery function, and set up an external output function get-ans-from-rule. The following is a sample code that uses these functions to output to the web api.

(ns test01.server
  (:require [test01.rules :as rule]
            [ring.util.response :as r]
            [ring.adapter.jetty :as server]
            [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [ring.middleware.json :refer [wrap-json-response wrap-json-body]]
            [ring.middleware.cors :refer [wrap-cors]]
            [ring.middleware.x-headers :refer [wrap-frame-options]]))
(defonce server (atom nil))

(defn ans-response [req]
  (r/response (response-data (rule/get-ans-from-rules req ))))

;;route
(defroutes app-routes
  (GET "/ans-response" [] ans-response)
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      wrap-json-body
      wrap-json-response
      (wrap-defaults site-defaults)
      (wrap-cors :access-control-allow-origin [#".*"] :access-control-allow-methods [:get])))

;;servef
(defn start-server []
  (when-not @server
    (reset! server (server/run-jetty app {:port 3000 :join? false}))))

(defn stop-server []
  (when @server
    (.stop @server)
    (reset! server nil)))

(defn restart-server []
  (when @server
    (stop-server)
    (start-server)))

(defn -main []
  (start-server))

(start-server)
(stop-server)
(restart-server) 

 

コメント

Exit mobile version
タイトルとURLをコピーしました