Skip to documentation
SLOP

tiny.smt.smtlib.write

Reference tiny.smt smtlib write

Defined in smtlib.

Prints a script or a single term as SMT-LIB text.

API (2)

Actions

Public operations.

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

Source

Called byCallstest sourcelib.smt.src.smtlib.writetest: SMT-LIB writer emits declaratio...smtlib.writewriteTermsmtlib.writewriteScript
Static calls · unresolved targets: 4 · external targets: 1.
Called byCallsprivate sourcelib.smt.src.smtlib.writewriteApplyprivate sourcelib.smt.src.smtlib.writewriteBinaryprivate sourcelib.smt.src.smtlib.writewriteExtensionprivate sourcelib.smt.src.smtlib.writewriteExtractprivate sourcelib.smt.src.smtlib.writewriteNary+3 moreprivate sourcelib.smt.src.smtlib.writewriteApplyprivate sourcelib.smt.src.smtlib.writewriteBinaryprivate sourcelib.smt.src.smtlib.writewriteExtensionprivate sourcelib.smt.src.smtlib.writewriteExtractprivate sourcelib.smt.src.smtlib.writewriteNary+2 moresmtlib.writewriteTerm
Static calls · unresolved targets: 1 · external targets: 1.

Source: lib/smt/src/smtlib/root.zig:20

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

Source: lib/smt/src/smtlib/write.zig

