(ns nal.deriver.normalization
(:require [clojure.string :as s]
[clojure.set :as set]
[clojure.core.match :as m])) | |
operators that should be movet from infix to prefix position | (def operators
#{'&| '--> '<-> '==> 'retro-impl 'pred-impl 'seq-conj 'inst 'prop 'inst-prop
'int-image 'ext-image '=/> '=|> '| '<=> '</> '<|> '- 'int-dif '|| '&&
'ext-inter 'conj}) |
commutative: <-> <=> <|> & | && || not commutative: --> ==> =/> => > &/ - ~ | |
(def commutative-ops #{'<-> '<=> '<|> '| '|| 'conj 'ext-inter}) | |
Makes transformaitions like [A --> B] to [--> A B]. | (defn infix->prefix
[premise]
(if (coll? premise)
(let [[f s & tail] premise]
(map infix->prefix
(if (operators s)
(concat [s f] tail)
premise)))
premise)) |
Checks if symbol starts with --, true for --A, --X | (defn- neg-symbol? [el] (and (not= el '-->) (symbol? el) (s/starts-with? (str el) "--"))) |
Removes -- from symbols with negation: (trim-negation '--A) => A | (defn- trim-negation [el] (symbol (s/join (drop 2 (str el))))) |
(defn neg [el] (list '-- el)) | |
Replaces negations's "new notation". | (defn replace-negation
[statement]
(cond
(neg-symbol? statement) (neg (trim-negation statement))
(or (vector? statement) (and (seq? statement) (not= '-- (first statement))))
(:st
(reduce
(fn [{:keys [prev st] :as ac} el]
(if (= '-- el)
(assoc ac :prev true)
(->> [(cond prev (neg el)
(coll? el) (replace-negation el)
(neg-symbol? el) (neg (trim-negation el))
:else el)]
(concat st)
(assoc ac :prev false :st))))
{:prev false :st '()}
statement))
:else statement)) |
(defn sort-commutative [conclusions]
(if (coll? conclusions)
(let [f (first conclusions)]
(if (commutative-ops f)
(vec (conj (sort-by hash (drop 1 conclusions)) f))
conclusions))
conclusions)) | |
https://gist.github.com/TonyLo1/a3f8e05458c5e90c2e72 | (defn union ([c1 c2] (sort-by hash (set (concat c1 c2)))) ([op c1 c2] (vec (conj (union c1 c2) op)))) |
(defn diff ([c1 c2] (into '() (set/difference (set c1) (set c2)))) ([op c1 c2] (vec (conj (diff c1 c2) op)))) | |
(defn reduce-ext-inter
[st]
(m/match
st
[_ t] t
[_ ['ext-inter & l1] ['ext-inter & l2]] (union 'ext-inter l1 l2)
[_ ['ext-inter & l1] l2] (union 'ext-inter l1 [l2])
[_ l1 ['ext-inter & l2]] (union 'ext-inter [l1] l2)
[_ ['int-set & l1] ['int-set & l2]] (union 'int-set l1 l2)
;[_ ['ext-set & l1] ['ext-set & l2]] (union 'ext-set l1 l2)
:else st)) | |
(defn reduce-int-inter
[st]
(m/match st
['| t] t
['| ['| & l1] ['| & l2]] (union '| l1 l2)
['| ['| & l1] l2] (union '| l1 [l2])
['| l1 ['| & l2]] (union '| [l1] l2)
['| ['int-set & l1] ['int-set & l2]] (union 'int-set l1 l2)
['| ['ext-set & l1] ['ext-set & l2]] (union 'ext-set l1 l2)
:else st)) | |
(defn reduce-int-dif
[st]
(m/match st
[_ ['int-set & l1] ['int-set & l2]] (diff 'int-set l1 l2)
:else st)) | |
(defn reduce-ext-dif
[st]
(m/match st
[_ ['ext-set & l1] ['ext-set & l2]] (diff 'ext-set l1 l2)
:else st)) | |
(defn reduce-symilarity
[st]
(m/match st
['<-> ['ext-set s] ['ext-set p]] ['<-> s p]
['<-> ['int-set s] ['int-set p]] ['<-> s p]
:else st)) | |
(defn reduce-production
[st]
(m/match st
['* ['* & l1] & l2] (vec (conj (concat l1 l2) '*))
:else st)) | |
(defn reduce-image
[st]
(m/match st
[_ ['* t1 t2] t3] (if (and (= t2 t3) (not= t1 t2)) t1 st)
:else st)) | |
(defn reduce-neg
[st]
(m/match st
['-- ['-- t]] t
:else st)) | |
(defn reduce-or
[st]
(m/match st
['|| t] t
['|| ['|| & l1] ['|| & l2]] (union '|| l1 l2)
['|| ['|| & l1] l2] (union '|| l1 [l2])
['|| l1 ['|| & l2]] (union '|| [l1] l2)
['|| t1 t2] (if (= t1 t2) t1 st)
:else st)) | |
(defn reduce-and
[st]
(m/match st
['conj t] t
['conj ['conj & l1] ['conj & l2]] (union 'conj l1 l2)
['conj ['conj & l1] l2] (union 'conj l1 [l2])
['conj l1 ['conj & l2]] (union 'conj [l1] l2)
['conj t1 t2] (if (= t1 t2) t1 st)
:else st)) | |
(defn reduce-seq-conj
[st]
(let [cnt (count st)]
(cond
(= 3 cnt) (second st)
(odd? cnt) (vec (butlast st))
:else st))) | |
(def reducible-ops
{'ext-inter `reduce-ext-inter
'| `reduce-int-inter
'- `reduce-ext-dif
'int-dif `reduce-int-dif
'<-> `reduce-symilarity
'* `reduce-production
'int-image `reduce-image
'ext-image `reduce-image
'-- `reduce-neg
'conj `reduce-and
'|| `reduce-or}) | |
(defn reduce-ops
[st]
(let [f (first st)]
(case f
ext-inter (reduce-ext-inter st)
| (reduce-int-inter st)
- (reduce-ext-dif st)
int-dif (reduce-int-dif st)
<-> (reduce-symilarity st)
* (reduce-production st)
int-image (reduce-image st)
ext-image (reduce-image st)
-- (reduce-neg st)
conj (reduce-and st)
|| (reduce-or st)
st))) | |