I've used clojure for a while but just starting out with core.logic.
Given a domain like 1 2 3 4
I want to get a vector of two vectors back like ([[1 2] [3 4]])
.
Note: This is just a simplified version of what I'm really trying to do. :) See: https://github.com/adamhoward/lineup
I found this definition for not-membero on the web:
(defne not-membero [x l]
([_ []])
([_ [?y . ?r]]
(!= x ?y)
(not-membero x ?r)))
And I'm trying to use it like this:
(run 1 [q]
(fresh [w x
y z]
(== q [[w x]
[y z]])
(infd w x y z (domain 1 2 3 4))
(everyg distinctfd [[w x] [y z]])
(everyg #(not-membero % [y z]) [w x])))
Running this in Emacs gives me an Evaluation aborted.
message.
When I try switching out membero
for not-membero
I get back ([[1 2] [1 2]])
which makes sense to me. Every element in the first vector [w x]
is a member of the second vector [y z]
.
But, when I call run 2
I get back ([[1 2] [1 2]] [[1 2] [1 3]])
. I don't understand how [[1 2] [1 3]]
can be correct for the rules above. Am I not understanding everyg
correctly? Any guidance (including rtfmanual, rtfbook, rtfdissertation) will be appreciated.
Thanks.
Edit: May have solved this.
Still not sure about the strange results from membero
but instead of the not-membero
goal I found that I could do this:
(everyg #(distinctfd (conj [y z] %)) [w x])
Each element of [w x]
conj'd to [y z]
contains all distinct values. This may be less efficient than not-membero so I'm still open to any help.
Your example seems to be doing the same as this:
(run* [q]
(fresh [w x y z]
(fd/in w x y z (fd/domain 1 2 3 4))
(== q [[w x] [y z]])
(fd/distinct [w x y z])))
But seeing the soccer problem...
(ns test
(:refer-clojure :exclude [==])
(:use clojure.core.logic)
(require [clojure.core.logic.fd :as fd]))
(defn game [g] (fresh [a b c d e] (== g [a b c d e])))
(def players (range 1 11))
(defne not-membero [x l]
([_ []])
([_ [?y . ?r]]
(!= x ?y)
(not-membero x ?r)))
(defne plays [player games]
([_ []])
([_ [?f ?s . ?r]]
(membero player ?f) ; if you play this game
(not-membero player ?s) ; do not play next game
(plays player ?r))
([_ [?f ?s . ?r]]
(membero player ?s)
(not-membero player ?f)
(plays player ?r)))
(defne goalies [games]
([[[_ _ _ _ ?a]
[_ _ _ _ ?b]
[_ _ _ _ ?c]
[_ _ _ _ ?d]]]
(fd/in ?a ?b ?c ?d (apply fd/domain players))
(not-membero 1 [?a ?b ?c ?d]) ; star player != goalie
(fd/distinct [?a ?b ?c ?d]))) ; not goalie twice
(defn -main [& args]
(run 1 [q]
(fresh [a b c d]
(game a)
(game b)
(game c)
(game d)
(== q [a b c d])
(goalies q)
(everyg #(plays % q) players))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With