How to solve math equations using core.logic - clojure

I tried typing in a query in core.logic:
(run* [q] (== 0 (+ (* q q) (* 4 q) 4)))
And the prompt says,
error: lvar cannot be cast to a number
In the event that i haven't completely misconcieved what logic programming is about, are there ways that this problem can be solved using core.logic?

You should read The Reasoned Schemer for ideas. Basically the way to do math in a logic program is to create list-based encodings of numbers, which the logic engine can grow as needed to try things out. I don't have the book handy, but it encodes integers as a list of bits, in some weird way I can't quite recall: maybe (1) represents 0, (0) is illegal, and the MSB is last in the list?
Anyway, that's a lot of work; David Nolen has also recently introduced something about finite domains into core.logic. I don't know how those work, but I think they simplify the problem a lot for you by letting you specify what kinds of numbers to consider as a solution to your problem.

So far as I can find core.logic can't do the algebra to solve this equation. It can do basic math though the inputs to that math need to be actual values not LVars because the math functions can't operate on these:
user> (run* [q]
(fresh [x]
(== x 1)
(project [x] (== q (+ (* x x) 4)))))
(5)
works when x has a clear value and fails when x does not:
user> (run* [q]
(fresh [x]
(== x q)
(project [x] (== q (+ (* x x) 4)))))
ClassCastException clojure.core.logic.LVar cannot be cast to java.lang.Number

core.logic in it's current form is not designed as an numerical equation solver - it is more appropriate for solving logical and relational expressions.
You basically have two practical routes for solving mathematical equations:
Analytical solvers - solutions can be found quite easily for simple cases e.g. quadratic equations like the one you have above, but start to get increasingly complex quite quickly and then become impossible/infeasible for many equations. This is a huge open research topic.
Numerical solvers - these techniques are much more general and can be used on pretty much any kind of equation. However the results are not exact and the algorithms can fail to find the right solution(s) if the equation has "nasty" features (discontinuities, odd gradients, complex sets of local minima etc.)
Equation solvers require special intelligence to understand the "rules" of mathematical equations, e.g. how to factor polynomial expressions (for analytic solutions) or how to estimate a derivative (for numerical solutions).
Some links that may be interesting:
Quadratic equation solver in Incanter
http://programming.wonderhowto.com/how-to/solve-equations-for-any-variable-with-clojure-1-1-380687/
Example of a simple numeric solver in Clojure (Newton-Raphson method)

Related

Is it possible to insert a Clojure statement in the middle of a series of core.logic calls, "à la Prolog"?

Prolog mixes logic (fallible) goals, and (infallible) processes like write/2 or assert/1. Is it possible to do so with Clojure's core.logic?
For example:
(pldb/with-db myFacts
(l/run* [x y]
(person x)
(println "we found a person!")
(likes y x)
)
)
It looks like this can't work because (println ...) is a Clojure function embedded in a core.logic run (which is supposed to contain only conditions/constraints I'm guessing).
More interestingly, I would like to be able to assert new facts in the midst of checking logical conditions like in Prolog:
liked(x,y):-
person(x),
assertz(likable(x)),
likes(y,x).
Which would approximatively look like this in core.logic I'm guessing:
(pldb/with-db myFacts
(l/run* [x y]
(person x)
(def newFacts (-> newFacts (pldb/db-fact likeable x)))
(likes y x)
)
)
Those examples are silly but, in general, the question is about inserting procedural commands in the midst of constraint checking in core.logic like it is done in Prolog.
One concrete application of that, for instance, would be the capability to collect arcs in the recursive traversal of a graph by using assertion. But, unless I am mistaken, that's only possible if we have the possible to mix assertion with logical conditions.
Thank you very much for your help and guidance in this.
UPDATE:
I think I might have figured it out: including a Clojure statement is fine but it must return true ; unlike in Prolog, those functions don't automatically "succeed". So all we need to add is:
(l/== (println "hello") true))
Does it sound correct?
FYI, this post was really helpful: https://ask.clojure.org/index.php/9546/can-core-logic-ask-questions

