(ns zebra.core (:refer-clojure :exclude [==]) (:use [clojure.core.logic] [clojure.tools.macro :as macro])) (defne lefto [x y l] ([_ _ [x y . ?r]]) ([_ _ [_ . ?r]] (lefto x y ?r))) (defn nexto [x y l] (conde ((lefto x y l)) ((lefto y x l)))) (defn zebrao [hs] (macro/symbol-macrolet [_ (lvar)] (all (== [_ _ _ _ _] hs) (membero ['englishman _ _ _ 'red] hs) (membero ['swede _ _ 'dog _] hs) (membero ['dane _ 'tea _ _] hs) (lefto [_ _ _ _ 'green] [_ _ _ _ 'white] hs) (membero [_ _ 'coffee _ 'green] hs) (membero [_ 'pallmall _ 'birds _] hs) (membero [_ 'dunhill _ _ 'yellow] hs) (== [_ _ [_ _ 'milk _ _] _ _ ] hs) (firsto hs ['norwegian _ _ _ _]) (nexto [_ 'blend _ _ _] [_ _ _ 'cats _ ] hs) (nexto [_ _ _ 'horse _] [_ 'dunhill _ _ _] hs) (membero [_ 'bluemaster 'beer _ _] hs) (membero ['german 'prince _ _ _] hs) (nexto ['norwegian _ _ _ _] [_ _ _ _ 'blue] hs) (nexto [_ _ 'water _ _] [_ 'blend _ _ _] hs) (membero [_ _ _ 'zebra _] hs)))) (let [solns (run* [q] (zebrao q)) soln (first solns) zebra-owner (->> soln (filter #(= 'zebra (% 3))) first (#(% 0)))] (println "solution count:" (count solns)) (println "zebra owner is the" zebra-owner) (println "full solution (in house order):") (doseq [h soln] (println " " h)))