### [LOGIC-185] finite domain uncomplete results Created: 01/Nov/17  Updated: 01/Nov/17

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: pierre baille Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: finite-domains Environment: mac os 10.12.6 clojure.core.logic 0.8.11

 Description
 I was trying to implement a relation similar to (map + list1 list2) -> list3 My code is: ```(require '[clojure.core.logic :as l]) (require '[clojure.core.logic.fd :as fd]) (defn zip+o [x y z] (l/conde [(l/== () x) (l/== () y) (l/== () z)] [(l/fresh [fx rx fy ry fz rz] (l/conso fx rx x) (l/conso fy ry y) (l/conso fz rz z) (fd/in fx fy fz (fd/interval 10)) (fd/+ fx fy fz) (zip+o rx ry rz))])) (def expected-solutions #{{:x [0 0] :y [1 1]} {:x [0 1] :y [1 0]} {:x [1 1] :y [0 0]} {:x [1 0] :y [0 1]}}) (l/run* [q] (l/fresh [x y] (l/== q {:x x :y y}) (zip+o x y [1 1]))) ;=> ({:x (1 0), :y (0 1)} ; {:x (0 0), :y (1 1)})``` I've manage to get the expected behavior (I think...) by removing the call to onceo in clojure.core.logic/enforce-constraints ```(defn enforce-constraints [x] (all (force-ans x) (fn [a] (let [constrained (enforceable-constrained a)] (verify-all-bound a constrained) ((force-ans constrained) a) ;; <--- Here #_((onceo (force-ans constrained)) a)))))``` Sadly it breaks one test... ```FAIL in (test-simplefd-in-last) (tests.clj:1797) expected: (= (run* [q] (fresh [x y z p0 p1] (== q [x y]) (fd/+ x y 9) (fd/* x 2 p0) (fd/* y 4 p1) (fd/+ p0 p1 24) (fd/in x y z (fd/interval 0 9)))) (quote ([6 3]))) actual: (not (= ([6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3] [6 3]) ([6 3])))``` I hope it will at least help you to find the real problem.

 Comment by pierre baille [ 01/Nov/17 10:44 AM ] this test is actually a bit weird, since it introduce a fresh lvar z and give it the domain 0..9 but never use it...

### [LOGIC-183] The extension of IDisunifyTerms to LCons calls seq on lcons values. LCons doesn't implement ISeq Created: 19/Apr/17  Updated: 19/Apr/17

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Kevin Downey Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 I don't have a good repro case for this, I hit the issue in the middle of some other code. on like 2332 or so of master you have some code like: ```(cond ... (lcons? v) (loop [u u v (seq v) cs cs] ... )``` This is obviously incorrect, because anything that returns true to lcons? will throw an exception with you call seq on it.

 Comment by Kevin Downey [ 19/Apr/17 7:56 PM ] looks like a dupe of http://dev.clojure.org/jira/browse/LOGIC-174

### [LOGIC-182] An lvar unified with a keyword behaves differently from a keyword Created: 15/Jan/17  Updated: 15/Jan/17

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: N/A Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 (run 1 [q] (fresh [x] (== x :a) (== q ({:a 0} x)))) => (nil) (run 1 [q] (fresh [x] (== x :a) (== q ({:a 0} :a)))) => (0) (run 1 [q] (fresh [x] (== x :a) (== {:a 0} {x q}))) => () (run 1 [q] (fresh [x] (== x :a) (== {:a 0} {:a q}))) => (0)

### [LOGIC-181] Running rembero returns :- (!= _0 _0) Created: 06/Dec/16  Updated: 06/Dec/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: N/A Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 (run* [out] (fresh [y z] (rembero y (list 'a 'b y 'd z 'e) out))) => ((b a d _0 e) (a b d _0 e) ((a b d _0 e) :- (Unable to render embedded object: File (= (_1 b)) () not found.= (_1 a))) ((a b _0 d e) :- (Unable to render embedded object: File (= (_0 _0)) () not found.= (_0 b)) (Unable to render embedded object: File (= (_0 d)) () not found.= (_0 a))))

### [LOGIC-180] spec detects error in -inc macro Created: 13/Sep/16  Updated: 21/Oct/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Steve Miner Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: Clojure 1.9.0-alpha12

 Attachments: logic-180-inc-macro-spec.patch Patch: Code

 Description
 As reported on the Clojure mailing list by Burt: with "1.9.0-alpha10" and core.logic "0.8.10": (ns lwb.nd.rules (:refer-clojure :exclude [==]) (:require [clojure.core.logic :refer :all])) => nil with "1.9.0-alpha12" and core.logic "0.8.10": (ns lwb.nd.rules (:refer-clojure :exclude [==]) (:require [clojure.core.logic :refer :all])) CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/fn did not conform to spec: In: [0] val: clojure.core.logic/-inc fails spec: :clojure.core.specs/arg-list at: [:args :bs :arity-1 :args] predicate: vector? In: [0] val: clojure.core.logic/-inc fails spec: :clojure.core.specs/args+body at: [:args :bs :arity-n] predicate: (cat :args :clojure.core.specs/arg-list :prepost (? map?) :body (* any?)) :clojure.spec/args (clojure.core.logic/-inc [] (bind (this) g)) #:clojure.spec{:problems ({:path [:args :bs :arity-1 :args], :pred vector?, :val clojure.core.logic/-inc, :via [:clojure.core.specs/args+body :clojure.core.specs/arg-list :clojure.core.specs/arg-list], :in [0]} {:path [:args :bs :arity-n], :pred (cat :args :clojure.core.specs/arg-list :prepost (? map?) :body (* any?)), :val clojure.core.logic/-inc, :via [:clojure.core.specs/args+body :clojure.core.specs/args+body], :in [0]}), :args (clojure.core.logic/-inc [] (bind (this) g))}, compiling:(clojure/core/logic.clj:1130:5)

 Comment by Steve Miner [ 13/Sep/16 12:52 PM ] It looks like the problem is with the macro -inc. It should quote the internal fn name so that it stays an unqualified symbol during macro expansion. Comment by Steve Miner [ 13/Sep/16 12:58 PM ] Macro needs to protect internal name of fn during expansion. Comment by Steve Miner [ 21/Oct/16 7:48 AM ] The same fix was recently committed by puredanger. https://github.com/clojure/core.logic/commit/29917372ef066c42ca362e3a94f68d620ddd1b56

### [LOGIC-175] Disequality might not eliminate when `(!= (_0 _0))` Created: 05/Dec/15  Updated: 05/Dec/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Nelson Morris Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: 0.8.10

 Description
 When a unification constraint and a disequality constraint are applied to the same lvars they might eliminate possibilities. Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java```(run 1 [q] (fresh [v n] (== q v) (!= q v))) ;=> ()``` However when a separate disequality is interleaved the possibility is not eliminated. Unable to find source-code formatter for language: clojure. Available languages are: javascript, sql, xhtml, actionscript, none, html, xml, java```(run 1 [q] (fresh [v n] (== q v) (!= q n) (!= q v))) ;=> ((_0 :- (!= (_0 _0)) (!= (_0 _1))))``` I expected this to also return '().

### [LOGIC-174] LCons fails for inequality Created: 11/Aug/15  Updated: 11/Aug/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Wei Tang Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: Both Clojure 1.6 and Clojure 1.7

 Attachments: ticket174.patch

 Description
 The following expression results in an Exception "IllegalArgumentException Don't know how to create ISeq from: clojure.core.logic.LCons clojure.lang.RT.seqFrom (RT.java:505)", but should return (). ``` (run 1 [q] (!= (lcons 1 1) (lcons 1 1)))

### [LOGIC-173] 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 [...] ```

