Nothing
test_that("the cheap-screen depth is one value across the R and C++ defaults", {
# The screening depth exists at three points -- the registry the front door
# reads, the literal the cpp entry declares (an Rcpp attribute default has
# to be a literal, so it cannot read the engine constant), and the engine
# constant the grid driver falls back to. A fit's cost and its cheap ranking
# both move with it, so two live values would mean the same grid screened at
# two depths depending on which layer supplied the number.
ref <- as.integer(tulpa:::.nl_screen("iters"))
# The cpp entry's own default, as the generated R wrapper carries it.
entry <- formals(tulpa:::cpp_nested_laplace_joint_multi)$screen_iters
expect_false(is.null(entry))
expect_identical(as.integer(eval(entry)), ref)
# And the engine constant behind it.
src <- test_path("..", "..", "src", "nested_laplace_grid.h")
skip_if_not(file.exists(src), "package sources not available")
line <- grep("static const int CHEAP_SCREEN_ITERS",
readLines(src, warn = FALSE), value = TRUE)
expect_length(line, 1L)
expect_identical(
as.integer(sub(".*=\\s*([0-9]+).*", "\\1", line)), ref)
})
skip_on_cran()
# Engine settings (R/settings.R): the single source of truth for every default
# the nested-Laplace machinery lays down on its own.
#
# Three things are tested, in order of what they protect:
# 1. INTEGRITY -- the table is well-formed and every binding resolves, so a
# new family cannot be half-registered.
# 2. THE VALUES -- each default axis is pinned to its exact nodes. These are
# the numbers the engine's behaviour rests on; a change to one is a change
# to every fit that does not pin that axis, so it has to be deliberate
# enough to update a test.
# 3. NO RE-SCATTERING -- a source-level check that a default axis is not
# written inline again somewhere else, which is the condition the table
# exists to remove (gcol33/tulpa#293 turned on the engine being able to
# recognise its OWN default, which is impossible while five files each
# carry a copy of it).
# Runs at every tier: no fit, pure table and source inspection.
test_that("every grid axis materialises to a usable vector", {
skip_on_cran()
for (key in names(tulpa:::.NL_GRID)) {
spec <- tulpa:::.NL_GRID[[key]]
if (isTRUE(spec$data_dependent)) {
# Refuses materialisation rather than silently returning something
# shaped like an axis.
expect_error(tulpa:::.nl_grid_axis(key), "data-dependent",
info = key)
expect_true(!is.null(spec$n) || !is.null(spec$lo_mult), info = key)
next
}
ax <- tulpa:::.nl_grid_axis(key)
expect_true(is.numeric(ax), info = key)
expect_gt(length(ax), 1L)
expect_true(all(is.finite(ax)), info = key)
expect_false(anyDuplicated(ax) > 0L, info = key)
expect_identical(ax, sort(ax), info = key)
}
expect_error(tulpa:::.nl_grid_axis("no_such_axis"), "Unknown default grid axis")
})
test_that("every family binding resolves to a declared axis", {
skip_on_cran()
for (fam in names(tulpa:::.NL_FAMILY_AXES)) {
bind <- tulpa:::.NL_FAMILY_AXES[[fam]]
expect_true(length(bind) > 0L, info = fam)
expect_true(all(nzchar(names(bind))), info = fam)
for (field in names(bind)) {
key <- bind[[field]]
expect_true(key %in% names(tulpa:::.NL_GRID),
info = paste(fam, field, key))
}
}
# Every registry family is bound, except the ones that genuinely default no
# axis (lf carries no outer axes at all).
unbound <- setdiff(names(tulpa:::.NL_REGISTRY),
names(tulpa:::.NL_FAMILY_AXES))
expect_identical(unbound, "lf")
# And every binding names a real family, or is a documented path
# pseudo-type (leading dot).
extra <- setdiff(names(tulpa:::.NL_FAMILY_AXES),
names(tulpa:::.NL_REGISTRY))
expect_true(all(startsWith(extra, ".")), info = paste(extra, collapse = ", "))
})
test_that("the default axes are exactly these values", {
skip_on_cran()
# Pinned deliberately: these numbers ARE the engine's behaviour on every
# fit that does not name its own grid.
expect_equal(tulpa:::.nl_grid_axis("field_sd"),
exp(seq(log(0.1), log(3), length.out = 5)))
expect_equal(tulpa:::.nl_grid_axis("gmrf_tau"),
exp(seq(log(0.3), log(30), length.out = 9)))
expect_equal(tulpa:::.nl_grid_axis("car_tau"),
exp(seq(log(0.3), log(30), length.out = 5)))
expect_equal(tulpa:::.nl_grid_axis("ar1_tau"),
exp(seq(log(0.5), log(20), length.out = 5)))
expect_equal(tulpa:::.nl_grid_axis("gp_var"),
exp(seq(log(0.05), log(2), length.out = 5)))
expect_equal(tulpa:::.nl_grid_axis("gp_lengthscale"),
exp(seq(log(0.05), log(1.5), length.out = 5)))
expect_equal(tulpa:::.nl_grid_axis("mo_field_sd"),
exp(seq(log(0.3), log(1.5), length.out = 3)))
expect_equal(tulpa:::.nl_grid_axis("mo_lengthscale"),
exp(seq(log(0.1), log(1.0), length.out = 3)))
expect_equal(tulpa:::.nl_grid_axis("bym2_rho"),
c(0.2, 0.5, 0.8, 0.95, 0.99, 0.999))
expect_equal(tulpa:::.nl_grid_axis("joint_car_rho"),
c(0.5, 0.8, 0.95, 0.99))
expect_equal(tulpa:::.nl_grid_axis("ar1_rho"), c(0, 0.4, 0.7, 0.9, 0.97))
expect_equal(tulpa:::.nl_grid_axis("mo_rho"), c(-0.4, 0, 0.4))
expect_equal(tulpa:::.nl_grid_axis("mcar_sd"), c(0.4, 0.7, 1.1, 1.7))
expect_equal(tulpa:::.nl_grid_axis("mcar_rho"),
c(-0.8, -0.4, 0, 0.4, 0.7, 0.9))
# `prepend` puts the exact no-transfer node in the copy axis, at the front.
alpha <- tulpa:::.nl_grid_axis("copy_alpha")
expect_identical(alpha[1L], 0)
expect_equal(alpha, c(0, exp(seq(log(0.1), log(3), length.out = 9))))
# Shape parameters of the data-dependent axes.
expect_identical(tulpa:::.nl_grid_par("car_rho", "n"), 5L)
expect_equal(tulpa:::.nl_grid_par("car_rho", "margin"), 0.05)
expect_equal(tulpa:::.nl_grid_par("car_rho", "bounds"), c(0, 1))
expect_equal(tulpa:::.nl_grid_par("spde_registry", "span"), 1.4)
expect_equal(tulpa:::.nl_grid_par("spde_direct", "lo_mult"), 0.3)
expect_equal(tulpa:::.nl_grid_par("spde_direct", "hi_mult"), 3)
expect_equal(tulpa:::.nl_grid_par("tgmrf_axis", "half_width"), 2)
# Diagnostic / recenter / spatiotemporal defaults.
expect_equal(tulpa:::.nl_diag("k_usable"), 0.7)
# ONE outer-k draw budget across all four backends (gcol33/tulpa#632). 500,
# not the 200 this held before: the joint path was raised to it at
# gcol33/tulpa#127 when outer scoring stopped being adaptive-batched, and it
# is the budget every shipped outer-k number was read at. Under
# gcol33/tulpa#631 this also fixes the PSIS tail fraction (13.6%), so it is
# not a pure cost knob and a change to it moves reported k-hats.
expect_identical(tulpa:::.nl_diag("k_samples"), 500L)
expect_identical(tulpa:::.nl_diag("k_samples_ok"), 800L)
expect_identical(tulpa:::.nl_diag("k_samples_good"), 2000L)
expect_identical(tulpa:::.nl_diag("k_bootstrap"), 1000L)
expect_equal(tulpa:::.nl_diag("gamma3_ok"), 0.5)
expect_equal(tulpa:::.nl_diag("gamma3_unreliable"), 1.0)
# The two skew-correction defaults, both decided on measurement and both
# recorded here so a change to either is deliberate: the CENTRE band is off
# (gcol33/tulpa#376) and the correction itself is ON (gcol33/tulpa#364).
expect_identical(tulpa:::.nl_diag("centre_unreliable"), Inf)
expect_true(tulpa:::.nl_diag("skew_correct"))
# The within-cell default, decided against dense references at the
# placement the engine ships (gcol33/tulpa#932), and the kind that admits it.
expect_identical(tulpa:::.nl_diag("within_cell"), "log_quadratic")
expect_true("log_quadratic" %in% tulpa:::.NL_SUPPORT[["density"]]$within)
expect_equal(tulpa:::.nl_diag("grid_resolved"), 1)
expect_identical(tulpa:::.nl_recenter("n_pts"), 5L)
expect_equal(tulpa:::.nl_recenter("span"), 2.5)
expect_identical(tulpa:::.nl_recenter("max_attempts_joint"), 2L)
expect_identical(tulpa:::.nl_recenter("max_attempts_registry"), 1L)
# A multiple of what a flat marginal puts on one node, not a share of the
# axis's weight (gcol33/tulpa#375). `2` is the retired 0.5 share at the four
# nodes it was tuned on.
expect_equal(tulpa:::.nl_recenter("edge_mass_mult"), 2)
expect_error(tulpa:::.nl_recenter("edge_mass"), "Unknown recenter setting")
expect_identical(tulpa:::.nl_st_default("n_spatial"), 4L)
expect_equal(tulpa:::.nl_st_default("tau_upper"), 16)
# Cheap-pass grid screening. `iters` is a cost-against-ranking-fidelity
# trade paid on every cell of the grid, so it is a number the engine's
# throughput rests on and a change to it has to be deliberate.
expect_equal(tulpa:::.nl_screen("prune_tol"), 1e-3)
expect_identical(tulpa:::.nl_screen("iters"), 2L)
expect_error(tulpa:::.nl_diag("nope"), "Unknown diagnostic setting")
expect_error(tulpa:::.nl_screen("nope"), "Unknown screening setting")
expect_error(tulpa:::.nl_recenter("nope"), "Unknown recenter setting")
expect_error(tulpa:::.nl_st_default("nope"), "Unknown spatiotemporal")
})
test_that("registry defaults() fill exactly the bound fields, crossed", {
skip_on_cran()
fill <- function(type, p = list()) {
tulpa:::.NL_REGISTRY[[type]]$defaults(p, list())
}
# Single-axis family: the axis, unexpanded.
expect_equal(fill("icar")$tau_grid, tulpa:::.nl_grid_axis("gmrf_tau"))
expect_equal(fill("iid")$sigma_grid, tulpa:::.nl_grid_axis("field_sd"))
# Two-axis family: the Cartesian product, in binding order, stored
# pre-paired (one row of theta_grid per tuple).
b <- fill("bym2")
gr <- expand.grid(sigma = tulpa:::.nl_grid_axis("field_sd"),
rho = tulpa:::.nl_grid_axis("bym2_rho"))
expect_equal(b$sigma_grid, gr$sigma)
expect_equal(b$rho_grid, gr$rho)
expect_identical(length(b$sigma_grid), length(b$rho_grid))
# Four-axis family: 3^4 cells.
mo <- fill("hsgp_mo")
expect_identical(length(mo$sigma_1_grid), 81L)
expect_equal(sort(unique(mo$lengthscale_grid)),
tulpa:::.nl_grid_axis("mo_lengthscale"))
# A supplied axis is honoured; the family's OTHER axes are then also taken
# as supplied (a family's axes are pre-paired, so a partial fill would pair
# unequal lengths).
pinned <- fill("bym2", list(sigma_grid = c(1, 2), rho_grid = c(0.5, 0.5)))
expect_equal(pinned$sigma_grid, c(1, 2))
expect_equal(pinned$rho_grid, c(0.5, 0.5))
expect_error(fill("bym2", list(sigma_grid = c(1, 2, 3), rho_grid = c(0.5, 0.7))),
"PAIRED outer-grid cells.*got 3 / 2")
# A length-1 field is a value held fixed and is broadcast across the cells.
held <- fill("bym2", list(sigma_grid = c(1, 2, 3), rho_grid = 0.5))
expect_equal(held$rho_grid, rep(0.5, 3))
# ONE supplied axis is kept as an axis and crossed with the default of the
# other; replacing it by the default too discarded it (gcol33/tulpa#884).
half <- fill("bym2", list(sigma_grid = c(0.4, 0.2, 0.2)))
gr <- expand.grid(sigma = c(0.2, 0.4),
rho = tulpa:::.nl_grid_axis("bym2_rho"))
expect_equal(half$sigma_grid, gr$sigma)
expect_equal(half$rho_grid, gr$rho)
a1 <- fill("ar1", list(tau_grid = c(1, 2, 4, 8)))
expect_equal(sort(unique(a1$tau_grid)), c(1, 2, 4, 8))
expect_equal(sort(unique(a1$rho_grid)), tulpa:::.nl_grid_axis("ar1_rho"))
expect_identical(length(a1$tau_grid), 4L * length(tulpa:::.nl_grid_axis("ar1_rho")))
# nngp / hsgp share the GP axes, so they default identically.
expect_equal(fill("nngp")$sigma2_grid, fill("hsgp")$sigma2_grid)
expect_equal(fill("nngp")$phi_gp_grid, fill("hsgp")$lengthscale_grid)
# An unbound type is returned untouched rather than erroring.
expect_identical(tulpa:::.nl_fill_family_axes(list(a = 1), "not_a_family"),
list(a = 1))
})
test_that("provenance narrows to the family that laid the axis", {
skip_on_cran()
pinned <- tulpa:::.nl_axis_is_pinned
# Each family's OWN default is recognised on its own field.
expect_false(pinned(list(type = "icar",
tau_grid = tulpa:::.nl_grid_axis("gmrf_tau")),
"tau_grid", type = "icar"))
expect_false(pinned(list(type = "nngp",
sigma2_grid = tulpa:::.nl_grid_axis("gp_var")),
"sigma2_grid", type = "nngp"))
expect_false(pinned(list(type = "ar1",
rho_grid = tulpa:::.nl_grid_axis("ar1_rho")),
"rho_grid", type = "ar1"))
# The two PATH pseudo-types: the joint areal backends and every copy block
# default the field-SD axis on `sigma_grid`, where the icar REGISTRY entry
# defaults a precision axis instead. Narrowing to the wrong one here is what
# would re-break gcol33/tulpa#293 for the occu_cover shape.
fsd <- tulpa:::.nl_grid_axis("field_sd")
expect_false(pinned(list(type = "icar", sigma_grid = fsd), "sigma_grid",
type = ".joint_areal"))
expect_false(pinned(list(type = "rw1", sigma_grid = fsd), "sigma_grid",
type = ".copy"))
# A grid that is some OTHER family's default axis is a pin, not a default.
expect_true(pinned(list(type = "icar",
tau_grid = tulpa:::.nl_grid_axis("ar1_tau")),
"tau_grid", type = "icar"))
# A real user grid is a pin.
expect_true(pinned(list(type = "icar", tau_grid = c(1, 2, 3)), "tau_grid",
type = "icar"))
# Absent is a default; marked is a default whatever the values.
expect_false(pinned(list(type = "icar"), "tau_grid", type = "icar"))
expect_false(pinned(list(type = "icar", tau_grid = auto_grid(c(1, 2, 3))),
"tau_grid", type = "icar"))
# `type` is never inferred from the block. A joint areal block carries
# `type = "icar"` while its `sigma_grid` default comes from `.joint_areal`;
# inferring would read the engine's own default as a pin, which is the #293
# failure one layer down.
expect_false(pinned(list(type = "icar", sigma_grid = fsd), "sigma_grid"))
# Without a type, every family's binding for that field is a candidate.
expect_false(tulpa:::.nl_axis_matches_default(
tulpa:::.nl_grid_axis("ar1_tau"), "tau_grid", type = "icar"))
expect_true(tulpa:::.nl_axis_matches_default(
tulpa:::.nl_grid_axis("ar1_tau"), "tau_grid"))
# A data-dependent axis never matches, so such a grid is left alone.
expect_false(tulpa:::.nl_axis_matches_default(seq(0.05, 0.95, length.out = 5),
"rho_grid", type = "car_proper"))
# A field no family binds has no candidates.
expect_false(tulpa:::.nl_axis_matches_default(c(1, 2), "not_a_grid_field"))
})
test_that("default grid axes are not written inline outside the settings file", {
skip_on_cran()
# The regression this file exists to prevent. A geometric axis over LITERAL
# bounds is a default written where it is consumed; parameterised bounds
# (`log(lo)`, `log(mode * span)`) are a caller building a data-dependent
# axis from shape parameters the table holds, which is the sanctioned form.
r_dir <- test_path("..", "..", "R")
skip_if_not(dir.exists(r_dir), "package sources not available")
files <- setdiff(list.files(r_dir, pattern = "\\.R$", full.names = TRUE),
file.path(r_dir, "settings.R"))
offenders <- character(0)
for (f in files) {
src <- readLines(f, warn = FALSE)
code <- src[!grepl("^\\s*#", src)]
hits <- grep("exp\\(seq\\(log\\(\\s*[0-9]", code, value = TRUE)
if (length(hits)) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(hits)))
}
}
expect_identical(offenders, character(0))
})
test_that("the reported Pareto-k threshold is read, never restated", {
skip_on_cran()
r_dir <- test_path("..", "..", "R")
skip_if_not(dir.exists(r_dir), "package sources not available")
files <- setdiff(list.files(r_dir, pattern = "\\.R$", full.names = TRUE),
file.path(r_dir, "settings.R"))
# The literal 0.7 next to a Pareto-k / k-hat / k_threshold comparison. Bare
# 0.7 elsewhere (a plotting alpha, a cex) is unrelated and not matched.
pat <- paste0("(pareto_k|k_hat|khat|k_threshold|pk_i)\\s*(<|<=|>|>=|=)+\\s*0\\.7",
"|0\\.7\\s*(<|<=|>|>=)\\s*(pareto_k|k_hat|khat)")
offenders <- character(0)
for (f in files) {
code <- readLines(f, warn = FALSE)
code <- code[!grepl("^\\s*#", code)]
hits <- grep(pat, code, value = TRUE)
if (length(hits)) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(hits)))
}
}
expect_identical(offenders, character(0))
# And the outer-k draw budget likewise (gcol33/tulpa#632). This rule used to
# read `k_samples\\s*(=|<-|%||%)\\s*200`, keyed to ONE name and ONE literal,
# and that is exactly how the joint path drifted: gcol33/tulpa#127 renamed
# the internal variable to `diagnose_draws` and raised the default to 500 in
# the same commit, so the site was invisible to a rule looking for the name
# `k_samples` next to the number 200. The rule is keyed to the CONCEPT
# instead -- any budget in this family defaulted to a numeric literal
# anywhere but the settings file -- so a future rename cannot walk out from
# under it. `n_samples` matches only against a literal, which leaves the
# unrelated uses (`n_samples = nrow(draws)`, the reported draw count, the
# `cpp_laplace_sample()` argument) alone.
offenders <- character(0)
for (f in files) {
code <- readLines(f, warn = FALSE)
code <- code[!grepl("^\\s*#|^#'", code)]
hits <- grep(paste0("(k_samples|diagnose_draws|n_samples|k_bootstrap)",
"\\s*(=|<-|%\\|\\|%)\\s*[0-9]"),
code, value = TRUE)
if (length(hits)) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(hits)))
}
}
expect_identical(offenders, character(0))
# The cheap-screen defaults likewise: the weight below which a cell is
# dropped and the number of Newton steps the screen takes on every cell.
# Keyed to the CONCEPT, so a rename cannot walk out from under it, and to a
# NONZERO literal, because `prune_tol = 0` is the sentinel that turns
# screening off entirely rather than a restatement of the default.
# `RcppExports.R` is generated from the cpp entry's own formals, where an
# Rcpp attribute default has to be a literal; the test below pins that
# literal to the registry instead.
offenders <- character(0)
for (f in setdiff(files, file.path(r_dir, "RcppExports.R"))) {
code <- readLines(f, warn = FALSE)
code <- code[!grepl("^\\s*#|^#'", code)]
pat <- paste0("(prune_tol|screen_iters)\\s*(=|<-|%\\|\\|%)\\s*",
"([0-9][0-9.eE+-]*L?)")
hits <- grep(pat, code, value = TRUE)
for (h in hits) {
lit <- sub(paste0("^.*", pat, ".*$"), "\\3", h)
val <- suppressWarnings(as.numeric(sub("L$", "", lit)))
if (!is.na(val) && val != 0) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(h)))
}
}
}
expect_identical(offenders, character(0))
# The gamma_3 bands: a comparison of a skewness magnitude against the
# literal band edges. `.tulpa_inner_skew_summary()` restated both after
# `.tulpa_gamma3_band()` was already reading them.
offenders <- character(0)
for (f in files) {
code <- readLines(f, warn = FALSE)
code <- code[!grepl("^\\s*#|^#'", code)]
hits <- grep("\\b(ag|abs_gamma3|gamma3|g)\\s*(<|<=|>|>=)\\s*(0\\.5|1\\.0)\\b",
code, value = TRUE)
if (length(hits)) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(hits)))
}
}
expect_identical(offenders, character(0))
})
test_that("no user-facing text tells the caller to set a knob that hard-errors", {
skip_on_cran()
r_dir <- test_path("..", "..", "R")
skip_if_not(dir.exists(r_dir), "package sources not available")
# `control$diagnose_draws` was renamed to `control$k_samples` and the joint
# front door hard-errors on the old name, so a message or a doc line telling
# the reader to raise it sends them into that error. Two shipped for a while
# -- the PSIS decline vocabulary and the tail-cap warning -- because the
# rename swept the code and not the prose.
#
# The pattern is an IMPERATIVE aimed at the knob. Naming `diagnose_draws` as
# a returned FIELD (`fit$diagnose_draws` is real) or quoting the old name in
# the rename error itself is legitimate and must keep passing.
dead <- c("diagnose_draws", "diagnose_cost")
verbs <- "(raise|increase|lower|bump|set|use|pass|supply)"
files <- list.files(r_dir, pattern = "\\.R$", full.names = TRUE)
offenders <- character(0)
for (f in files) {
code <- readLines(f, warn = FALSE)
for (k in dead) {
pat <- paste0(verbs, "\\s+\\W{0,3}(control\\$)?", k, "\\b")
hits <- grep(pat, code, value = TRUE, ignore.case = TRUE)
if (length(hits)) {
offenders <- c(offenders, paste0(basename(f), ": ", trimws(hits)))
}
}
}
expect_identical(offenders, character(0))
# And the knob the reader IS meant to reach exists on every front door that
# reports the diagnostic, under one name, reached the same way.
for (fn in c("tulpa_nested_laplace", "tulpa_nested_laplace_joint",
"tulpa_re_cov_nested", "fit_spde")) {
expect_true("control" %in% names(formals(getExportedValue("tulpa", fn))),
info = fn)
}
})
test_that("every outer-k entry point defaults to the registry's draw budget", {
skip_on_cran()
# The source lint above catches a budget written as a literal. It cannot
# catch a SECOND registry-shaped default that reads a different key, and it
# says nothing about what the defaults evaluate to -- which is the half that
# mattered in gcol33/tulpa#632, where four backends scored the same
# hyperparameter posterior at two budgets. Under gcol33/tulpa#631 the budget
# fixes the PSIS tail FRACTION (20.0% at 200, 13.6% at 500) and the k-hat is
# read against the fixed `k_usable` band, so two live defaults are two
# different quantiles of the weight distribution and can band a fit
# differently for no reason the fit records.
ns <- asNamespace("tulpa")
ref <- tulpa:::.nl_diag("k_samples")
entries <- list(
.joint_pareto_k = "n_samples",
.nested_outer_pareto_k = "n_samples",
.nested_is_pareto_k = "n_samples",
.nested_grid_pareto_k = "n_samples",
.joint_attach_pareto_k_single = "diagnose_draws",
.joint_attach_pareto_k_multi = "diagnose_draws",
.joint_dispatch_multi = "diagnose_draws"
)
for (fn in names(entries)) {
arg <- entries[[fn]]
f <- get(fn, envir = ns)
expect_true(arg %in% names(formals(f)), info = fn)
expect_identical(eval(formals(f)[[arg]], envir = ns), ref, info = fn)
}
# And the two `k_quality` entry budgets sit above the base one: the ladder
# they start is a raise, so an inversion here would make naming a target
# band LOWER the budget that has to resolve it.
expect_gt(tulpa:::.nl_diag("k_samples_ok"), ref)
expect_gt(tulpa:::.nl_diag("k_samples_good"), tulpa:::.nl_diag("k_samples_ok"))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.