<< Back to previous view

[LOGIC-156] Two consecutive calls to run* return different results Created: 22/Feb/14  Updated: 05/Mar/14

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: File core.clj     File core.clj    

 Description   

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



 Comments   
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.





[LOGIC-155] Dynamic variables are not seen inside a logic query Created: 28/Jan/14  Updated: 06/Jul/14  Resolved: 06/Jul/14

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

Type: Defect Priority: Major
Reporter: Reinout Stevens Assignee: David Nolen
Resolution: Declined Votes: 0
Labels: binding, bug, dynamic
Environment:

core.logic version 0.8.6
clojure version 1.5.1



 Description   

core.logic does not work correctly with dynamic variables, as illustrated by the following code:

(def ^:dynamic dvar 'original)
(binding [*dvar* 'changed]
(logic/run* [?x] (logic/== ?x dvar)))

;;outputs (original), expected (changed)

To the best of my knowledge this used to work in older versions, although I do not know when the behaviour changed.



 Comments   
Comment by David Nolen [ 28/Jan/14 10:56 AM ]

This is because core.logic became lazy (been a year now? . There are now non lazy run variants or you can use doall yourself.





[LOGIC-127] Swapping noms turns maps (and other collections) into seqs Created: 02/Apr/13  Updated: 28/Jul/13  Resolved: 10/Apr/13

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

Type: Defect Priority: Major
Reporter: Jiří Maršík Assignee: Nada Amin
Resolution: Completed Votes: 0
Labels: bug, nominal

Attachments: Text File INomSwap-vectors-maps.patch     Text File INomSwap-vectors-maps-with-test.patch    
Approval: Accepted

 Description   

When I unify two binders, the swapping procedure turns all the maps inside the body into seqs of key/value pairs, which do not unify with maps, leading to the following trickiness:

(require '[clojure.core.logic :as l])
(require '[clojure.core.logic.nominal :as n])
(l/run* [q]
  (l/fresh [body]
    (n/fresh [a b]
      (l/== (n/tie a {:k a}) (n/tie b body))
      (l/== {:k q} body))))
;=> ()
; Expected (a_0)

For my purposes, fixing this by adding two new implementations of INomSwap for vectors and maps works well.



 Comments   
Comment by Jiří Maršík [ 02/Apr/13 11:14 AM ]

Oops, sorry for the malformatted code snippet. Here it is inside a code tag.

(require '[clojure.core.logic :as l])
(require '[clojure.core.logic.nominal :as n])
(l/run* [q]
        (l/fresh [body]
                 (n/fresh [a b]
                          (l/== (n/tie a {:k a}) (n/tie b body))
                          (l/== {:k q} body))))
;=> ()
; Expected (a_0)
Comment by David Nolen [ 02/Apr/13 11:22 AM ]

This seems like a easy one to fix, perhaps Nada can see quicker than I can. If not I can take a look.

Also your patch may very well solve the issue best, feel free to attach it to the ticket. We won't be able to apply it until you've submitted your Contributor Agreement - if you have a free moment please send it in. Thanks!

Comment by Jiří Maršík [ 02/Apr/13 11:48 AM ]

The patch that I use to fix the issue. I haven't signed the CA, but I would definitely like to. Might take a while to arrive though, since I'm in Europe and I'm lazy.

Comment by Nada Amin [ 03/Apr/13 2:36 AM ]

The patch LGTM. I would also add a test from the ticket example.

I guess we have to wait until the CA arrives, now.

Comment by Jiří Maršík [ 03/Apr/13 4:28 AM ]

I have also added the test case, the new patch INomSwap-vectors-maps-with-test.patch contains both the fix and the test case. I have just signed the CA and I plan to post it today.

Comment by Jiří Maršík [ 09/Apr/13 10:55 AM ]

OK, the CA has arrived and been processed.

http://clojure.org/contributing

  • Jiri Marsik (jirkamarsik)
Comment by Nada Amin [ 10/Apr/13 3:32 AM ]

Applied as https://github.com/clojure/core.logic/commit/d73c836c0d4bab2af12b4bdedb31daad4a661fb6

Thanks!





[LOGIC-116] ClassCastException in core.logic depending on ordering Created: 08/Mar/13  Updated: 28/Jul/13  Resolved: 17/Mar/13

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

Type: Defect Priority: Major
Reporter: Matthew O. Smith Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: 0.8.0, bug

Attachments: File corefail.clj    

 Description   

I have two files:
1 -https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/coresucceed.clj
2 -https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/corefail.clj

The first one compiles and runs fine. The second throws a ClassCastException. The only difference is that rule-0 is moved in the second file.



 Comments   
Comment by David Nolen [ 11/Mar/13 7:40 AM ]

There's far too much context here. Do you have a minimal case? Thanks much!

Comment by Matthew O. Smith [ 11/Mar/13 9:15 AM ]

Here is the stack trace. I will try to narrow it down further.

java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IPersistentSet
at clojure.core$disj.invoke (core.clj:1420)
clojure.core.logic.ConstraintStore/fn (logic.clj:339)
clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
clojure.core.protocols/fn (protocols.clj:94)
clojure.core.protocols$fn_5854$G5849_5863.invoke (protocols.clj:19)
clojure.core.protocols$seq_reduce.invoke (protocols.clj:31)
clojure.core.protocols/fn (protocols.clj:60)
clojure.core.protocols$fn_5828$G5823_5841.invoke (protocols.clj:13)
clojure.core$reduce.invoke (core.clj:6030)
clojure.core.logic.ConstraintStore.remc (logic.clj:338)
clojure.core.logic$remcg$fn__3272.invoke (logic.clj:2374)
clojure.core.logic$BANG$reify_3422.invoke (logic.clj:2719)
clojure.core.logic$composeg$fn__2569.invoke (logic.clj:1141)
clojure.core.logic$composeg$fn__2569.invoke (logic.clj:1142)
clojure.core.logic$run_constraint$fn__3285.invoke (logic.clj:2397)
clojure.core.logic$fix_constraints.invoke (logic.clj:2424)
clojure.core.logic$run_constraints$fn__3290.invoke (logic.clj:2434)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$run_constraints_STAR_$fn__3296.invoke (logic.clj:2444)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$run_constraints_STAR_$fn__3296.invoke (logic.clj:2446)
clojure.core.logic$EQEQ$fn__2647.invoke (logic.clj:1255)
clojure.core.logic.Substitutions.bind (logic.clj:612)
clojure.core.logic$rembero$fn_3465$_inc3466$fn3475$fn3476$_inc3477$fn3478$_inc_3479.invoke (logic.clj:2790)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2633$_inc_2634.invoke (logic.clj:1223)
clojure.core.logic$eval2628$fn_2637$_inc_2638.invoke (logic.clj:1220)
clojure.core.logic$eval2628$fn_2629$fn_2630.invoke (logic.clj:1225)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:67)
clojure.lang.RT.seq (RT.java:473)
clojure.core$seq.invoke (core.clj:133)
clojure.core$take$fn__4112.invoke (core.clj:2501)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.LazySeq.first (LazySeq.java:82)
clojure.lang.RT.first (RT.java:566)
clojure.core$first.invoke (core.clj:55)
clojure.pprint$pprint_reader_macro.invoke (dispatch.clj:50)
clojure.pprint$pprint_list.invoke (dispatch.clj:77)
clojure.lang.MultiFn.invoke (MultiFn.java:163)
clojure.pprint$write_out.invoke (pprint_base.clj:194)
clojure.pprint$pprint_vector$fn__7949.invoke (dispatch.clj:83)
clojure.pprint$pprint_vector.invoke (dispatch.clj:82)
clojure.lang.MultiFn.invoke (MultiFn.java:163)
clojure.pprint$write_out.invoke (pprint_base.clj:194)
clojure.pprint$pprint$fn__7359.invoke (pprint_base.clj:250)
clojure.pprint$pprint.invoke (pprint_base.clj:248)
clojure.pprint$pprint.invoke (pprint_base.clj:245)
logicpuzzles.corefail$show.invoke (corefail.clj:9)
logicpuzzles.corefail$eval3796.invoke (corefail.clj:153)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.load (Compiler.java:6952)
user$eval971.invoke (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__544.invoke (interruptible_eval.clj:56)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:41)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn_585$fn_587.invoke (interruptible_eval.clj:171)
clojure.core$comp$fn__4034.invoke (core.clj:2278)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__578.invoke (interruptible_eval.clj:138)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
java.lang.Thread.run (Thread.java:722)

Comment by Matthew O. Smith [ 11/Mar/13 9:24 AM ]

I tightened up the fail case https://github.com/m0smith/LogicPuzzles/blob/master/src/logicpuzzles/corefail.clj . Is that enough?

Comment by David Nolen [ 11/Mar/13 10:17 AM ]

Thanks can you add the failing code to the ticket as an attachment? Thanks.

Comment by Matthew O. Smith [ 11/Mar/13 6:23 PM ]

corefail.clj exhibits the error

Comment by David Nolen [ 17/Mar/13 6:29 PM ]

fixed, http://github.com/clojure/core.logic/commit/7e4d0b6b71707e248fd4d0de3f6c090b50a18624





[LOGIC-75] Combining maps and finite domains in core.logic returns only one result Created: 11/Dec/12  Updated: 28/Jul/13  Resolved: 12/Dec/12

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

Type: Defect Priority: Major
Reporter: Frederik De Bleser Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bug
Environment:

Clojure 1.4.0, core.logic 0.8.0-beta2



 Description   

I'm trying to combine maps with finite domains with some odd results.

A simple query using finite domains correctly returns all values:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q x)))
	
	;=> (1 2 3)

But putting this result in a map returns only the first value:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q {:foo x})))
	
	;=> ({:foo 1})

