mirror of
https://github.com/Z3Prover/z3
synced 2026-06-05 08:30:50 +00:00
Add missing API bindings: importModelConverter, OnClause, and user propagator
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
43dee82caa
commit
0de7af9112
8 changed files with 672 additions and 0 deletions
162
src/api/go/propagator_callbacks.go
Normal file
162
src/api/go/propagator_callbacks.go
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
package z3
|
||||
|
||||
/*
|
||||
#include "z3.h"
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"runtime/cgo"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// goPushCb is exported to C as a callback for Z3_push_eh.
|
||||
//
|
||||
//export goPushCb
|
||||
func goPushCb(ctx unsafe.Pointer, cb C.Z3_solver_callback) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
p.iface.Push()
|
||||
}
|
||||
|
||||
// goPopCb is exported to C as a callback for Z3_pop_eh.
|
||||
//
|
||||
//export goPopCb
|
||||
func goPopCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, numScopes C.uint) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
p.iface.Pop(uint(numScopes))
|
||||
}
|
||||
|
||||
// goFreshCb is exported to C as a callback for Z3_fresh_eh.
|
||||
//
|
||||
//export goFreshCb
|
||||
func goFreshCb(ctx unsafe.Pointer, newContext C.Z3_context) unsafe.Pointer {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
freshCtx := &Context{ptr: newContext}
|
||||
freshIface := p.iface.Fresh(freshCtx)
|
||||
freshProp := &UserPropagator{
|
||||
ctx: freshCtx,
|
||||
iface: freshIface,
|
||||
}
|
||||
freshProp.handle = cgo.NewHandle(freshProp)
|
||||
return unsafe.Pointer(uintptr(freshProp.handle))
|
||||
}
|
||||
|
||||
// goFixedCb is exported to C as a callback for Z3_fixed_eh.
|
||||
//
|
||||
//export goFixedCb
|
||||
func goFixedCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, t C.Z3_ast, value C.Z3_ast) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(FixedHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Fixed(newExpr(p.ctx, t), newExpr(p.ctx, value))
|
||||
}
|
||||
}
|
||||
|
||||
// goEqCb is exported to C as a callback for Z3_eq_eh (equality).
|
||||
//
|
||||
//export goEqCb
|
||||
func goEqCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(EqHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Eq(newExpr(p.ctx, s), newExpr(p.ctx, t))
|
||||
}
|
||||
}
|
||||
|
||||
// goDiseqCb is exported to C as a callback for Z3_eq_eh (disequality).
|
||||
//
|
||||
//export goDiseqCb
|
||||
func goDiseqCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(DiseqHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Diseq(newExpr(p.ctx, s), newExpr(p.ctx, t))
|
||||
}
|
||||
}
|
||||
|
||||
// goFinalCb is exported to C as a callback for Z3_final_eh.
|
||||
//
|
||||
//export goFinalCb
|
||||
func goFinalCb(ctx unsafe.Pointer, cb C.Z3_solver_callback) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(FinalHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Final()
|
||||
}
|
||||
}
|
||||
|
||||
// goCreatedCb is exported to C as a callback for Z3_created_eh.
|
||||
//
|
||||
//export goCreatedCb
|
||||
func goCreatedCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, t C.Z3_ast) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(CreatedHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Created(newExpr(p.ctx, t))
|
||||
}
|
||||
}
|
||||
|
||||
// goDecideCb is exported to C as a callback for Z3_decide_eh.
|
||||
//
|
||||
//export goDecideCb
|
||||
func goDecideCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, t C.Z3_ast, idx C.uint, phase C.bool) {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(DecideHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
h.Decide(newExpr(p.ctx, t), uint(idx), phase == C.bool(true))
|
||||
}
|
||||
}
|
||||
|
||||
// goOnBindingCb is exported to C as a callback for Z3_on_binding_eh.
|
||||
//
|
||||
//export goOnBindingCb
|
||||
func goOnBindingCb(ctx unsafe.Pointer, cb C.Z3_solver_callback, q C.Z3_ast, inst C.Z3_ast) C.bool {
|
||||
p := cgo.Handle(uintptr(ctx)).Value().(*UserPropagator)
|
||||
if h, ok := p.iface.(OnBindingHandler); ok {
|
||||
old := p.cb
|
||||
p.cb = cb
|
||||
defer func() { p.cb = old }()
|
||||
if h.OnBinding(newExpr(p.ctx, q), newExpr(p.ctx, inst)) {
|
||||
return C.bool(true)
|
||||
}
|
||||
return C.bool(false)
|
||||
}
|
||||
return C.bool(true)
|
||||
}
|
||||
|
||||
// goOnClauseCb is exported to C as a callback for Z3_on_clause_eh.
|
||||
//
|
||||
//export goOnClauseCb
|
||||
func goOnClauseCb(ctx unsafe.Pointer, proofHint C.Z3_ast, n C.uint, deps *C.uint, literals C.Z3_ast_vector) {
|
||||
oc := cgo.Handle(uintptr(ctx)).Value().(*OnClause)
|
||||
var ph *Expr
|
||||
if proofHint != nil {
|
||||
ph = newExpr(oc.ctx, proofHint)
|
||||
}
|
||||
goDepSlice := make([]uint, uint(n))
|
||||
if n > 0 {
|
||||
depSlice := (*[1 << 28]C.uint)(unsafe.Pointer(deps))[:n:n]
|
||||
for i := uint(0); i < uint(n); i++ {
|
||||
goDepSlice[i] = uint(depSlice[i])
|
||||
}
|
||||
}
|
||||
vec := newASTVector(oc.ctx, literals)
|
||||
oc.handler(ph, goDepSlice, vec)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue