aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-10-10 00:32:29 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-10-10 00:32:29 -0300
commit0161187d843c84011749139a85c0eb31685bbc4c (patch)
tree1861790b104e40995c05898766a5b5c972d379e6 /lib
parent6044d2ee551eed72407027c58df625af8a7a8119 (diff)
downloadRNT-0161187d843c84011749139a85c0eb31685bbc4c.tar.gz
RNT-0161187d843c84011749139a85c0eb31685bbc4c.zip
rework store ephemeral relation under program and fail at path look
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/Branch.ml4
-rw-r--r--lib/kernel/EphemeralRelation.ml97
-rw-r--r--lib/kernel/Multigroup.ml6
-rw-r--r--lib/kernel/Program.ml26
4 files changed, 72 insertions, 61 deletions
diff --git a/lib/kernel/Branch.ml b/lib/kernel/Branch.ml
index 70e0711..ac8978b 100644
--- a/lib/kernel/Branch.ml
+++ b/lib/kernel/Branch.ml
@@ -108,7 +108,9 @@ module Make (S : Abstract.Storage.STORAGE) = struct
method protocols : Protocols.Handle.protocol list =
let bind =
- Option.map (fun root -> Source.bind root ~within:(Protocols.Handle.make {<>})) root
+ Option.map
+ (fun root -> {EphemeralRelation.root; within= Protocols.Handle.make {<>}})
+ root
in
let multigroups =
Prototype.mixture_of node (fun make node ->
diff --git a/lib/kernel/EphemeralRelation.ml b/lib/kernel/EphemeralRelation.ml
index 7f1e79c..8cae91f 100644
--- a/lib/kernel/EphemeralRelation.ml
+++ b/lib/kernel/EphemeralRelation.ml
@@ -7,17 +7,6 @@ type t =
| `Temporary of Protocols.Schematics.attribute_description BatMap.String.t ];
program: program option }
-(* [name] is the relation a stored program defines, once it is read from
- where it was stored under that name. *)
-type Protocols.Handle.protocol +=
- | Stored of {evaluator: string; code: Concepts.Blob.t; name: string option}
-
-let stored handle =
- Protocols.Handle.into handle (function
- | Stored {evaluator; code; name} -> Some (evaluator, code, name)
- | _ -> None )
- |> Option.map (fun i -> Protocols.Handle.invoke i Fun.id)
-
module Error = struct
open Concepts.Condition
@@ -70,7 +59,7 @@ let persisted = function
Some {Persisted.name; schematics; program}
| _ -> None
-class ephemeral_relation ?code description value enumerate inputs =
+class ephemeral_relation ?program description value enumerate inputs =
object (self)
inherit Lifecycle.counted
inherit Identity.of_id
@@ -93,34 +82,29 @@ class ephemeral_relation ?code description value enumerate inputs =
Concepts.Hash.hash_equals (Concepts.Tuple.hash member) (Concepts.Tuple.hash tuple) ) )
method protocols : Protocols.Handle.protocol list =
- let protocols = Protocols.[Relation.make self; Enumerable.make self; Schematics.make self] in
+ let protocols =
+ Protocols.[Relation.make self; Enumerable.make self; Schematics.make self]
+ @ Option.fold ~none:[] ~some:Protocols.Handle.protocols program
+ in
match persisted relation with
| None -> protocols
| Some record ->
- let stored =
- Option.fold ~none:protocols
- ~some:(fun code ->
- Stored {evaluator= record.program.evaluator; code; name= Some record.name}
- :: protocols )
- code
- in
Protocols.Addressable.make
object
method address = Persisted.Representation.to_blob record |> Concepts.Hash.hash_of_blob
end
- :: stored
+ :: protocols
end
-let instantiate ?(inputs = []) ?code description value enumerate =
- new ephemeral_relation ?code description value enumerate inputs |> Protocols.Handle.make
+let instantiate ?(inputs = []) ?program description value enumerate =
+ new ephemeral_relation ?program description value enumerate inputs |> Protocols.Handle.make
let literal description tuples =
instantiate description
{name= None; schematics= `Temporary description; program= None}
(fun () -> Ok (Generator.cursor_of (fun ~yield -> List.iter yield tuples; Ok ())))
-type binding =
- string -> Protocols.Handle.t -> (Protocols.Handle.t, Concepts.Condition.condition) result
+type binding = {root: Protocols.Handle.t; within: Protocols.Handle.t}
(* The relation a program produced has to outlive the cursor over it. *)
let enumerate_owned relation =
@@ -144,44 +128,55 @@ let enumerate_owned relation =
method to_string = Protocols.Handle.to_string cursor
end )
+let run name program within () =
+ let open Utilities.Result in
+ match program, within with
+ | Some program, Some within ->
+ let* executable = Protocols.Executable.require program in
+ Result.bind (Protocols.Executable.invoke executable [] ~within) enumerate_owned
+ | _ -> Error (Error.unbound_program name)
+
+let view ?within description program =
+ instantiate ~program description
+ {name= None; schematics= `Temporary description; program= None}
+ (run (Protocols.Handle.to_string program) (Some program) within)
+
module Make (S : Abstract.Storage.STORAGE) = struct
module SI = Storage.Make (S)
module R = SubstantialRelation.Make (S)
- (* Unbound, a stored program is only its source. Bound, enumerating
- it runs the program through its evaluator, afresh each time. *)
- let restore ?bind ~code ({Persisted.name; schematics; program} : Persisted.t) description =
- let enumerate () =
- match bind with
- | None -> Error (Error.unbound_program name)
- | Some bind ->
- let source =
- Prototype.mixture [Stored {evaluator= program.evaluator; code; name= Some name}]
- in
- Result.bind (bind program.evaluator source) enumerate_owned
- in
- instantiate ~code description
- {name= Some name; schematics= `Persisted schematics; program= Some program}
- enumerate
+ let restore ?program ?within ({Persisted.name; schematics; program= pointer} : Persisted.t)
+ description =
+ instantiate ?program description
+ {name= Some name; schematics= `Persisted schematics; program= Some pointer}
+ (run name program within)
let load ?bind connection (record : Persisted.t) =
- SI.with_read connection (fun tx ->
- let open Utilities.Result in
- let* description = R.schema_of tx record.schematics in
- let* code = SI.get_req tx (S.Hash record.program.code) in
- Ok (restore ?bind ~code record description) )
+ let open Utilities.Result in
+ let* description, source =
+ SI.with_read connection (fun tx ->
+ let* description = R.schema_of tx record.schematics in
+ let* code = SI.get_req tx (S.Hash record.program.code) in
+ Ok (description, Bytes.to_string (Concepts.Blob.bytes_of_blob code)) )
+ in
+ match bind with
+ | None -> Ok (restore record description)
+ | Some {root; within} ->
+ let* program = Program.load root ~evaluator:record.program.evaluator ~source in
+ Ok (restore ~program ~within record description)
- let store tx ~name ~evaluator ~code description =
+ let store tx ~name ~evaluator ~source description =
let open Utilities.Result in
let* schematics = R.store_schema tx description in
- let* address = SI.store_blob tx code in
+ let* address = SI.store_blob tx (Concepts.Blob.blob_of_bytes (Bytes.of_string source)) in
let record = {Persisted.name; schematics; program= {evaluator; code= address}} in
let* _ = SI.store_blob tx (Persisted.Representation.to_blob record) in
Ok record
- let persist connection ~name ~evaluator ~code description =
+ let persist connection ~name program description =
+ let open Utilities.Result in
+ let* {Program.evaluator; source; _} = Program.require program in
SI.with_transaction connection (fun tx ->
- let open Utilities.Result in
- let* record = store tx ~name ~evaluator ~code description in
- Ok (restore ~code record description) )
+ let* record = store tx ~name ~evaluator ~source description in
+ Ok (restore ~program record description) )
end
diff --git a/lib/kernel/Multigroup.ml b/lib/kernel/Multigroup.ml
index 5a3390d..eaef8c3 100644
--- a/lib/kernel/Multigroup.ml
+++ b/lib/kernel/Multigroup.ml
@@ -31,12 +31,12 @@ module Make (S : Abstract.Storage.STORAGE) = struct
let admit name h =
let open Utilities.Result in
let address entry = Concepts.Hash.hash_of_blob (encode entry) in
- match EphemeralRelation.stored h with
- | Some (evaluator, code, _) ->
+ match Program.image h with
+ | Some {evaluator; source; _} ->
let* description = Protocols.Relation.heading h in
Ok
(fun tx ->
- let* record = E.store tx ~name ~evaluator ~code description in
+ let* record = E.store tx ~name ~evaluator ~source description in
Ok (address (Ephemeral record)) )
| None ->
let* description, tuples = Protocols.Relation.read h in
diff --git a/lib/kernel/Program.ml b/lib/kernel/Program.ml
index b528c5b..64a9fcf 100644
--- a/lib/kernel/Program.ml
+++ b/lib/kernel/Program.ml
@@ -17,6 +17,10 @@ module Error = struct
let no_evaluator evaluator =
condition "no-evaluator" "No evaluator is registered under that name"
("evaluator" |=| Concepts.Value.String evaluator)
+
+ let not_a_program name =
+ condition "not-a-program" "A handle was expected to carry a program and did not"
+ ("object" |=| Concepts.Value.String name)
end
type kind = Protocols.Evaluator.kind = ..
@@ -33,10 +37,17 @@ let reference evaluator =
| Some i ->
String.sub evaluator 0 i, String.sub evaluator (i + 1) (String.length evaluator - i - 1)
-let lookup root evaluator =
+let require handle =
+ image handle |> Option.to_result ~none:(Error.not_a_program (Protocols.Handle.to_string handle))
+
+let with_evaluator root evaluator f =
+ let open Utilities.Result in
let scope, language = reference evaluator in
- Path.lookup root Path.(scope @/ "evaluator" @/ language @/ this)
- |> Result.map_error (fun _ -> Error.no_evaluator evaluator)
+ let* found =
+ Path.lookup root Path.(scope @/ "evaluator" @/ language @/ this)
+ |> Result.map_error (fun _ -> Error.no_evaluator evaluator)
+ in
+ Protocols.Handle.releasing found (fun () -> Result.bind (Protocols.Evaluator.require found) f)
class program ?root image =
object (self)
@@ -47,9 +58,7 @@ class program ?root image =
method invoke inputs ~within =
let open Utilities.Result in
let* root = Option.to_result ~none:(Error.unloaded image.evaluator) root in
- let* found = lookup root image.evaluator in
- Protocols.Handle.releasing found (fun () ->
- let* evaluator = Protocols.Evaluator.require found in
+ with_evaluator root image.evaluator (fun evaluator ->
Protocols.Evaluator.eval evaluator image.kind inputs ~within )
method protocols : Protocols.Handle.protocol list =
@@ -58,3 +67,8 @@ class program ?root image =
let make ?root ~evaluator ~source kind =
new program ?root {evaluator; kind; source} |> Protocols.Handle.make
+
+let load root ~evaluator ~source =
+ with_evaluator root evaluator (fun found ->
+ Protocols.Evaluator.parse found source
+ |> Result.map (make ~root ~evaluator ~source) )