This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi! I'm a total beginner in Datascript (and Datalog). Trying to figure it out by doing this years Advent of Code. 🙂
The task in the https://adventofcode.com/2023/day/2 seemed like a good fit to apply it. I got a DB in the form of tuples like this: [game-id draw-order cube-color cubes-number]
, e.g. [1 0 :red 4]
.
I am able to make a single Datascript query to remove all rows that contain impossible draws (more cubes of the given color than total provided).
I can also easily show all impossible draws with a single query:
(d/q '[:find ?gid ?ord ?col ?num ?total
:keys gid ord col num total
:in [[?gid ?ord ?col ?num]] ?total-cubes
:where
[(?total-cubes ?col) ?total]
[(> ?num ?total)]]
db
total-cubes)
Do you see a way to give the Part I's answer in a single query (i.e. sum of all possible game IDs )?
It feels like I should try to use not-join
, but I couldn't make it work yet...PS: my current working solution in plain Clojure requires use of every?
at two levels of data structure nesting to keep only the legal games: https://github.com/a1exsh/advent-of-clerk/blob/main/src/advent_of_clerk/year_2023/day_02.clj#L48-L60
I can't think of a way around needing to make two queries - pretty sure if you need to build up an intermediate set and not individual values then a second query will be needed:
(d/q '[:find [?valid-gid ...]
:in ?row ?totals
:where
[(datalevin.core/q
[:find ?gid
:in [[?gid ?ord ?col ?num]] ?total-cubes
:where [(?total-cubes ?col) ?total]
[(> ?num ?total)]]
?row ?totals)
[[?out-gid]]]
[(identity ?row) [[?valid-gid]]]
[(not= ?valid-gid ?out-gid)] ]
[[0 0 :red 4]
[0 0 :green 12]
[1 0 :red 4]
[1 0 :green 10]
[2 0 :red 4]
[2 0 :green 18]]
{:red 12 :blue 14 :green 13})
=> [0 1]
Interesting, thanks. It still looks like a "single" query, even with a sub-query to me, so maybe that's good enough. Why datalevin
? Doesn't Datascript supports sub-queries?
it's a db built with datascript for its query interface https://github.com/juji-io/datalevin I just had it setup and not datascript locally to test your query out
Actually, back to where I've seen a use for logical programming in this task: I wanted to be able to ask the system, when it gives some answer, how and from which given facts did it derive that answer. Is this something that Datalog / Datascript can do or should I be looking for actual Prolog implementations?
have you seen meander? https://github.com/noprompt/meander it is logic programming in clojure. Not really Prolog implementation but still can help in many usecases
Actually, back to where I've seen a use for logical programming in this task: I wanted to be able to ask the system, when it gives some answer, how and from which given facts did it derive that answer. Is this something that Datalog / Datascript can do or should I be looking for actual Prolog implementations?