zig
//! Prints a script or a single term as SMT-LIB text. A caller hands a formula it built to another//! solver, or stores it, and needs text any SMT-LIB reader accepts.//!//! Each term kind prints as its SMT-LIB operator applied to its operands, and bit-vector constants//! print as `(_ bvV W)`. A list operator with one operand prints as the operand alone, and an `and`//! with none prints as `true` and an `or` with none as `false`. The same rule changes the meaning//! of `distinct` with one operand, which prints as its operand, and of `+` and `*` with none, which//! print as `false`. A negative integer prints as `-5`, which standard SMT-LIB readers refuse,//! since SMT-LIB writes it `(- 5)`. The writer recurses once per level of the term, with no depth//! bound.const std = @import("std");const smt = @import("../root.zig");const term = smt.term;/// Writes `(set-logic L)` with the script's logic, then one `declare-const` per named constant of/// the `Context`, one `declare-fun` per function declaration, one `assert` per assertion of the/// script, and `(check-sat)`, so code can hand a whole formula to another solver or read it back./// Declarations follow the order in which the `Context` built them. The call declares every/// constant and function of the `Context`, including those no assertion uses. Two constants that/// share a name print two `declare-const` lines with that name, which a reader refuses. The/// function returns only the writer's errors.pub fn writeScript(writer: *std.Io.Writer, script: *const term.Script) std.Io.Writer.Error!void {    try writer.print("(set-logic {s})\n", .{script.logic});    for (script.ctx.nodes.items) |node| {        switch (node) {            .symbol => |symbol| {                try writer.print("(declare-const {s} ", .{symbol.name});                try symbol.sort.write(writer);                try writer.writeAll(")\n");            },            else => {},        }    }    for (script.ctx.functions.items) |decl| {        try writer.print("(declare-fun {s} (", .{decl.name});        for (decl.params, 0..) |param, index| {            if (index > 0) try writer.writeAll(" ");            try param.write(writer);        }        try writer.writeAll(") ");        try decl.result.write(writer);        try writer.writeAll(")\n");    }    for (script.assertions.items) |assertion| {        try writer.writeAll("(assert ");        try writeTerm(writer, script.ctx, assertion);        try writer.writeAll(")\n");    }    try writer.writeAll("(check-sat)\n");}/// Writes the term `id` of `ctx` in SMT-LIB syntax, so code can print a single term for a message/// or a log, and `writeScript` calls it for every assertion. A constant prints as its name, and an/// application of a function with no arguments as the function's name alone. An `and` with no/// operands prints as `true` and an `or` with none as `false`, and a list operator with one operand/// prints the operand alone. `distinct` with one operand prints as its operand, `+` and `*` with no/// operands print as `false`, and a negative integer prints as `-5`: each reads back as a different/// term or fails in standard readers. An `id` past the terms of `ctx` makes the call panic. The/// function returns only the writer's errors.pub fn writeTerm(writer: *std.Io.Writer, ctx: *const term.Context, id: term.Term) std.Io.Writer.Error!void {    const node = ctx.nodes.items[id];    switch (node) {        .symbol => |symbol| try writer.writeAll(symbol.name),        .apply => |item| try writeApply(writer, ctx, item.function, item.args),        .bool => |value| try writer.writeAll(if (value) "true" else "false"),        .int => |value| try writer.print("{d}", .{value}),        .bitvec => |value| try writer.print("(_ bv{d} {d})", .{ value.value, value.width }),        .not => |operand| try writeUnary(writer, ctx, "not", operand),        .and_ => |operands| try writeNary(writer, ctx, "and", operands),        .or_ => |operands| try writeNary(writer, ctx, "or", operands),        .implies => |pair| try writeBinary(writer, ctx, "=>", pair.lhs, pair.rhs),        .eq => |pair| try writeBinary(writer, ctx, "=", pair.lhs, pair.rhs),        .distinct => |operands| try writeNary(writer, ctx, "distinct", operands),        .add => |operands| try writeNary(writer, ctx, "+", operands),        .mul => |operands| try writeNary(writer, ctx, "*", operands),        .le => |pair| try writeBinary(writer, ctx, "<=", pair.lhs, pair.rhs),        .lt => |pair| try writeBinary(writer, ctx, "<", pair.lhs, pair.rhs),        .ge => |pair| try writeBinary(writer, ctx, ">=", pair.lhs, pair.rhs),        .gt => |pair| try writeBinary(writer, ctx, ">", pair.lhs, pair.rhs),        .bvule => |pair| try writeBinary(writer, ctx, "bvule", pair.lhs, pair.rhs),        .bvult => |pair| try writeBinary(writer, ctx, "bvult", pair.lhs, pair.rhs),        .bvsle => |pair| try writeBinary(writer, ctx, "bvsle", pair.lhs, pair.rhs),        .bvslt => |pair| try writeBinary(writer, ctx, "bvslt", pair.lhs, pair.rhs),        .bvuaddo => |pair| try writeBinary(writer, ctx, "bvuaddo", pair.lhs, pair.rhs),        .bvsaddo => |pair| try writeBinary(writer, ctx, "bvsaddo", pair.lhs, pair.rhs),        .bvssubo => |pair| try writeBinary(writer, ctx, "bvssubo", pair.lhs, pair.rhs),        .bvumulo => |pair| try writeBinary(writer, ctx, "bvumulo", pair.lhs, pair.rhs),        .bvsmulo => |pair| try writeBinary(writer, ctx, "bvsmulo", pair.lhs, pair.rhs),        .bvnot => |operand| try writeUnary(writer, ctx, "bvnot", operand),        .bvand => |pair| try writeBinary(writer, ctx, "bvand", pair.lhs, pair.rhs),        .bvor => |pair| try writeBinary(writer, ctx, "bvor", pair.lhs, pair.rhs),        .bvxor => |pair| try writeBinary(writer, ctx, "bvxor", pair.lhs, pair.rhs),        .bvshl => |pair| try writeBinary(writer, ctx, "bvshl", pair.lhs, pair.rhs),        .bvlshr => |pair| try writeBinary(writer, ctx, "bvlshr", pair.lhs, pair.rhs),        .bvashr => |pair| try writeBinary(writer, ctx, "bvashr", pair.lhs, pair.rhs),        .bvudiv => |pair| try writeBinary(writer, ctx, "bvudiv", pair.lhs, pair.rhs),        .bvurem => |pair| try writeBinary(writer, ctx, "bvurem", pair.lhs, pair.rhs),        .bvsdiv => |pair| try writeBinary(writer, ctx, "bvsdiv", pair.lhs, pair.rhs),        .bvsrem => |pair| try writeBinary(writer, ctx, "bvsrem", pair.lhs, pair.rhs),        .bvsmod => |pair| try writeBinary(writer, ctx, "bvsmod", pair.lhs, pair.rhs),        .array_select => |item| try writeBinary(writer, ctx, "select", item.array, item.index),        .array_store => |item| try writeTernary(writer, ctx, "store", item.array, item.index, item.value),        .bvconcat => |pair| try writeBinary(writer, ctx, "concat", pair.lhs, pair.rhs),        .bvextract => |item| try writeExtract(writer, ctx, item.operand, item.high, item.low),        .bvzeroext => |item| try writeExtension(writer, ctx, "zero_extend", item.operand, item.extra),        .bvsignext => |item| try writeExtension(writer, ctx, "sign_extend", item.operand, item.extra),        .bvrotl => |item| try writeExtension(writer, ctx, "rotate_left", item.operand, item.amount),        .bvrotr => |item| try writeExtension(writer, ctx, "rotate_right", item.operand, item.amount),        .bvadd => |pair| try writeBinary(writer, ctx, "bvadd", pair.lhs, pair.rhs),        .bvsub => |pair| try writeBinary(writer, ctx, "bvsub", pair.lhs, pair.rhs),        .bvmul => |pair| try writeBinary(writer, ctx, "bvmul", pair.lhs, pair.rhs),    }}fn writeApply(writer: *std.Io.Writer, ctx: *const term.Context, function_id: term.Function, args: []const term.Term) std.Io.Writer.Error!void {    const decl = ctx.functions.items[function_id];    if (args.len == 0) {        try writer.writeAll(decl.name);        return;    }    try writer.print("({s}", .{decl.name});    for (args) |arg| {        try writer.writeAll(" ");        try writeTerm(writer, ctx, arg);    }    try writer.writeAll(")");}fn writeUnary(writer: *std.Io.Writer, ctx: *const term.Context, name: []const u8, operand: term.Term) std.Io.Writer.Error!void {    try writer.print("({s} ", .{name});    try writeTerm(writer, ctx, operand);    try writer.writeAll(")");}fn writeBinary(writer: *std.Io.Writer, ctx: *const term.Context, name: []const u8, lhs: term.Term, rhs: term.Term) std.Io.Writer.Error!void {    try writer.print("({s} ", .{name});    try writeTerm(writer, ctx, lhs);    try writer.writeAll(" ");    try writeTerm(writer, ctx, rhs);    try writer.writeAll(")");}fn writeTernary(writer: *std.Io.Writer, ctx: *const term.Context, name: []const u8, first: term.Term, second: term.Term, third: term.Term) std.Io.Writer.Error!void {    try writer.print("({s} ", .{name});    try writeTerm(writer, ctx, first);    try writer.writeAll(" ");    try writeTerm(writer, ctx, second);    try writer.writeAll(" ");    try writeTerm(writer, ctx, third);    try writer.writeAll(")");}fn writeExtract(writer: *std.Io.Writer, ctx: *const term.Context, operand: term.Term, high: u32, low: u32) std.Io.Writer.Error!void {    try writer.print("((_ extract {d} {d}) ", .{ high, low });    try writeTerm(writer, ctx, operand);    try writer.writeAll(")");}fn writeExtension(writer: *std.Io.Writer, ctx: *const term.Context, name: []const u8, operand: term.Term, extra: u32) std.Io.Writer.Error!void {    try writer.print("((_ {s} {d}) ", .{ name, extra });    try writeTerm(writer, ctx, operand);    try writer.writeAll(")");}fn writeNary(writer: *std.Io.Writer, ctx: *const term.Context, name: []const u8, operands: []const term.Term) std.Io.Writer.Error!void {    if (operands.len == 0) {        try writer.writeAll(if (std.mem.eql(u8, name, "and")) "true" else "false");        return;    }    if (operands.len == 1) {        try writeTerm(writer, ctx, operands[0]);        return;    }    try writer.print("({s}", .{name});    for (operands) |operand| {        try writer.writeAll(" ");        try writeTerm(writer, ctx, operand);    }    try writer.writeAll(")");}test "SMT-LIB writer emits declarations and assertions" {    var ctx = term.Context.init(std.testing.allocator);    defer ctx.deinit();    var script = term.Script.init(&ctx, "QF_LIA");    defer script.deinit();    const x = try ctx.symbol("x", .int);    const zero = try ctx.intValue(0);    try script.assertTerm(try ctx.ge(x, zero));    var buffer: [512]u8 = undefined;    var stream = std.Io.Writer.fixed(&buffer);    try writeScript(&stream, &script);    const text = stream.buffered();    try std.testing.expect(std.mem.indexOf(u8, text, "(set-logic QF_LIA)\n") != null);    try std.testing.expect(std.mem.indexOf(u8, text, "(declare-const x Int)\n") != null);    try std.testing.expect(std.mem.indexOf(u8, text, "(assert (>= x 0))\n") != null);}

Complete caller list for smtlib.write.writeTerm

8 direct callers.

Complete call list for smtlib.write.writeTerm

7 direct calls.

Audit

Definitions3
Public names5
Members0
Version26.7.0
Revisiondaab053ee433