core-logic

tsdh 2015-07-28T06:15:15.000017Z

@jballanc: Yes, in the code, b could be anything as long as 1 and 3 are member of the vector q and a is 1 or c is 3. So with the 8th result, there's no way to complete it to a solution, no matter what you insert for b.

tsdh 2015-07-28T09:19:05.000018Z

Does someone have a minimal example showing the difference between conda and condu? As far as I understand,

(run* [x y]
  (conda  ;; or condu
   [(== x 1) (membero 2 y)]
   [(== x 2) (== y 3)]))
should blow the stack whereas it should work with condu and deliver ([1 (2)]). But actually it also blows the stack with condu.

tsdh 2015-07-28T09:20:57.000019Z

Well, with condu it might also return ([1 #{2}]) or ([1 [2]]) since the collection type isn't fixed, and of course the collection doesn't need to be minimal although that would make sense.

tsdh 2015-07-28T09:29:03.000020Z

Or with a much simpler example:

(defn y-or-n [x]
  (conde
   [(== x :y)]
   [(== x :n)]))

(run* [x y]
  (condu
   [(== x 1) (y-or-n y)]
   [(== x 2) (== y 3)]))
;;=> ([1 :y] [1 :n])
I had expected to get only ([1 :y]). Why the second solution? condu should succeed at most once for any goal in the clause it committed to, no?

tsdh 2015-07-28T09:46:09.000022Z

Hm, it works when I swap the two goals in the first clause. So it seems that only the head goal has the once-semantics.

jballanc 2015-07-28T13:22:28.000023Z

tsdh: I implemented FizzBuzz with core.logic (don’t ask), and made use of condu (in the form of defnu) - https://github.com/jballanc/logicbuzz/blob/master/src/logicbuzz/core.clj#L17

jballanc 2015-07-28T13:25:58.000025Z

essentially, as I understand it, you’re building up a tree of solutions: first make the first condition pass, then cycle back and fill in any remaining fresh vars, then make the second condition pass, then cycle back and fill remaining fresh, etc.

jballanc 2015-07-28T13:26:19.000026Z

with condu, if you can make the first condition pass, then you fill the remaining fresh vars and stop

jballanc 2015-07-28T13:26:30.000027Z

if you can’t, then you try the second, and so on

tsdh 2015-07-28T13:28:53.000028Z

@jballanc: I think with your fizzbuzzo you can use defna and defnu. Both commit to a clause as soon as the head goal succeeds.

tsdh 2015-07-28T13:29:13.000029Z

@jballanc: And in your case, x is always ground.

jballanc 2015-07-28T13:30:14.000030Z

it’s been a while, but I think I tried defna and didn’t have success...

tsdh 2015-07-28T13:31:45.000031Z

@jballanc: The difference with conda/`defna` versus condu/`defnu` only shows up when the head goal of a clause may produce multiple solutions. With the former, all of them are considered, with the latter, only the first one is considered. Thus, some programs which diverge with conda may terminate with condu.

jballanc 2015-07-28T13:32:09.000032Z

hmm…ok

tsdh 2015-07-28T13:32:50.000033Z

At least that's what I've read in W. Byrd's thesis and validated with experimentation here.

jballanc 2015-07-28T13:37:49.000034Z

ok, yeah, stated that way I think it matches with what I’ve found in the past

jballanc 2015-07-28T13:38:21.000035Z

(that FizzBuzz solution was a lot of trial and error to get everything done with only using core.logic)