Neat! I see that you figured out defne, you could probably simplify doactiono with matche as well.
The Clojure REPL doesn't print exceptions by default, but I'm sure if you print it out with (clojure.repl/pst *e) you'd see that it does let you know that you called firsto with the wrong number of arguments. David On Thu, Mar 22, 2012 at 9:32 AM, Cesare <cesare.zavatt...@gmail.com> wrote: > Hi all, > I'm experimenting with clojure.core: very nice! This is a simple > planner for the Farmer Crosses River puzzle: > > > (def characters [:farmer :goat :wolf :cabbage]) > > ;;; they all start on the left side of the river > (def _starting-state {:farmer :l, :goat :l :wolf :l :cabbage :l}) > > ;;; they all must cross the river > (def _final-state {:farmer :r, :goat :r :wolf :r :cabbage :r}) > > (defn validstateo > "constraints for state s" > [s] > (fresh [farm goat wolf cabb] > (== s {:farmer farm, :goat goat, :wolf wolf, :cabbage cabb}) > (conde > [(== farm goat)] ; farmer is with goat > or... > [(!= wolf goat) (!= cabb goat)]))) ; goat/wolf (or goat/ > cabbage) not alone > > (defn initialstateo [s] > (== s _starting-state)) > > (defn finalstateo [s] > (== s _final-state)) > > (defn doactiono [s a ns] ; state action nextstate > "action a change state s to state ns" > (fresh [farm goat wolf cabb] > (== s {:farmer farm, :goat goat, :wolf wolf, :cabbage cabb}) > (validstateo ns) ; target state must be valid > (conde > ;; farmer travels with goat > [(== a :bringgoat) > (== farm goat) ; they must be on the same side > (conde > ;; flip side for them > [(== farm :l) (== ns {:farmer :r, :goat :r, :wolf > wolf, :cabbage cabb})] > [(== farm :r) (== ns {:farmer :l, :goat :l, :wolf > wolf, :cabbage cabb})])] > ;; farmer travels with wolf > [(== a :bringwolf) > (== farm wolf) > (conde > [(== farm :l) (== ns {:farmer :r, :goat > goat, :wolf :r, :cabbage cabb})] > [(== farm :r) (== ns {:farmer :l, :goat > goat, :wolf :l, :cabbage cabb})])] > ;; farmer travels with cabbage > [(== a :bringcabb) > (== farm cabb) > (conde > [(== farm :l) (== ns {:farmer :r, :goat goat, :wolf > wolf, :cabbage :r})] > [(== farm :r) (== ns {:farmer :l, :goat goat, :wolf > wolf, :cabbage :l})])] > ;; farmer travels alone > [(== a :travalone) > (conde > [(== farm :l) (== ns {:farmer :r, :goat goat, :wolf > wolf, :cabbage cabb})] > [(== farm :r) (== ns {:farmer :l, :goat goat, :wolf > wolf, :cabbage cabb})])] > ))) > > > (defne plano > "a plan is a sequence of (action, state) towards the final state" > [plan] > ([[[?a ?s]]] (finalstateo ?s)) ; last state must be final > ([[[?a ?s] . ?r]] > (fresh [a2 s2 r2] > (conso [a2 s2] r2 ?r) > (doactiono ?s a2 s2) > (plano ?r)))) > > (defn print-solution [sol] > (let [formatstring (clojure.string/join > "" > (repeat (inc (count characters)) "%10s"))] > (print (format "%10s" "__ACTION__")) > (doseq [c characters] (print (format "%10s" c))) > (println) > (doseq [[a s] sol] > (let [row (cons a (map (fn [f] (f s)) > characters))] > (println (apply (partial format formatstring) row)))))) > > This can be executed with: > > (doseq [sol (set (run 1 [q] > (fresh [a s] > (firsto q [a s]) > (initialstateo s) > (plano q))))] > (print-solution sol)) > > This is the output: > > __ACTION__ :farmer :goat :wolf :cabbage > _.0 :l :l :l :l > :bringgoat :r :r :l :l > :travalone :l :r :l :l > :bringwolf :r :r :r :l > :bringgoat :l :l :r :l > :bringcabb :r :l :r :r > :travalone :l :l :r :r > :bringgoat :r :r :r :r > > > Due to lvar handling, I have problems in writing a more concise > version of doactiono: any idea? > > Moreover, core.logic should be more informative, e.g. if I try to > execute: > > user> (run* [q] (== q (firsto [1 2]))) ; wrong use of firsto and > wrong number of args passed to it > > the only message printed is: > > ; Evaluation aborted. > > In any case, thanks to core.logic authors! > > Ciao > > -- > 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