13. API reference¶
Include tididi.h and link tididi::tididi from CMake. The header works in
both C and C++; all exported functions use the C calling convention.
Ownership and errors defines the common pointer and lifetime rules; What are we counting?
compares observations, substitution and projection.
Construction and transformations return owned circuits through an output slot.
Queries borrow circuits. Optional final TididiLimits * arguments accept
NULL for unrestricted work. Literal values are signed, one-based integers:
3 means variable 3 is true, -3 means false; zero is invalid.
13.1. Types¶
/**
* Classification of an operation failure.
*/
typedef enum TididiErrorCode {
/**
* Invalid input, incompatible domains, or a finished counter.
*/
TIDIDI_ERROR_CODE_INVALID_ARGUMENT = 1,
/**
* A live circuit handle no longer contains a circuit.
*/
TIDIDI_ERROR_CODE_CONSUMED_CIRCUIT = 2,
/**
* A callback tried to mutate or free an actively borrowed handle.
*/
TIDIDI_ERROR_CODE_BORROW_CONFLICT = 3,
/**
* The operation exceeded its charged-storage budget.
*/
TIDIDI_ERROR_CODE_MEMORY_LIMIT = 4,
/**
* The operation reached its timeout or output-node cap.
*/
TIDIDI_ERROR_CODE_RESOURCE_LIMIT = 5,
/**
* A count or index cannot fit the requested integer representation.
*/
TIDIDI_ERROR_CODE_OVERFLOW = 6,
/**
* An unexpected Rust panic was caught at the boundary.
*/
TIDIDI_ERROR_CODE_INTERNAL_PANIC = 7,
} TididiErrorCode;
/**
* An owned byte buffer. Read its data/length and free it with tididi_bytes_free.
*/
typedef struct TididiBytes TididiBytes;
/**
* An owned circuit handle. Transformations consume its payload, not this handle.
* Free every handle, including consumed ones, with tididi_circuit_free.
*/
typedef struct TididiCircuit TididiCircuit;
/**
* A reusable evidence counter that owns its circuit until finish. Free its handle even after finish.
*/
typedef struct TididiCounter TididiCounter;
/**
* An owned error. Read its code/message, then call tididi_error_free.
*/
typedef struct TididiError TididiError;
/**
* A reusable exact weighted evaluator owning its circuit until finish. Free even after finish.
*/
typedef struct TididiEvaluator TididiEvaluator;
/**
* An owned list of signed, one-based literals. Its data remains valid until the list is freed.
*/
typedef struct TididiLiterals TididiLiterals;
/**
* An owned snapshot of internal-node sizes, independent of the circuit's lifetime.
*/
typedef struct TididiNodeSizes TididiNodeSizes;
/**
* A shared vtree handle. Circuits retain the vtree after this handle is freed.
*/
typedef struct TididiVtree TididiVtree;
/**
* Per-operation limits. Pass NULL for unlimited work or initialize with tididi_limits_default.
*/
typedef struct TididiLimits {
/**
* Charged operation storage in bytes; UINT64_MAX means unlimited.
*/
uint64_t memory_bytes;
/**
* Maximum emitted circuit nodes; UINT64_MAX means unlimited.
*/
uint64_t output_nodes;
/**
* Cooperative timeout in seconds; -1 means unlimited. Other values must be finite and nonnegative.
*/
double timeout_seconds;
} TididiLimits;
/**
* One partial assignment used in an update. Omitted variables are free; an empty cube matches all assignments.
*/
typedef struct TididiCube {
const int64_t *literals;
size_t len;
} TididiCube;
/**
* One internal node's storage size. IDs are local and may change after transformations.
*/
typedef struct TididiNodeSize {
uint32_t vtree_node;
size_t local_node;
size_t pairs;
} TididiNodeSize;
/**
* Exact negative/positive literal weights, written as integers or fractions such as "3/5".
*/
typedef struct TididiWeight {
uint32_t variable;
const char *negative;
const char *positive;
} TididiWeight;
/**
* Numeric evaluation callbacks. Every callback is required; userdata is borrowed for the call.
* leaf sign is 1 (true), 0 (false), or -1 (free). Callbacks must not unwind or longjmp.
* add combines disjoint alternatives; mul combines independent variable groups.
* Both operations must be associative and commutative, mul must distribute over add,
* and zero must be the identity for add and absorbing for mul.
* leaf(v, -1) must equal add(leaf(v, 0), leaf(v, 1)): a free variable includes both signs.
* Equivalent circuits need not evaluate equally if these laws are violated.
* Double arithmetic approximates these laws; use weighted_count for exact rational sums.
*/
typedef struct TididiAlgebra {
void *userdata;
double (*zero)(void*);
double (*leaf)(void*, uint32_t, int8_t);
double (*add)(void*, double, double);
double (*mul)(void*, double, double);
} TididiAlgebra;
13.2. Functions¶
13.2.1. Vtrees and limits¶
-
struct TididiLimits tididi_limits_default(void)¶
Return unlimited limits. Modify fields before passing their address to an operation.
-
struct TididiError *tididi_vtree_balanced(uint32_t n, struct TididiVtree **out)¶
Build a balanced vtree over variables 1 through n; n must be positive. out must point to NULL.
-
struct TididiError *tididi_vtree_balanced_over(const uint32_t *order, size_t len, struct TididiVtree **out)¶
Build a balanced vtree over distinct positive variable IDs in the given leaf order.
-
struct TididiError *tididi_vtree_linear(const uint32_t *order, size_t len, struct TididiVtree **out)¶
Build a right-linear vtree over distinct positive IDs in the supplied order.
-
struct TididiError *tididi_vtree_join(const struct TididiVtree *left, const struct TididiVtree *right, struct TididiVtree **out)¶
Join disjoint vtrees under a new root. Borrows both inputs; the result is a new domain.
-
struct TididiError *tididi_vtree_to_text(const struct TididiVtree *value, char **out)¶
Serialize the vtree as an owned UTF-8 string. Free it with tididi_string_free.
-
struct TididiError *tididi_vtree_from_text(const char *value, struct TididiVtree **out)¶
Parse vtree text. Load related circuits onto this one returned domain.
-
struct TididiError *tididi_vtree_clear_scratch(const struct TididiVtree *value)¶
Release idle operation buffers without changing circuits.
-
void tididi_vtree_free(struct TididiVtree *value)¶
Free this vtree handle; NULL is accepted. Existing circuits retain their shared vtree.
-
struct TididiError *tididi_circuit_vtree(const struct TididiCircuit *value, struct TididiVtree **out)¶
Return another handle to a live circuit’s shared vtree. Free the returned handle normally.
13.2.2. Construct and transform circuits¶
-
struct TididiError *tididi_copy(const struct TididiCircuit *value, struct TididiCircuit **out)¶
Copy diagram storage while sharing the vtree. The input remains usable.
-
struct TididiError *tididi_is_consumed(const struct TididiCircuit *value, bool *out)¶
Report whether an operation consumed this handle’s payload. The handle itself must still be live.
-
struct TididiError *tididi_circuit_free(struct TididiCircuit *value)¶
Free a circuit handle, including a consumed one. NULL is accepted. Returns BorrowConflict without freeing if a callback attempts to free an active handle.
-
struct TididiError *tididi_literal(const struct TididiVtree *tree, int64_t value, struct TididiCircuit **out, const struct TididiLimits *config)¶
Construct a signed, one-based literal; zero is invalid. out must point to NULL.
-
struct TididiError *tididi_one(const struct TididiVtree *tree, struct TididiCircuit **out)¶
Construct the constant true function over all vtree variables.
-
struct TididiError *tididi_zero(const struct TididiVtree *tree, struct TididiCircuit **out)¶
Construct the constant false function over all vtree variables.
-
struct TididiError *tididi_cube(const struct TididiVtree *tree, const int64_t *values, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Conjoin signed literals, each variable occurring once. An empty cube is true; omitted variables are free.
-
struct TididiError *tididi_clause(const struct TididiVtree *tree, const int64_t *values, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Disjoin signed literals. An empty clause is false.
-
struct TididiError *tididi_and(struct TididiCircuit *left, struct TididiCircuit *right, struct TididiCircuit **out, const struct TididiLimits *config)¶
Conjoin two circuits, consuming both. Preflight errors preserve inputs; execution failures consume them.
-
struct TididiError *tididi_or(struct TididiCircuit *left, struct TididiCircuit *right, struct TididiCircuit **out, const struct TididiLimits *config)¶
Disjoin two circuits, consuming both. Operands must be distinct handles sharing one vtree.
-
struct TididiError *tididi_xor(struct TididiCircuit *left, struct TididiCircuit *right, struct TididiCircuit **out, const struct TididiLimits *config)¶
Exclusive-or two circuits, consuming both.
-
struct TididiError *tididi_negate(struct TididiCircuit *value, struct TididiCircuit **out, const struct TididiLimits *config)¶
Complement a circuit, consuming it.
-
struct TididiError *tididi_minimize(struct TididiCircuit *value, struct TididiCircuit **out, const struct TididiLimits *config)¶
Minimize without changing the function. Consumes the old payload and returns a canonical circuit for its vtree.
-
struct TididiError *tididi_condition(struct TididiCircuit *value, const int64_t *assignments, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Substitute literal values, consuming the circuit. Repeats are ignored; opposite signs produce false. Substituted variables remain free in the counting universe; use a counter to count under observations.
-
struct TididiError *tididi_exists(struct TididiCircuit *value, const uint32_t *vars, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Existentially quantify variables, consuming the circuit. They remain free in the vtree’s counting universe.
-
struct TididiError *tididi_and_exists(struct TididiCircuit *left, struct TididiCircuit *right, const uint32_t *vars, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Conjoin then quantify in one call, consuming both inputs. Equivalent to and followed by exists.
-
struct TididiError *tididi_rename(struct TididiCircuit *value, const uint32_t *from, const uint32_t *to, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Rename from[i] to to[i] simultaneously, consuming the circuit. Swaps and cycles are simultaneous. Each source occurs once; several sources may share a target. The vtree stays unchanged.
-
struct TididiError *tididi_or_many(struct TididiCircuit *const *values, size_t len, struct TididiCircuit **out, const struct TididiLimits *config)¶
Union a nonempty array of distinct circuit handles, consuming every payload.
-
struct TididiError *tididi_ite(struct TididiCircuit *condition, struct TididiCircuit *yes, struct TididiCircuit *no, struct TididiCircuit **out, const struct TididiLimits *config)¶
Build if-then-else, consuming three distinct circuit handles sharing one vtree.
-
struct TididiError *tididi_from_models(const struct TididiVtree *tree, const uint32_t *vars, size_t nvars, const uint8_t *rows, size_t nrows, struct TididiCircuit **out, const struct TididiLimits *config)¶
Build a set of row-major Boolean rows. Every cell is 0 or 1; duplicates count once. rows contains nrows*nvars bytes. Other vtree variables are free.
-
struct TididiError *tididi_update(struct TididiCircuit *value, const struct TididiCube *insert, size_t ninsert, const struct TididiCube *remove, size_t nremove, struct TididiCircuit **out, const struct TididiLimits *config)¶
Insert cubes, then remove cubes; consume the old circuit and return its minimized replacement. Contradictory cubes change nothing. Limits apply to individual updates and final minimization.
13.2.3. Query and inspect¶
-
struct TididiError *tididi_model_count(const struct TididiCircuit *value, uint64_t *out, const struct TididiLimits *config)¶
Count models over every vtree variable, borrowing the circuit. Overflow leaves out unchanged.
-
struct TididiError *tididi_model_count_decimal(const struct TididiCircuit *value, char **out, const struct TididiLimits *config)¶
Count exactly, returning an owned decimal string of arbitrary length. Free it with tididi_string_free.
-
struct TididiError *tididi_projected_model_count(const struct TididiCircuit *value, const uint32_t *vars, size_t len, uint64_t *out, const struct TididiLimits *config)¶
Count distinct assignments to the selected variables that extend to a model. Borrows the circuit.
-
struct TididiError *tididi_projected_model_count_decimal(const struct TididiCircuit *value, const uint32_t *vars, size_t len, char **out, const struct TididiLimits *config)¶
Count distinct projections exactly, returning an owned decimal string.
-
struct TididiError *tididi_is_sat(const struct TididiCircuit *value, bool *out, const struct TididiLimits *config)¶
Whether at least one assignment satisfies the circuit. Borrows it.
-
struct TididiError *tididi_equivalent(const struct TididiCircuit *left, const struct TididiCircuit *right, bool *out, const struct TididiLimits *config)¶
Compare Boolean functions without consuming either handle. Aliases are allowed; vtrees must match.
-
struct TididiError *tididi_implies(const struct TididiCircuit *left, const struct TididiCircuit *right, bool *out, const struct TididiLimits *config)¶
Whether every model of left satisfies right. Borrows both handles; vtrees must match.
-
size_t tididi_literals_len(const struct TididiLiterals *value)¶
Return the size of a live, nonnull literal list.
-
const int64_t *tididi_literals_data(const struct TididiLiterals *value)¶
Borrow the signed literal array. Do not write to or free it separately.
-
void tididi_literals_free(struct TididiLiterals *value)¶
Free a literal list; NULL is accepted.
-
struct TididiError *tididi_implied_literals(const struct TididiCircuit *value, struct TididiLiterals **out, const struct TididiLimits *config)¶
Return literals implied by the function. False implies both signs of every vtree variable.
-
struct TididiError *tididi_satisfying_assignment(const struct TididiCircuit *value, struct TididiLiterals **out, const struct TididiLimits *config)¶
Return one complete satisfying assignment, or an empty list when unsatisfiable. Borrows the circuit.
-
struct TididiError *tididi_support(const struct TididiCircuit *value, struct TididiLiterals **out, const struct TididiLimits *config)¶
Return the function’s support as positive variable IDs in a literal list. Borrows the circuit.
-
struct TididiError *tididi_size(const struct TididiCircuit *value, size_t *nodes, size_t *pairs)¶
Report stored nodes and child pairs, not models. Implicit leaves are excluded from the node count.
-
struct TididiError *tididi_node_sizes(const struct TididiCircuit *value, struct TididiNodeSizes **out)¶
Snapshot the size of every stored internal node, borrowing the circuit.
-
size_t tididi_node_sizes_len(const struct TididiNodeSizes *value)¶
Return the length of a live, nonnull node-size snapshot.
-
const struct TididiNodeSize *tididi_node_sizes_data(const struct TididiNodeSizes *value)¶
Borrow the snapshot’s rows until it is freed. Do not modify or free the array separately.
-
void tididi_node_sizes_free(struct TididiNodeSizes *value)¶
Free a snapshot; NULL is accepted.
13.2.4. Observe choices¶
-
struct TididiError *tididi_counter(struct TididiCircuit *value, struct TididiCounter **out)¶
Move a circuit into an evidence counter. Copy first if the original must remain usable.
-
struct TididiError *tididi_counter_observe(struct TididiCounter *value, const int64_t *values, size_t len)¶
Observe signed literals. Later observations replace pins for named variables and retain the other pins.
-
struct TididiError *tididi_counter_clear(struct TididiCounter *value, uint32_t var)¶
Remove the observation for one variable.
-
struct TididiError *tididi_counter_clear_all(struct TididiCounter *value)¶
Remove all observations, retaining the circuit and reusable counter.
-
struct TididiError *tididi_counter_model_count(struct TididiCounter *value, uint64_t *out, const struct TididiLimits *config)¶
Count assignments consistent with observations. Does not consume the counter.
-
struct TididiError *tididi_counter_model_count_decimal(struct TididiCounter *value, char **out, const struct TididiLimits *config)¶
Count under observations exactly, returning an owned decimal string.
-
struct TididiError *tididi_counter_finish(struct TididiCounter *value, struct TididiCircuit **out)¶
Discard observations/cache and return the original circuit. Closes the counter; its handle still needs freeing.
-
struct TididiError *tididi_counter_free(struct TididiCounter *value)¶
Free a counter handle, whether open or finished. NULL is accepted; active handles return BorrowConflict.
-
struct TididiError *tididi_evaluator(struct TididiCircuit *value, const struct TididiWeight *values, size_t len, struct TididiEvaluator **out)¶
Move a circuit into an evaluator. Supply weights for every variable; they are copied. Invalid weights leave the circuit usable. Copy the circuit first to retain it after success.
-
struct TididiError *tididi_evaluator_observe(struct TididiEvaluator *value, const int64_t *values, size_t len)¶
Observe signed literals; later values replace earlier observations of the same variable. Invalid input preserves all observations.
-
struct TididiError *tididi_evaluator_clear(struct TididiEvaluator *value, uint32_t var)¶
Clear one variable’s observation.
-
struct TididiError *tididi_evaluator_clear_all(struct TididiEvaluator *value)¶
Clear all observations, retaining cached storage.
-
struct TididiError *tididi_evaluator_set_weights(struct TididiEvaluator *value, const struct TididiWeight *values, size_t len)¶
Replace every variable’s weights, retaining observations and invalidating cached values. Invalid weights leave the previous values in place.
-
struct TididiError *tididi_evaluator_value(struct TididiEvaluator *value, char **out, const struct TididiLimits *config)¶
Return the exact weighted sum under observations as an owned integer/fraction string. Probability weights give joint probability, without normalization. Free with tididi_string_free. Reads obey limits, including cached reads; refused work retains observations for retry.
-
struct TididiError *tididi_evaluator_finish(struct TididiEvaluator *value, struct TididiCircuit **out)¶
Close an evaluator and return its original circuit, discarding observations. The handle still needs freeing.
-
struct TididiError *tididi_evaluator_free(struct TididiEvaluator *value)¶
Free an evaluator handle. NULL is accepted; active handles return BorrowConflict.
13.2.5. Evaluate weights and costs¶
-
struct TididiError *tididi_weighted_count(const struct TididiCircuit *value, const struct TididiWeight *values, size_t len, char **out, const struct TididiLimits *config)¶
Exact weighted sum, returned as an owned integer/fraction string. Supply weights for every vtree variable. Borrows the circuit. The string is freed with tididi_string_free.
-
struct TididiError *tididi_weighted_ratio(const struct TididiCircuit *numerator, const struct TididiCircuit *denominator, const struct TididiWeight *values, size_t len, char **out, const struct TididiLimits *config)¶
Divide two exact weighted sums, borrowing both circuits on one shared vtree. For P(query|evidence), numerator must already represent query AND evidence. A zero denominator returns InvalidArgument; out is an owned integer/fraction string.
-
struct TididiError *tididi_evaluate_f64(const struct TididiCircuit *value, const struct TididiAlgebra *algebra, double *out, const struct TididiLimits *config)¶
Evaluate a numeric algebra while borrowing the circuit. Callback values use double precision. Reentrant attempts to consume or free this circuit return BorrowConflict.
13.2.6. Save and export¶
-
size_t tididi_bytes_len(const struct TididiBytes *value)¶
Return the size of a live, nonnull buffer.
-
const uint8_t *tididi_bytes_data(const struct TididiBytes *value)¶
Borrow a buffer’s data until it is freed. Never modify it or free it separately.
-
void tididi_bytes_free(struct TididiBytes *value)¶
Free an owned byte buffer; NULL is accepted.
-
struct TididiError *tididi_to_bytes(const struct TididiCircuit *value, struct TididiBytes **out)¶
Serialize a circuit without consuming it. Save its vtree separately.
-
struct TididiError *tididi_from_bytes(const struct TididiVtree *tree, const uint8_t *data, size_t len, struct TididiCircuit **out)¶
Load circuit bytes onto an existing vtree. Use one shared vtree for related circuits.
-
struct TididiError *tididi_to_dot(const struct TididiCircuit *value, char **out)¶
Export a circuit as owned Graphviz text. Does not consume it.
-
struct TididiError *tididi_vtree_to_dot(const struct TididiVtree *value, char **out)¶
Export a vtree as owned Graphviz text.
13.2.7. Errors and strings¶
-
enum TididiErrorCode tididi_error_code(const struct TididiError *error)¶
Return an error’s code. error must be nonnull and live.
-
const char *tididi_error_message(const struct TididiError *error)¶
Borrow a UTF-8 message until error is freed. error must be nonnull and live.
-
void tididi_error_free(struct TididiError *error)¶
Free an error; NULL is accepted.
-
void tididi_string_free(char *value)¶
Free an unchanged string returned by this library; NULL is accepted. Never use free().
-
const char *tididi_version(void)¶
Return the binding version as a borrowed static string. Do not free it.