Z3
 
Loading...
Searching...
No Matches
propagator_callbacks.go
Go to the documentation of this file.
1package z3
2
3/*
4#include "z3.h"
5#include <stdint.h>
6*/
7import "C"
8import (
9 "runtime/cgo"
10 "unsafe"
11)
12
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()) {
15 old := p.cb
16 p.cb = cb
17 defer func() { p.cb = old }()
18 fn()
19}
20
21// goPushCb is exported to C as a callback for Z3_push_eh.
22//
23//export goPushCb
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)
27}
28
29// goPopCb is exported to C as a callback for Z3_pop_eh.
30//
31//export goPopCb
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))
36 })
37}
38
39// goFreshCb is exported to C as a callback for Z3_fresh_eh.
40//
41//export goFreshCb
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{
47 ctx: freshCtx,
48 iface: freshIface,
49 }
50 freshProp.handle = cgo.NewHandle(freshProp)
51 return C.uintptr_t(freshProp.handle)
52}
53
54// goFixedCb is exported to C as a callback for Z3_fixed_eh.
55//
56//export goFixedCb
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))
62 })
63 }
64}
65
66// goEqCb is exported to C as a callback for Z3_eq_eh (equality).
67//
68//export goEqCb
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))
74 })
75 }
76}
77
78// goDiseqCb is exported to C as a callback for Z3_eq_eh (disequality).
79//
80//export goDiseqCb
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))
86 })
87 }
88}
89
90// goFinalCb is exported to C as a callback for Z3_final_eh.
91//
92//export goFinalCb
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)
97 }
98}
99
100// goCreatedCb is exported to C as a callback for Z3_created_eh.
101//
102//export goCreatedCb
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))
108 })
109 }
110}
111
112// goDecideCb is exported to C as a callback for Z3_decide_eh.
113//
114//export goDecideCb
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))
120 })
121 }
122}
123
124// goOnBindingCb is exported to C as a callback for Z3_on_binding_eh.
125//
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)
134 }
135 })
136 }
137 return result
138}
139
140// goOnClauseCb is exported to C as a callback for Z3_on_clause_eh.
141//
142//export goOnClauseCb
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)
145 var ph *Expr
146 if proofHint != nil {
147 ph = newExpr(oc.ctx, proofHint)
148 }
149 goDepSlice := make([]uint, uint(n))
150 if n > 0 {
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])
154 }
155 }
156 vec := newASTVector(oc.ctx, literals)
157 oc.handler(ph, goDepSlice, vec)
158}