;; there is a transitive relationship between x & z if there is a
;; relationship between x & some y and some y & z
(defn transitive [r]
  (fn t
    ;; if passed only two args create the path logic var
    ([x z] (t x z (lvar)))
    ;; take an x, z, and a path from x to z
    ([x z path]
       (fresh [y]
         (conde
           ;; there is a direct relationship between x & z
           ;; update the path
           [(r x z) (== path (list [x z]))]
           ;; there is not a direct relationship between x & z
           ;; try some y that has a relationship with x, update the path
           [(fresh [a d]
              (r x y)
              (conso a d path)
              (== a [x y])
              ;; prove there is a relationship between y & z
              (t y z d))])))))

(defn iso
  ([entity parent]
     ((transitive is-a) entity parent))
  ([entity parent path]
     ((transitive is-a) entity parent path)))


On Tue, Dec 18, 2012 at 11:28 AM, Stathis Sideris <side...@gmail.com> wrote:

> Hello David,
>
> Yes, I wasn't expecting for this to be built-in. Your example is exactly
> what I was looking for, thanks a lot! I'll to need to spend some time to
> figure it out :-)
>
> Stathis
>
>
> On Tuesday, 18 December 2012 15:52:47 UTC, David Nolen wrote:
>
>> There is no general "explain" functionality. However the following simple
>> solution should give you some ideas:
>>
>> (defrel is-a Entity Parent)
>> (fact is-a :pitbull :dog)
>> (fact is-a :dog :mammal)
>> (fact is-a :mammal :chordate)
>> (fact is-a :chordate :animal)
>>
>> (defn transitive [r]
>>   (fn t
>>     ([x z] (t x z (lvar)))
>>     ([x z path]
>>        (fresh [y]
>>          (conde
>>            [(r x z) (== path '())]
>>            [(fresh [a d]
>>               (r x y)
>>               (conso a d path)
>>               (== a [x y])
>>               (t y z d))])))))
>>
>> (defn iso
>>   ([entity parent]
>>      ((transitive is-a) entity parent))
>>   ([entity parent path]
>>      ((transitive is-a) entity parent path)))
>>
>> (comment
>>   (run* [q]
>>     (iso :dog :animal q))
>>   )
>>
>>
>> On Tue, Dec 18, 2012 at 9:06 AM, Stathis Sideris <sid...@gmail.com>wrote:
>>
>>> Hello,
>>>
>>> With the code below you can query transitive relationships between
>>> entities successfully. Is there any way to use core.logic "explain" the
>>> relationship? Specifically, is there any way to write a function explain so
>>> that:
>>>
>>> > (explain :pitbull :chordate)
>>>
>>> will give you:
>>>
>>> [:pitbull :dog]
>>> [:dog :mammal]
>>> [:mammal :chordate]
>>>
>>> Thanks,
>>>
>>> Stathis
>>>
>>>
>>> Code:
>>>
>>> (ns test.logic
>>>   (:refer-clojure :exclude [==])
>>>   (:use clojure.core.logic))
>>>
>>> (defrel is-a Entity Parent)
>>> (fact is-a :pitbull :dog)
>>> (fact is-a :dog :mammal)
>>> (fact is-a :mammal :chordate)
>>> (fact is-a :chordate :animal)
>>>
>>> (defn transitive [r]
>>>   (fn t [p1 p2]
>>>     (fresh [intermediate]
>>>            (conde
>>>               ((r p1 p2))
>>>               ((r p1 intermediate)
>>>                (t intermediate p2))))))
>>>
>>> (defn iso [entity parent]
>>>   ((transitive is-a) entity parent))
>>>
>>> In the REPL:
>>> > (run* [q] (iso :dog :animal))
>>> (_.0)
>>>
>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@**googlegroups.com
>>>
>>> For more options, visit this group at
>>> http://groups.google.com/**group/clojure?hl=en<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
>

-- 
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