mirror of
https://github.com/Z3Prover/z3
synced 2026-02-24 01:01:19 +00:00
163 lines
4.2 KiB
Go
163 lines
4.2 KiB
Go
package z3
|
|
|
|
/*
|
|
#include "z3.h"
|
|
#include <stdint.h>
|
|
*/
|
|
import "C"
|
|
import (
|
|
"runtime/cgo"
|
|
"unsafe"
|
|
)
|
|
|
|
// goPushCb is exported to C as a callback for Z3_push_eh.
|
|
//
|
|
//export goPushCb
|
|
func goPushCb(ctx C.uintptr_t, cb C.Z3_solver_callback) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, numScopes C.uint) {
|
|
p := cgo.Handle(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 C.uintptr_t, newContext C.Z3_context) C.uintptr_t {
|
|
p := cgo.Handle(ctx).Value().(*UserPropagator)
|
|
freshCtx := &Context{ptr: newContext}
|
|
freshIface := p.iface.Fresh(freshCtx)
|
|
freshProp := &UserPropagator{
|
|
ctx: freshCtx,
|
|
iface: freshIface,
|
|
}
|
|
freshProp.handle = cgo.NewHandle(freshProp)
|
|
return C.uintptr_t(freshProp.handle)
|
|
}
|
|
|
|
// goFixedCb is exported to C as a callback for Z3_fixed_eh.
|
|
//
|
|
//export goFixedCb
|
|
func goFixedCb(ctx C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast, value C.Z3_ast) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, s C.Z3_ast, t C.Z3_ast) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, t C.Z3_ast, idx C.uint, phase C.bool) {
|
|
p := cgo.Handle(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 C.uintptr_t, cb C.Z3_solver_callback, q C.Z3_ast, inst C.Z3_ast) C.bool {
|
|
p := cgo.Handle(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 C.uintptr_t, proofHint C.Z3_ast, n C.uint, deps *C.uint, literals C.Z3_ast_vector) {
|
|
oc := cgo.Handle(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)
|
|
}
|