Skip to documentation
SLOP

tiny.pluck.toplevel.lifecycle

Reference tiny.pluck toplevel lifecycle

Defined in toplevel.

API (16)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstoplevellifecycle
Static calls · unresolved targets: unknown · external targets: unknown.

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,};
Called byCallsNo direct callstiny.smgstorage.database.lifecycleopentoplevel.lifecycledeinit
Static calls · unresolved targets: 0 · external targets: 9.
Called byCallstest sourcelib.pluck.src.toplevel.lifecycletest: full distribution resolves fini...test sourcelib.pluck.src.toplevel.lifecycle.test_lowerca...jl programs parse and evaluatetest sourcelib.pluck.src.toplevel.lifecycletest: patchConfig updates context con...test sourcelib.pluck.src.toplevel.lifecycle.test_query_t...jl public constructorstest sourcelib.pluck.src.toplevel.lifecycletest: stdlib ADT equality helpers com...+6 morebdd.Managerinitpexpr.Definitionsinitpexpr.TypeRegistryinitWithDefaultstoplevel.lifecycleinit
Static calls · unresolved targets: 1 · external targets: 7.
Called byCallsNo direct callersbdd.Managerinittoplevel.lifecycleinitWorker
Static calls · unresolved targets: 0 · external targets: 13.
Called byCallsNo direct callersbdd.Managerinitpexpr.Definitionsinitpexpr.TypeRegistryinitWithDefaultstoplevel.lifecyclereset
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsNo direct callersbdd.Managerinittoplevel.lifecycleresetManagerForQuery
Static calls · unresolved targets: 0 · external targets: 1.

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.

Audit

Definitions17
Public names23
Members34
Version26.7.0
Revisiondaab053ee433