Hi all,

I've just implemented insertion sort with core.logic:

--8<---------------cut here---------------start------------->8---
(declare inserto)
(defn isorto
  "A relation where sl is a sorted version of the list l."
  ([l sl]
   (isorto l () sl))
  ([l acc sl]
   (conde
    [(== l ()) (== acc sl)]
    [(fresh [f r nacc]
       (conso f r l)
       (inserto f acc nacc)
       (isorto r nacc sl))])))

(defn cconso
  "A relation where consing s and then f to r gives l."
  [f s r l]
  (fresh [l1]
    (conso s r l1)
    (conso f l1 l)))

(defn inserto
  "A relation where inserting x into l gives the sorted list nl."
  [x l nl]
  (conde
   [(== l ()) (== nl (list x))]
   [(fresh [f r nf nr]
      (conso f r l)
      (conso nf nr nl)
      (conde
       [(fd/> x f) (== f nf) (inserto x r nr)] ;; fd is an alias for 
clojure.core.logic.fd
       [(fd/<= x f) (cconso x f r nl)]))]))
--8<---------------cut here---------------end--------------->8---

That works fine in forwards direction

--8<---------------cut here---------------start------------->8---
(run* [q]
  (isorto (list 5 3 4 1 2) q))
;=> ((1 2 3 4 5))
--8<---------------cut here---------------end--------------->8---

and as a check

--8<---------------cut here---------------start------------->8---
(run* [q]
  (isorto (list 3 2 1 4 5) (list 1 2 3 4 5)))
(_0)
--8<---------------cut here---------------end--------------->8---

but won't terminate in backwards direction

--8<---------------cut here---------------start------------->8---
(run* [q]
  (isorto q (list 1 2 3)))
;; wait until hell freezes
--8<---------------cut here---------------end--------------->8---

where it ideally would unify q with all six possible permutations of the
sorted list (1 2 3).  It doesn't even terminate when I provide the empty
list or a one-element list as the sorted list sl.

Well, actually I don't need all permutations.  One would suffice which
could even be the sorted variant, i.e., in "backwards mode" I'd be happy
if it just unified l with sl.

I've tried partially replacing condes with condas or condus in various
combinations of the three occurrences but I only get to two different
outcomes.  Either it doesn't terminate just as the all-conde version, or
it terminates without any answer.

I think at least inserto should be pretty correct and reversible, at
least I can ask it for all element/list pairs which would complete to a
given sorted list when inserting at the right position.

--8<---------------cut here---------------start------------->8---
(run* [q a]
  (inserto q a (list 1 2 3 4 5)))
;=> ([1 (2 3 4 5)] [2 (1 3 4 5)] [3 (1 2 4 5)] [5 (1 2 3 4)] [4 (1 2 3 5)])
--8<---------------cut here---------------end--------------->8---

(Interesting that the 5 comes before the 4.  Does that give any clue?)

Do I have some error in the code which I don't see anymore after staring
at the code for more than an hour?  Or do I need to use some trick to
get it somehow reversible?

Bye,
Tassilo

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to