 (def iyye_human (ref 0))
 (def iyye_yumzya (ref 0))
 
-; Builtin relations
+; Builtin verbs and relations
 (def iyye_is_type (ref 0))
+(def iyye_is?_type (ref 0))
+(def iyye_is_type_rel (ref 0))
 (def iyye_consists_type (ref 0))
 (def iyye_create_instance (ref 0))
 
 (defn iyye_is_type_predicate_function [params]
-  (when (= 2 (count params))
+  (if (= 2 (count params))
     (let [[p1-type p2-type] params
-          p2-name (:Name (:atom p2-type))
-          rels1 (:Relations p1-type)]
-      (some true?
-            (for [rel rels1]
-              (= (:super (:Data rel)) p2-name)))))) ; FIXME Yumzia modal logic, FIXME 0 recursive
-
-(defn- iyye_add_relation [p1-type p2-type relation]
-  (let [is_type #(words/action-words relation)]
-    (let [p1-supertype (assoc (is_type) :Data {:super (:Name (:atom p2-type))})
-          p2-subtype (assoc (is_type) :Data {:sub (:Name (:atom p1-type))})
+          p2-name (:Name (:name (first p2-type)))
+          rels1 (:Relations (first p1-type))
+          rels2 (for [rel rels1]
+                  [rel (and p2-name (= (:super (:Data rel)) p2-name))])
+          rels3 (filter #(second %) rels2)]
+      (if (> (count rels3) 0)
+        (:Predicate (first (first rels3)))
+        (words/->Iyye_ModalPredicate :IYE :AXIOM "now" :NEVER)
+        ))
+    (words/->Iyye_Error (pr-str "No relation, unrelated: " params) pr-str)
+    )
+  ) ; FIXME Yumzia modal logic, FIXME 0 recursive
+
+(defn iyye_is_predicate_function [params]
+    (let [[relations & rest] params
+          rel (first (filter #(= "relation" (:Type (:name %))) relations))]
+      (if rel
+        ((:PredicateFunction rel) rest)
+        (words/->Iyye_Error (pr-str "No relation: " relations) pr-str))))
+
+(defn iyye_add_relation [p1-type p2-type relation]
+  (let [is_type relation]
+    (let [p1-supertype (assoc is_type :Data {:super (:Name (:name p2-type))})
+          p2-subtype (assoc is_type :Data {:sub (:Name (:name p1-type))})
           new-p1-type (assoc p1-type :Relations
                                      (conj (:Relations p1-type) p1-supertype))
           new-p2-type (assoc p2-type :Relations

(defn- init-db-kb []
  (let [types-loaded (persistence/read-knowledge-from-db "types" {})
        types (map words/create-iyye-type-from-db types-loaded)
        a-f (fn [col el] (conj col (create-entry el)))]
    (dosync (alter words/action-words #(apply conj %1 %2) (persistence/read-knowledge-from-db "relations" {}))) ; {:When :ALWAYS}
    (dosync (alter words/noun-words #(apply a-f %1  %2) types)) ; {:When :ALWAYS}
    ; others
    ))


        iyye (words/create-iyye-type "iyye" true)
        human (words/create-iyye-type "human" true)
        yumzya (words/create-iyye-type "yumzya" true)
        create-entry (fn [entry] {(:Uname (:name entry)) entry})
        uname #(:Uname (:name %))]
     (dosync (ref-set iyye_actor (uname actor)))
     (dosync (ref-set iyye_ai (uname ai)))
     (dosync (ref-set iyye_iyye (uname iyye)))
    (dosync (ref-set iyye_human (uname human)))
    (dosync (ref-set iyye_yumzya (uname yumzya)))
    (dosync (alter words/builtin-words conj (create-entry type) (create-entry actor)
                   (create-entry ai) (create-entry iyye) (create-entry human)
                   (create-entry yumzya)))))

(defn- init-builtin-relations []
  (let [t_is (create-iyye-builtin-relation "type" ["type" "*"] iyye_is_type_function_relation iyye_is_type_predicate_function)
        ;t_is2 (create-iyye-builtin-relation "is" [:UNKNOWN "type"] iyye_is_type_create_function iyye_is_type_predicate_function)
        ;  consistsof (create-iyye-builtin-relation "has" [] iyye_consists_function iyye_is_type_predicate_function)
        ;instof (create-iyye-builtin-relation "instance" ["type"] iyye_instance_function iyye_is_type_predicate_function)
        uname #(:Uname (:name %))
        create-entry (fn [entry] {(:Uname (:name entry)) entry})]
    (dosync (ref-set iyye_is_type_rel (uname t_is)))
    ; (dosync (ref-set iyye_consists_type (uname consistsof)))
    ;  (dosync (ref-set iyye_create_instance (uname instof)))
    (dosync (alter words/builtin-words conj (create-entry t_is)))))

(defn- init-builtin-verbs []
  (let [t_is (create-iyye-builtin-verb "is" ["relation" "type" "*"] "relation" iyye_is_type_function)
        t_is? (create-iyye-builtin-query "is?" ["relation" "type" "*"] iyye_is_predicate_function)
        ;t_is2 (create-iyye-builtin-relation "is" [:UNKNOWN "type"] iyye_is_type_create_function iyye_is_type_predicate_function)
        consistsof (create-iyye-builtin-verb "has" ["type" "*"] "relation" iyye_consists_function)
        ;instof (create-iyye-builtin-relation "instance" ["type"] iyye_instance_function iyye_is_type_predicate_function)
        uname #(:Uname (:name (:name %)))
        create-entry (fn [entry] {(:Uname (:name (:name entry))) entry})]
    (dosync (ref-set iyye_is_type (uname t_is)))
    (dosync (ref-set iyye_is?_type (uname t_is?)))
    (dosync (ref-set iyye_consists_type (uname consistsof)))
    ;   (dosync (ref-set iyye_create_instance (uname instof)))
    (dosync (alter words/builtin-words conj (create-entry t_is) (create-entry t_is?) (create-entry consistsof)))))

(defn apply-builtin-relations []
  (let [get-type #(words/builtin-words %)
        get-function #(:Function (words/builtin-words %))
        f (get-function @iyye_is_type)]
        (when f
          (do
            (f [(get-type @iyye_is_type_rel) (get-type @iyye_ai) (get-type @iyye_actor)])
            (f [(get-type @iyye_is_type_rel) (get-type @iyye_human) (get-type @iyye_actor)])
            (f [(get-type @iyye_is_type_rel) (get-type @iyye_iyye) (get-type @iyye_ai)])
            (f [(get-type @iyye_is_type_rel) (get-type @iyye_yumzya) (get-type @iyye_human)])))))

(defn- init-builtins-kb []
  (init-builtin-words)
  (init-builtin-verbs)
  (init-builtin-relations)
  (apply-builtin-relations)
  )

;(dorun (map #(do ( persistence/write-fact-to-db (into {} %))) @action-words))
; (apply str (rest (str (:When {:When :ALWAYS}))))
