tiny.pluck.toplevel.lifecycle
Defined in toplevel.
API (16)
Actions
Public operations.
QueryConfig.mergeWithasSharedContextcreateQueryContextdeinitinitinitWorkerloadStdlibpatchConfigresetresetManagerForQuerysetConfig
Types and contracts
Public types and contracts.
Source
Source: lib/pluck/src/query.zig:47
zig
pub const QueryConfig = struct { max_depth: ?u32 = null, ite_limit: ?u64 = null, time_limit: ?f64 = null, sample_after_max_depth: ?bool = null, use_strict_order: ?bool = null, use_reverse_order: ?bool = null, definition_order_mode: ?DefinitionOrderMode = null, parallel_wmc: ?bool = null, rng_seed: ?u64 = null, pub fn mergeWith(self: QueryConfig, session: SessionConfig) ResolvedConfig { return .{ .max_depth = self.max_depth orelse session.max_depth, .ite_limit = self.ite_limit orelse session.ite_limit, .time_limit = self.time_limit orelse session.time_limit, .sample_after_max_depth = self.sample_after_max_depth orelse session.sample_after_max_depth, .use_strict_order = self.use_strict_order orelse session.use_strict_order, .use_reverse_order = self.use_reverse_order orelse session.use_reverse_order, .definition_order_mode = self.definition_order_mode orelse session.definition_order_mode, .parallel_wmc = self.parallel_wmc orelse session.parallel_wmc, .rng_seed = self.rng_seed orelse session.rng_seed orelse session.lpsmc_rng_seed, }; }};Source: lib/pluck/src/query.zig:107
zig
pub const QueryContext = struct { allocator: Allocator, arena: std.heap.ArenaAllocator, manager: *Manager, shared: SharedContext, config: ResolvedConfig, stats: LazyKCStats,};Source: lib/pluck/src/query.zig:121
zig
pub const RunContext = struct { state: LazyKCState, worker_id: u32, query: *QueryContext,};Source: lib/pluck/src/query.zig:33
zig
pub const SessionConfig = struct { max_depth: ?u32 = null, ite_limit: ?u64 = limits.default_agent_ite_limit, time_limit: ?f64 = null, sample_after_max_depth: bool = false, use_strict_order: bool = true, use_reverse_order: bool = false, definition_order_mode: DefinitionOrderMode = .none, parallel_wmc: bool = false, verbose: bool = false, rng_seed: ?u64 = null, lpsmc_rng_seed: ?u64 = null,};Source: lib/pluck/src/query.zig:21
zig
pub const SharedContext = struct { allocator: Allocator, arena: *alloc_arena.Arena, types: *const TypeRegistry, definitions: *const Definitions, config: SessionConfig,};Source: lib/pluck/src/toplevel/lifecycle.zig
zig
const std = @import("std");const alloc_arena = @import("alloc_arena");const pluck = @import("../root.zig");const log = pluck.logger;const Allocator = std.mem.Allocator;const pexpr = pluck.pexpr;const Definitions = pexpr.Definitions;const TypeRegistry = pexpr.TypeRegistry;const lpsmc_module = pluck.lpsmc;const bdd = pluck.bdd;const Manager = bdd.Manager;const context_owner = @import("context.zig");const ToplevelContext = context_owner.ToplevelContext;const top_types = @import("types.zig");const ToplevelError = top_types.ToplevelError;const config_owner = @import("config.zig");const ToplevelConfig = config_owner.ToplevelConfig;const ToplevelConfigPatch = config_owner.ToplevelConfigPatch;const ConfigError = config_owner.ConfigError;const shared_owner = @import("shared.zig");const source_owner = @import("source.zig");const stdlib_source = @embedFile("../stdlib.pluck");pub fn init(allocator: Allocator) !ToplevelContext { const arena_ptr = try allocator.create(alloc_arena.Arena); errdefer allocator.destroy(arena_ptr); arena_ptr.* = alloc_arena.Arena.init(allocator); errdefer arena_ptr.deinit(); const query_arena_ptr = try allocator.create(alloc_arena.Arena); errdefer allocator.destroy(query_arena_ptr); query_arena_ptr.* = alloc_arena.Arena.init(allocator); errdefer query_arena_ptr.deinit(); const arena_alloc = arena_ptr.allocator(); const types = try TypeRegistry.initWithDefaults(arena_alloc); const definitions = Definitions.init(arena_alloc); const manager = try allocator.create(Manager); errdefer allocator.destroy(manager); manager.* = try Manager.init(arena_alloc); errdefer manager.deinit(); var self = ToplevelContext{ .allocator = allocator, .owns_shared = true, .owns_arena = true, .arena = arena_ptr, .query_arena = query_arena_ptr, .types = types, .definitions = definitions, .manager = manager, .config = .{}, }; try loadStdlib(&self); return self;}pub fn initWorker(self: *const ToplevelContext, allocator: Allocator) !ToplevelContext { const arena_ptr = try allocator.create(alloc_arena.Arena); errdefer allocator.destroy(arena_ptr); arena_ptr.* = alloc_arena.Arena.init(allocator); errdefer arena_ptr.deinit(); const query_arena_ptr = try allocator.create(alloc_arena.Arena); errdefer allocator.destroy(query_arena_ptr); query_arena_ptr.* = alloc_arena.Arena.init(allocator); errdefer query_arena_ptr.deinit(); const manager = try allocator.create(Manager); errdefer allocator.destroy(manager); manager.* = try Manager.init(arena_ptr.allocator()); errdefer manager.deinit(); const arena_alloc = arena_ptr.allocator(); var cloned_defs = try shared_owner.cloneDefinitionsShallow(arena_alloc, &self.definitions); errdefer cloned_defs.defs.deinit(); var cloned_types = try shared_owner.cloneTypesShallow(arena_alloc, &self.types); errdefer { cloned_types.type_of_constructor.deinit(); cloned_types.constructors_of_type.deinit(); cloned_types.args_of_constructor.deinit(); } var worker = self.*; worker.allocator = allocator; worker.owns_shared = false; worker.owns_arena = true; worker.arena = arena_ptr; worker.query_arena = query_arena_ptr; worker.manager = manager; worker.definitions = cloned_defs; worker.types = cloned_types; worker.incremental_lpsmc = null; worker.last_query_constructor_typo = null; worker.current_source = null; worker.loading_stdlib = false; return worker;}pub fn loadStdlib(self: *ToplevelContext) error{ OutOfMemory, StdlibLoadFailed }!void { self.loading_stdlib = true; defer self.loading_stdlib = false; source_owner.processSourceSexprNoWriter(self, stdlib_source) catch |err| { if (@import("builtin").mode == .debug) { log.err("stdlib load failed: {}", .{err}); } return switch (err) { ToplevelError.OutOfMemory => error.OutOfMemory, else => error.StdlibLoadFailed, }; };}pub fn deinit(self: *ToplevelContext) void { if (!self.owns_shared) { self.definitions.defs.deinit(); self.types.type_of_constructor.deinit(); self.types.constructors_of_type.deinit(); self.types.args_of_constructor.deinit(); } if (self.incremental_lpsmc) |lpsmc| { lpsmc_module.deinit(lpsmc); self.allocator.destroy(lpsmc); } self.manager.deinit(); self.allocator.destroy(self.manager); if (self.owns_arena) { self.arena.deinit(); self.allocator.destroy(self.arena); } self.query_arena.deinit(); self.allocator.destroy(self.query_arena);}pub fn setConfig(self: *ToplevelContext, config: ToplevelConfig) void { self.config = config;}pub fn patchConfig(self: *ToplevelContext, patch: ToplevelConfigPatch) ConfigError!void { try config_owner.applyPatch(&self.config, patch);}const query_context = pluck.query_context;pub const SharedContext = query_context.SharedContext;pub const QueryContext = query_context.QueryContext;pub const RunContext = query_context.RunContext;pub const QueryConfig = query_context.QueryConfig;pub const SessionConfig = query_context.SessionConfig;pub fn asSharedContext(self: *const ToplevelContext) SharedContext { return SharedContext{ .allocator = self.allocator, .arena = self.arena, .types = &self.types, .definitions = &self.definitions, .config = SessionConfig{ .max_depth = self.config.max_depth, .ite_limit = self.config.ite_limit, .time_limit = self.config.time_limit, .sample_after_max_depth = self.config.sample_after_max_depth, .use_strict_order = self.config.use_strict_order, .use_reverse_order = self.config.use_reverse_order, .definition_order_mode = self.config.definition_order_mode, .parallel_wmc = self.config.parallel_wmc, .verbose = self.config.verbose, .rng_seed = self.config.rng_seed, .lpsmc_rng_seed = self.config.lpsmc_rng_seed, }, };}pub fn createQueryContext(self: *const ToplevelContext, query_config: QueryConfig) !QueryContext { return try query_context.initQueryContext(asSharedContext(self), query_config);}pub fn reset(self: *ToplevelContext) error{ OutOfMemory, StdlibLoadFailed, MacroAlreadyExists }!void { if (self.incremental_lpsmc) |lpsmc| { lpsmc_module.clearCaches(lpsmc); } _ = self.arena.reset(.retain_capacity); const alloc = self.arena.allocator(); self.types = try TypeRegistry.initWithDefaults(alloc); self.definitions = Definitions.init(alloc); self.manager.* = try Manager.init(alloc); self.current_source = null; self.last_query_constructor_typo = null; try loadStdlib(self);}pub fn resetManagerForQuery(self: *ToplevelContext) !void { const manager_alloc = self.manager.allocator; self.manager.deinit(); self.manager.* = try Manager.init(manager_alloc);}test "query type registry matches Pluck.jl public constructors" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); try std.testing.expect(ctx.types.hasConstructor("Marginal")); try std.testing.expect(ctx.types.hasConstructor("Posterior")); try std.testing.expect(ctx.types.hasConstructor("PosteriorSamples")); try std.testing.expect(ctx.types.hasConstructor("AdaptiveRejection")); try std.testing.expect(!ctx.types.hasConstructor("SubproblemMonteCarlo")); try ctx.reset(); try std.testing.expect(ctx.types.hasConstructor("Marginal")); try std.testing.expect(ctx.types.hasConstructor("Posterior")); try std.testing.expect(ctx.types.hasConstructor("PosteriorSamples")); try std.testing.expect(ctx.types.hasConstructor("AdaptiveRejection")); try std.testing.expect(!ctx.types.hasConstructor("SubproblemMonteCarlo"));}test "patchConfig updates context config" { var ctx = try init(std.testing.allocator); defer ctx.deinit(); try ctx.patchConfig(.{ .time_limit = .{ .set = 0.5 }, .var_order = .reverse, .fallback_lpsmc_k = 3, }); try std.testing.expectEqual(@as(?f64, 0.5), ctx.config.time_limit); try std.testing.expect(ctx.config.use_strict_order); try std.testing.expect(ctx.config.use_reverse_order); try std.testing.expectEqual(@as(usize, 3), ctx.config.fallback_lpsmc_k);}test "worker context validates definitions without mutating parent" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); try ctx.processSource("(define p 0.25)"); var worker = try ctx.initWorker(allocator); defer worker.deinit(); try worker.processSource( \\(define-type result (Yes) (No)) \\(define p 0.75) ); try std.testing.expect(worker.types.hasConstructor("Yes")); try std.testing.expect(!ctx.types.hasConstructor("Yes")); var parent_result = try ctx.processForm("(Marginal (flip p))") orelse return error.TestExpectedEqual; defer parent_result.deinit(); var parent_true: f64 = 0; for (parent_result.outcomes) |outcome| { if (std.mem.eql(u8, outcome.value_str, "True")) parent_true = outcome.probability; } try std.testing.expectApproxEqAbs(@as(f64, 0.25), parent_true, 1e-9); var worker_result = try worker.processForm("(Marginal (flip p))") orelse return error.TestExpectedEqual; defer worker_result.deinit(); var worker_true: f64 = 0; for (worker_result.outcomes) |outcome| { if (std.mem.eql(u8, outcome.value_str, "True")) worker_true = outcome.probability; } try std.testing.expectApproxEqAbs(@as(f64, 0.75), worker_true, 1e-9);}test "stdlib list and nat helpers support comparison programs" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const maybe_result = try ctx.processForm( "(Marginal (and (eq_nat (length (Cons True (Cons False Nil))) 2) (list_eq eq_nat (take 2 (Cons 0 (Cons 1 (Cons 2 Nil)))) (Cons 0 (Cons 1 Nil)))))", ); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "stdlib operator names support Pluck.jl programs" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const maybe_result = try ctx.processForm( "(Marginal (and (nat=? (+ 1 2) 3) (and (nat=? (- 3 1) 2) (and (nat=? (* 2 3) 6) (and (> 3 2) (and (< 2 3) (and (>= 3 3) (and (<= 3 3) (and (list=? nat=? [1 2] (Cons 1 (Cons 2 Nil))) (=? (Cons True Nil) (Cons True Nil)))))))))))", ); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "stdlib reference helpers support Pluck.jl programs" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const maybe_result = try ctx.processForm( "(Marginal (and (nat=? (dec 2) 1) (and (iseven 2) (list=? nat=? (zip_with + [1 2] [3 4]) [4 6]))))", ); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "stdlib reference list helpers match Pluck.jl names" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const maybe_result = try ctx.processForm( "(Marginal (and (nat=? (mod 7 3) 1) (and (isempty (cdr_safe Nil)) (and (nat=? (fold + 0 [1 2 3]) 6) (and (list=? nat=? (mapi + [2 3]) [2 4]) (and (list=? nat=? (filter (fn x -> (< x 3)) [1 3 2]) [1 2]) (and (list=? nat=? (filteri (fn x i -> (< i 2)) [5 6 7]) [5 6]) (and (list=? nat=? (range 3) [0 1 2]) (and (list=? nat=? (append_one [1 2] 3) [1 2 3]) (and (nat=? (head-or Nil 4) 4) (and (nat=? (head-or [5] 4) 5) (and (int2=? (Int2 True False) (Int2 True False)) (constructor=? (suspendible-list=? nat=? [1] [1]) (Suspend FinallyTrue))))))))))))))", ); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "stdlib reference distribution helpers parse and evaluate" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const uniform_result = try ctx.processForm("(Marginal (make-uniform [True False]))"); try std.testing.expect(uniform_result != null); var uniform = uniform_result.?; defer uniform.deinit(); try std.testing.expect(!uniform.program_error); try std.testing.expectEqual(@as(usize, 1), uniform.outcomes.len); try std.testing.expectEqualStrings("(Cons (Pair True 0.5) (Cons (Pair False 0.5) (Nil)))", uniform.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), uniform.outcomes[0].probability, 1e-10); const normalized_result = try ctx.processForm("(Marginal (normalize-seq [(Pair True 1.0) (Pair False 1.0)]))"); try std.testing.expect(normalized_result != null); var normalized = normalized_result.?; defer normalized.deinit(); try std.testing.expect(!normalized.program_error); try std.testing.expectEqual(@as(usize, 1), normalized.outcomes.len); try std.testing.expectEqualStrings("(Cons (Pair True 0.5) (Cons (Pair False 1) (Nil)))", normalized.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), normalized.outcomes[0].probability, 1e-10); const sample_result = try ctx.processForm("(Marginal (sample-seq (normalize-seq [(Pair True 1.0) (Pair False 1.0)])))"); try std.testing.expect(sample_result != null); var sample = sample_result.?; defer sample.deinit(); try std.testing.expect(!sample.program_error); try std.testing.expectEqual(@as(usize, 2), sample.outcomes.len); try std.testing.expectEqualStrings("False", sample.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 0.5), sample.outcomes[0].probability, 1e-10); const randnat_result = try ctx.processForm("(Marginal (< (randnat) 2))"); try std.testing.expect(randnat_result != null); var randnat = randnat_result.?; defer randnat.deinit(); try std.testing.expect(!randnat.program_error); try std.testing.expectEqual(@as(usize, 2), randnat.outcomes.len); try std.testing.expectEqualStrings("False", randnat.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 0.25), randnat.outcomes[0].probability, 1e-10); try std.testing.expectEqualStrings("True", randnat.outcomes[1].value_str); try std.testing.expectApproxEqAbs(@as(f64, 0.75), randnat.outcomes[1].probability, 1e-10);}test "lowercase constructors from Pluck.jl programs parse and evaluate" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); try std.testing.expect(try ctx.processForm("(define-type char (a_) (b_))") == null); const maybe_result = try ctx.processForm("(Marginal (constructor=? (a_) (a_)))"); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "full distribution resolves finite lazy values beyond one thousand thunks" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); try std.testing.expect(try ctx.processForm("(define (long-list n) (case n of O => Nil | S k => (Cons O (long-list k))))") == null); const maybe_result = try ctx.processForm("(Marginal (long-list 1005))"); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expect(result.limit_reason == null); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}test "stdlib ADT equality helpers compare constructed values" { const allocator = std.testing.allocator; var ctx = try init(allocator); defer ctx.deinit(); const maybe_result = try ctx.processForm( "(Marginal (adt_eq (Cons True (Cons False Nil)) (Cons True (Cons False Nil))))", ); try std.testing.expect(maybe_result != null); var result = maybe_result.?; defer result.deinit(); try std.testing.expect(!result.program_error); try std.testing.expectEqual(@as(usize, 1), result.outcomes.len); try std.testing.expectEqualStrings("True", result.outcomes[0].value_str); try std.testing.expectApproxEqAbs(@as(f64, 1.0), result.outcomes[0].probability, 1e-10);}Source: lib/pluck/src/toplevel/root.zig:9
zig
pub const lifecycle = @import("lifecycle.zig");Complete caller list for toplevel.lifecycle.init
11 direct callers.
lib.pluck.src.toplevel.lifecycle.test_full_distribution_resolves_finite_lazy_values_beyond_one_thousand_thunks[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:423in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_lowercase_constructors_from_Pluck.jl_programs_parse_and_evaluate[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:405in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_patchConfig_updates_context_config[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:235in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_query_type_registry_matches_Pluck.jl_public_constructors[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:216in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_ADT_equality_helpers_compare_constructed_values[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:441in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_list_and_nat_helpers_support_comparison_programs[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:285in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_operator_names_support_Pluck.jl_programs[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:303in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_reference_distribution_helpers_parse_and_evaluate[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:357in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_reference_helpers_support_Pluck.jl_programs[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:321in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_stdlib_reference_list_helpers_match_Pluck.jl_names[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:339in nearest public ownertiny.pluck.toplevel.lifecyclelib.pluck.src.toplevel.lifecycle.test_worker_context_validates_definitions_without_mutating_parent[function] — test source atlib/pluck/src/toplevel/lifecycle.zig:251in nearest public ownertiny.pluck.toplevel.lifecycle
Audit
| Definitions | 17 |
|---|---|
| Public names | 23 |
| Members | 34 |
| Version | 26.7.0 |
| Revision | daab053ee433 |