what are some real-world use cases for logical programming?
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
I think rackspace is actually planning on something similar (also using core.logic)
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
@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?
well, so I think desdemona and threatgrid's use most likely look sort of like an expert system or rules engine
I like to try and use it to figure out my inlaws secrete santa every year
they set certain rules on the exchange about couples not getting each other in the exchange, that sort of thing
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
it rarely goes well, they practice good opsec
hahaha! that's awesome. so expert systems, rules engines, got it. I'll at least learn it for fun :simple_smile:
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)
@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?
yeah
@hiredman: why do you not recommend it?
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
@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?the translation from prolog isn't that direct
== doesn't have any kind sugar, just unification
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)
there are some macros for defining functions that can do pattern matching sort of unification on arguments, but I haven't really used those
nice, it does work:
(run* [q]
(== [(lvar) (lvar) (lvar) q] [1 2 3 4]))
now to figure out variable lengths...
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)))))