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.