# Query Engine in the Geolog Big Picture This is a scratch note based on the architecture diagram and the current IR note. ## Short answer The query engine fits below the IR, not above it. The top part of the system is the language pipeline: 1. concrete syntax 2. parser 3. abstract syntax 4. elaborator 5. elaborated syntax 6. lowering 7. intermediate representation After that point, the system stops being mostly front-end/compiler work and starts being backend/runtime work. That means the query engine should be one of the first consumers of the IR. ## What that means in the diagram The cleanest reading of the diagram is: - parser, elaborator, and lowering produce the IR - the IR is the contract between the front end and the execution backends - the query engine sits under the IR - backend-specific implementations then sit under that So a useful architecture shape would be: 1. `Lowering` 2. `Intermediate Representation` 3. `IR Execution / Query Engine` 4. backend implementations: - in-memory execution - Postgres execution - Rust storage/query execution ## Two ways to think about the query engine There are really two possible meanings. ### 1. Narrow meaning The query engine is just the thing that runs queries against a backend. In that version: - the in-memory backend has its own query engine - the Postgres backend has its own query engine - the Rust backend has its own query engine The IR is compiled into whatever each backend needs. ### 2. Broad meaning The query engine is the main execution layer for the IR. In that version it is responsible for more than just user queries. It may also handle: - law checking - chase steps - fixpoint iteration - planning or rewriting - backend-specific lowering of queries This broader meaning is probably closer to what Geolog will eventually need. ## Practical conclusion Right now, the best big-picture placement is: - the query engine belongs after lowering - it consumes IR - it is part of the execution layer - it may have multiple backend implementations So the IR should be treated as the interface, and the query engine should be treated as the first major runtime component that uses that interface. ## Questions for the team 1. Is the query engine meant to be one shared execution layer over the IR, or a thin abstraction over several backend-specific engines? 2. Is `FlatTheory` supposed to be enough for execution, or do we expect a second runtime IR above it for chase state, branches, and equality? 3. Should law checking and user querying be handled by the same engine, or by separate components that both consume the IR? 4. Do we expect the first real executor to be in-memory, Postgres-backed, or Rust-native? 5. Is Postgres only a storage/query backend, or is it intended to become a serious execution target for law checking and chase steps too? 6. What parts of execution must be backend-independent: query planning, law translation, chase scheduling, provenance, branch management? 7. Do existential witness generation, disjunctive branching, and equality merging belong inside the query engine, or in a separate chase/runtime layer above it? 8. Should the query engine operate directly on relational tables, or should it also understand higher-level Geolog structure like paths, theories, and dependencies? 9. What is the expected contract between Haskell lowering and Rust execution: raw IR data only, or also precompiled queries/plans? 10. What is the earliest milestone for the engine: run queries, check laws, perform simple fixpoint evaluation, or support full chase behavior?