core-logic

risto 2018-09-12T10:09:11.000100Z

hi everyone

risto 2018-09-12T10:09:25.000100Z

i'm trying to figure out what's making appendo terminate, from the looks of it, it seems like it should just be infinite like anyo

risto 2018-09-12T10:09:30.000100Z

does anyone have any insight into that?

2018-09-12T16:30:00.000100Z

it is a recursive goal with 3 args (x y z) and 2 cases. the first case is the base case and is only true if x unifies with the empty list and z unifies with y, the second case is only true if the first element of x and the first element of z unify, and if it is true it calls appendo again with the rest of x, y, and the rest of z

2018-09-12T16:38:27.000100Z

so it must terminate because every step where case 2 matches causes the recursive call to be made with the rest of x, so the x argument gets smaller and smaller, until case 2 no long holds and case 1 might hold

risto 2018-09-12T18:17:44.000100Z

that makes sense, but the issue for me is how conj and disj are implemented

risto 2018-09-12T18:18:09.000100Z

even though it's a lazy stream, conj is implemented using flatmap and disj with a fair append

risto 2018-09-12T18:18:27.000100Z

so it seems like it would continue to recurse forever, because under the hood it's calling flatmap or append

2018-09-12T18:23:45.000100Z

are you actually asking about core.logic or minikanren? because flatmap isn't a string that appears in core.logic

2018-09-12T18:25:40.000100Z

append is not the same thing as appendo

risto 2018-09-12T18:27:44.000100Z

isn't core.logic an implementation of minikanren?

risto 2018-09-12T18:30:42.000100Z

(def appendo [xs ys out]
   (conde
     [(eq xs []) (eq ys out)]
     [(fresh [first rest rec]
        (conso first rest xs)
        (conso first rec out)
        (appendo rest ys out))]))
here fresh is calling call-fresh and conj under the hood, and conj is implemented using flatmap aka bind aka mapcat-stream

risto 2018-09-12T18:31:09.000100Z

so it would just keep going forever it seems, like anyo

2018-09-12T18:32:38.000100Z

no

2018-09-12T18:33:00.000100Z

you are confusing goals implemented in core.logic with functions implemented in clojure

1👍
risto 2018-09-12T18:33:23.000100Z

why do you think i'm confusing it with functions in clojure?

2018-09-12T18:33:52.000100Z

actually it is hard to say, because call-fresh doesn't exist in core.logic either

2018-09-12T18:34:14.000100Z

because conj in clojure is the function clojure.core/conj which is definitely not implemented using flatmap

2018-09-12T18:34:47.000100Z

there is a core.logic goal called conjo, which is a constraint goal, which is kind of a different kettle of fish

risto 2018-09-12T18:34:58.000100Z

ah i see the confusion, i'm referring to the names of these things from the minikanren implementation

risto 2018-09-12T18:35:12.000100Z

maybe core.logic is using a different scheme for it, but it's implementing minikanren under the hood

risto 2018-09-12T18:35:37.000100Z

yeah i meant conjo, sorry

risto 2018-09-12T18:36:04.000200Z

it has something called conj under the hood which isn't a goal

risto 2018-09-12T18:36:12.000100Z

but not the same as clojure.core/conj

2018-09-12T18:36:12.000200Z

it is minikanren in a kind of hand wavey sense, it isn't a direct port

2018-09-12T18:37:23.000100Z

I don't think core-logic's conjo is the same as conj in minikanren

2018-09-12T18:38:31.000100Z

I think, and it has been a long time since I've looked at minikanren, conj in mk is an operator on the underlying lazy stream implementation

risto 2018-09-12T18:39:48.000100Z

yeah, it has a minimal implementation at the end of the paper http://webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdf

2018-09-12T18:40:50.000100Z

so it is a level of abstraction problem

risto 2018-09-12T18:40:54.000100Z

but that's not enough to stop it from infinitely recursing appendo afaict. It might be because it's such a minimal implementation of kanren that they leave out the more important parts to make something like appendo work, not sure

2018-09-12T18:41:03.000100Z

mk is not implemented in mk

2018-09-12T18:41:41.000100Z

micro kanren is another thing again

risto 2018-09-12T18:42:08.000100Z

what's the difference between minikanren and microkaren? microkanren is just an even more minimal version of kanren?

risto 2018-09-12T18:42:56.000100Z

its on the minikanren website, i thought it was the same thing

2018-09-12T18:47:52.000100Z

yeah, it is an even more stripped down version

risto 2018-09-12T18:50:31.000100Z

yeah

risto 2018-09-12T18:51:22.000100Z

anyways, it says on the minikaren website that core.logic is an implementation of it.. even if it deviates somewhat it has to have some way of making sure appendo doesn't just recurse forever. I guess my question is how they manage to pull that off without ending up with a neverending stream like anyo