Fork me on GitHub

@jballanc: That I've used numbers is just for simplicity. The more general question is: if (thingo x) can unify x with both :fork and :spoon, is there a way to tell if x is unified first with :fork and then :spoon or the other way round?


@jballanc: Basically, what I am looking for is a way to transform between multiple unifications and a list of the unifications.


tsdh: hmm…if I understand you correctly, I’d be tempted to say that this falls into the category of “implementation detail” in core.logic


that is, if you have, say: (run* [q] (conde [(== q 1) (== q 2)])) and you want to know did q match 1 first, or 2 first?


yeah…I mean, IIRC the implementation of conde and friends is more-or-less a depth-first tree walk, so unifications should happen in roughly the order they’re provided


but I think that’s definitely “implementation detail” since, as I understand it, in Will Byrd’s ideal world all mini-Kanren conditions would be relational, i.e. order independent


He does a really good job explaining that concept in this podcast:


So, while it might be possible to hack a solution to get what you want, I think you have to keep in mind that you’d be directly controverting one of the goals of mini-Kanren as a logic system


(…but I’m far from an expert on the matter)


@jballanc: Yes, I'm with you in your concrete example. But with your own relations, you can define the order in which things get unified. For example, say you deal with the concepts block and statement in some programming language. Clearly, a block contains statements, and the order of statements in a block does matter. Now you have to choices to model that with relations: 1. (block-has-stmto block stmt) where the relation unifies stmt once for each statement in a concrete block, or 2. (block-has-stmts block stmts) where stmts gets unified with the list of statements in a concrete block. Variant 1 is much nicer to work with in case you don't care about the order. With variant 2, you have the order but if you don't care about it, queries become a bit more complicated (basically you need membero goals over the place).


@jballanc: Well, I guess just providing both versions makes everybody happy, and variant 1 can easily be implemented on top of variant 2.


@jballanc: Just the reverse seems to be not so trivial, and of course I started with variant 1. simple_smile


tsdh: It’s an interesting use-case to be sure. About the only thing I can think of that might make it easier to work with is if you could describe an ordering relationship between the individual statements. Something like: endif must come after if but before enddef…or something like that. I suspect, though, that you’d quickly find yourself implementing a full parser/AST walker.


…which, to be sure, is definitely an interesting use case. You might be interested to check out Will Byrd’s Quine generator in mini-Kanren, as it has similar-ish elements as I recall.


@jballanc: ok, thanks for the pointer


Another thing: can I define a relation which asserts that some goal succeeds but some other goal fails? I'd be fine with such a must-fail construct was non-relational, that is, only applicable if all logic variables of the goal are ground.


I guess that's easy to implement myself but probably there's already something predefined.


@nberger: great, thank you!


@tsdh: you are welcome