Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve math equations using core.logic

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?

like image 790
zcaudate Avatar asked Sep 25 '12 22:09

zcaudate


3 Answers

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.

like image 139
amalloy Avatar answered Nov 17 '22 09:11

amalloy


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
like image 6
Arthur Ulfeldt Avatar answered Nov 17 '22 09:11

Arthur Ulfeldt


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)
like image 4
mikera Avatar answered Nov 17 '22 08:11

mikera