mirror of
https://github.com/Z3Prover/z3
synced 2026-07-04 14:26:10 +00:00
Fix Go bindings reference counting for Z3_ast_vector objects
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
1e77b150a8
commit
ea1f5a333a
3 changed files with 30 additions and 30 deletions
|
|
@ -128,6 +128,10 @@ func (o *Optimize) GetUpper(index uint) *Expr {
|
||||||
// otherwise it's represented as value + eps * EPSILON.
|
// otherwise it's represented as value + eps * EPSILON.
|
||||||
func (o *Optimize) GetLowerAsVector(index uint) []*Expr {
|
func (o *Optimize) GetLowerAsVector(index uint) []*Expr {
|
||||||
vec := C.Z3_optimize_get_lower_as_vector(o.ctx.ptr, o.ptr, C.uint(index))
|
vec := C.Z3_optimize_get_lower_as_vector(o.ctx.ptr, o.ptr, C.uint(index))
|
||||||
|
// Increment reference count for the vector since we're using it
|
||||||
|
C.Z3_ast_vector_inc_ref(o.ctx.ptr, vec)
|
||||||
|
defer C.Z3_ast_vector_dec_ref(o.ctx.ptr, vec)
|
||||||
|
|
||||||
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
||||||
if size != 3 {
|
if size != 3 {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -144,6 +148,10 @@ func (o *Optimize) GetLowerAsVector(index uint) []*Expr {
|
||||||
// otherwise it's represented as value + eps * EPSILON.
|
// otherwise it's represented as value + eps * EPSILON.
|
||||||
func (o *Optimize) GetUpperAsVector(index uint) []*Expr {
|
func (o *Optimize) GetUpperAsVector(index uint) []*Expr {
|
||||||
vec := C.Z3_optimize_get_upper_as_vector(o.ctx.ptr, o.ptr, C.uint(index))
|
vec := C.Z3_optimize_get_upper_as_vector(o.ctx.ptr, o.ptr, C.uint(index))
|
||||||
|
// Increment reference count for the vector since we're using it
|
||||||
|
C.Z3_ast_vector_inc_ref(o.ctx.ptr, vec)
|
||||||
|
defer C.Z3_ast_vector_dec_ref(o.ctx.ptr, vec)
|
||||||
|
|
||||||
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
||||||
if size != 3 {
|
if size != 3 {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -173,34 +181,19 @@ func (o *Optimize) SetParams(params *Params) {
|
||||||
// Assertions returns the assertions in the optimizer.
|
// Assertions returns the assertions in the optimizer.
|
||||||
func (o *Optimize) Assertions() []*Expr {
|
func (o *Optimize) Assertions() []*Expr {
|
||||||
vec := C.Z3_optimize_get_assertions(o.ctx.ptr, o.ptr)
|
vec := C.Z3_optimize_get_assertions(o.ctx.ptr, o.ptr)
|
||||||
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
return astVectorToExprs(o.ctx, vec)
|
||||||
result := make([]*Expr, size)
|
|
||||||
for i := uint(0); i < size; i++ {
|
|
||||||
result[i] = newExpr(o.ctx, C.Z3_ast_vector_get(o.ctx.ptr, vec, C.uint(i)))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objectives returns the objectives in the optimizer.
|
// Objectives returns the objectives in the optimizer.
|
||||||
func (o *Optimize) Objectives() []*Expr {
|
func (o *Optimize) Objectives() []*Expr {
|
||||||
vec := C.Z3_optimize_get_objectives(o.ctx.ptr, o.ptr)
|
vec := C.Z3_optimize_get_objectives(o.ctx.ptr, o.ptr)
|
||||||
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
return astVectorToExprs(o.ctx, vec)
|
||||||
result := make([]*Expr, size)
|
|
||||||
for i := uint(0); i < size; i++ {
|
|
||||||
result[i] = newExpr(o.ctx, C.Z3_ast_vector_get(o.ctx.ptr, vec, C.uint(i)))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsatCore returns the unsat core if the constraints are unsatisfiable.
|
// UnsatCore returns the unsat core if the constraints are unsatisfiable.
|
||||||
func (o *Optimize) UnsatCore() []*Expr {
|
func (o *Optimize) UnsatCore() []*Expr {
|
||||||
vec := C.Z3_optimize_get_unsat_core(o.ctx.ptr, o.ptr)
|
vec := C.Z3_optimize_get_unsat_core(o.ctx.ptr, o.ptr)
|
||||||
size := uint(C.Z3_ast_vector_size(o.ctx.ptr, vec))
|
return astVectorToExprs(o.ctx, vec)
|
||||||
result := make([]*Expr, size)
|
|
||||||
for i := uint(0); i < size; i++ {
|
|
||||||
result[i] = newExpr(o.ctx, C.Z3_ast_vector_get(o.ctx.ptr, vec, C.uint(i)))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromFile parses an SMT-LIB2 file with optimization objectives and constraints.
|
// FromFile parses an SMT-LIB2 file with optimization objectives and constraints.
|
||||||
|
|
|
||||||
|
|
@ -134,23 +134,13 @@ func (s *Solver) NumScopes() uint {
|
||||||
// Assertions returns the assertions in the solver.
|
// Assertions returns the assertions in the solver.
|
||||||
func (s *Solver) Assertions() []*Expr {
|
func (s *Solver) Assertions() []*Expr {
|
||||||
vec := C.Z3_solver_get_assertions(s.ctx.ptr, s.ptr)
|
vec := C.Z3_solver_get_assertions(s.ctx.ptr, s.ptr)
|
||||||
size := uint(C.Z3_ast_vector_size(s.ctx.ptr, vec))
|
return astVectorToExprs(s.ctx, vec)
|
||||||
result := make([]*Expr, size)
|
|
||||||
for i := uint(0); i < size; i++ {
|
|
||||||
result[i] = newExpr(s.ctx, C.Z3_ast_vector_get(s.ctx.ptr, vec, C.uint(i)))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnsatCore returns the unsat core if the constraints are unsatisfiable.
|
// UnsatCore returns the unsat core if the constraints are unsatisfiable.
|
||||||
func (s *Solver) UnsatCore() []*Expr {
|
func (s *Solver) UnsatCore() []*Expr {
|
||||||
vec := C.Z3_solver_get_unsat_core(s.ctx.ptr, s.ptr)
|
vec := C.Z3_solver_get_unsat_core(s.ctx.ptr, s.ptr)
|
||||||
size := uint(C.Z3_ast_vector_size(s.ctx.ptr, vec))
|
return astVectorToExprs(s.ctx, vec)
|
||||||
result := make([]*Expr, size)
|
|
||||||
for i := uint(0); i < size; i++ {
|
|
||||||
result[i] = newExpr(s.ctx, C.Z3_ast_vector_get(s.ctx.ptr, vec, C.uint(i)))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReasonUnknown returns the reason why the result is unknown.
|
// ReasonUnknown returns the reason why the result is unknown.
|
||||||
|
|
|
||||||
|
|
@ -787,3 +787,20 @@ boundPtr = &cBound[0]
|
||||||
ptr := C.Z3_mk_lambda_const(c.ptr, C.uint(numBound), boundPtr, body.ptr)
|
ptr := C.Z3_mk_lambda_const(c.ptr, C.uint(numBound), boundPtr, body.ptr)
|
||||||
return newLambda(c, ptr)
|
return newLambda(c, ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// astVectorToExprs converts a Z3_ast_vector to a slice of Expr.
|
||||||
|
// This function properly manages the reference count of the vector by
|
||||||
|
// incrementing it on entry and decrementing it on exit.
|
||||||
|
// The individual AST elements are already reference counted by newExpr.
|
||||||
|
func astVectorToExprs(ctx *Context, vec C.Z3_ast_vector) []*Expr {
|
||||||
|
// Increment reference count for the vector since we're using it
|
||||||
|
C.Z3_ast_vector_inc_ref(ctx.ptr, vec)
|
||||||
|
defer C.Z3_ast_vector_dec_ref(ctx.ptr, vec)
|
||||||
|
|
||||||
|
size := uint(C.Z3_ast_vector_size(ctx.ptr, vec))
|
||||||
|
result := make([]*Expr, size)
|
||||||
|
for i := uint(0); i < size; i++ {
|
||||||
|
result[i] = newExpr(ctx, C.Z3_ast_vector_get(ctx.ptr, vec, C.uint(i)))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue