Clojure core.logic : nafc and ground - clojure

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.

Related

pseudo-relation in core.logic

In core.logic of function, I see the below definition for clojure.core.logic/everyg.
A pseudo-relation that takes a coll and ensures that the goal g
succeeds on every element of the collection.
What exactly a pseudo-relation means in this context?
Here's a good explanation of relational (and non-relational): What does non-relational mean in practice for core.logic? Another bit of background is everyg was renamed from everyo in this commit because the o suffix should only used for relations.
One property of relational goals is that they can contribute answers when all/some/none of their inputs are non-ground. conso is relational and so we can ask what are the values that satisfy the relation where l is a prepended to d, where all variables are fresh:
(run* [a d l] (conso a d l))
=> ([_0 _1 (_0 . _1)])
This tells us a (_0) is fresh, d (_1) is fresh, and l ((_0 . _1)) is a prepended to d. While none of these values are ground, we can still see the relationship between them in the answer.
The same is not true for everyg:
(run* [g coll] (everyg g coll)) ;; Don't know how to create ISeq from: clojure.core.logic.LVar
everyg can't tell us what the relationship between g and coll is, nor can it tell us what g or coll might be if we supply either ground value:
(run* [coll] (everyg succeed coll)) ;; throws
(let [coll (repeatedly 3 lvar)] ;; throws too
(run* [g]
(everyg g coll)))
While everyg itself isn't a relation, you can pass it a goal g and coll of fresh and/or ground variables:
(let [coll (cons 1 (repeatedly 2 lvar))] ;; 1 prepended to two fresh logic vars
(run* [q]
(== q coll)
(everyg #(fd/in % (fd/domain 0 1)) coll)))
=> ((1 0 0) (1 1 0) (1 0 1) (1 1 1))
This example will give the same answers regardless of the position of the everyg goal, which is another property of relational goals.
And we can pass the conso relation to everyg with all fresh logic variables and still see the relationship in the answer, exactly as it was above with the conso example:
(run* [a d q]
(everyg #(conso a d %) [q]))
=> ([_0 _1 (_0 . _1)])
So with some caveats, everyg can be used relationally which is why I think it's considered pseudo-relational rather than non-relational.

How to deal with list of goals in core.logic

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))

Why (= (run 1 [q] (membero 'cat q)) ['(cat . _.0)]) is false?

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.

Using core.logic to solve the sum product riddle

So I've been trying to teach myself clojure and core.logic and decided to try and implement a solution to the sum product problem (http://en.wikipedia.org/wiki/Impossible_Puzzle).
So far I've implemented the first two steps.
(ns sum-product-problem.core
(:refer-clojure :exclude [==])
(:use clojure.core.logic)
(:require [clojure.core.logic.fd :as fd]))
(def non-unique-factors
(tabled [product]
(fresh [p q x y]
(fd/in p q x y (fd/interval 2 99))
(fd/>= q p)
(fd/* p q product)
(fd/>= y x)
(fd/* x y product)
(fd/distinct [p x]))))
(defn inscruitable-summands [sum x]
(fresh [y product]
(conde
[(fd/> (* 2 x) sum)]
[(fd/in y (fd/interval 2 99))
(fd/+ x y sum)
(fd/* x y product)
(non-unique-factors product)
(inscruitable-summands sum (+ x 1))])))
(defn solution []
(run* [q]
(fd/in q (fd/interval 17 17))
(inscruitable-summands q 2)))
This seems to give the correct answer when the domain is limited to a single number in (solution) but if I extend that domain it immediately stops working.
The results when searching over a single member domain also contains the answer multiple times. It seems to be caused by each recursion of inscruitable-summands but I'm not really sure why.
Finally, I was hoping someone could take a quick look at my non-unique-factors function. It feels like a bit of a bodge and I was wondering if anyone could suggest a better alternative?
Thanks for the help,
Dean
I don't believe this puzzle is solvable with CLP(FD) facilities alone (though someone better versed in Prolog may be able to answer this one), solutions I've seen in Prolog require some form of subquery facility like like setof.

Expressing that a specific subset of X's have property Y in core.logic

I want to:
Describe a fact about a subset of a class of objects.
Declare that an object has a property that consists of other properties.
Take the following as an example:
Red robotic birds are only composed of buttons, cheese, and wire.
I want to express that a class of birds, birds that are red and robotic, have a property.
This property is that they are composed only of buttons, cheese, and wire. There are no restrictions on the type of wire cheese or buttons. Also as a result, it should be deducible that there are no red robotic birds that are composed of paper. Also, these birds can be composed of a subset of the items buttons, cheese, and wire.
In clojure/core.logic.prelude, there are relations and facts using defrel and fact.
However, I can't come up with a combination to explain this fact.
In Prolog there is no distinction between facts and goals as there are in miniKanren. I might address this in the future.
BTW, I'm not sure that this completely answers your question - it would be helpful to hear what types of queries you wish to run.
This is tested code (for Clojure 1.3.0-beta1) since I'm using the ^:index trick, this code will run fine in 1.2.0 if you swap it for ^{:index true}:
(ns clojure.core.logic.so
(:refer-clojure :exclude [==])
(:use [clojure.core.logic]))
(defrel property* ^:index p ^:index t)
(fact property* :bird :red-robotic-bird)
(fact property* :red :red-robotic-bird)
(fact property* :robotic :red-robotic-bird)
(fact property* :tasty :cake)
(fact property* :red-robotic-bird :macaw)
(defn property [p t]
(conde
[(property* p t)]
[(fresh [ps]
(property* ps t)
(property p ps))]))
(defrel composition* ^:index m ^:index t)
(fact composition* :buttons :red-robotic-bird)
(fact composition* :cheese :red-robotic-bird)
(fact composition* :wire :red-robotic-bird)
(fact composition* :flour :cake)
(defn composition [m t]
(fresh [p]
(composition* m p)
(conde
[(== p t)]
[(property p t)])))
Trying it out.
(comment
;; what is a macaw composed of?
(run* [q] (composition q :macaw))
;; (:wire :cheese :buttons)
;; what things include buttons in their composition?
(run* [q] (composition :buttons q))
;; (:red-robotic-bird :macaw)
;; does a macaw include flour in its composition?
(run* [q] (composition :flour :macaw))
;; ()
;; is a macaw a bird?
(run* [q] (property :bird :macaw))
;; (_.0)
;; is a cake a bird?
(run* [q] (property :bird :cake))
;; ()
;; what are the properties of a macaw?
(run* [q] (property q :macaw))
;; (:red-robotic-bird :robotic :bird :red)
)
Not entirely sure if this is what you need, but you can easily express that a class has a set of properties by creating a graph structure of facts (see the list of properties facts below and the rule for finding the properties within a set).
Then to express the composition of that set of properties you need another set of composition facts and rule that discovers any sub-properties of the class and as a result things it can be composed of.
I've given a code example below as well to help explain.
property(bird, red_robotic_bird).
property(red, red_robotic_bird).
property(robot, red_robotic_bird).
property(tasty, cake).
property(red_robotic_bird, macaw).
property(Property, Thing) :-
property(PropertySet, Thing),
property(Property, PropertySet).
composition(buttons, red_robotic_bird).
composition(cheese, red_robotic_bird).
composition(wire, red_robotic_bird).
composition(flour, cake).
composition(Material, Thing) :-
property(Property, Thing),
composition(Material, Property).
example queries
?- composition(Material, macaw).
Material = buttons ;
Material = cheese ;
Material = wire ;
no
?- composition(buttons, Thing).
Thing = red_robotic_bird ;
Thing = macaw ;
no
?- composition(flour, macaw).
no
?- property(bird, macaw).
yes
?- property(bird, cake).
no
property(Property, macaw).
Property = red_robotic_bird ;
Property = bird ;
Property = red ;
Property = robot ;
no
Prolog rules in brief.
Rules are essentially just facts (eg. animal(cat).) that are conditional on other rules or facts being true. A rule is made up a head and a body (head :- body.). A body is a logical proof most commonly expressed in conjunctive normal form (A /\ B /\ C). The and operator in prolog is ,, the or operator is ; (but its use is discouraged in rules), and the period (.) denotes the end of a rule or fact.
Note that if a later rule or fact in the body fails then prolog will backtrack and ask for an alternative answer from a previous rule or fact and then try again. Consider the somewhat contrived example below.
share_same_colour(FruitA, FruitB) :-
colour(Colour, FruitA),
colour(Colour, FruitB).
If we execute the query share_same_colour(apple, strawberry). then colour(Colour, apple). might return Colour as being green. However, there no green strawberries, so prolog will backtrack and ask what other colours do apples come in. The next answer might be red, upon which the second colour statement would succeed and the whole rule be true.