Skip to documentation
SLOP

tiny.smt.sat.types

Reference tiny.smt sat types

Defined in sat.

The values a caller hands to the solver and reads back from it: literals, answers, truth values that may be unset, counts of a solve's work, and the restart schedule.

API (5)

Types and contracts

Public types and contracts.

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

Source

Source: lib/smt/src/sat/root.zig:52

zig
pub const types = @import("types.zig");

Source: lib/smt/src/sat/types.zig

zig
//! The values a caller hands to the solver and reads back from it: literals, answers, truth values//! that may be unset, counts of a solve's work, and the restart schedule.//!//! A caller writes clauses as literals over variables numbered from 0, reads one of three answers//! after each solve, and reads the value of each variable after a satisfiable answer. Clause files//! in the common text format number variables from 1 and write a negated variable as a negative//! number (DIMACS), so a caller reading or writing them converts each literal.//!//! The solver keeps one list per literal, so a literal has to map to a small number that can index//! an array. A literal packs its variable and its sign into one 32-bit number (`Literal.raw`)://! twice the variable index, plus one for a negated literal. That number indexes the solver's//! per-literal lists directly, and negating a literal flips its lowest bit. `Literal.fromDimacs`//! and `Literal.toDimacs` convert between that number and the signed numbers of the text format. A//! truth value has a third state, unset (`BoolValue.unset`), for an unassigned variable./// The answer of one solve. A caller switches on it to decide whether to read a satisfying/// assignment, an unsat core and a proof, or neither.pub const Status = enum {    /// Some assignment makes every clause and every assumption of the solve true. `Solver.value`    /// and `Solver.literalValue` read that assignment until the next solve.    sat,    /// No assignment makes every clause and every assumption of the solve true. The solver then    /// holds a proof trace that ends in the empty clause, and after a solve under assumptions an    /// unsat core.    unsat,    /// The solve ran out of its conflict limit (`Solver.conflict_budget`) before it reached an    /// answer, or while core minimization certified a smaller core. After the second case the core    /// is empty, but the proof trace still holds a refutation under every assumption of the solve.    unknown,};/// A truth value that may also be unset. A caller switches on the value `Solver.literalValue`/// returns to read a literal in a satisfying assignment.pub const BoolValue = enum {    /// The variable is unassigned, or the literal names a variable at or above the solver's    /// variable count.    unset,    /// The literal or variable is false.    false,    /// The literal or variable is true.    true,    /// Returns `.true` for true and `.false` for false. The solver and the proof checker record an    /// assigned value through it.    pub fn fromBool(value: bool) BoolValue {        return if (value) .true else .false;    }    /// Returns the opposite value, and `.unset` for `.unset`. The solver and the proof checker read    /// a negated literal's value from its variable's value through it.    pub fn invert(self: BoolValue) BoolValue {        return switch (self) {            .unset => .unset,            .false => .true,            .true => .false,        };    }};/// Counts of the work one solve did. A caller reads them from `Solver.lastSolveStats` to report how/// much work a solve took. The solver sets every count to zero when a solve starts. The counts/// cover the main search: the extra solves of core minimization change only `proof_steps`, which/// takes the certified trace's length.pub const SolveStats = struct {    /// Decisions the search made, each giving an unassigned variable a value.    decisions: usize = 0,    /// Decisions that gave the variable the value it last held, in this solve or an earlier one,    /// counted within `decisions`.    phase_saved_decisions: usize = 0,    /// Literals the search assigned because every other literal of a clause was false. Unit clauses    /// of the formula and assumptions sit outside the count.    propagations: usize = 0,    /// Times the main search found a clause with every literal false. `Solver.conflict_budget`    /// limits this count.    conflicts: usize = 0,    /// Clauses the search learned from conflicts in this solve.    learned_clauses: usize = 0,    /// Learned clauses the solver removed to stay within `Solver.max_learned_clauses`, removals at    /// the start of the solve included.    evicted_clauses: usize = 0,    /// Steps in the proof trace at the end of the solve: one per learned clause, plus the final    /// empty clause after an unsatisfiable answer. After core minimization certified a smaller    /// core, the count is the certifying solve's step count.    proof_steps: usize = 0,    /// Times the search went back to the first decision, on the restart schedule or to remove    /// learned clauses.    restarts: usize = 0,    /// The largest number of decisions in force at once during the solve.    max_decision_level: u32 = 0,    /// Conflicts found at decision level zero, counted within `conflicts`. Assumptions sit below    /// every decision, so a conflict among the assumptions counts here.    root_conflicts: usize = 0,};/// The restart schedule: the search goes back to the first decision after a conflict count that/// starts at `first_conflict_interval` and multiplies by `growth` after each restart. A caller/// passes one to `Solver.setRestartPolicy` to change the schedule, for example to restart after/// every conflict. The default restarts after 128 conflicts, then after 256 more, then 512,/// doubling each time. The solver keeps its learned clauses across a restart. The count starts over/// at each solve, and a restart happens only while a decision is in force.pub const RestartPolicy = struct {    /// Conflicts before the first restart of each solve, 128 by default. Zero turns restarts off.    first_conflict_interval: usize = 128,    /// The factor the interval grows by after each restart, 2 by default. A factor of 0 or 1 keeps    /// the interval fixed, and the interval stops growing at the largest `usize`.    growth: usize = 2,    /// Returns a policy that turns restarts off: an interval of 0 and a growth of 1. A caller that    /// turns restarts off passes it to `Solver.setRestartPolicy`.    pub fn disabled() RestartPolicy {        return .{ .first_conflict_interval = 0, .growth = 1 };    }};/// A variable or its negation, packed into one 32-bit number. A caller builds every clause and/// every assumption from literals. Variables are numbered from 0 in the order `Solver.addVariable`/// returns them.pub const Literal = struct {    /// The packed number: twice the variable index, plus one for a negated literal. Two literals    /// are equal when their `raw` values are equal, and callers compare literals that way.    raw: u32,    /// Returns the literal of variable `variable_index`, unnegated when `polarity` is true and    /// negated when it is false. Code that picks the sign at run time calls it. An index of    /// 2147483648 or more overflows the packed number, which panics in safe builds.    pub fn init(variable_index: u32, polarity: bool) Literal {        return .{ .raw = variable_index * 2 + if (polarity) @as(u32, 0) else @as(u32, 1) };    }    /// Returns the unnegated literal of variable `variable_index`. A caller writes a clause whose    /// signs it knows in its source.    pub fn positive(variable_index: u32) Literal {        return init(variable_index, true);    }    /// Returns the negated literal of variable `variable_index`. A caller writes a clause whose    /// signs it knows in its source.    pub fn negative(variable_index: u32) Literal {        return init(variable_index, false);    }    /// Returns the variable index of the literal. A caller finds which variable a literal names,    /// for example to check it against a variable count.    pub fn variable(self: Literal) u32 {        return self.raw >> 1;    }    /// Returns true for an unnegated literal. A caller reads a literal's sign to evaluate it under    /// an assignment.    pub fn isPositive(self: Literal) bool {        return self.raw & 1 == 0;    }    /// Returns the literal of the same variable with the opposite sign. An encoder calls it to    /// state the negation of a condition.    pub fn negated(self: Literal) Literal {        return .{ .raw = self.raw ^ 1 };    }    /// Returns the packed number as a `usize`. The solver indexes its per-literal lists of watching    /// clauses by it, two entries per variable.    pub fn index(self: Literal) usize {        return @intCast(self.raw);    }    /// Returns the literal a DIMACS number stands for: variable `|value| - 1`, negated when `value`    /// is negative. The DIMACS and proof readers call it on each number of a clause. The call    /// returns `error.InvalidDimacsLiteral` for 0, the number that ends a clause in that format.    /// The value -2147483648 makes it panic, because its negation does not fit in 32 bits.    pub fn fromDimacs(value: i32) !Literal {        if (value == 0) return error.InvalidDimacsLiteral;        const magnitude: u32 = @intCast(if (value < 0) -value else value);        return init(magnitude - 1, value > 0);    }    /// Returns the DIMACS number of the literal: the variable index plus one, negative for a    /// negated literal. The DIMACS and proof writers call it on each literal they print. Variable    /// index 2147483647 makes it panic, because its number does not fit in `i32`.    pub fn toDimacs(self: Literal) i32 {        const one_based: i32 = @intCast(self.variable() + 1);        return if (self.isPositive()) one_based else -one_based;    }};

Audit

Definitions1
Public names1
Members0
Version26.7.0
Revisiondaab053ee433