### [LOGIC-172] 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.

 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 :dont-know)])) (run* [q] (fresh [a b] (== q (list a b)) (everyg answero q) (nafc membero :maybe q) (nafc membero :dont-know 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: EXPERIMENTAL: negation as failure constraint. All arguments to the goal c must be ground. If some argument is not ground the execution of this constraint will be delayed. 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.

### [LOGIC-171] The docstring of condu is incorrect or at least confusing Created: 28/Jul/15  Updated: 28/Jul/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Major Reporter: Tassilo Horn Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: docs, docstring

 Description
 The docstring of condu reads Committed choice. Once the head (first goal) of a clause has succeeded, remaining goals of the clause will only be run once. Non-relational. The sentence with respect to the once-semantics isn't correct. The head (first goal) can succeed at most once whereas the remaining goals of the clause committed to can succeed an unbounded number of times. The following example demonstrates that. ```(defn y-or-n [x] (conde [(== x :y)] [(== x :n)])) (run* [x y] (condu [(y-or-n x) (== y 1)] ;; (y-or-n x) succeeds once because it's the head goal [(== x :y) (== y 2)])) ;;=> ([:y 1]) (run* [x y] (condu [(== y 1) (y-or-n x)] ;; (y-or-n x) succeeds twice because it's not the head goal [(== x :y) (== y 2)])) ;;=> ([:y 1] [:n 1]) ``` The current behavior shown in the example is in compliance with miniKanren on Scheme, so it's just the docstring which isn't right. The implementation is correct.

### [LOGIC-168] Allow partial matching of keys not existing in a map Created: 20/May/15  Updated: 20/May/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Hugo Duncan Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: 0001-Add-support-for-matching-on-key-not-being-present.patch Patch: Code and Test

 Description
 When matching maps, it is sometimes useful to specify a map that doesn't include specific keys. Eg. to specify a map that doesn't include a :foo key: ```(def _! :clojure.core.logic/not-found) (run* [x] (featurec x {:foo _!}))``` The patch is minimal, and demonstrates the functionality.

### [LOGIC-165] Add non-interleaving version of conde Created: 21/Dec/14  Updated: 21/Dec/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Major Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 For validation use cases having depth first search as an option would be very useful.

### [LOGIC-162] FD logic doesn't always return all solutions Created: 20/Oct/14  Updated: 10/Mar/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Viktar Basharymau Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: finite-domains Environment: org.clojure/core.logic 0.8.8

 Description
 Given the following code ```(run* [x11 x12 x13 x21 x22 x24 x31 x33 x34 x42 x43 x44] (fd/in x11 x12 x13 x21 x22 x24 x31 x33 x34 x42 x43 x44 (fd/interval 1 9)) (fd/eq (= (+ x11 (/ x12 x13)) 5) (= (+ x21 (/ x22 2)) x24) (= (+ x31 (/ 6 x33)) x34) (= (+ 4 (/ x42 x43)) x44) (= (+ x11 (/ x21 x31)) 4) (= (* x12 (/ x22 6)) x42) (= (+ x13 (- 2 x33)) x43) (= (+ (- 5 x24) x34) x44)))``` I have {{([1 4 1 3 6 6 1 1 7 4 2 6] [2 6 2 4 6 7 2 1 8 6 3 6])}} as a result. However, as soon as I change (fd/interval 1 9) to (fd/interval 0 9), the result becomes an empty sequence. However, I expect it to include at least the two aforementioned solutions.

 Comment by David Nolen [ 21/Oct/14 4:34 AM ] It would help if you could confirm that the issue is present without using fd/eq - which is just macro sugar. Writing out the long form is tedious but it will help isolate the issue. Thanks. Comment by Viktar Basharymau [ 21/Oct/14 8:08 AM ] I actually suspect that the bug is in `fd/eq`. Here is a smaller test case: ```(run* [q] (fd/in q (fd/interval 1 2)) (fd/eq (= (/ q q) 1)))``` It returns `(1 2)` as expected, but as soon as I change `fd/interval` to `0 2`, it returns an empty seq. Comment by David Nolen [ 09/Nov/14 6:09 PM ] Thanks for the minimal case, yeah looks like an issue with fd/eq as it works fine if you write it out long hand. Comment by David Nolen [ 10/Mar/15 2:49 PM ] See also LOGIC-156

### [LOGIC-156] Finite Domains - Two consecutive calls to run* return different results Created: 22/Feb/14  Updated: 10/Mar/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Mauro Lopes Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: bug

 Attachments: core.clj     core.clj

 Description
 Calling run* twice with the same input may return different results for no apparent reason. See attachment.

 Comment by David Nolen [ 05/Mar/14 9:19 AM ] The problematic code incorrectly uses finite domain operations on fresh variables that have not be assigned domains. Can we get an updated version of the problematic code that demonstrate the issue after the corrections? Comment by Mauro Lopes [ 05/Mar/14 9:25 PM ] Sure. I have just added a new code version with finite domains assigned to each variable that is involved in an fd operation. The problem persists. Comment by David Nolen [ 10/Mar/15 2:49 PM ] This issue is likely related to LOGIC-162

### [LOGIC-154] walk* of an empty set overflows the stack Created: 31/Dec/13  Updated: 31/Dec/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Kevin Downey Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: 0001-logic-154-walk-of-an-empty-set-overflows-the-stack.patch

 Description
 I noticed this issue when asserting a relation with an empty set in it in the new pldb stuff, the minimal case I have is (walk* empty-s #{})

 Comment by Norman Richards [ 31/Dec/14 2:01 PM ] Here's an update that allows sets to be uses as terms and correctly walks sets. It does not do unification of one set with another, which is a much harder problem. Comment by David Nolen [ 31/Dec/14 2:32 PM ] The fact that equal sets don't unify is problematic. That at least should work. Sets with logic vars in them should throw. Unification (assignment) of a set to a logic var should work.

### [LOGIC-144] Extending cljs.core.logic with all of the functionality from clojure.core.logic Created: 19/Nov/13  Updated: 02/Jan/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Major Reporter: Adrian Medina Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Repo I've been working from is here: https://github.com/aamedina/cljs.core.logic I've followed the code layout in clojure.core.logic pretty much verbatim, compensating for ClojureScript necessities, moved macros into sister .clj files. I have no hard opinions about the best way to organize the macros for each file, the way I do it is just the way I've found easiest, because then you don't have to namespace qualify every syntax quoted form that references a function in the sister .cljs file. Additionally I ported all of the clojure.core.logic tests with clojurescript.test.

 Comment by Adrian Medina [ 27/Nov/13 10:43 PM ] So I've updated the repo to reflect a more faithful adherence to the existing cljs.core.logic code conventions and organization. I'd appreciate any insight into how to potentially optimize the code to run more on par with the JVM. Comment by David Nolen [ 04/Dec/13 1:09 AM ] What kinds of performance problems are you observing? Do you have a particular benchmark that you're running? Comment by Adrian Medina [ 04/Dec/13 12:18 PM ] Appendo and membero are particularly slow. (dotimes [i ie5] (run* [q] (== q true))) takes around ~4500ms, which is about 10x slower than the JVM. After profiling, I've discovered the problem - pretty standard recursion optimizations are necessary, it's re-walking (by reunifying) lvars recursively as the code is executed. E.g., for appendo, (run 5 [q] (fresh [x y] (appendo x y q))) will expand into something like.. ((_0) (_0 . _1) (_0 _1 . _2) ... )) and it's slow because every new list is actually re-walking every previously unified lvar again. I'll have more time to investigate this over the weekend, but I think it might be as simple as not generating unique lvars by default, since then the identical? for unification check should catch any attempted walk. Comment by Ryan Munro [ 02/Jan/16 3:58 PM ] I've been using clojure.core.logic & cljs.core.logic, and have been stumbling with API differences. With the new reader conditionals, I think it would make sense to deprecate cljs.core.logic in favor of clojure.core.logic. Does cljs.core.logic have specific implementations to make it performant on JS vms? Just looking at the code, it looks quite different, so these performance issues could also be caused by not as optimized algorithms. I could help look into making clojure.core.logic portable, though I'm pretty new to clojure. My strategy would be adding reader conditionals until the test suite passes in clojurescript.

### [LOGIC-142] Unified map values are returned as LVar rather than the unified value in ClojureScript Created: 29/Sep/13  Updated: 31/Dec/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Darrick Wiebe Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: ClojureScript

 Attachments: 0001-logic-142-arraymap-not-correctly-walked.patch

 Description
 This works correctly in core.logic for clojure: ```(run 1 [q] (fresh [v] (== v 1) (== {:x v} q)))``` In ClojureScript, I get this though: `({:x })`

 Comment by Norman Richards [ 31/Dec/14 2:06 PM ] The clojurescript code did not implement -walk-term for PersistentArrayMap. I've copied the PersistentHashMap implementation for PersistentArrayMap. Note: the current implementation (walk-term-map*) does not actually work for hash maps due to the use of -next and -first. Changing these to next and first would fix this for hash maps, but I'm not sure if this has any implications in clojurescript or not. Comment by David Nolen [ 31/Dec/14 2:35 PM ] Norman, do you mean -next, -first doesn't work for array maps?

### [LOGIC-140] compile time occurs check for pattern matching Created: 25/Jun/13  Updated: 25/Jun/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Claire Alvis correctly pointed out that it's easy to make a mistake when you have many clauses and accidentally use parameter name in a match for that parameter - we could easily do a compile time occurs check for these cases.

### [LOGIC-136] Make benchmark suite as easy to run as `lein test` Created: 09/May/13  Updated: 09/May/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Major Reporter: Austin Haas Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 `lein benchmark` (or some other non-lein-based incantation) prints a report listing the name of each benchmark and its timing. Example: ```\$ lein benchmark membero 2839 zebra 152738 \$ lein benchmark comparison-report {:baseline "benchmark-5.9.2013-1" :runs 5 :diffs-only true :threshold 25} ; only consider different if the delta is > 25 ms. membero +68ms zebra -122ms \$ lein benchmark {:pretty true} Thu May 9 11:21:41 PDT 2013 Linux mars 2.6.32-5-amd64 #1 SMP Fri Feb 15 15:39:52 UTC 2013 x86_64 GNU/Linux java version "1.7.0_21" Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode) membero 2839 ms zebra 152738 ms``` I haven't looked for any Clojure benchmarking libs, but ideally this would be a trivial script that automates the repetitive manual task of running benchmark tests. Unlike the test suite, we aren't looking for binary success or failure. Every run will generate unique results, so the script should accommodate a fuzzier comparison. A "pretty" output that includes system info would be great for bug reports.

 Comment by David Nolen [ 09/May/13 1:44 PM ] Sounds like an excellent enhancement to me. Patch welcome for this.

### [LOGIC-133] Add label goal Created: 29/Apr/13  Updated: 11/Jan/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 This goal should enumerate any fd vars found in a fresh/ground var bound to a sequence. This would avoid some unintuitive behavior that came up on the mailing list: ```(defne weighted-listo [l w] ([() _] (fd/== w 0)) ([[h . t] _] (fresh [n] (fd/in n (fd/interval 0 java.lang.Integer/MAX_VALUE)) (fd/in h (fd/interval 1 java.lang.Integer/MAX_VALUE)) (fd/+ h n w) (weighted-listo t n))))```

 Comment by Austin Haas [ 11/Jan/14 10:23 PM ] Here is a link to the discussion on the mailing list: https://groups.google.com/forum/#!topic/minikanren/MgcvtkA6_EI

### [LOGIC-129] matcha/matchu are not faithful to the semantics of conda/condu Created: 04/Apr/13  Updated: 09/Jun/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Austin Haas Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 The semantics of conda and condu give special importance to the head of each clause, but the pattern matching macros in core.logic that are built on top of them merge the body into the head. That means that every expression in a body position is considered when deciding which line is chosen, rather than just the expression in the head position. This is because the entire clause is wrapped in a fresh expression to bind the implicitly specified lvars that appear in the pattern. To illustrate: ```(matcha ['a] [['a] u#] [['a] s#]) ;; expands to: (conda [(fresh [] (== 'a 'a) u#)] [(fresh [] (== 'a 'a) s#)]) ;; which has a different meaning than: (conda [(== 'a 'a) u#] [(== 'a 'a) s#])``` Ideally, we could devise a new system to marry the semantics of conda with pattern matching. At the very least, I think the offending macros should carry a warning in their docstring, stating this semantic difference. I suspect this would also cause the "Third Commandment" warning to apply to the entire line, rather than just the head/question, but I have not investigated that issue. Here's an example that demonstrates the difference in meaning: ```;; This does not succeed, because we commit to the first line, ;; since the question succeeds, but then fail in the body. (run* [q] (conda [(== 'a 'a) u#] [(== 'a 'a) s#])) ;; => () ;; This succeeds, because the whole line is used to determine which line to commit to, ;; rather than just the pattern matching clause at the head. So when the first line fails, ;; the second line is tried. (run* [q] (matcha ['a] [['a] u#] [['a] s#])) ;; => (_0)```

Comment by Austin Haas [ 04/Apr/13 2:35 PM ]

For reference:

### The Third Commandment

If prior to determining the question of a conda (or condu) line a variable is fresh, it must remain fresh in the question of that line.

From The Reasoned Schemer.

Comment by David Nolen [ 04/Apr/13 5:16 PM ]

Comment by David Nolen [ 09/Jun/13 12:11 PM ]

The issue is that we rely on the `conde` macro which isn't very flexible. We should probably do something one step lower so can wrap each conde line in a `let` that constructs the logic vars and then ensure that all the head unifications are wrapped in one `fresh` so that the semantics of conda/u are preserved.

### [LOGIC-119] tie disequality Created: 12/Mar/13  Updated: 12/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Nada Amin Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 ```(deftest test-tie-disequality (is (= (run* [q] (nom/fresh [a b] (!= (nom/tie a a) 'hello))) '(_0))) (is (= (run* [q] (nom/fresh [a b] (!= (nom/tie a a) (nom/tie b b)))) ())))``` Currently, the first causes an error, because IPersistentMap (which gets called because Tie is a record!) assumes that the the other term is also a record (that seems like a bug). If we revert the commit which makes Tie a record, this works. The other one succeeds, when it should fail. This is regardless of whether Tie is a record or not.

 Comment by Nada Amin [ 12/Mar/13 5:52 AM ] for actually doing != modulo alpha equivalence requires the opposite of nom/hash.

### [LOGIC-117] one-shot constraints with multiple rands may run more than once Created: 11/Mar/13  Updated: 19/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Nada Amin Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Here are two examples using fixc: ```(run* [q] (fresh [x y] (fixc [x y] (fn [[x y] a _] (!= x 1)) (fn [[x y] a] (= (walk a x) (walk a y))) '...) (== x y))) (run* [q] (fresh [x y c d] (fixc [x y] (fn [[x y] a _] (!= x y)) (fn [[x y] a] (or (not (lvar? (walk a x))) (not (lvar? (walk a y))))) '...) (== [x y] [[c] [d]])))``` The constraint != is reified twice in each example, showing that the fixc constraint indeed ran twice.

 Comment by David Nolen [ 17/Mar/13 7:27 PM ] For the first example I see the following as a result on master: `((_0 :- (!= (_1 1))))` Is this what you're seeing? As x isn't even part of the answer I wonder if we should show these constraints? Comment by Nada Amin [ 19/Mar/13 1:36 AM ] I changed the reifier by setifying the set of constraints, hence you get only one result now. So my illustration is now out-of-date but the problem remains. It's a separate issue to filter out irrelevant constraints, and I agree it should be done (I try to do it for the nominal constraints).

### [LOGIC-114] stack overflow with conda/u Created: 14/Feb/13  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: Austin Haas Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 ```(ns test (:refer-clojure :exclude [==]) (:require [clojure.core.logic :refer :all])) (defn foo [in out] (matcha [in out] ([('and a b . ()) ('and x y . ())] (foo a x) (foo b y)) ([a ('bar ('baz a . ()) . ())]))) ;; I get a stack overflow with the following, but if I remove one conjunct, then it will run. (run 1 [q] (foo '(and p (and p (and p (and p (and p (and p (and p (and p (and p (and p (and p p))))))))))) q))```

 Comment by David Nolen [ 14/Feb/13 1:22 PM ] It looks this issue still exists even if you swap the matcha with matche Comment by Austin Haas [ 14/Feb/13 8:06 PM ] I think the overflow is occurring during reification. I was getting this error when returning a result from run, but now that I'm using the same value as the input to another goal there is no overflow. If you replace q in the foo call with a fresh variable, it will not overflow. Comment by David Nolen [ 17/Mar/13 7:30 PM ] This works for me on master. Can you give me more specifics about your setup so I can try to recreate? I'm on OS X 10.8 running JDK 7 64bit. Comment by Austin Haas [ 17/Mar/13 8:50 PM ] I don't see the issue anymore, but I believe I was using Java 1.6 when I reported it and now I am using: \$ java -version java version "1.7.0_15" Java(TM) SE Runtime Environment (build 1.7.0_15-b03) Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode) Comment by David Nolen [ 17/Mar/13 9:02 PM ] OK, thanks for the quick response, I'll double check how things look under 1.6.

### [LOGIC-99] StackOverflow for large `appendo` Created: 05/Jan/13  Updated: 31/Dec/14

Status: In Progress
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Major Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 ```(def l (range 0 2000)) (run* [q] (appendo l l q))``` Stacktrace ```user=> (def l (range 0 2000)) #'user/l user=> (run* [q] (appendo l l q)) StackOverflowError clojure.core.logic.LVar (logic.clj:1307) user=> (pst) StackOverflowError clojure.core.logic.LVar (logic.clj:1307) clojure.lang.KeywordLookupSite\$1.get (KeywordLookupSite.java:45) clojure.core.logic.LVar (logic.clj:1325) clojure.lang.Util.equiv (Util.java:32) clojure.lang.PersistentHashMap\$BitmapIndexedNode.find (PersistentHashMap.java:601) clojure.lang.PersistentHashMap\$ArrayNode.find (PersistentHashMap.java:370) clojure.lang.PersistentHashMap\$ArrayNode.find (PersistentHashMap.java:370) clojure.lang.PersistentHashMap.entryAt (PersistentHashMap.java:133) clojure.lang.RT.find (RT.java:720) clojure.core/find (core.clj:1432) clojure.core.logic.Substitutions (logic.clj:1134) clojure.core.logic/walk*/fn--2847 (logic.clj:1005)```

 Comment by David Nolen [ 05/Jan/13 2:44 PM ] I cannot recreate on my machine but should try a large N & wait and see. Comment by Norman Richards [ 31/Dec/14 2:17 PM ] It happens for me by 5000. I note the following comment on the implementation of walk-term (the method that blows the stack up) for LCons: ;; TODO: no way to make this non-stack consuming w/o a lot more thinking ;; we could use continuation passing style and trampoline IWalkTerm (walk-term [v f] (lcons (f (lfirst v)) (f (lnext v))))

### [LOGIC-177] binding to a deep nested vector takes too much time Created: 24/Dec/15  Updated: 28/Dec/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Dmitry Geurkov Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: performance Environment: Ubuntu Linux 12.04 Java: OpenJDK 64-Bit Server VM 1.8.0_45-internal-b14 Clojure: 1.7.0 core.logic "0.8.10"

 Description
 It's probably related to how core.logic is printing out the vector structure Following is minimal case to reproduce the issue (ns testclj.logic (:require [clojure.core.logic :as l])) (def data [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[:a]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]) (time (l/run* [q] (l/== q data)))

 Comment by Dmitry Geurkov [ 28/Dec/15 6:48 AM ] I think the problem is related to following piece of code ```(defn walk* [s v] (let [v (walk s v)] (walk-term v (fn [x] (let [x (walk s x)] (if (tree-term? x) (walk* s x) x))))))``` this on the other hand calls ```clojure.lang.IPersistentVector (walk-term [v f] (with-meta (loop [v v r (transient [])] (if (seq v) (recur (next v) (conj! r (walk-term (f (first v)) f))) (persistent! r))) (meta v)))``` What this does is that it recursively calls walk-term for all elements of vector. and subsequently calls walk-term for each element of vector which in turn results in calling walk* over the elements of vector which had previously been visited which in turn ends into calling walk-term again on the elements of the vector again going down and until it visits the entire structure multiple times. This overall results in revisiting sub nodes multiple times The problem is in walk* function part which is recursively calling walk* for vector elements that had been previously walked by walk-term function call itself ```(if (tree-term? x) (walk* s x) x)``` I think there is a huge problem with how this whole part is designed, I'm not sure what to suggest here but I think we need to somehow combine walk-term and walk* into one function that would walk the entire datastructure in one go, any suggestions? Possible solution is following code but I'm not sure if it's correct one or not ```(defn walk* [s v] (let [v (walk s v)] (walk-term v #(walk s %))))```

### [LOGIC-176] Extending IUnifyTerms doesn't work anymore Created: 16/Dec/15  Updated: 16/Dec/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Daniel Ziltener Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: bug

 Description
 The procedure as described on https://github.com/clojure/core.logic/wiki/Extending-core.logic-%28Datomic-example%29 doesn't work anymore. Clojure complains that IUnifyTerms "isn't a protocol" (even though it clearly is).

### [LOGIC-170] Replacing Marker Interfaces Created: 23/Jul/15  Updated: 23/Jul/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: J David Smith Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: cljs, enhancement

 Description
 Summary: There is a pattern of (definterface IFoo) and subsequent uses of IFoo as a type marker for efficient (instance? IFoo x) checks. This pattern is not platform agnostic and could potentially block improving support for core.logic on CLJS (which does not support definterface according to http://dev.clojure.org/jira/browse/CLJS-1190). Background: I was investigating the possibility of using reader conditionals to port parts of core.logic to CLJS (specifically: core.logic.fd) and noticed the usage of interfaces as type markers. The problem with this is that there is no definterface in CLJS (to my knowledge; attempting to run (definterface IFoo) fails in a CLJS repl but works in a CLJ repl). I have started trying to look for a platform-agnostic replacement for the marker interface pattern but wanted to know if there were specific reasons that this pattern was used before diving into actual coding. I also wanted to know if there were already plans to replace this pattern. Remediation: Ideally a cross-platform method for achieving this could be implemented. If not, then an alternative method could be defined for and used by CLJS at the cost of some performance. A possible change would be to replace the marker interfaces with marker protocols, and the instances of instance? with instances of satisfies?. The following seem to be equivalent in Clojure: ; interfaces (definterface IFoo) (definterface IBar) (deftype T [] IFoo) (instance? IFoo (T.)) ; true (instance? IBar (T.)) ; false ; protocols (defprotocol IFoo) (defprotocol IBar) (deftype T [] IFoo) (satisfies? IFoo (T.)) ; true (satisfies? IBar (T.)) ; false However, the protocol version also works in ClojureScript.

### [LOGIC-166] walk* exponential in depth of tree terms? Created: 27/Jan/15  Updated: 03/Feb/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Tom Jack Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: performance Environment: [org.clojure/clojure "1.7.0-alpha5"] [org.clojure/core.logic "0.8.9"]

 Attachments: 0001-Walk-less.patch

 Description
 By 'reification' I mean e.g.: ```(run 1 [t] (== t ))``` Demonstration of exponential performance, using nested vectors ([], [[]], [[[]]]...): https://www.refheap.com/1e30c198d528300fcba9ef24a Is this expected, or a bug? I'm guessing the former, but hoping the latter. Feel free to close without comment if this is just the way it is.

 Comment by Tom Jack [ 28/Jan/15 4:31 AM ] Attached patch 0001-Walk-less.patch gets me this nice result. It also makes my real case work quite speedily (25ms now, where before it took so long that I never saw it finish). That's a huge relief! The problem wasn't reification, but walk-term. In the patch I attempt to avoid doing some walking which appears to be redundant. I hope the fact that most of the tests still pass is good evidence that it's redundant. However, the patch breaks some unifier tests. I noticed that my refheap test 'passes' as of bd65104ec3~, but fails as of bd65104ec3 (the patch for LOGIC-69). It seems the fix made the unifier rely on the current behavior of walk-term. I'm going to press on with my patched ./checkouts copy for now, since I'm not using the unifier. I may come back to try to fix it sometime.

### [LOGIC-153] deftest test-34-unify-with-metadata appears incorrect Created: 23/Dec/13  Updated: 01/Jan/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Andy Fingerhut Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 ```(deftest test-34-unify-with-metadata (is (run* [q] (== q (quote ^:haz-meta-daytuhs (form form form)))) '((^:haz-meta-daytuhs (form form form)))))``` I am not sure what was intended for this, but replacing it with the following causes the test to fail. ```(deftest test-34-unify-with-metadata (is (= (run* [q] (== q (quote ^:haz-meta-daytuhs (form form form)))) '((^:haz-meta-daytuhs (form form form))))))``` I think the correct version is probably close to that, though.

 Comment by David Nolen [ 30/Dec/13 7:20 PM ] I'm pretty sure meta data on forms caused exceptions and that's what this test was for. Comment by Andy Fingerhut [ 01/Jan/14 12:05 PM ] As that test is written now, it is of the form: ```(is (run* [q] (expr)) '(expr2))``` The second argument to the macro 'is' is optional, and if present should be a string, not something like '(expr2). The test passes if (run* [q] (expr)) returns true without throwing an exception, and '(expr2) is ignored completely. That is why the test appears to be written incorrectly.

### [LOGIC-146] run macro should take * in addition to n Created: 26/Nov/13  Updated: 16/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

### [LOGIC-141] dcg: def--> ClassCastException Created: 23/Aug/13  Updated: 23/Aug/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Greg Chapman Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 I believe def--> needs to put its lsyms into a vector (as does -->). lsyms is passed to handle-clauses (as the env param), and there is used as a function. This causes an exception since a seq cannot be cast to a function.

### [LOGIC-138] Allow tying multiple noms in one binder Created: 10/Jun/13  Updated: 10/Jun/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Tom Jack Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: nominal

 Description
 I think it may be useful to be able to tie multiple noms in one binder, with or without significant order. A couple use cases I've thought of so far: Lambdas in a non-currying language. Here order matters. ```(== (list 'fn (ties [x y] (list '+ x y))) (list 'fn (ties [z w] (list '+ z w)))``` My original use case, free/quantified variables in logical formulas. Order doesn't matter (note the second body has its noms swapped). ```(== (list '∀ (ties #{x y} (list '= (list '+ x y) (list '+ y x)))) (list '∀ (ties #{z w} (list '= (list '+ w z) (list '+ z w)))))``` I have a draft implementation here: https://github.com/tomjack/core.logic/compare/ties Possible issues with this implementation: Is it OK to reextend IWalkTerm to IPersistentSet? Should Tie and Ties present a uniform interface? (e.g. (tie? (ties #{x} x)))

 Comment by David Nolen [ 10/Jun/13 3:37 PM ] I really don't think the set bit is necessary, the vector syntax is fine. Also avoid needing to bring IWalkTerm back for sets. And yes, tie? should work in either case. Comment by Tom Jack [ 10/Jun/13 3:55 PM ] Hmm.. should: ```(== (list 'fn (ties [x y] (list '- x y))) (list 'fn (ties [z w] (list '- w z)))``` I'd think not. Do you mean that order should always matter (take out the permutations stuff), or that it should never matter (don't use ties for cases like the above)? Comment by David Nolen [ 10/Jun/13 4:07 PM ] Ah hm, good point. Will think on it some more.

### [LOGIC-130] StackOverFlowError when walking over set Created: 16/Apr/13  Updated: 31/Dec/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Coen De Roover Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: core.logic 0.8.3 Clojure 1.5

 Description
 Walking a Clojure set seems to cause a StackOverFlowError: ```(run* [?s] (== ?s #{1 2 3})) (let [s #{1 2 3}] (run* [?s] (== ?s s))) (run* [?convertedseq ?seq] (== ?seq #{1 2 3}) (project [?seq] (== ?convertedseq (vector ?seq))))``` ```StackOverflowError clojure.core.logic/walk*/fn--2722 (logic.clj:216) clojure.core.logic/eval2927/fn--2928 (logic.clj:956) clojure.core.logic.protocols/eval1478/fn--1479/G--1469--1486 (protocols.clj:55) clojure.core.logic/walk* (logic.clj:214) clojure.core.logic/walk*/fn--2722 (logic.clj:218) clojure.core.logic/eval2927/fn--2928 (logic.clj:956) clojure.core.logic.protocols/eval1478/fn--1479/G--1469--1486 (protocols.clj:55) clojure.core.logic/walk* (logic.clj:214) clojure.core.logic/walk*/fn--2722 (logic.clj:218) clojure.core.logic/eval2927/fn--2928 (logic.clj:956) clojure.core.logic.protocols/eval1478/fn--1479/G--1469--1486 (protocols.clj:55) clojure.core.logic/walk* (logic.clj:214)```

 Comment by David Nolen [ 16/Apr/13 5:28 PM ] core.logic no longer supports unification of sets so you're just seeing an error as result of a complete lack of support. I'm not against supporting basic unification of completely grounded sets, as then we only need to test for equality, but I'm inclined to make the system throw if any logic vars appear in the sets. Comment by Norman Richards [ 31/Dec/14 2:21 PM ] The proposed fix for LOGIC-154 fixes this.

### [LOGIC-128] add mod/rem/abs/min/max Created: 02/Apr/13  Updated: 15/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 SWI-Prolog's CLP(FD) module has this functionality http://www.swi-prolog.org/man/clpfd.html

### [LOGIC-123] Allow unification with sequential in both directions Created: 23/Mar/13  Updated: 26/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Mike Anderson Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Currently I can't find a way to enable a custom data type to do unification with sequential objects in both direction. You can use IUnifyTerms to make it work in one direction, but it isn't possible to make it work in the other direction (i.e. when the sequential object is first). The problem seemes to be in the following code: ```(defn unify-with-sequential* [u v s] (cond (sequential? v) (if (and (counted? u) (counted? v) (not= (count u) (count v))) nil (loop [u u v v s s] (if (seq u) (if (seq v) (if-let [s (unify s (first u) (first v))] (recur (next u) (next v) s) nil) nil) (if (seq v) nil s)))) (lcons? v) (unify-terms v u s) :else nil))``` If the final nil could be replaced with a call to a protocol (IUnifyTermsReversed ???IUnifyWithSequential ???) then I believe it would make this extensible.

 Comment by David Nolen [ 23/Mar/13 9:53 PM ] I'm assume it's undesirable for your datatype to implement ISequential? Comment by Mike Anderson [ 23/Mar/13 11:06 PM ] It's undesirable because an expression can be a leaf node as well: (+ 3 X) ;; OK as sequential 7 ;; definitely not sequential! Hence making Expression implement ISequential would be problematic and break all kinds of contracts..... Trying to unify the leaf node with a sequential object should fail of course, but that's logic I need to implement myself (I think??) Comment by David Nolen [ 24/Mar/13 12:11 PM ] I'm still not following as there's some context about your use case that I'm missing. Do you have a concrete core.logic example that you should think should work? Comment by Mike Anderson [ 25/Mar/13 2:21 AM ] Sure, here is my test case: ```(let [ex1 (ex [+ 1 X])] ;; an expression containing (+ 1 X) (is (= [(ex X)] (run* [q] (fresh [op p] (== [op p q] ex1))))) ;; fails (is (= [(ex X)] (run* [q] (fresh [op p] (== ex1 [op p q]))))) ;; OK )``` The first case fails (because of unify-with-sequential* returning nil as above). The second case is OK because it goes through my own implementation of IUnifyTerms. I may be wrong, but I don't think I can make it work without a change in core.logic itself. Comment by David Nolen [ 25/Mar/13 7:39 AM ] We used to support unifying in both directions but it made for a large number of protocols that had to be implemented. Recently I've been thinking it may be useful to provide coercion protocols, something like ICoerceToSequential. Comment by Mike Anderson [ 25/Mar/13 7:37 PM ] I think it is necessary to be able to support unifying in both directions somehow if custom data structures are ever going to be first-class citizens in core.logic? I see how you could achieve this with ICoerceToSequential however so that might be a good solution. We do something a bit similar in core.matrix (to handle coercions between different back-end matrix implementations). Comment by David Nolen [ 25/Mar/13 7:44 PM ] custom data structures are already first class. Whether we should allow overloading unification of custom types with core Clojure interfaces/protocols/types is another matter entirely. And sorry for the confusion. It's not clear to me why you want sequential to work, from your examples it appears that you have a proper expression type, what advantage is there for you to unify with sequential? Comment by Mike Anderson [ 26/Mar/13 1:07 AM ] I think it may be important if you have "sequence-like" data structures that aren't precisely sequential? but are conceptually equivalent to sequences. My custom Expression type is one example, and for interop reasons things like java.util.ArrayList spring to mind. As it happens, I've switched back to using regular lists for the moment so the issue isn't a blocker for me. But it may still be worth thinking about. Couple of advantages of doing this kind of unification would appear to be: a) notational - you can use regular Clojure lists and vectors for unifying with something sequence-like b) efficiency - avoid constructing a new custom object when it isn't needed (though the cost is probably too trivial to bother about in most cases....) Of course, you may decide it is simpler and purer to avoid these complications, which is fine. But it seems a shame to have all the nice extensible protocols, and not quite be able to fully extend the functionality to custom types....

### [LOGIC-89] Allow application again in pattern matches Created: 01/Jan/13  Updated: 15/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: 0.8.0

 Description
 Perhaps we can support simple function application in the following manner. ```(defne substo [e new a out] (['(var ~a) _ _ new]) (['(var ~y) _ _ '(var ~y)] (nom/hash a y)) (['(app ~rator ~rand) _ _ '(app ~rator-res ~rand-res)] (substo rator new a rator-res) (substo rand new a rand-res)) (['(lam ~(nom/tie c body)) _ _ '(lam ~(nom/tie c body-res))] (nom/hash c a) (nom/hash c new) (substo body new a body-res)))``` If we have a seq in an unquote then we know we have an application. All function symbols are left alone, all arguments are considered to be fresh vars or locals.

### [LOGIC-87] Decomplect the narrowing of the constraint space from the search order Created: 27/Dec/12  Updated: 28/Dec/12

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Jamie Brandon Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: flexible_search.patch Patch: Code and Test

 Description
 From a high-level point of view a constraint solver takes a constraint space, generates a tree of narrowings of the space and runs some search algorithm on the tree. Core.logic complects the generation of this tree and the search algorithm by representing the search space as a lazy stream of the leaves of the tree. By explicitly representing the search tree we get new search algorithms, optional fair conjunction and parallel search via fork-join. Github fork: https://github.com/clojure/core.logic/pull/13 Attached is a cleaned-up patch against d68e3400472c5f745e4c13d64433459e11ba4871

 Comment by David Nolen [ 28/Dec/12 12:41 AM ] Thanks! Will try to find some time this weekend to do a thorough review.

### [LOGIC-86] make `defc` more useful Created: 26/Dec/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 As we start adding more constraints it's becoming clear we really want to have to specify less boiler plate. Instead of: ```(defn -treec ([x fc cform] (-treec x fc cform nil)) ([x fc cform _id] (reify clojure.lang.IFn (invoke [this a] (let [x (walk a x)] (if (tree-term? x) ((composeg (constrain-tree x (fn [t a] ((treec t fc cform) a))) (remcg this)) a) ((composeg (fc x) (remcg this)) a)))) IConstraintId (id [this] _id) IWithConstraintId (with-id [this _id] (-treec x fc cform _id)) IConstraintOp (rator [_] `treec) (rands [_] [x]) IReifiableConstraint (reifyc [_ v r a] (let [x (walk* r x)] `(treec ~x ~cform))) IRelevant (-relevant? [_ a] true) IRunnable (runnable? [_ a] (not (lvar? (walk a x)))) IConstraintWatchedStores (watched-stores [this] #{::subst})))) (defn treec [x fc cform] (cgoal (-treec x fc cform)))``` We should be able to write just: ```(defc treec [x fc cform] clojure.lang.IFn (invoke [this a] (let [x (walk a x)] (if (tree-term? x) ((composeg (constrain-tree x (fn [t a] ((treec t fc cform) a))) (remcg this)) a) ((composeg (fc x) (remcg this)) a)))) IConstraintRands (rands [_] [x]) IReifiableConstraint (reifyc [_ v r a] (let [x (walk* r x)] `(treec ~x ~cform))))``` `defc` should intelligently fill in the details.

### [LOGIC-70] support for defaults in the simple unifier Created: 19/Nov/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 There should be a way to specify a logic var with default values. If it is not unified with something it should unify with the default provided value.

### [LOGIC-68] add Prolog meta-logical predicates bagof, setof, findall Created: 16/Nov/12  Updated: 15/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 This can be done by annotating logic variables and embedding a run within a run by passing in the current substitution, running on it, and extracting out the reified values and unifying it back into the current substitution.

 Comment by Aaron Brooks [ 16/Nov/12 1:23 PM ] I'm working on understanding the answers given for this StackOverflow question: http://stackoverflow.com/questions/7647758/prolog-findall-implementation Comment by Aaron Brooks [ 16/Nov/12 10:02 PM ] For discussion — Initial working patch supporting nested version of 'run-a/'run-a*. Binding symbols must match existing lvars with which vectors of all returned values will be unified. Comment by Aaron Brooks [ 17/Nov/12 4:07 PM ] Should we provide wrappers that emulate each of bagof, setof and findall? I'm still not sold on the current names run-a/run-a*. "a" is really an internal implementation detail. Expect a revised patch with better names when I think of them (any ideas?). Comment by David Nolen [ 17/Nov/12 8:32 PM ] Yes please. Yeah I don't think the names of run-a/etc are critical - implementation details for now until we really understand the implications and it gets some use. Comment by Aaron Brooks [ 21/Nov/12 10:51 AM ] I'm considering simply making run/run* conditionalized on the first argument, using the nesting form if we are being called with a substitution map as the first argument. My current understanding of bagof and findall makes me think they're not worth implementing beyond the nesting run functionality. I'm still thinking about setof which is quite useful and will want help from the infrastructure to be fully efficient. I'll submit a new patch after Thanksgiving. Comment by David Nolen [ 21/Nov/12 10:57 AM ] Excellent, thanks much. Comment by Aaron Brooks [ 06/Dec/12 12:30 AM ] I have not forgotten, I've just gotten swamped. There's a small chance I'll get to this before Christmas, otherwise, it's after the new year. Comment by Aaron Brooks [ 04/Feb/13 5:50 PM ] After a car accident, travel to London and Morocco, getting caught up at work and getting caught up on the apparently very busy stream of core.logic activity (great work!), I'm back on this. I found some bugs in my implementation after porting the patch forwards and realized these issues highlighted my sloppy understanding of some of the semantics I had created. I'm fairly convinced now that we don't want to name this after run or run*. It's too much of a strain to try to make it mean the same thing in a nested context. The current mechanism is still not quite a match for findall/bagof/setof, however, so I'm seeing what a good fit would be. I'll post meaningful thoughts for review as I have them. Comment by David Nolen [ 13/Feb/13 1:50 PM ] Glad to hear you're OK! No worries, will take a patch whenever you get around to one. Comment by Aaron Brooks [ 12/Jun/13 9:03 PM ] Having switched to Datomic which has bagof/setof type aggregation and subqueries (though the switch wasn't for those specifically) I don't know if or when I'll get back to this. Sorry! Comment by David Nolen [ 13/Jun/13 1:36 AM ] No worries! Glad Datomic is working out for you

### [LOGIC-48] fd/in should provide a default domain if none specified Created: 30/Aug/12  Updated: 17/May/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 This domain should probably be (interval 0 Long/MAX_VALUE). In order for this to work this means we should probably accept passing in the vars to assigned domains as a seqable. It would be easy to accept the current way and this new way since if the first arg is not a symbol then the new behavior is being requested. ```(fd/in [x y]) (fd/in [x y z] (interval 0 10))```

### [LOGIC-47] is macro needs to be improved Created: 30/Aug/12  Updated: 15/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 the is macro should work like the following: `(is x (- (+ a b) c))` All locals appearing in the right expression should be walked.

### [LOGIC-44] ex* could expand macros in patterns Created: 19/Jul/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Joe Osborn Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: enhancement, patch, test

 Attachments: exstar-macros.patch Patch: Code and Test

 Description
 So, tagged data structures are probably interesting in a relational context. Say you have a relation with some default logic about dogs: ```(defna friendlyo [Dog-Or-Breed] ([:Spot] succeed) ([:Spike] fail) ([Other-Dog] (fresh [Breed] (dog-breed Other-Dog Breed) (friendlyo Breed))) ([(breed :miniature-dachshund)] fail) ([(breed :golden-retriever)] succeed) ;. . .)``` Assume there's a (defmacro breed [t] `[:breed ~t]). That's nicer than having to drop [:breed :golden-retriever] in there or whatever, since it's compile-time-checkable, less error-prone, reduces duplication, etc. This little patch makes ex* expand macros in patterns so it doesn't treat e.g. (breed :golden-retriever) as introducing a new LVar called "breed". Test also provided.

 Comment by David Nolen [ 19/Jul/12 4:41 PM ] I'm surprised that this doesn't already work. We have support for unifying expressions in the pattern already. Look at line 1230 in tests.clj in the master branch. So this should just work, no need to explicitly support macros as far as I can tell. If it's not working, then there's a bug. Comment by Joe Osborn [ 19/Jul/12 5:18 PM ] At least on 0.7.5, matching against a macro gives a runtime error: ```Exception in thread "main" java.lang.ClassCastException: clojure.core.logic.LVar cannot be cast to clojure.lang.IFn at rl.core\$glyph_\$fn__123\$fn__144\$fn__165\$fn__166\$_inc__167\$fn__168.invoke(core.clj:61) at clojure.core.logic.Substitutions.bind(logic.clj:211) at rl.core\$glyph_\$fn__123\$fn__144\$fn__165\$fn__166\$_inc__167.invoke(core.clj:58) at clojure.core.logic\$fn__1056\$_inc__1057.invoke(logic.clj:1160) at clojure.core.logic\$fn__1056\$_inc__1057.invoke(logic.clj:1160) at clojure.core.logic\$fn__898\$_inc__899.invoke(logic.clj:823) at clojure.core.logic\$fn__890\$fn__891.invoke(logic.clj:828)``` Using a fn instead of a macro gives the same: ```Exception in thread "main" java.lang.ClassCastException: clojure.core.logic.LVar cannot be cast to clojure.lang.IFn at rl.core\$drawable_\$fn__235\$fn__248\$fn__249\$_inc__250\$fn__251.invoke(core.clj:67) at clojure.core.logic.Substitutions.bind(logic.clj:211) at rl.core\$drawable_\$fn__235\$fn__248\$fn__249\$_inc__250.invoke(core.clj:65) at clojure.core.logic\$fn__1056\$_inc__1057.invoke(logic.clj:1160) at clojure.core.logic\$fn__894\$_inc__895.invoke(logic.clj:826) at clojure.core.logic\$fn__1056\$_inc__1057.invoke(logic.clj:1160) at clojure.core.logic\$fn__898\$_inc__899.invoke(logic.clj:823) at clojure.core.logic\$fn__898\$_inc__899.invoke(logic.clj:823) at clojure.core.logic\$fn__898\$_inc__899.invoke(logic.clj:823) at clojure.core.logic\$fn__890\$fn__891.invoke(logic.clj:828)``` Here's (glyph-) for reference (don't mind all the extra [], I have a weird key/value thing because of some conveniences for maintaining fact identity in a temporal database): ```(defna glyph- [Key Val] ([[Thing] [Glyph]] (thing- [Thing]) (on-fire_ *turn* [Thing]) (== Glyph \δ)) ([[Thing] [Glyph]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (glyph- [Type] [Glyph]))) ([[(type-enum :player)] [Glyph]] (== Glyph \@)) ([[(type-enum :dragon)] [Glyph]] (== Glyph \D)) ([[Type] [Glyph]] (== Glyph \?)))``` and type-enum as a macro: `(defmacro type-enum [v] `[:enum :type ~v])` and as a fn: `(defn type-enum [v] [:enum :type ~v])` I'll mess around and see if my example works in HEAD. Comment by Joe Osborn [ 19/Jul/12 5:37 PM ] Same exception with this test case in HEAD (sorry for all the facts): ```(defrel thing- [Thing]) (defrel type- [Thing] [Type]) (fact thing- [0]) (fact thing- [1]) (fact thing- [2]) (fact type- [0] [:player]) (fact type- [1] [:dragon]) (fact type- [2] [:pig]) (defn type-enum [t] [:type t]) (defna drawable- [Key] ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type]))) ([[(type-enum :player)]] succeed) ([[(type-enum :dragon)]] succeed)) (deftest do-fns-work (is (= (run* [q] (drawable- [q])) '(0 1))))``` Now that I look at it, I may be expecting a wrong-format return value, but the point is that I don't even get that far. Using the REPL, I checked out how (defna drawable- . . .) expands (tidied up slightly): ```(def drawable- (clojure.core/fn ([Key] (clojure.core.logic/conda ((clojure.core.logic/fresh [Thing] (clojure.core.logic/== [Thing] Key) (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))) ((clojure.core.logic/fresh [type-enum] (clojure.core.logic/== [(type-enum :player)] Key) succeed)) ((clojure.core.logic/fresh [type-enum] (clojure.core.logic/== [(type-enum :dragon)] Key) succeed))))))``` Note the (clojure.core.logic/fresh [type-enum] . . .) forms, which are exactly what I would not want to see in this case. I'm not really sure why this doesn't work here yet works for the matche test case. Comment by David Nolen [ 19/Jul/12 5:47 PM ] `[(type-enum :dragon)]` This pattern make it seem like you want to match: `[[:type :dragon]]` Note extra level of brackets here. Is this the case? Even so I agree that the expansion doesn't look quite right. We should never descend into a seq form like that. Comment by Joe Osborn [ 19/Jul/12 5:57 PM ] Yes, that's exactly the desired outcome in this case--a tagged value in my naive interpretation. Is the reason it fails whereas the test on :1230 doesn't the fact that it's producing a vector and not a list? Changing the fn to return a list instead of a vector didn't seem to help. My patch, fwiw, doesn't exhibit that behavior (at least for macros, haven't tested it with fns). Comment by David Nolen [ 19/Jul/12 9:11 PM ] What I mean is don't you want the following instead? ```(defna drawable- [Key] ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type]))) ([(type-enum :player)] succeed) ([(type-enum :dragon)] succeed))``` Note that I removed a layer of square brackets. Comment by Joe Osborn [ 20/Jul/12 10:28 AM ] Nope! I actually want both. I'm doing some temporal logic stuff and I wanted some conveniences for "updating" a fluent, so I wanted to distinguish between the "key part" and the "value part" of the arguments. It looks silly for facts with no "value part", but it lets me write procedures and fns something like this: ```(defrel heldo Time Fluent) (defrel ¬heldo Time Fluent) (declare fluent-obtainedo) ; most recent 'held' not terminated by a '¬held', or fail (defn alter-fluent [Time Rel Key NewVal] ;todo: error check, ensure old != new, old obtains, new does not obtain (doseq [old-val (run* [old-val] (fluent-obtainedo Time [Rel Key old-val]))] (fact ¬heldo Time [Rel Key old-val])) (fact heldo Time [Rel Key NewVal])) . . . (fact heldo 0 ['pos [0] [0 0]]) . . . (alter-fluent 1 'pos [0] [1 1])``` And I write all the non-temporal fluents that way too for consistency and to help prevent mistakes. Comment by David Nolen [ 20/Jul/12 2:58 PM ] I'll try to give a closer look at this issue over the weekend. Comment by David Nolen [ 17/Mar/13 7:05 PM ] We're thinking about a more general solution here: http://github.com/clojure/core.logic/wiki/Better-syntax-support

### [LOGIC-43] LVar should print readably Created: 05/Jul/12  Updated: 05/Jul/12

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Alan Malloy Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Currently LVar objects print the same as symbols; they should either print as an unreadable form, or in a way that the reader can read them back in and get an LVar. Attached patch causes them to be read in as LVars. However, (read-string (pr-str lv)) does not compare as equal to lv, because the implementation of .equals relies on their string :name objects being identical? - which they will not be, if one LVar was created by the lvar function, which uses str, and the other created by read-string, which uses String/intern. It seems plausible to say that LVars can't be compared for equality after sending them through strings, but that's awkward and unpleasant. We could instead define LVars to compare their names with = rather than with identical?, but David expressed concern about the performance implications of that change.

### [LOGIC-38] Logic Threading Macro Created: 13/May/12  Updated: 15/Oct/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Jason Jackson Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 This macro was somewhat useful when I was implementing static analysis for a compiler with core.logic. (defmacro ==>> [expr-in & rel-forms] "Thread the expr-in through rel-forms then unify with last rel-forms (the 'out expression'). Example: (==>> [[1]] (firsto) (firsto) x)) ;; 'x' will become bound to value 1 This macro expands to: (fresh [_A _B] (firsto [[1]] _A) (firsto _A _B) (== _B q)) If you imagine that the 'return value' of firsto is its last parameter, then it works just like clojure.core/-> as return value of each form is first argument of the following form."

 Comment by Jason Jackson [ 13/May/12 11:08 AM ] There might be a better name, not sure. Comment by Jason Jackson [ 13/May/12 11:18 AM ] renamed ==>> to ==->

### [LOGIC-35] Core.logic equivalent of multimethods Created: 02/Apr/12  Updated: 28/Dec/12

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Minor Reporter: Gabriel Pickard Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: enhancement

 Description
 I need to define predicates to which I can later (and from other namespaces) attach further clauses (so not just facts). I couldn't find any such functionality in the source. Due to the extensive use of macros, hacking such a system onto core.logic from the outside is extremely difficult, if not impossible (to me at least). I'd love to implement this myself too, if given an OK and rough direction.

 Comment by Gabriel Pickard [ 03/Apr/12 6:27 PM ] I actually did manage to tack on a prototype that covers the basic behavior I would like to see: https://github.com/werg/herpderp/blob/master/src/herpderp/multo.clj I use a set stored in a ref in the defne's metadata to manage dynamic changes to the clauses. Upon changing that set using defclause I use eval to re-define the var using defne. This might not be nice, but allows me to continue developing features against it. Comment by David Nolen [ 28/Dec/12 12:48 AM ] I don't think the current implementation can really support this and I don't think it's wise to try to hack around the current implementation. I'd be willing to consider a comprehensive solution if someone is willing to do the legwork.

### [LOGIC-28] defrel cannot be called inside function Created: 15/Feb/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: Jason Jackson Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: 0001-allow-defrel-to-be-called-from-within-a-function-if-.patch     patch-defrel

 Comment by David Nolen [ 20/Feb/12 2:15 PM ] Can you reformat the patch w/ git so it has the proper attribution information? Thanks! Comment by Jason Jackson [ 13/May/12 10:06 AM ] New patch with attribution info. Sorry about super long turn around time, in the future I should be much faster. Comment by Martin Trojer [ 20/Sep/12 3:32 AM ] This patch solved the exact same problem for me aswell. Cheers... Comment by David Nolen [ 20/Sep/12 10:57 AM ] I've yet to hear a good rationale for this patch. defrel has the same semantics as def and should only exist at the top level. If someone puts more though into what defining a rel dynamically should look like I will consider it. Comment by Jason Jackson [ 20/Sep/12 2:02 PM ] I only implemented this so I could delete relation state. There's probably a better way to do this though. Comment by Martin Trojer [ 21/Sep/12 2:47 AM ] Indeed, a make-rel function would be optimal, then you can def it (or store it somewhere else) at your leisure.

### [LOGIC-26] Generate a better error when adding facts for arities that do not exist Created: 23/Jan/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Minor Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

### [LOGIC-184] requiring pldb issues warning about referring to indexed? Created: 17/Jul/17  Updated: 17/Jul/17

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Trivial Reporter: Michael Fogleman Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: 184-exclude-indexed.patch

 Description
 I required pldb in a namespace and received the following warning: WARNING: indexed? already refers to: #'clojure.core/indexed? in namespace: clojure.core.logic.pldb, being replaced by: #'clojure.core.logic.pldb/indexed?. Seems like refer-clojure exclude indexed? would fix this.

### [LOGIC-179] Document how defn/implicit do with multiple goals does not work Created: 05/Aug/16  Updated: 05/Aug/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Trivial Reporter: Oskar Wickstrom Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: documentation Environment: Clojure 1.8 core.logic 0.8.10

 Attachments: logic-repl.txt

 Description
 Hi! I have a small documentation improvement proposal: When using regular `defn` to create a relation, I've found that an empty (fresh [] ...) is needed if you want to use multiple relations and goals inside your defn:ed relation, otherwise your goals are in the implicit do from defn, and only the last one has any effect. Simple example: {{ defn-logic> (defn test [a b] (== a 1) (== b 2)) #'defn-logic/test defn-logic> (run* [q] (fresh [a b] (== q [a b]) (test a b))) ([_0 2]) defn-logic> (defn test [a b] (fresh [] (== a 1) (== b 2))) #'defn-logic/test defn-logic> (run* [q] (fresh [a b] (== q [a b]) (test a b))) ([1 2]) defn-logic> }} Again, this is perfectly correct and reasonable, but maybe a bit confusing for beginners, in that the implicit do "fails silently". What I'm looking for here is probably just a heads up in the Wiki docs. I couldn't find it, but maybe it exists already? I'd be happy to add it to the documentation and send a PR.

 Comment by Oskar Wickstrom [ 05/Aug/16 6:03 AM ] The REPL session got messed up, now attached as a file instead. Comment by Oskar Wickstrom [ 05/Aug/16 7:48 AM ] Oh, I just found `all` (http://clojuredocs.org/clojure.core.logic/all) which seems to be preferred over `(fresh [] ...)`.

### [LOGIC-178] Example of unifier on wiki uses wrong syntax? Created: 11/Jan/16  Updated: 11/Jan/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Task Priority: Trivial Reporter: Alex Memory Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: wiki Environment: [org.clojure/core.logic "0.8.10"]

 Description
 The example of clojure.core.logic.unifier/unifier on the Features wiki page is (unifier '(?x ?y ?z) '(1 2 ?y)) ; (1 2 _.0) Shouldn't it be something like (unifier ['(?x ?y ?z) '(1 2 ?y)]) ; {?y 2, ?x 1, ?z 2} ?

### [LOGIC-169] equality of non-unique lvars broken for clojure 1.7 Created: 25/Jun/15  Updated: 05/Aug/15

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Trivial Reporter: Maik Schünemann Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: clojure-1.7

 Attachments: 0001-alter-equality-of-non-unique-lvars-for-clojure-1.7.patch Patch: Code and Test

 Description
 clojure 1.7 changes the interning of strings when creating symbols, as is described here https://github.com/clojure/clojure/blob/master/changes.md#23-keyword-and-symbol-construction Therefore, two non-unique lvars with the same name don't have to be equal anymore with the current Lvar equality method which checks (identical? name (:name o)). This is causing expresso, which relies on non-unique lvars for the rule engine to fail with clojure 1.7 changing the identical? to a = fixes the issue.

### [LOGIC-164] Guard against arity missmatches between rels, facts and retractions Created: 10/Dec/14  Updated: 27/Dec/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Enhancement Priority: Trivial Reporter: Reid McKenzie Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Attachments: 0001-Catch-arity-missmatches-between-rels-facts.patch

 Description
 This patch adds arity checking to relations, facts and retractions so that if a user specifies that a rel "foo" shall be 3-tuple in the def-rel form it will be illegal to add a 4-tuple as a fact to the db. This protects the state of the DB against a class of user errors which would otherwise silently fail through. This is more a work proposal than anything, as it may well be legitimate to have a variable arity relation. I would just consider such a construct suspect, and this patch supports the way I've approached pldb.

 Comment by David Nolen [ 21/Dec/14 2:12 PM ] Interesting, thanks for the patch. Will think about it. Comment by Norman Richards [ 27/Dec/14 3:13 PM ] Many of our pldb relations have a large number of arguments. Being able to detect incorrect declarations early would not be bad.

### [LOGIC-157] A warning is thrown regarding the redefinition of record? in clojure 1.6.0 Created: 27/Mar/14  Updated: 15/May/14

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Task Priority: Trivial Reporter: Justin Overfelt Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None Environment: Linux x64

 Description
 Clojure 1.6.0 adds a record? function that has the same implementation as the one in clojure.core.logic. As a result, a warning is shown when the code in the core.logic namespace is evaluated under clojure 1.6.0. Since the two functions have the same implementation, this is purely a cosmetic issue.

 Comment by Justin Overfelt [ 15/May/14 7:17 PM ] I saw that this is now fixed in master - thanks! This also breaks AOT compilation if used with clojure 1.6.0 as referenced in CLJ-1241. Is there a timeline for a 0.8.8 release? Comment by David Nolen [ 15/May/14 7:22 PM ] I will try to cut a release next week. Comment by Justin Overfelt [ 15/May/14 7:25 PM ] Awesome - thank you!

### [LOGIC-96] relevant-var? logic incorrectly discards a vars constraint set Created: 04/Jan/13  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

 Type: Defect Priority: Trivial Reporter: David Nolen Assignee: David Nolen Resolution: Unresolved Votes: 0 Labels: None

 Description
 Need a patch and a test showing that the vars constraint set is preserved.

 Comment by David Nolen [ 07/Jan/13 7:04 PM ] Currently dead code so this is not a blocker.

Generated at Thu Jan 18 10:17:49 CST 2018 using JIRA 4.4#649-r158309.