module Z3

Defined in:

z3.cr
z3/api.cr
z3/bitvec_expr.cr
z3/bitvec_sort.cr
z3/bool_expr.cr
z3/bool_sort.cr
z3/char_expr.cr
z3/char_sort.cr
z3/check_result.cr
z3/checkable.cr
z3/float_expr.cr
z3/float_sort.cr
z3/func_decl.cr
z3/func_interp.cr
z3/int_expr.cr
z3/int_sort.cr
z3/model.cr
z3/optimize.cr
z3/range_indexing.cr
z3/real_expr.cr
z3/real_sort.cr
z3/rounding_mode_expr.cr
z3/rounding_mode_sort.cr
z3/seq_expr.cr
z3/seq_sort.cr
z3/solver.cr
z3/string_expr.cr
z3/string_sort.cr

Constant Summary

VERSION = "0.1.0"

Class Method Summary

Class Method Detail

def self.add(args : Array(IntExpr | Int32)) #

[View source]
def self.add(args : Array(RealExpr)) #

[View source]
def self.and(args : Array(BoolExpr | Bool)) #

[View source]
def self.and(args : Array(BitvecExpr)) #

Bitvec has no n-ary and/or in Z3, so reduce with the bitwise operators.


[View source]
def self.at_least(args : Array(BoolExpr), k : Int32) #

Native cardinality constraint: at least k of the given Bool exprs are true, or at least k units of weight when given {expr, weight} pairs


[View source]
def self.at_least(args : Array(Tuple(BoolExpr, Int32)), k : Int32) #

[View source]
def self.at_most(args : Array(BoolExpr), k : Int32) #

Native cardinality constraint: at most k of the given Bool exprs are true. An {expr, weight} pair list weighs them instead, so Z3.at_most([{a, 3}, {b, 2}], 4) allows either one but not both.

Ruby's z3 spells the weighted form as an expr => weight Hash. Exprs can't be Hash keys here - see the Limitations section of the README.


[View source]
def self.at_most(args : Array(Tuple(BoolExpr, Int32)), k : Int32) #

[View source]
def self.bitvec(name : String, size : UInt32) #

[View source]
def self.bool(name : String) #

[View source]
def self.char(name : String) #

[View source]
def self.distinct(args : Array(IntExpr)) #

[View source]
def self.distinct(args : Array(RealExpr)) #

[View source]
def self.distinct(args : Array(BoolExpr)) #

[View source]
def self.distinct(args : Array(BitvecExpr)) #

[View source]
def self.distinct(args : Array(CharExpr)) #

[View source]
def self.distinct(args : Array(StringExpr)) #

[View source]
def self.distinct(args : Array(SeqExpr)) #

[View source]
def self.distinct(args : Array(FloatExpr)) #

Z3's own .distinct, so this is term inequality - +zero and -zero are distinct floats even though +zero == -zero, and two NaNs are not


[View source]
def self.distinct(args : Array(RoundingModeExpr)) #

[View source]
def self.exactly(args : Array(BoolExpr), k : Int32) #

Native cardinality constraint: exactly k of the given Bool exprs are true, or exactly k units of weight when given {expr, weight} pairs


[View source]
def self.exactly(args : Array(Tuple(BoolExpr, Int32)), k : Int32) #

[View source]
def self.float(name : String, ebits : Int, sbits : Int) #

[View source]
def self.float(name : String, sort : FloatSort) #

The sort is a width - 16, 32, 64 or 128 - a name - :half, :single, :double or :quadruple - a FloatSort, or the two bit counts spelled out


[View source]
def self.float(name : String, width : Int | Symbol) #

[View source]
def self.fresh_function(prefix : String, *sorts : AnySort) : FuncDecl #

The same as Z3.function with a name Z3 picks, for helper functions which mustn't collide with anything you've named


[View source]
def self.function(name : String, *sorts : AnySort) : FuncDecl #

An uninterpreted function - a symbol the solver decides the meaning of. The last sort is the range and the ones before it the domain, so Z3.function("f", Int, Int, Bool) is a two argument predicate. Apply it with f[x, y].


[View source]
def self.int(name : String) #

[View source]
def self.mul(args : Array(IntExpr | Int32)) #

[View source]
def self.mul(args : Array(RealExpr)) #

[View source]
def self.or(args : Array(BoolExpr | Bool)) #

[View source]
def self.or(args : Array(BitvecExpr)) #

[View source]
def self.real(name : String) #

[View source]
def self.rec_function(name : String, *sorts : AnySort) : FuncDecl #

A function which is its body, rather than one the solver gets to interpret - SMT-LIB's define-fun-rec. Declaring and defining are two steps so that the body can mention the function it defines, and so that mutually recursive functions can both be declared before either is defined:

even = Z3.rec_function("even", Z3::IntSort, Z3::BoolSort)
odd = Z3.rec_function("odd", Z3::IntSort, Z3::BoolSort)
even.define { |args| ... odd[...] ... }
odd.define { |args| ... even[...] ... }

A declaration never given a body is not an error and doesn't announce itself - it simply behaves as an uninterpreted function. Z3 doesn't check that the recursion terminates either, and one it can't finish unfolding comes back as Unknown.

A definition belongs to the context rather than to any solver, exactly as it would in an SMT-LIB script, so it is permanent and every solver made afterwards carries it.


[View source]
def self.rounding_mode(name : String) #

[View source]
def self.seq(name : String, element_sort) #

[View source]
def self.string(name : String) #

[View source]
def self.version #

[View source]