tiny.smt.choir
Defined in tiny.smt.
A checker that asks an SMT solver about a program can state its questions as formulas in the same intermediate representation as the program.
API (8)
Actions
Public operations.
loadDialect: Loads the dialect's specification intoctx, registering its operations and types, for a caller that wants the dialect's operations registered with a context at once and for the package's tests before they build operations.registerDialect: Adds the dialect's loader to the registry ofctxunder the namesmt, for a caller that prepares a context for the dialect so the context loads the dialect when it first meets the namesmt.
Types and contracts
Public types and contracts.
SmtDialect: The SMT dialect: its name, its specification, one struct per operation, and the functions that build and read its types.attr_names: The keys of the seven attributes the dialect's operations carry.type_names: The names of the dialect's three types,boolean,bvandarray.
Namespaces
Public namespaces.
dialect: Code that builds formulas in a compiler's intermediate representation needs, for each operator, a way to create the operation and a way to read its parts back.names: Code that reads a formula back from an intermediate representation tells its types apart and finds each operation's extra data by comparing names as text, so those names live in one place.
Values and defaults
Public values and defaults.
registry: The dialect's registry entry: the namesmtpaired with the function that loads the dialect's specification.
Source
Source: lib/smt/src/choir/root.zig
zig
//! A checker that asks an SMT solver about a program can state its questions as formulas in the//! same intermediate representation as the program. The namespace defines those formulas as the//! operations and types of one dialect: Boolean, fixed-width bit-vector and array formulas,//! applications of uninterpreted functions, and named assertions.//!//! A checker builds one formula per property it must check, names each assertion and gives it a//! group label, and later reads the assertions back to hand them to a solver. Code that reads a//! formula back needs each value's type to carry what a solver needs: a bit-vector its width, an//! array its index width and its element width.//!//! Operators change width: concatenation adds the widths of its operands, extraction keeps a range//! of bits, extension adds bits, and reading an array yields its element width. The type of such a//! result depends on the operands' types and on numbers the operation carries. Other operators need//! Boolean operands or operands of one type, and code that builds an operation from values made//! elsewhere can pass values that break those rules. The representation finds the dialect that owns//! an operation or a type from the first part of its name, so a context has to know the dialect//! before it can make the dialect's operations and types.//!//! [MLIR](https://mlir.llvm.org/), a compiler framework from the LLVM project, groups the//! operations and types of one domain into a dialect that a context loads, and names each operation//! by its dialect's name, a dot and a short name. Its operations produce typed results that later//! operations take as operands. [SMT-LIB](https://smt-lib.org/), the standard text language of SMT//! solvers, defines theories of Booleans, fixed-size bit-vectors and arrays and names their//! operators. The dialect takes those three theories, and most of its operations take the SMT-LIB//! operator's name.//!//! The operations form one dialect, `smt`, of the compiler intermediate representation the package//! depends on (*Choir*), which follows MLIR's model. Each operation's name is `smt.` followed by a//! short name. For 27 of the 42 operations the short name is the SMT-LIB operator's name, such as//! `smt.bvadd`, `smt.bvult` and `smt.bvuaddo`. The other 15 operations take short names of the//! dialect's own, such as `smt.eq` for the SMT-LIB operator `=`, `smt.bvzeroext` for `zero_extend`,//! and `smt.var` for a declared constant. The three types are `smt.bool`, `smt.bv` and `smt.array`.//! A bit-vector type carries its width as decimal text, such as `64`, and an array type maps//! bit-vectors to bit-vectors and carries its index width and element width as text, such as//! `8:32`. Only the rotation, width-changing and array operations check their operands' types when//! they are created, and the width-changing and array operations compute their result's width from//! those types. For every other rule (Boolean operands, operands of one type, a result of the//! operands' type), the dialect registers the rule with the context, and the IR's verifier//! (`ir.verifyOperation`) checks it. A caller makes the dialect known to a context in one of three//! ways. `registerDialect` records a loader that the context runs when it first meets the name//! `smt`, `loadDialect` loads the dialect at once, and each type getter of `SmtDialect` loads the//! dialect on first use. The package has no function that turns these operations into its own terms//! or into clauses. A caller reads the assertions back and builds one term for each operation, with//! the term operator of the same meaning. The namespace exports its two files as `dialect` and//! `names`, and it re-exports `SmtDialect`, `registerDialect`, `loadDialect` and `registry` from//! `dialect` and `type_names` and `attr_names` from `names`.pub const dialect = @import("dialect.zig");pub const names = @import("names.zig");pub const attr_names = names.attr_names;pub const loadDialect = dialect.loadDialect;pub const registerDialect = dialect.registerDialect;pub const registry = dialect.registry;pub const SmtDialect = dialect.SmtDialect;pub const type_names = names.type_names;Source: lib/smt/src/root.zig:99
zig
pub const choir = @import("choir/root.zig");Audit
| Definitions | 1 |
|---|---|
| Public names | 1 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |