 
 (defn save-iyye-type-to-db [type]
   (let [types-list-str (fn [types]
-          (reduce #(str %1 "_" %2) types))
+                         (reduce #(str %1 "_" %2) types))
         rel-key (fn [name ind]
-          (keyword (str name ind)))
+                  (keyword (str name ind)))
         get-rel
         (fn [ind rel]
-          {(rel-key "Relation-name" ind) (:Name (:atom rel))
-             (rel-key "Relation-uname" ind) (:Uname (:atom rel))
-            (rel-key "Relation-AccordingTo" ind) (:AccordingTo (:Predicate rel))
-            (rel-key "Relation-When" ind) (:When (:Predicate rel))
-            (rel-key "Relation-Time" ind) (:Time (:Predicate rel))
-             (rel-key "Relation-Prob" ind) (:Prob (:Predicate rel))
-             (rel-key "Relation-Types-List" ind) (types-list-str (:Types rel))
-           (rel-key "Relation-Data-List1" ind) (types-list-str (map name (keys (:Data rel))))
-               (rel-key "Relation-Data-List2" ind) (types-list-str (vals (:Data rel)))
+          {(rel-key "Relation-name" ind)        (:Name (:name rel))
+           (rel-key "Relation-uname" ind)       (:Uname (:name rel))
+           (rel-key "Relation-AccordingTo" ind) (:AccordingTo (:Predicate rel))
+           (rel-key "Relation-When" ind)        (:When (:Predicate rel))
+           (rel-key "Relation-Time" ind)        (:Time (:Predicate rel))
+           (rel-key "Relation-Prob" ind)        (:Prob (:Predicate rel))
+           (rel-key "Relation-Types-List" ind)  (types-list-str (:Types rel))
+           (rel-key "Relation-Data-List1" ind)  (types-list-str (map name (keys (:Data rel))))
+           (rel-key "Relation-Data-List2" ind)  (types-list-str (vals (:Data rel)))
            })]
-    (let [write-type (reduce conj {:Uname (:Uname (:atom type))
-                                   :Name  (:Name (:atom type))}
+    (let [write-type (reduce conj {:Uname (:Uname (:name type))
+                                   :Name  (:Name (:name type))}
                              (map-indexed get-rel (:Relations type)))
           ]
       ; (when @dbg-IO (print-io-str @dbg-IO (pr-str "add list: " type ":::"

  )
;(persistence/write-noun-to-db (into {} type))


(defn get-iyye-atoms [name builtins]
  "returns a list of found atoms with supplied name"
  (let [builtin-types
        (for [word (vals @builtins) :when (= (:Name (:atom word)) name)] word)]
    (if (empty? builtin-types) (list {:UNKNOWN name}) builtin-types)))

(defn get-iyye-types [name]
  (get-iyye-atoms name noun-words))

(defn get-iyye-relations [name]
  (get-iyye-atoms name action-words))

(defn set-iyye-type! [type]
  (let [uname (:Uname (:atom type))
        builtin (:Builtin (:atom type))]
      (do
        (dosync (alter noun-words #(assoc % uname type)))
        (if-not builtin
          (save-iyye-type-to-db type)
          (save-iyye-builtin-type-to-db type)))))

(defn check-params [action params]
  (let [act-params (:Types action)]
    (when (= (count params) (count act-params))
      (let [params-types (map #(get-supertypes %) params)
        ;   vec-params (vec (map #(:Name (:atom %)) params))
            pairs (map vector act-params params-types)
            ok (every? true? (for [cur pairs]
                               (if (= :UNKNOWN (first cur))
                                 (if (:UNKNOWN (second cur)) true false)
                                 (some true?
                                       (map #(= (first cur) %) (map :Name (second cur)))))))]
    ok))))  ; FIXME Yumzya context aware compare

(defn apply-relation [relation params]
  (when (check-params relation params)
    ((:Function relation) params)))

(defn apply-query [relation params]
  (when (check-params relation params)
    ((:PredicateFunction relation) params)))

(defn- run-action [cmd params IO func]
  (let [actions-list (get-iyye-relations cmd)
        params-list (apply concat (map get-iyye-types params))]
    (case (count actions-list)
      0 (print-io-str IO (str "failed to parse: no matching action to " cmd))
      1 (let [action (first actions-list)
              result (func action params-list)]
          (if result
            (print-io-str IO result)))
      (let [matching-actions
            (for [action actions-list :when (check-params action params-list)] action)]
        (if (empty? matching-actions)
          (print-io-str IO (pr-str "Cant find " cmd " " params))
          (let [result (func (first matching-actions) params-list)]
            (if result
              (print-io-str IO result)
              (print-io-str IO "False"))))))))


(defn action [cmd params IO]
  (when (not @dbg-IO) (dosync (ref-set dbg-IO IO)))
  (if (= \? (last cmd))
    (run-action (subs cmd 0 (dec (count cmd))) params IO apply-query)
    (run-action cmd params IO apply-relation)))

            rel-vec
            (let [rel-uname (t (mykey "Relation-uname" num))]
              (recur (conj rel-vec
                           (->Iyye_Relation
                             (->Iyye_Name (t (mykey "Relation-name" num))
                                          rel-uname
                                          "relation"
                                          nil {})
                             []
                             (->Iyye_ModalPredicate
                               (t (mykey "Relation-AccordingTo" num))
                               (t (mykey "Relation-When" num))
                               (t (mykey "Relation-Time" num))
                               (t (mykey "Relation-Prob" num)))
                             nil
                             ;  (create-types num)
                             ; (:Function (@verb-words (t (mykey "Relation-uname" num))))
                             (:PredicateFunction (@builtin-words (t (mykey "Relation-uname" num))))
                             (create-data num)))
                     (inc num)))))]
    (->Iyye_Type (->Iyye_Name (:Name t) (:Uname t) "type" nil {}) relations-list str)))

(defn create-iyye-verb [Name Types Result Function & builtin]
  (let [action-atom (create-iyye-type Name "verb" builtin)
        relation (->Iyye_Verb action-atom Types Result Function [])]
    relation))

(defn create-iyye-relation [Name Predicate Types Function PredicateFunction & builtin]
  (let [action-atom (create-iyye-name Name "relation" builtin)
        relation (->Iyye_Relation action-atom Types Predicate Function PredicateFunction [])]
    relation))

(def time-start (persistence/local-time-to-string))

(defn get-supertypes [atype]
  "gets types: self, type, immediate parents"               ; FIXME Yumzia:0 get all parents
  (if-not (:UNKNOWN atype)
    (if-not (and (= "type" (:Name (:name atype))) (not= "relation" (:Type (:name atype))))
      (let [rels (:Relations atype)]
       (conj (for [supertype rels :when (:super (:Data supertype))]
                {:Name (:super (:Data supertype)) :Predicate (:Predicate supertype)})
             {:Name (:Type (:name atype)) :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}
             {:Name (:Name (:name atype)) :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}))
      (list {:Name "type" :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}))
    {:UNKNOWN (:UNKNOWN atype)}))

(defn create-iyye-instance [values])
