Fork me on GitHub
#core-logic
<
2023-01-17
>
dregre03:01:29

I am a core logic newbie, and am playing around with finite domains. I’m puzzled by something, and I was hoping others could help me understand what is going on. Basically, I am trying to put a distinct constraint on a sequence of lvars whose size is equal to the size of the domain — no other constraints. It works fine for 10, 100, even 1,000 lvars … but when I try it on 10,000 it runs interminably (on my poor little Macbook Air). Could anyone help me understand why it behaves this way? Snippet:

(let [size   10000
      lvars  (repeatedly size l/lvar)
      domain (fd/interval size)]
  (l/run 1 [q]
         (l/everyg #(fd/dom % domain) lvars)
         (fd/distinct lvars)
         (l/== q lvars)))

dregre03:01:47

Notice, too, I am only trying to arrive at a single answer, though seems not to have any bearing on speed that I have discerned, versus run*.

agh2o18:01:42

Hi, I'm trying to understand how to deal with large amounts of data that I want to process using core.logic.. I read about various techniques including pre-processing, memoization, and more. but I wondered if there was a more striaght forward domain independent technique that is possible with core.logic. such as distributed computation or having the facts come from a db query instead of being in memory (and the query itself being a more specific query than querying everything). I know that without domain specific knowledge it could be hard but maybe I missed something. Another option I thought of is calculating intermediate results given partial data and then adding data (after options have been eliminated). The problem with this one is that I think there is no way around getting a suboptimal solution.. Thanks for any advice. I'd also be happy to redirection to relevant literature!

Ben Sless18:01:23

As always, it depends, but the most general (and useless) answer is: The computational model is a logic monads Monadic computations can be distributed, a+b+c+d can be computed on different machines and aggregated on another How you'd do that with core.logic, and if it even has the facilities for that, no idea

agh2o18:01:20

I'll try to think if the logic monad applies to what I'm doing. Thanks

Ben Sless19:01:06

The things you're adding are the streams of answers

Ben Sless19:01:38

If you have a way of modeling choice (e.g. or) then you can distribute those parts

Ben Sless19:01:14

The background literature is Logic Transformer Monad (approximate title) by Oleg Kiselyov

agh2o19:01:41

Great, I appreciate it

agh2o19:01:44

Say I got a modeling choice as you called it. And say I want to calculate each of the sides of that "or" on different Machines. Each instance will return a group of possible variables that satisfy the constraint. Then I need to find the intersection of both these groups (what if there are many options in each?) is it possible for each instance to instead of providing possible solutions to provide some other thing that might be used as pre-processed information or top level constraints that will make the entire calculation easier?

Ben Sless20:01:38

or doesn't return an intersection, but a unification of domains. In core.logic it's mplus iirc The way computations are run in core.logic (and kanren) is basically a stream of states of substitutions for logic variables. In the end, that stream is reified, so you can put that aside for now, what you'd want is to play with those raw substitutions streams, get them from two machines, mplus them, continue the processing and reify in the end.

rickmoynihan10:01:43

I’ve looked into this in the past and you can plug other backends/databases into core.logic and reason over them… there’s an example in the core.logic repo itself which is backed off datomic; but you could in principle plug anything in. On the parallelisation front I’ve also superficially looked at that too — parallelising it is in theory trivially easy; the difficulty is doing so in such a way that you don’t make it slower. There have been a number of experiments already doing precisely sort of things you’re talking about e.g. porting the monadic streams to core.async/CSP processes: https://github.com/halgari/async-mu-kanren/blob/master/src/async_mu_kanren/core.clj To my knowledge though they’re usually slower because you end up with too much parallelism and the coordination overhead quickly dominates the computation.

agh2o07:01:31

@U06HHF230 thanks! I'll look into it