tiny.smt.smtlib.write
Defined in smtlib.
Prints a script or a single term as SMT-LIB text.
API (2)
Actions
Public operations.
writeScript: Writes(set-logic L)with the script's logic, then onedeclare-constper named constant of theContext, onedeclare-funper function declaration, oneassertper assertion of the script, and(check-sat), so code can hand a whole formula to another solver or read it back.writeTerm: Writes the termidofctxin SMT-LIB syntax, so code can print a single term for a message or a log, andwriteScriptcalls it for every assertion.
Source
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.
lib.smt.src.smtlib.write.writeApply[function] — private source atlib/smt/src/smtlib/write.zig:116in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeBinary[function] — private source atlib/smt/src/smtlib/write.zig:136in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeExtension[function] — private source atlib/smt/src/smtlib/write.zig:160in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeExtract[function] — private source atlib/smt/src/smtlib/write.zig:154in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeNary[function] — private source atlib/smt/src/smtlib/write.zig:166in nearest public ownertiny.smt.smtlib.writetiny.smt.smtlib.write.writeScript[function] atlib/smt/src/smtlib/write.zig:23lib.smt.src.smtlib.write.writeTernary[function] — private source atlib/smt/src/smtlib/write.zig:144in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeUnary[function] — private source atlib/smt/src/smtlib/write.zig:130in nearest public ownertiny.smt.smtlib.write
Complete call list for smtlib.write.writeTerm
7 direct calls.
lib.smt.src.smtlib.write.writeApply[function] — private source atlib/smt/src/smtlib/write.zig:116in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeBinary[function] — private source atlib/smt/src/smtlib/write.zig:136in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeExtension[function] — private source atlib/smt/src/smtlib/write.zig:160in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeExtract[function] — private source atlib/smt/src/smtlib/write.zig:154in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeNary[function] — private source atlib/smt/src/smtlib/write.zig:166in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeTernary[function] — private source atlib/smt/src/smtlib/write.zig:144in nearest public ownertiny.smt.smtlib.writelib.smt.src.smtlib.write.writeUnary[function] — private source atlib/smt/src/smtlib/write.zig:130in nearest public ownertiny.smt.smtlib.write
Audit
| Definitions | 3 |
|---|---|
| Public names | 5 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |