(ns nal.deriver.backward-rules
(:require [nal.deriver.key-path :refer [rule-path]]
[clojure.string :as s])) | |
Return true if rule allows backward inference. http://pastebin.com/3zLX7rPx | (defn allow-backward?
[{:keys [conclusions]}]
(some #{:allow-backward} (:post (first conclusions)))) |
(defn has-prefix? [prefix cond]
(when (keyword? cond)
(s/starts-with? (str cond) prefix))) | |
(defn not-equal? [cond]
(when (coll? cond)
(= :!= (first cond)))) | |
(defn check-not-equal [pre conclusion]
(if (some not-equal? pre)
(let [pre (remove not-equal? pre)]
(if (and (coll? conclusion) (= 3 (count conclusion)))
(let [[_ t1 t2] conclusion]
(conj pre (list :!= t1 t2)))
pre))
pre)) | |
If rule allows backward inference it will be expanded to three rules, where first one is the rule itself, and rest rules will be generated by swapping conclusion with every premise. | (defn expand-backward-rules
[{:keys [p1 p2 conclusions pre] :as rule}]
(mapcat (fn [{:keys [conclusion post] :as fc}]
(let [post (reduce #(remove (partial has-prefix? %2) %1)
post [":t/" ":d/"])]
(conj (map
(fn [r] (update r :pre conj :question?))
[(assoc rule :conclusions [(assoc fc :post post)])
(assoc rule :p1 conclusion
:conclusions [{:conclusion p1
:post post}]
:full-path (rule-path conclusion p2)
:pre (check-not-equal pre p1))
(assoc rule :p2 conclusion
:conclusions [{:conclusion p2
:post post}]
:full-path (rule-path p1 conclusion)
:pre (check-not-equal pre p2))])
rule)))
conclusions)) |