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.
Related
I'm representing a simple data-base in Clojure's core.logic.
There are two predicates : page(p) and link(p,q).
page(p) represents the existence of pages in a wiki called p
link(p,q) represents that page p contains a link to page q.
I'm now trying to query this database to find
a) broken links (that is links in page p, for which there's no page q), and
b) orphaned pages (pages that have no links to them)
My code for these queries is this :
(defn broken-links []
(pldb/with-db #facts
(logic/run* [p q]
(link p q)
(logic/nafc page q)
)))
(defn orphans []
(pldb/with-db #facts
(logic/run* [p q]
(logic/nafc link p q)
(page q)
)))
broken-links is working as expected, but orphans is giving me a list of :- symbols.
I'm assuming that this has something to do with nafc's limitation. According to the documentation :
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.
And these are "delayed" because they are not "ground".
Can someone explain what ground really means here. I know it's "has no free variables" but I still don't really understand what that means in this context.
Secondly, how should I write this orphans query?
In the context of nafc, non-ground inputs are handled by giving non-ground outputs, so to get meaningful answers your inputs "must be ground." It cannot negate a constraint involving non-ground values.
For example, this program gives all possible values of q where q satisfies emptyo:
(run* [q]
(emptyo q))
;=> (())
If we ask for all possible values of q that don't satisfy emptyo we get this:
(run* [q]
(nafc emptyo q))
;=> ((_0 :- (clojure.core.logic/nafc #object[clojure.core.logic$emptyo 0x212442c1 "clojure.core.logic$emptyo#212442c1"] _0)))
A simplified phrasing is ((_0 :- (nafc emptyo _0))), which means there's only one answer but it could be any value that satisfies the RHS constraint. The logic program can't give us ground values because it doesn't know every possible non-empty list.
Here's an example DB setup for completeness:
(pldb/db-rel page q)
(pldb/db-rel link p q)
(def facts
(pldb/db
[page 'a]
[page 'b]
[page 'z]
[link 'a 'b]
[link 'b 'c]))
And your working broken-link program:
;; find links to non-pages
(pldb/with-db facts
(run* [p q]
(link p q)
(nafc page q)))
;=> ([b c])
Here's a way to write the orphaned page program:
;; find pages without incoming links
(pldb/with-db facts
(run* [q]
(fresh [p]
(page q)
(conda
[(link p q) fail]
[succeed]))))
;=> (a z)
The negation here is expressed with conda to form a kind of if-else logic: if there is a link to page q we fail else we succeed.
Also note the use of fresh to introduce a logic variable p that isn't part of the desired answer output, since we only care about orphaned page values.
Does anyone know how to solve the compressing of big lists of Common Lisp
i'm getting (# # # #) (# 0 #) kind of lists instead of ((black round full) (white square empty)...) as it should
Lisp is compressing my lists and I want to send to files without the compression.
How?
Maybe *print-circle* is set to T. Hard to say, given your vague description.
CL-USER 7 > (let ((foo '(BRANCA REDONDA BAIXA CHEIA))) (list foo foo))
(#1=(BRANCA REDONDA BAIXA CHEIA) #1#)
CL-USER 8 > (setf *print-circle* nil)
NIL
CL-USER 9 > (let ((foo '(BRANCA REDONDA BAIXA CHEIA))) (list foo foo))
((BRANCA REDONDA BAIXA CHEIA) (BRANCA REDONDA BAIXA CHEIA))
The relevant variable for this is *print-level*. It is unusual that it is set to such a low value.
Lispworks additionally has dbg:*debug-print-level* and hcl:*trace-print-level* which it uses for debugging and tracing output, respectively.
In order to print everything, bind *print-level* to nil. This can be done either explicitly, as in
(let ((*print-level* nil))
(print my-stuff))
or by using the keyword parameter of write:
(write my-stuff :level nil)
Found the problem, LispWorks starts to get memory full and start to use # to save memory. if I restart the Lispworks (sometimes works, sometimes don't) it will show the full list.
Thanks for the help!
I'm sure this must be a stupid question, but how do I deal with a list of goals in core.logic?
(run* [g]
(f))
(defn f[]
'(succeed succeed))
Will throw an exception, as run* doesn't expect a list. I feel like I need to do (apply all (f)), but all is a macro, so that doesn't work.
What's the solution? I feel I'm missing something trivially obvious here...
Adrian.
If your goals take only one parameter then you can use everyg as suggested in another answer. Basically (everyg g coll) is a goal that succeeds when the goal g succeeds on each element of coll. Therefore coll is not a collection of goal, but a collection of single parameter to g. This still helps because, combined with project, this makes it possible to write:
(defn applyg
[g v]
"Goal that succeeds when the goal g applied to v succeeds.
Non-relational as g must be ground."
(project [g] (everyg g [v])))
And when there is a collection of goals to apply:
(defna apply-collg
[gcoll v]
([() _])
([[gh . gt] _] (applyg gh v) (apply-collg gt v)))
Using pred to make a goal out of a clojure predicate, it becomes easy to test:
(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 1))
=> (_0)
(run* [q] (apply-collg [#(pred % pos?) #(pred % odd?)] 2))
=> ()
If the goals to apply take 2 or more parameters then one just need to transform them into goals taking a single collection of parameters.
I'm still quite new to core.logic so comments are welcomed.
This seems to work:
(everyg succeed (f))
I'm still interested if there is a better or at least more idiomatic solution.
I haven't tried this, but looking at http://www.clojure.net/2012/10/02/More-core.logic/ there seems to be a similar thing using this construct:
(def f (all
succeed
succeed))
I see some examples that show we can get a nice head/tail destructuring of a sequence in clojure as follows:
(if-let [[x & xs] (seq coll)]
However I assume this won't work as desired for lazy sequences because this puts the values into a vector, which aren't lazy. I tried changing the vector form to a list form, and it gave me binding errors, quoted or not.
Without having binding like this, it seems that if I've got a lazy sequence where each element was a computationally-intensive equation of the previous element, I'd have to do that computation twice to get the head and tail as separate statements, right?
(let [head (first my-lazy-seq) ;; has to calculate the value of head.
tail (rest my-lazy-seq)] ;; also has to calculate the value of head to prepare the rest of the sequence.
Is there any way around this, or am I making an incorrect assumption somewhere?
user=> (let [[x & xs] (range)] [x (take 10 xs)])
[0 (1 2 3 4 5 6 7 8 9 10)]
xs is still a lazy seq, so you can use the destructuring with no problems. This will force the first element of xs, though. (Destructuring uses vector notation, but it doesn't necessarily use vectors under the covers.)
With respect to your second question: lazy seqs cache their results, so your second option would also work without extra recalculation. The head will only be calculated once.
The binding vector [x & xs] isn't actually constructing a vector at runtime. It's just the notation used for destructuring into head & tail.
So it works fine on infinite sequences:
(if-let [[x & xs] (range)]
(apply str x (take 9 xs)))
=> "0123456789"
The destructuring form is actually producing a lazy sequence in this case, which you can observe as follows:
(if-let [[x & xs :as my-seq] (range)]
(class my-seq))
=> clojure.lang.LazySeq
(defn square [x]
(do
(println (str "Processing: " x))
(* x x)))
(println (map square '(1 2 3 4 5)))
Why is the output
(Processing: 1
Processing: 2
1 Processing: 3
4 Processing: 4
9 Processing: 5
16 25)
not
(Processing: 1
1 Processing: 2
4 Processing: 3
9 Processing: 4
16 Processing: 5
25)
?
Because map is lazy. It uses lazy-seq under the covers, which pre-caches the result of rest. So you see the two println statements appear when your code grabs the first value of the map sequence.
See also this blog post: Lazy Sequences
println uses [[x & xs] xs] destructuring form in its implementation. This is equivelent to [x (first xs), xs (next xs)] and next is less lazy than rest, so it realizes the two items before printing the first.
For example,
=> (defn fn1 [[x & xs]] nil)
#'user/fn1
=> (fn1 (map square '(1 2 3 4 5)))
Processing: 1
Processing: 2
nil
Are you like me to learn with code snippets? Here are some.
Let's have a look at the documentation of map.
user=> (doc map)
-------------------------
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
Returns a lazy sequence consisting of the result of applying f to the
set of first items of each coll, followed by applying f to the set
of second items in each coll, until any one of the colls is
exhausted. Any remaining items in other colls are ignored. Function
f should accept number-of-colls arguments.
nil
map returns a lazy sequence (you should already read the references given by #noahz). To fully realize the lazy sequence (it's often not a good practice as the lazy seq might be infinite and hence never end) you can use dorun or doall.
user=> (doc dorun)
-------------------------
clojure.core/dorun
([coll] [n coll])
When lazy sequences are produced via functions that have side
effects, any effects other than those needed to produce the first
element in the seq do not occur until the seq is consumed. dorun can
be used to force any effects. Walks through the successive nexts of
the seq, does not retain the head and returns nil.
nil
user=> (doc doall)
-------------------------
clojure.core/doall
([coll] [n coll])
When lazy sequences are produced via functions that have side
effects, any effects other than those needed to produce the first
element in the seq do not occur until the seq is consumed. doall can
be used to force any effects. Walks through the successive nexts of
the seq, retains the head and returns it, thus causing the entire
seq to reside in memory at one time.
nil
Although they seem similar they are not - mind the difference with how they treat the head of the realized sequence.
With the knowledge, you can influence the way the map lazy sequence behaves with doall.
user=> (defn square [x]
#_=> (println (str "Processing: " x))
#_=> (* x x))
#'user/square
user=> (doall (map square '(1 2 3 4 5)))
Processing: 1
Processing: 2
Processing: 3
Processing: 4
Processing: 5
(1 4 9 16 25)
As you might've noticed I also changed the definition of the square function as you don't need do inside the function (it's implicit with the defn macro).
In the Clojure Programming book, there's the sentence you may like for the case of '(1 2 3 4 5):
"Most people simply use a vector literal for such cases, within which member expressions
will always be evaluated."
Instead of copying the relevant sections to support this statement, I'd rather recommend the book as it's worth the time and money.