I'm doing clojure/core.logic koans and stuck on this one:
"Here we give run a specific number to control how many answers we get. Think
carefully. Is there only one list in the universe that satisfies this relation?
Are there infinitely many?"
(= (run 1 [q]
(membero 'cat q))
[__])
Running (run 1 [q] (membero 'cat q))
in the REPL said me that the answer is ((cat . _.0))
. I'm not quite sure what the dot in the middle means, but anyway, sticking '(cat . _.0)
instead of the __
placeholder in the original koan doesn't help (assertion still fails). Could you please point me to the right direction? And also explain what the dot between cat
and _.0
means? My guess is that it means what follows (i.e. _.0
) is a tail of any length, but I'm not 100% sure.
=== UPDATE
amalloy pointed me to the right direction (thank you, sir!). lcons
does the trick:
(= (run 1 [q]
(membero 'cat q))
[(lcons 'cat '_.0)])
And a bit of REPL:
user=> (lcons 'cat '_.0)
(cat . _.0)
user=> '(cat . _.0)
(cat . _.0)
user=> (= '(cat . _.0) (lcons 'cat '_.0))
false
The dot is used to represent, well, dotted lists. According to Wikipedia, a dotted list is a kind of improper lists, where another kind is a circular list. So, in the REPL session above, the first list was a dotted list with two elements ('cat
and '_.0
), whereas the second list was a proper list with three elements ('cat'
, '.
and '._0
). Their string representation are the same, but nevertheless they are different.
The
(a . b)
notation is a carryover from other lisps which use cons cells to build improper lists. You are correct that it means "the symbol cat followed by any list of any length", but really it's a printed representation of a core.logic LCons value. There's no easy literal you can type to produce a value of that type, so you can't really do comparisons against it with values of your own. However, I would expect that an LCons is seqable, so you could compare(first the-thing)
to'cat
, and so on.