[LOGIC173] StackOverflowError when logic variable is unified with a set Created: 03/Aug/15 Updated: 03/Aug/15 

Status:  Open 
Project:  core.logic 
Component/s:  None 
Affects Version/s:  None 
Fix Version/s:  None 
Type:  Defect  Priority:  Major 
Reporter:  Tassilo Horn  Assignee:  David Nolen 
Resolution:  Unresolved  Votes:  0 
Labels:  bug  
Environment: 
core.logic 0.8.10, Clojure 1.7.0 
Description 
It is pretty common to unify a variable with a vector or list of a fixed length like (== q (list a b)) and then define more goals on a and b with the intention of being able to define the run* query's result format. However, if one does the same using a set one gets a StackOverflowError. Example: (run* [q] (fresh [a b] (== q #{a b}) ;; StackOverflowError ;;(== q [a b]) ;; works ;;(== q (list a b)) ;; works, too (conde [(== a 1)] [(== a 2)] [(== a 3)]) (conde [(== b 1)] [(== b 2)] [(== b 3)]))) Basically, what I wanted to express here is that the order of a and b is not significant so that (distinct (run* ...)) gives me the unique results. The backtrace is: logic.clj: 231 clojure.core.logic/walk*/fn logic.clj: 984 clojure.core.logic/eval8917/fn protocols.clj: 55 clojure.core.logic.protocols/eval7398/fn/G logic.clj: 229 clojure.core.logic/walk* logic.clj: 233 clojure.core.logic/walk*/fn logic.clj: 984 clojure.core.logic/eval8917/fn protocols.clj: 55 clojure.core.logic.protocols/eval7398/fn/G logic.clj: 229 clojure.core.logic/walk* logic.clj: 233 clojure.core.logic/walk*/fn logic.clj: 984 clojure.core.logic/eval8917/fn protocols.clj: 55 clojure.core.logic.protocols/eval7398/fn/G [...] 
[LOGIC172] nafc doesn't work with more complex goals Created: 31/Jul/15 Updated: 31/Jul/15 

Status:  Open 
Project:  core.logic 
Component/s:  None 
Affects Version/s:  None 
Fix Version/s:  None 
Type:  Defect  Priority:  Major 
Reporter:  Tassilo Horn  Assignee:  David Nolen 
Resolution:  Unresolved  Votes:  0 
Labels:  bug  
Environment: 
core.logic 0.8.10, clojure 1.7.0 
Description 
The negation as failure constraint nafc is supposed to succeed if and only if the goal provided by a relation and its args fails. The test cases just cover very simple cases like (nafc == q 'b) which is essentially equivalent to (!= q 'b) (at least to my understanding). But with a slightly more complex case, it doesn't seem to work anymore. Example: (run* [q] (fresh [a b] (== q (list a b)) (fd/in a b (fd/interval 1 3)) ;; fd is an alias for clojure.core.logic.fd (fd/< a b) (nafc membero 2 q))) ;=> ((1 2) (2 3) (1 3)) The constraint specifies that the number 2 must NOT be contained in the list q but still it is. I expected to get the single answer (1 3) here. 
Comments 
Comment by Tassilo Horn [ 31/Jul/15 2:40 AM ] 
It seems that this problem could be specific to clojure.core.logic.fd. At least this example works: (defn answero [x] (conde [(== x :yes)] [(== x :no)] [(== x :maybe)] [(== x :dontknow)])) (run* [q] (fresh [a b] (== q (list a b)) (everyg answero q) (nafc membero :maybe q) (nafc membero :dontknow q))) ;=> ((:yes :yes) (:yes :no) (:no :yes) (:no :no)) 
Comment by Nicolás Berger [ 31/Jul/15 11:01 AM ] 
This is not a bug. It's expected behavior because not all arguments to the nafc goal are ground. From `nafc` docstring:
In the example using fd, q is not ground (because a and b are not ground), so it's almost the same as if the nafc wasn't there. 
Comment by Tassilo Horn [ 31/Jul/15 1:40 PM ] 
My interpretation of the docstring is that the check will be delayed until the point in time where the variables become ground. And eventually q is ground in my first example. I mean, otherwise nafc would be pretty useless. 