aboutsummaryrefslogtreecommitdiffstats
path: root/docs/evaluators.org
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-09-13 14:36:15 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-09-13 14:36:15 -0300
commit097cf958cf25c63035f6434f12b421dd9ab1c60e (patch)
treebfed8eafb7417a6e05e23be82550c2f78d774e68 /docs/evaluators.org
parentca8c92915bd3a7fa19ef57b8bd5a9b3f16d05254 (diff)
downloadRNT-097cf958cf25c63035f6434f12b421dd9ab1c60e.tar.gz
RNT-097cf958cf25c63035f6434f12b421dd9ab1c60e.zip
docs
Diffstat (limited to '')
-rw-r--r--docs/evaluators.org100
1 files changed, 64 insertions, 36 deletions
diff --git a/docs/evaluators.org b/docs/evaluators.org
index 1e0d7cc..84bc493 100644
--- a/docs/evaluators.org
+++ b/docs/evaluators.org
@@ -24,55 +24,83 @@ indexes them so a client can ask which evaluators declare =dml= and
get back B and C.
* Protocols
-Three object components, following the existing =implementation= /
-=make= / =from= pattern.
-
-=Protocols.Evaluator= admits programs in string format. Admission
-validates a program in the evaluator's own representation (as in:
-parses, type checks and does all it requires to validate it) and
-yields a handle.
+An evaluator is an object like any other, that can be used to execute
+program with a context, exactly as an interpreter takes an expression
+and an environment. The plan tree should already bear every value the
+program needs, so there is nothing left to bind. Each invocation
+carries independent state based atop of a database view of the world
+(being therefore hash dependent and isolated).
#+begin_src ocaml
+module Make (P : PROGRAM) : sig
class type implementation = object
- method capabilities : string BatSet.t
- method admit : string -> (Handle.t, condition) result
+ method invoke :
+ program:P.t -> Context.t -> (Handle.t, condition) result
end
+end
#+end_src
-=Protocols.Program= exposes entry points and an invocation, making a
-program reusable, since each invocation carries independent state
-based atop of a database view of the world (hash dependent and
-isolated).
+The protocol is parameterized by the evaluator's own plan type, so a
+plan is never encoded into values only to be decoded again. Each
+application of the functor yields its own protocol constructor, which
+is what keeps one evaluator from answering another's programs: a
+client obtains the interface through the module of the evaluator it
+intends to speak to. The FOL evaluator, which lives under
+=lib/evaluators= alongside the evaluators shipped with RNT, currently
+understands a single node:
#+begin_src ocaml
-class type implementation = object
- method entry_points : string list
- method invoke :
- entry:string -> bindings:Concepts.Tuple.t -> Runtime.Context.t ->
- (Handle.t, condition) result
-end
+type plan = Base of string
#+end_src
+=Base= names a relation, which is resolved through the context and
+enumerated to exhaustion. The name is resolved rather than an address
+being followed, which keeps the evaluator free of storage and makes
+every resolution happen under one snapshot.
+
The returned handle carries a result protocol with =Protocols.Cursor=,
-giving it incremental consumption. A successor state and a command
-completion are further result protocols, added for DML and DDL
-later. It's important to notice that the kernel enumerates result
-protocols; it thererfore does not enumerate sublanguages. That is not
-to say however that we cannot have a builtin catalog relation
-installed and configured by the client that enumerates them (that's a
-concern for the future).
+giving it incremental consumption. Since executing a plan node yields
+a cursor, operators stack as cursors over cursors, in the manner of a
+volcano iterator, and no intermediate result is materialized. A
+successor state and a command completion are further result protocols,
+added for DML and DDL later. It's important to notice that the kernel
+enumerates result protocols; it thererfore does not enumerate
+sublanguages. That is not to say however that we cannot have a builtin
+catalog relation installed and configured by the client that
+enumerates them (that's a concern for the future).
* Context
-=Runtime.Context.t= supplies the selected database state, handles
-(which assume authorization, since we are a capability based system),
-cancellation, and resource usage. Evaluators reach kernel resources
-*only* through it.
-
-A nested invocation shares state, transaction, cancellation, and
-budget, and may be given less authority than its caller. Reads keep
-the selected state so that nesting does not need to resolve a branch
-tip again, and a successful evaluation and cursor exhaustion never
-commit. Commit should be an explicit host operation.
+=Protocols.Context.t= supplies the selected database state, the root
+handle through which names are resolved (which assumes authorization,
+since we are a capability based system), and the status of the
+evaluation. Evaluators reach kernel resources *only* through it.
+
+#+begin_src ocaml
+type t =
+ { snapshot : Concepts.Hash.hash
+ ; root : Handle.t
+ ; status : unit -> [`Live | `Cancelled | `Exhausted] }
+#+end_src
+
+The snapshot is the hash of a commit. Since every object is content
+addressed and prolly trees do not depend on insertion order, equal
+state yields an equal hash, so a commit hash is a frozen world rather
+than a pointer into a changing one. A cursor therefore pins a hash
+instead of an open transaction, and every node of a plan reads the
+same state, which gives repeatable reads across a whole plan for free
+and makes concurrent commits simply invisible to a running
+evaluation.
+
+=status= collapses cancellation and resource exhaustion into the
+single question an operator asks between tuples, namely whether it may
+produce another tuple. The runtime owns how =Exhausted= is decided. A
+nested invocation shares the snapshot, so nesting does not need to
+resolve a branch tip again, and a successful evaluation and cursor
+exhaustion never commit. Commit should be an explicit host operation.
+
+Budgets, authority narrowing, and resource accounting are not
+implemented, and adding a fourth status case would break exhaustive
+matches in consumers, which is the price of keeping this closed.
* Composition
Evaluators compose through invocation and result protocols alone. A