This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-08
Channels
- # adventofcode (49)
- # babashka (21)
- # babashka-sci-dev (12)
- # beginners (250)
- # calva (23)
- # cider (6)
- # clj-kondo (11)
- # cljsrn (8)
- # clojure (129)
- # clojure-europe (50)
- # clojure-france (8)
- # clojure-italy (6)
- # clojure-nl (14)
- # clojure-romania (7)
- # clojure-spec (21)
- # clojure-uk (3)
- # clojurescript (17)
- # conjure (1)
- # core-async (40)
- # core-logic (24)
- # core-typed (7)
- # datavis (2)
- # datomic (2)
- # emacs (29)
- # fulcro (10)
- # graalvm (6)
- # graphql (24)
- # gratitude (6)
- # jobs (1)
- # lsp (9)
- # malli (6)
- # missionary (1)
- # nextjournal (46)
- # off-topic (2)
- # other-languages (3)
- # pathom (5)
- # portal (2)
- # re-frame (37)
- # remote-jobs (1)
- # shadow-cljs (15)
- # spacemacs (9)
- # testing (6)
- # tools-deps (13)
- # vim (32)
- # xtdb (16)
Hi, I’m trying to understand some core logic basics. Based on the tutorial, I can do this (and it makes sense):
(run* [q r]
(== {:a q :b r} {:a 1 :b 2}))
;=> ([1 2])
What I want to do is this:
(run* [a b c]
(== {:a #{1 2} :b #{2 3}}
{:a #{a b} :b #{b c}}))
;=> ()
I would naively hope for ([1 2 3]) instead of (). How can I recast this to make it work?Good catch. I’ve updated the above. Still gives the same result.
afaik set and hashmap unification is not supported by core.logic, feature extraction from hashmap is supported via featurec
@U0JUR9FPH, I just looked through the source. The problem is that core.logic only unifies sequentials and maps (and Lcons
, which are special but replace Clojure’s lists to make improper lists work as in Scheme/Lisp). But (sequential? #{1 2}) ==> false
, so it takes the case for Java Objects. If the two Objects aren’t =
, then unification fails. And to be clear, no substructure is compared in the case of anything that takes the default Object path. So:
(run* [q]
(== #{1 2} #{1 2}))
==> (_0)
works as expected, as does:
(run* [q]
(== #{1 2} #{2 1}))
==> (_0)
because sets can be compared for equality irrespective of how items are ordered. But sets are just compared, they are not truly unified. See the code around line 900 in the main core.logic source file.@U487Z32UF, map unification is supported for map values, but not keys. All maps must have the same size and the same keys, otherwise unification fails. The values corresponding to equal keys are unified correctly. Thus:
(run* [q]
(== {:a 1} {:a q}))
==> (1)
Interesting. Key unification was my next step in leveling up. Appears I need to learn other ways of making it work. Thanks for the insights!
BTW, thinking about this further, the behavior for sets is expected. Unification within the substructure of a collection relies on a consistent ordering or position. Core.logic can do that with maps as long as it just unifies against values and not keys. But sets, by definition, have no internal structure whatsoever. Any permutation of items in a set is equally valid. So, there's no real way to perform unification with ING the (entirely lacking) substructure. Summary: it basically has to work like this for sets.
Anyone ever written production rules or term rewriting with core logic? Can you share an example or approaches?
I have not, but I think the kind of current favored approach is using equality saturation, which solves the problem of divergence that naive rewriting can have in core.logic
https://www.youtube.com/watch?v=LKELTEOFY-s is a nice talk about optimizing equality saturation, but it includes a nice explanation of what it is
https://github.com/clojure-numerics/expresso does look like it uses core.logic in someway
I had the misguided idea of trying to embed pi calculus in core.logic by embedding its production rules
Oh, sure, a kind of interpreter? That is a common thing done for the lamda calculus with minikanren. There are extensions to minikanren for working with languages and binders, and I believe core.logic includes some of that stuff, if you look around the code base for nom
but I am not very familiar with that
http://webyrd.net/alphamk/alphamk.pdf is the alphakanren paper and https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/nominal.clj is the core.logic version
It might be better to start by just implementing regular evalo, too, if I'm writing an interpreter I should cut my teeth on something I more familiar first
Are you specifically looking to use core.logic, or would something like Meander fit? Meander has reasonable support for this and I’ve used it before to do transformation from a parsed Markdown representation to HTML via term rewriting and it worked quite reasonably.
I asked the same qs a while ago, you might want to check the thread below it : https://clojurians.slack.com/archives/C0566T2QY/p1635351009001600