@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
.
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
.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.
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?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.
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
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.
with condu
, if you can make the first condition pass, then you fill the remaining fresh vars and stop
if you can’t, then you try the second, and so on
@jballanc: I think with your fizzbuzzo
you can use defna
and defnu
. Both commit to a clause as soon as the head goal succeeds.
@jballanc: And in your case, x
is always ground.
it’s been a while, but I think I tried defna
and didn’t have success...
@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
.
hmm…ok
At least that's what I've read in W. Byrd's thesis and validated with experimentation here.
ok, yeah, stated that way I think it matches with what I’ve found in the past
(that FizzBuzz solution was a lot of trial and error to get everything done with only using core.logic
)