One way:

(ns hierarchy.core
  (:refer-clojure :exclude [==])
  (:use [clojure.core.logic]))

(def order [:domain :kingdom :phylum :class :order :family :genus :species])

(def homo-sapiens
  {:domain :eukarya
   :kingdom :animalia-metazoa
   :phylum :chordata
   :class :mammalia
   :order :primate
   :family :hominidae
   :genus :homo
   :species :homo-sapiens})

(defrel rank ^:index rank ^:index name)
(defrel typeof* ^:index a ^:index b)

(defn add-to-db [data]
  (doseq [[a b] (map (fn [a b]
                       [(find data a)
                        (find data b)])
               order (rest order))]
    (apply fact rank a)
    (fact typeof* (second b) (second a))))

(defn typeof [a b]
  (conde
    [(typeof* a b)]
    [(fresh [x]
       (typeof* a x)
       (typeof x b))]))

(comment
  (add-to-db homo-sapiens)

  ; find all domains
  (run* [q]
    (rank :domain q))

  ; (true)
  (run* [q]
    (typeof :mammalia :eukarya)
    (typeof :homo-sapiens :hominidae)
    (typeof :homo-sapiens :primate)
    (typeof :homo-sapiens :eukarya)
    (== q true))
  )

On Mon, Jan 23, 2012 at 8:35 PM, Base <basselh...@gmail.com> wrote:

> Hi -
>
> I am attempting to model some hierarchical data for use in my first
> logic program and am having some problems understanding how to create
> a “typeof?” relationship with my data.
>
> Defining parent child is easy enough of course; however I would like
> to design a generic way of defining a subclass or superclass such
> that, given some set of hierarchical data, for example:
>
> Domain - Eukarya
>        Kingdom - Animalia/Metazoa
>                Phylum - Chordata
>                        Class - Mammalia
>                                Order - Primate
>                                        Family - Hominidae
>                                                Genus - Homo
>                                                        Species - Homo
> sapiens
>
> (typeof? “Mammalia” “Eukarya”)  and
> (typeof? “Primate” “Eukarya”) and
> (typeof? “Hominidae” Eukarya”)
>
> all are true using the same mechanism without having to explicitly
> define the order one by one like:
>
> (defrel typeof? p c)
> (fact typeof? “Homo”  “Homo sapiens”)
> (fact typeof? “Hominidae” “Homo sapiens”)
> (fact typeof? “Primate” “Homo sapiens”)
> (fact typeof? “Mammalia” “Homo sapiens”)
> ...
>
> Any help getting started on this would be most appreciated!
> Thanks!
>
> Base
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to