Hi all, I want to write a query with a rule like
(or
[?e :entity/a1 ?v1]
[?e :entity/a2 true])
Where ?v1
is a parameter.
Datomic throws on it because all or
clauses must use same set of vars.
Kondo also diagnoses a problem there that "join variable is not declared inside clauses"
Any way to do it besides add a negation?
(or
[?e :entity/a1 ?v1]
(and
(not [?e :entity/a1 ?v1])
[?e :entity/a2 true]))
@ben.sless For the datomic case, I would suggest looking at rules. If you're on cloud, https://docs.datomic.com/cloud/query/query-data-reference.html#rules is the reference docs. Specifically, you're looking for this subsection https://docs.datomic.com/cloud/query/query-data-reference.html#multiple-rule-heads
Rules allow disjunction
Well, that was surprisingly painless, thanks @lanejo01! This worked:
[[(pred ?e ?v1)
[?e :entity/a1 ?v1]]
[(pred ?e ?v1)
[?e :entity/a2 true]]]
Just curious, was there a reason you didn't post this question in the datomic channel?
Yes, because I did not know if it was specific to datomic's implementation or if I was thinking about datalog wrong
I tend to think it's the latter
Thanks for the info!
A nice bonus is that it performs faster than my previous version which used negation
If you run into more issues while using datomic, feel free to reach out on the #datomic channel, there are ~2000 Members in that channel, as opposed to 134 here. I presume folks here will have a very deep understanding of datalog, but the question you asked would be answerable by most who use datomic in anger. Please reach out if you have any more questions, good luck and have fun!
🙏 thank you!
Out of curiosity, assuming that you don’t need ?v1
then would it work to use:
(or
[?e :entity/a1]
[?e :entity/a2 true])
I don’t know if the first part of the or
clause creates an internal “hidden” variable (which could result in it not working), or if it just doesn’t leave it bound. If it’s the latter, then it should work, but if it’s the former then it still have the problem
A side project I'm working on is a clojure implementation of a turn based game. It's quite complex, with lots of state. Up until now I've been keeping the state in a big nested map. On one hand this works great as the game logic consists of only pure functions. But I've started amassing quite a pile of little functions to get and update the state. It's a mix of vanilla clojure and specter. I recently just re-organized the state to be normalized with most entities at the top level, using ids to reference relations. This simplified some of my grab bag functions, but there are still quite a few and they are gnarly. I'm pondering switching to datascript to dump the state into and query. Since processing all happens in memory, I'd simply deserialize, process, and serialize the game state. No need for datomic. But I'm wondering about schema migrations. Once the single source of truth is a datascript db and I can't change the schema.. this seems like a bad idea. Any thoughts from ya'll?
At the risk of sounding self-serving, you could always try Asami. It does not use a schema, and the queries work similarly