How to properly use "iterate" and "partial" in Clojure?

Most reference to iterate are for operators, and all the applications on functions are so confusing that I still don't get how to use iterate in my code, and what partial is.
I am doing a programming homework, trying to use Newton's method to get square root for a number n. That is, with guess as the initial approximation, keep computing new approximations by computing the average of the approximation and n/approximation. Continue until the difference between the two most recent approximations is less than epsilon.
I am trying to do the approximation part first, I believe that is something I need to use iterate and partial. And later the epsilon is something I need to use "take"?
Here is the code I have for approximation without the epsilon:
(defn sqrt [n guess]
(iterate (partial sqrt n) (/ (+ n (/ n guess)) 2)))
This code does not work properly though, when I enter (sqrt 2 2), it gives me (3/2 user=> ClassCastException clojure.lang.Cons cannot be cast to java.lang.Number clojure.lang.Numbers.divide (Numbers.java:155).
I guess this is the part I need to iterate over and over again? Could someone please give me some hints? Again, this is a homework problem, so please do not provide me direct solution to the entire problem, I need some ideas and explanations that I can learn from.
partial takes a function and at least one parameter for that function and returns a new function that expects the rest of the parameters.
(def take-five (partial take 5))
(take-five [1 2 3 4 5 6 7 8 9 10])
;=> (1 2 3 4 5)
iterate generates an infinite sequence by taking two parameters: a function and a seed value. The seed value is used as the first element in the generated list and the second is computed by applying the function to the seed, the second value is used as the input for the function to get the third value and so on.
(take-five (iterate inc 0))
;=> (0 1 2 3 4)
ClojureDocs offers good documentation on both functions: http://clojuredocs.org/clojure_core/clojure.core/iterate and http://clojuredocs.org/clojure_core/clojure.core/partial.
So, #ponzao explained quite well what iterate and partial do, and #yonki made the point that you don't really need it. If you like to explore some more seq functions it's probably a good idea to try it anyways (although the overhead from lazy sequences might result in a somewhat not ideal performance).
Hints:
(iterate #(sqrt n %) initial-approximation) will give you a seq of approximations.
you can use partition to create pairs of subsequent approximations.
discard everything not fulfilling the epsilon condition using drop-while
get result.
It's probably quite rewarding to solve this using sequences since you get in contact with a lot of useful seq functions.
Note: There is a full solution somewhere in the edit history of this answer. Sorry for that, didn't fully get the "homework" part.
I think you're missing the point. You don't need iterate neither partial too.
If you need to execute some computation till condition is fulfilled you can use easy to understand loop/recur instruction. loop/recur can be understood as: do some computation, check if condition is fulfilled, if yes return computed value, if not repeat computation.
Since you don't want entire solution, only an advice where to go, have a proper look on loop/recur and everything gonna be all right.
#noisesmith made good point. reduce is not for computing till condition is fullfiled, but may be useful when performing some computation with limited number of steps.

Goal ordering in Clojure's `core.logic`

The following Clojure code uses core.logic to solve the same logic problem with the same goals in two different orders. This choice of ordering causes one to finish quickly and the other to hang.
(use `clojure.core.logic)
;; Runs quickly. Prints (1 2 3).
(clojure.pprint/pprint (run* [q] (fresh [x] (== x [1,2,3])
(membero q x))))
;; Hangs
(clojure.pprint/pprint (run* [q] (fresh [x] (membero q x)
(== x [1,2,3]))))
Is there a general solution or common practice to avoid this problem?
Here is my understanding:
With core.logic, you want to reduce the search space as early as possible. If you put the membero constraint first, the run will start by searching the membero space, and backtrack on failure produced by the == constraint. But the membero space is HUGE, since neither q nor x is unified or at least bounded.
But if you put the == constraint first, you directly unify x with [1 2 3], and the search space for membero now is clearly bounded to the elements of x.
If you're going to use membero there is no general solution to this problem. Calling membero with fresh vars will cause it to generate all (read, infinite) possible lists for which q is a member. Of course lists larger than 3 don't apply - but since you've used run* it will continue blindly trying lists larger than count 3 even though each one will fail.
It's possible to write a better version of membero in newer versions of core.logic using the constraint infrastructure, but the details of how one might do this are likely to change over the coming months. Until there's a solid public api for defining constraints you're stuck with the kind of subtle ordering and non-termination issues that trouble Prolog.

How to select from a set of possible values in minikanren / clojure-core.logic?

How do I express the constraint that n variables take different values from a set of n values?
For example, maybe I want to search for the expression of the form
(op1 a (op2 b c))
with the largest value, when a, b and c should 1, 2 and 3 (in some order) while op1 and op2 can each be anything from * + - / exp?
I can see how to make a have a value from 1 2 3 (by using conde for example). And the same for b and c. But then how do I exclude equality? Do I need to loop over all combinations and explicitly exclude them?
Obviously I can do the exclusion "by hand", but I am wondering if there is a better (more efficient) way, or a support library that includes things like this (I have a little more experience with linear programming libs and typically they have a bunch of helper functions that address these kinds of common cases).
And generalising it to the case where some values can appear a certain number of times seems like it's going to be a drag...
And now I think about it, how do I search for a maximum? Is there a good book or set of notes on this?!
[I'm using clojure but my understanding is that clojure-core.logic and minikanren are pretty much identical]
Update: anyone reading this question looking for a good introduction, check out the Alvis paper I mention below in a comment.
(run* [q]
(fresh [a b c]
(== q [a b c])
(fresh [x y z]
(rembero a '(* + / - exp) x)
(rembero b x y)
(rembero c y z))))

Computer algebra for Clojure

Short version:
I am interested in some Clojure code which will allow me to specify the transformations of x (e.g. permutations, rotations) under which the value of a function f(x) is invariant, so that I can efficiently generate a sequence of x's that satisfy r = f(x). Is there some development in computer algebra for Clojure?
For (a trivial) example
(defn #^{:domain #{3 4 7}
:range #{0,1,2}
:invariance-group :full}
f [x] (- x x))
I could call (preimage f #{0}) and it would efficiently return #{3 4 7}. Naturally, it would also be able to annotate the codomain correctly. Any suggestions?
Longer version:
I have a specific problem that makes me interested in finding out about development of computer algebra for Clojure. Can anyone point me to such a project? My specific problem involves finding all the combinations of words that satisfy F(x) = r, where F is a ranking function and r a positive integer. In my particular case f can be computed as a sum
F(x) = f(x[0]) + f(x[1]) + ... f(x[N-1])
Furthermore I have a set of disjoint sets S = {s_i}, such that f(a)=f(b) for a,b in s, s in S. So a strategy to generate all x such that F(x) = r should rely on this factorization of F and the invariance of f under each s_i. In words, I compute all permutations of sites containing elements of S that sum to r and compose them with all combinations of the elements in each s_i. This is done quite sloppily in the following:
(use 'clojure.contrib.combinatorics)
(use 'clojure.contrib.seq-utils)
(defn expand-counter [c]
(flatten (for [m c] (let [x (m 0) y (m 1)] (repeat y x)))))
(defn partition-by-rank-sum [A N f r]
(let [M (group-by f A)
image-A (set (keys M))
;integer-partition computes restricted integer partitions,
;returning a multiset as key value pairs
rank-partitions (integer-partition r (disj image-A 0))
]
(apply concat (for [part rank-partitions]
(let [k (- N (reduce + (vals part)))
rank-map (if (pos? k) (assoc part 0 k) part)
all-buckets (lex-permutations (expand-counter rank-map))
]
(apply concat (for [bucket all-buckets]
(let [val-bucket (map M bucket)
filled-buckets (apply cartesian-product val-bucket)]
(map vec filled-buckets)))))))))
This gets the job done but misses the underlying picture. For example, if the associative operation were a product instead of a sum I would have to rewrite portions.
The system below does not yet support combinatorics, though it would not be a huge effort to add them, loads of good code already exists, and this could be a good platform to graft it onto, since the basics are pretty sound. I hope a short plug is not inappropriate here, this is the only serious Clojure CAS I know of, but hey, what a system...
=======
It may be of interest to readers of this thread that Gerry Sussman's scmutils system is being ported to Clojure.
This is a very advanced CAS, offering things like automatic differentiation, literal functions, etc, much in the style of Maple.
It is used at MIT for advanced programs on dynamics and differential geometry, and a fair bit of electrical engineering stuff. It is also the system used in Sussman&Wisdom's "sequel" (LOL) to SICP, SICM (Structure and Interpretation of Classical Mechanics).
Although originally a Scheme program, this is not a direct translation, but a ground-up rewrite to take advantage of the best features of Clojure. It's been named sicmutils, both in honour of the original and of the book
This superb effort is the work of Colin Smith and you can find it at https://github.com/littleredcomputer/sicmutils .
I believe that this could form the basis of an amazing Computer Algebra System for Clojure, competitive with anything else available. Although it is quite a huge beast, as you can imagine, and tons of stuff remains to be ported, the basics are pretty much there, the system will differentiate, and handle literals and literal functions pretty well. It is a work in progress. The system also uses the "generic" approach advocated by Sussman, whereby operations can be applied to functions, creating a great abstraction that simplifies notation no end.
Here's a taster:
> (def unity (+ (square sin) (square cos)))
> (unity 2.0) ==> 1.0
> (unity 'x) ==> 1 ;; yes we can deal with symbols
> (def zero (D unity)) ;; Let's differentiate
> (zero 2.0) ==> 0
SicmUtils introduces two new vector types “up” and “down” (called “structures”), they work pretty much as you would expect vectors to, but have some special mathematical (covariant, contravariant) properties, and also some programming properties, in that they are executable!
> (def fnvec (up sin cos tan)) => fnvec
> (fnvec 1) ==> (up 0.8414709848078965 0.5403023058681398 1.5574077246549023)
> ;; differentiated
> ((D fnvec) 1) ==> (up 0.5403023058681398 -0.8414709848078965 3.425518820814759)
> ;; derivative with symbolic argument
> ((D fnvec) 'θ) ==> (up (cos θ) (* -1 (sin θ)) (/ 1 (expt (cos θ) 2)))
Partial differentiation is fully supported
> (defn ff [x y] (* (expt x 3)(expt y 5)))
> ((D ff) 'x 'y) ==> (down (* 3 (expt x 2) (expt y 5)) (* 5 (expt x 3) (expt y 4)))
> ;; i.e. vector of results wrt to both variables
The system also supports TeX output, polynomial factorization, and a host of other goodies. Lots of stuff, however, that could be easily implemented has not been done purely out of lack of human resources. Graphic output and a "notepad/worksheet" interface (using Clojure's Gorilla) are also being worked on.
I hope this has gone some way towards whetting your appetite enough to visit the site and give it a whirl. You don't even need Clojure, you could run it off the provided jar file.
There's Clojuratica, an interface between Clojure and Mathematica:
http://clojuratica.weebly.com/
See also this mailing list post by Clojuratica's author.
While not a CAS, Incanter also has several very nice features and might be a good reference/foundation to build your own ideas on.
Regarding "For example, if the associative operation were a product instead of a sum I would have to rewrite portions.": if you structure your code accordingly, couldn't you accomplish this by using higher-order functions and passing in the associative operation? Think map-reduce.
I am unaware of any computer algebra systems written in Clojure. However, for my rather simple mathematical needs I have found it often useful to use Maxima, which is written in lisp. It is possible to interact with Maxima using s-expressions or a higher-level representations, which can be really convenient. Maxima also has some rudimentary combinatorics functions which may be what you are looking for.
If you are hellbent on using Clojure, in the short term perhaps throwing your data back and forth between Maxima and Clojure would help you achieve your goals.
In the longer term, I would be interested in seeing what you come up with!