core-logic

2016-04-05T20:08:48.000032Z

what are some real-world use cases for logical programming?

2016-04-05T20:14:14.000033Z

threatgrid was(is? but they were acquired by cisco a while back) using core.logic for, uh, I guess threat recognition, they actually contributed the pldb fact database thing to core.logic

2016-04-05T20:15:50.000034Z

I think rackspace is actually planning on something similar (also using core.logic)

2016-04-05T20:16:05.000035Z

https://github.com/RackSec/desdemona

2016-04-05T20:18:18.000037Z

I've actually never ended up using core.logic at work, but since I have spent a little time with core.logic, and implemented minikanren, a lot of the ideas around searching and generating and unification have ended up popping up in stuff I do

2016-04-05T20:23:41.000038Z

@hiredman: woh cool! I'm trying to get a feel of whether or not it's worth investing the time to learn logical programming in clj. Are there generic classes of problems that solve well in logical programming?

2016-04-05T20:28:38.000039Z

well, so I think desdemona and threatgrid's use most likely look sort of like an expert system or rules engine

2016-04-05T20:30:50.000040Z

I like to try and use it to figure out my inlaws secrete santa every year

2016-04-05T20:31:36.000041Z

they set certain rules on the exchange about couples not getting each other in the exchange, that sort of thing

2016-04-05T20:33:12.000042Z

so I write a core.logic program that takes in to account those rules, and generates all possible gifting pairs, and then I observe and try to find out more facts and add them to the program until it gets down to one possible set

2016-04-05T20:33:37.000043Z

it rarely goes well, they practice good opsec

2016-04-05T20:36:25.000045Z

hahaha! that's awesome. so expert systems, rules engines, got it. I'll at least learn it for fun :simple_smile:

2016-04-05T20:47:00.000046Z

I started woodworking as a hobby and ended up using core.logic figure out dimensions for a workbench, https://gist.github.com/hiredman/05befd5b39eef89b86ca (I don't recommend this workbench btw)

2016-04-05T20:53:52.000047Z

@hiredman: huh, that's kind of awesome. So you give it constraints on what the table should look like, and it figures out the dimensions of all of the pieces of wood?

2016-04-05T20:55:42.000048Z

yeah

2016-04-05T21:13:48.000049Z

@hiredman: why do you not recommend it?

2016-04-05T21:28:05.000050Z

it is basically a really heavy table, which is maybe 80% of want you want from a handtool woodworking bench, but the 20%, the work holding, is kind of clutch. It is also on the small side (I was living in an apartment when I came up the dimensions). I have been contemplating building what people are calling a knockdown nicholson for a while now

2016-04-05T21:43:55.000051Z

@hiredman: that looks awesome! I built a guitar from scratch a few years ago, and I've been craving getting back into wood working. Using code for wood projects is a cool junction :simple_smile: Hey, can I ask a simple question? I'm going through some prolog "puzzles" to learn core.logic and I can't solve the first one, I just don't get how to "destructure" variable length lists. I just want to take the last of a list, and this is kinda what my approach is:

(run* [q]
  (== [_ | q] [1 2 3 4])
  )
or second from last:
(run* [q]
  (== [_ | q _] [1 2 3 4])
  )
Any idea if I'm on the right track?

2016-04-05T21:46:57.000053Z

the translation from prolog isn't that direct

2016-04-05T21:47:15.000054Z

== doesn't have any kind sugar, just unification

2016-04-05T21:48:09.000055Z

so something like (== [(lvar) q (lvar) (lvar) (lvar)] [1 2 3 4]) might work (I forget exactly the name of the function to generate a fresh lvar)

2016-04-05T21:49:03.000056Z

there are some macros for defining functions that can do pattern matching sort of unification on arguments, but I haven't really used those

2016-04-05T21:50:02.000057Z

nice, it does work:

(run* [q]
  (== [(lvar) (lvar) (lvar) q] [1 2 3 4]))

2016-04-05T21:50:11.000058Z

now to figure out variable lengths...

2016-04-05T23:22:34.000059Z

I can grab the first like this, but not the last:

(run* [q]
  (fresh [a o]
    (== a [1 2 3 4 5])
    (matche [a]
            ([ [o . _] ]
             (== q o)))))