Skip to documentation
SLOP

tiny.smt.smtlib.parse.term

Reference tiny.smt smtlib parse term

Defined in smtlib.parse.

Reads one SMT-LIB term and builds it in a Context.

API (1)

Actions

Public operations.

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

Source

Called byCallsprivate sourcelib.smt.src.smtlib.parse.termparseApplyprivate sourcelib.smt.src.smtlib.parse.termparseBinaryprivate sourcelib.smt.src.smtlib.parse.termparseIndexedprivate sourcelib.smt.src.smtlib.parse.termparseNaryprivate sourcelib.smt.src.smtlib.parse.termparseTernaryprivate sourcelib.smt.src.smtlib.parse.termparseUnaryprivate sourcelib.smt.src.smtlib.parse.termparseApplyprivate sourcelib.smt.src.smtlib.parse.termparseIndexedprivate sourcelib.smt.src.smtlib.parse.termparseIntegerprivate sourcelib.smt.src.smtlib.parse.termparseOperationsmtlib.parse.tokenatom+3 moresmtlib.parse.termparse
Static calls · unresolved targets: 2 · external targets: 4.

Source: lib/smt/src/smtlib/parse/root.zig:13

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

Source: lib/smt/src/smtlib/parse/term.zig

zig
//! Reads one SMT-LIB term and builds it in a `Context`. A script's formulas use the operators of//! different theories, so the reader has to map each operator name to the term it builds. A table//! maps each supported SMT-LIB operator name to its term kind. Every two-operand operator takes//! exactly two operands, so a chained `(= a b c)` fails. The reader refuses `let`, `ite`, `xor`,//! `-`, `bvneg`, the `#b` and `#x` literals and quoted symbols. It descends one call per//! parenthesis, with no depth bound.const std = @import("std");const smt = @import("../../root.zig");const errors = @import("error.zig");const state = @import("state.zig");const token = @import("token.zig");const Error = errors.Error;const ParseError = errors.ParseError;const Parser = state.Parser;const term = smt.term;const ExprTag = std.meta.Tag(term.Expr);const Operation = union(enum) {    unary: ExprTag,    binary: ExprTag,    ternary: ExprTag,    nary: ExprTag,};const OperationEntry = struct {    name: []const u8,    operation: Operation,};const operations = [_]OperationEntry{    .{ .name = "not", .operation = .{ .unary = .not } },    .{ .name = "=>", .operation = .{ .binary = .implies } },    .{ .name = "=", .operation = .{ .binary = .eq } },    .{ .name = "<=", .operation = .{ .binary = .le } },    .{ .name = "<", .operation = .{ .binary = .lt } },    .{ .name = ">=", .operation = .{ .binary = .ge } },    .{ .name = ">", .operation = .{ .binary = .gt } },    .{ .name = "bvule", .operation = .{ .binary = .bvule } },    .{ .name = "bvult", .operation = .{ .binary = .bvult } },    .{ .name = "bvsle", .operation = .{ .binary = .bvsle } },    .{ .name = "bvslt", .operation = .{ .binary = .bvslt } },    .{ .name = "bvuaddo", .operation = .{ .binary = .bvuaddo } },    .{ .name = "bvsaddo", .operation = .{ .binary = .bvsaddo } },    .{ .name = "bvssubo", .operation = .{ .binary = .bvssubo } },    .{ .name = "bvumulo", .operation = .{ .binary = .bvumulo } },    .{ .name = "bvsmulo", .operation = .{ .binary = .bvsmulo } },    .{ .name = "bvnot", .operation = .{ .unary = .bvnot } },    .{ .name = "bvand", .operation = .{ .binary = .bvand } },    .{ .name = "bvor", .operation = .{ .binary = .bvor } },    .{ .name = "bvxor", .operation = .{ .binary = .bvxor } },    .{ .name = "bvshl", .operation = .{ .binary = .bvshl } },    .{ .name = "bvlshr", .operation = .{ .binary = .bvlshr } },    .{ .name = "bvashr", .operation = .{ .binary = .bvashr } },    .{ .name = "bvudiv", .operation = .{ .binary = .bvudiv } },    .{ .name = "bvurem", .operation = .{ .binary = .bvurem } },    .{ .name = "bvsdiv", .operation = .{ .binary = .bvsdiv } },    .{ .name = "bvsrem", .operation = .{ .binary = .bvsrem } },    .{ .name = "bvsmod", .operation = .{ .binary = .bvsmod } },    .{ .name = "select", .operation = .{ .binary = .array_select } },    .{ .name = "store", .operation = .{ .ternary = .array_store } },    .{ .name = "concat", .operation = .{ .binary = .bvconcat } },    .{ .name = "bvadd", .operation = .{ .binary = .bvadd } },    .{ .name = "bvsub", .operation = .{ .binary = .bvsub } },    .{ .name = "bvmul", .operation = .{ .binary = .bvmul } },    .{ .name = "and", .operation = .{ .nary = .and_ } },    .{ .name = "or", .operation = .{ .nary = .or_ } },    .{ .name = "distinct", .operation = .{ .nary = .distinct } },    .{ .name = "+", .operation = .{ .nary = .add } },    .{ .name = "*", .operation = .{ .nary = .mul } },};/// Reads one term at the parser's position, builds it in the parser's `Context` and returns it. The/// command reader calls it for the term of each `assert`. An atom is `true`, `false`, an integer,/// the name of a function with no arguments, or the name of a declared constant. An integer is a/// decimal numeral with an optional leading `-`. A list is `(_ bvV W)` for a bit-vector constant,/// an indexed operator such as `((_ extract high low) x)`, a supported operator applied to its/// operands, or a declared function applied to its arguments. It returns `UnknownSymbol` for an/// undeclared name, `UnsupportedTerm` for an unsupported operator, `InvalidNumber` for a malformed/// number, and the errors of the `Context` builders, such as `FunctionArityMismatch`. It checks no/// sorts except the arguments of a function application.pub fn parse(parser: *Parser) Error!term.Term {    if (!token.peekLeft(parser)) {        const item = try token.atom(parser);        if (std.mem.eql(u8, item, "true")) return try parser.ctx.boolValue(true);        if (std.mem.eql(u8, item, "false")) return try parser.ctx.boolValue(false);        if (parseInteger(item)) |value| return try parser.ctx.intValue(value);        if (parser.functions.get(item)) |function_id| return try parser.ctx.apply(function_id, &.{});        return parser.symbols.get(item) orelse ParseError.UnknownSymbol;    }    try token.expectLeft(parser);    if (token.peekLeft(parser)) return try parseIndexed(parser);    const op = try token.atom(parser);    if (std.mem.eql(u8, op, "_")) {        const value_atom = try token.atom(parser);        if (!std.mem.startsWith(u8, value_atom, "bv")) return ParseError.UnsupportedTerm;        const value = std.fmt.parseInt(u128, value_atom[2..], 10) catch return ParseError.InvalidNumber;        const width = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        return try parser.ctx.bitvecValue(value, width);    }    inline for (operations) |entry| {        if (std.mem.eql(u8, op, entry.name)) return try parseOperation(parser, entry.operation);    }    if (parser.functions.get(op)) |function_id| return try parseApply(parser, function_id);    return ParseError.UnsupportedTerm;}fn parseOperation(parser: *Parser, comptime operation: Operation) Error!term.Term {    return switch (operation) {        .unary => |tag| try parseUnary(parser, tag),        .binary => |tag| try parseBinary(parser, tag),        .ternary => |tag| try parseTernary(parser, tag),        .nary => |tag| try parseNary(parser, tag),    };}fn parseIndexed(parser: *Parser) Error!term.Term {    try token.expectLeft(parser);    const underscore = try token.atom(parser);    if (!std.mem.eql(u8, underscore, "_")) return ParseError.UnsupportedTerm;    const op = try token.atom(parser);    if (std.mem.eql(u8, op, "extract")) {        const high = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        const low = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        const operand = try parse(parser);        try token.expectRight(parser);        return try parser.ctx.bvextract(operand, high, low);    }    if (std.mem.eql(u8, op, "zero_extend")) {        const extra = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        const operand = try parse(parser);        try token.expectRight(parser);        return try parser.ctx.bvzeroext(operand, extra);    }    if (std.mem.eql(u8, op, "sign_extend")) {        const extra = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        const operand = try parse(parser);        try token.expectRight(parser);        return try parser.ctx.bvsignext(operand, extra);    }    if (std.mem.eql(u8, op, "rotate_left")) {        const amount = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        const operand = try parse(parser);        try token.expectRight(parser);        return try parser.ctx.bvrotl(operand, amount);    }    if (std.mem.eql(u8, op, "rotate_right")) {        const amount = std.fmt.parseInt(u32, try token.atom(parser), 10) catch return ParseError.InvalidNumber;        try token.expectRight(parser);        const operand = try parse(parser);        try token.expectRight(parser);        return try parser.ctx.bvrotr(operand, amount);    }    return ParseError.UnsupportedTerm;}fn parseUnary(parser: *Parser, comptime tag: std.meta.Tag(term.Expr)) Error!term.Term {    const operand = try parse(parser);    try token.expectRight(parser);    return switch (tag) {        .not => try parser.ctx.not(operand),        .bvnot => try parser.ctx.bvnot(operand),        else => unreachable,    };}fn parseBinary(parser: *Parser, comptime tag: std.meta.Tag(term.Expr)) Error!term.Term {    const lhs = try parse(parser);    const rhs = try parse(parser);    try token.expectRight(parser);    return try parser.ctx.binary(tag, lhs, rhs);}fn parseTernary(parser: *Parser, comptime tag: std.meta.Tag(term.Expr)) Error!term.Term {    const first = try parse(parser);    const second = try parse(parser);    const third = try parse(parser);    try token.expectRight(parser);    return switch (tag) {        .array_store => try parser.ctx.arrayStore(first, second, third),        else => unreachable,    };}fn parseNary(parser: *Parser, comptime tag: std.meta.Tag(term.Expr)) Error!term.Term {    var operands: std.ArrayList(term.Term) = .empty;    defer operands.deinit(parser.ctx.allocator);    while (!token.peekRight(parser)) {        try operands.append(parser.ctx.allocator, try parse(parser));    }    try token.expectRight(parser);    return switch (tag) {        .and_ => try parser.ctx.and_(operands.items),        .or_ => try parser.ctx.or_(operands.items),        .distinct => try parser.ctx.distinct(operands.items),        .add => try parser.ctx.add(operands.items),        .mul => try parser.ctx.mul(operands.items),        else => unreachable,    };}fn parseApply(parser: *Parser, function: term.Function) Error!term.Term {    var operands: std.ArrayList(term.Term) = .empty;    defer operands.deinit(parser.ctx.allocator);    while (!token.peekRight(parser)) {        try operands.append(parser.ctx.allocator, try parse(parser));    }    try token.expectRight(parser);    return try parser.ctx.apply(function, operands.items);}fn parseInteger(text: []const u8) ?i128 {    if (text.len == 0) return null;    if (text[0] == '-' and text.len == 1) return null;    if (text[0] != '-' and (text[0] < '0' or text[0] > '9')) return null;    return std.fmt.parseInt(i128, text, 10) catch null;}

Complete call list for smtlib.parse.term.parse

8 direct calls.

Audit

Definitions2
Public names2
Members0
Version26.7.0
Revisiondaab053ee433