FYI this works with vectors:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q [x])))
	
	;=> ([1] [2] [3])

But lcons seems to fail as well:

(run* [q]
	  (fresh [x]
	    (infd x (interval 1 3))
	    (== q (lcons x 'foo))))
	
	;=> ((1 . foo))


 Comments   
Comment by David Nolen [ 12/Dec/12 11:53 AM ]

fixed, http://github.com/clojure/core.logic/commit/c96402f3e60b1118446b3e681d98e444e4ce417d





[LOGIC-74] Bug in conde (ClojureScript) Created: 26/Nov/12  Updated: 28/Jul/13  Resolved: 17/Mar/13

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

Type: Defect Priority: Minor
Reporter: Kevin De Valck Assignee: David Nolen
Resolution: Declined Votes: 0
Labels: bug
Environment:

[org.clojure/clojure "1.4.0"]
[org.clojure/core.logic "0.8.0-beta2"]



 Description   

While working on a project I found a somewhat strange behaviour. I reworked the problem in some simple predicate. Let's take this predicate foobad.

(defn foobad 
  [?bar]
  (l/project [?bar]
    (l/fresh [?var]
      (l/conde 
        [(l/== true (instance? js/Array ?bar))
          (membero ?var (seq ?bar))]))))

When running (l/run* [?f] (foobad 0)) it produces this error:

#<Error: No protocol method ISeqable.-seq defined for type number: 0>

Because 0 is not an instance of Array it should not be entering that conde clause where it tries (seq 0).

With this workaround we get a normal behaviour:

(defn foo 
  [?bar]
  (l/project [?bar]
    (l/fresh [?var]
      (l/conde 
        [(l/== true (instance? js/Array ?bar)) 
         (fresh [?s]
          (l/== ?s (seq ?bar))
          (membero ?var ?s))]))))

Running (l/run* [?f] (foo 0)) gives us (), which is what we expect.
While 0 is clearly not an instance of Array that conde clause is still executed resulting in previous error.



 Comments   
Comment by David Nolen [ 28/Dec/12 12:49 AM ]

I'm assuming this is referring the ClojureScript version of core.logic?

Comment by David Nolen [ 17/Mar/13 7:00 PM ]

This is not a bug. Goals do not delay evaluation in this way.





[LOGIC-52] Bug in finite domains (+fd, infd) Created: 10/Sep/12  Updated: 28/Jul/13  Resolved: 26/Oct/12

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

Type: Defect Priority: Major
Reporter: naeg Assignee: David Nolen
Resolution: Completed Votes: 1
Labels: +fd, bug, finite-domains, infd
Environment:

Clojure 1.4, core.logic 0.8-alpha3



 Description   

When running the code:

(run* [q]
(fresh [a b c d]
(infd a b c d (domain 1 3 4 5))
(+fd b 1 a)
(+fd c 1 b)
(+fd d 1 c)
(== q [a b c d])))

I get the ouput:

([5 4 3 1])

But I would expect:

()

Because [5 4 3 1] is no sequence where the next element is always one number higher than the one before.

It seems to me like +fd behaves as it would take the next element in the domain, instead of taking the next higher number (I hope I didn't misunderstand +fd or infd).



 Comments   
Comment by naeg [ 11/Sep/12 4:48 PM ]

There is workaround using membero:

(run* [q]
  (fresh [a b c d]
    (everyg #(membero % [1 3 4 5]) [a b c d])
    (+fd b 1 a)
    (+fd c 1 b)
    (+fd d 1 c)
    (== q [a b c d])))

=> ()

Note that this is quite a lot slower than it would be with infd.

Comment by David Nolen [ 26/Oct/12 1:03 AM ]

This is fixed try the latest 0.8.0 beta





Generated at Thu Nov 27 10:18:08 CST 2014 using JIRA 4.4#649-r158309.