13// withCallback temporarily sets the callback context, calls fn, and restores the old context.
14func (p *UserPropagator) withCallback(cb C.Z3_solver_callback, fn func()) {
17 defer func() { p.cb = old }()
21// goPushCb is exported to C as a callback for Z3_push_eh.
24func goPushCb(ctx C.uintptr_t, cb C.Z3_solver_callback) {
25 p := cgo.Handle(ctx).Value().(*UserPropagator)
26 p.withCallback(cb, p.iface.Push)
29// goPopCb is exported to C as a callback for Z3_pop_eh.
32func goPopCb(ctx C.uintptr_t, cb C.Z3_solver_callback, numScopes C.uint) {
33 p := cgo.Handle(ctx).Value().(*UserPropagator)
34 p.withCallback(cb, func() {
35 p.iface.Pop(uint(numScopes))
39// goFreshCb is exported to C as a callback for Z3_fresh_eh.
42func goFreshCb(ctx C.uintptr_t, newContext C.Z3_context) C.uintptr_t {
43 p := cgo.Handle(ctx).Value().(*UserPropagator)
44 freshCtx := &Context{ptr: newContext}
45 freshIface := p.iface.Fresh(freshCtx)
46 freshProp := &UserPropagator{
50 freshProp.handle = cgo.NewHandle(freshProp)
51 return C.uintptr_t(freshProp.handle)
54// goFixedCb is exported to C as a callback for Z3_fixed_eh.
57func goFixedCb(ctx C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast, value C.Z3_ast) {
58 p := cgo.Handle(ctx).Value().(*UserPropagator)
59 if h, ok := p.iface.(FixedHandler); ok {
60 p.withCallback(cb, func() {
61 h.Fixed(newExpr(p.ctx, t), newExpr(p.ctx, value))
66// goEqCb is exported to C as a callback for Z3_eq_eh (equality).
69func goEqCb(ctx C.uintptr_t, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
70 p := cgo.Handle(ctx).Value().(*UserPropagator)
71 if h, ok := p.iface.(EqHandler); ok {
72 p.withCallback(cb, func() {
73 h.Eq(newExpr(p.ctx, s), newExpr(p.ctx, t))
78// goDiseqCb is exported to C as a callback for Z3_eq_eh (disequality).
81func goDiseqCb(ctx C.uintptr_t, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
82 p := cgo.Handle(ctx).Value().(*UserPropagator)
83 if h, ok := p.iface.(DiseqHandler); ok {
84 p.withCallback(cb, func() {
85 h.Diseq(newExpr(p.ctx, s), newExpr(p.ctx, t))
90// goFinalCb is exported to C as a callback for Z3_final_eh.
93func goFinalCb(ctx C.uintptr_t, cb C.Z3_solver_callback) {
94 p := cgo.Handle(ctx).Value().(*UserPropagator)
95 if h, ok := p.iface.(FinalHandler); ok {
96 p.withCallback(cb, h.Final)
100// goCreatedCb is exported to C as a callback for Z3_created_eh.
103func goCreatedCb(ctx C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast) {
104 p := cgo.Handle(ctx).Value().(*UserPropagator)
105 if h, ok := p.iface.(CreatedHandler); ok {
106 p.withCallback(cb, func() {
107 h.Created(newExpr(p.ctx, t))
112// goDecideCb is exported to C as a callback for Z3_decide_eh.
115func goDecideCb(ctx C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast, idx C.uint, phase C.bool) {
116 p := cgo.Handle(ctx).Value().(*UserPropagator)
117 if h, ok := p.iface.(DecideHandler); ok {
118 p.withCallback(cb, func() {
119 h.Decide(newExpr(p.ctx, t), uint(idx), phase == C.bool(true))
124// goOnBindingCb is exported to C as a callback for Z3_on_binding_eh.
126//export goOnBindingCb
127func goOnBindingCb(ctx C.uintptr_t, cb C.Z3_solver_callback, q C.Z3_ast, inst C.Z3_ast) C.bool {
128 p := cgo.Handle(ctx).Value().(*UserPropagator)
129 result := C.bool(true) // default: allow binding when handler is not implemented
130 if h, ok := p.iface.(OnBindingHandler); ok {
131 p.withCallback(cb, func() {
132 if !h.OnBinding(newExpr(p.ctx, q), newExpr(p.ctx, inst)) {
133 result = C.bool(false)
140// goOnClauseCb is exported to C as a callback for Z3_on_clause_eh.
143func goOnClauseCb(ctx C.uintptr_t, proofHint C.Z3_ast, n C.uint, deps *C.uint, literals C.Z3_ast_vector) {
144 oc := cgo.Handle(ctx).Value().(*OnClause)
146 if proofHint != nil {
147 ph = newExpr(oc.ctx, proofHint)
149 goDepSlice := make([]uint, uint(n))
151 depSlice := (*[1 << 28]C.uint)(unsafe.Pointer(deps))[:n:n]
152 for i := uint(0); i < uint(n); i++ {
153 goDepSlice[i] = uint(depSlice[i])
156 vec := newASTVector(oc.ctx, literals)
157 oc.handler(ph, goDepSlice, vec)