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 <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en