WIP: Add bindings to the user propagator#344
WIP: Add bindings to the user propagator#344puyral wants to merge 19 commits intoprove-rs:masterfrom
Conversation
ignores Macos' DS_Store and some `nix` related files
Not tested yet, so there are probably many typos around still
many things are not ready yet, notably I'm not sure of the lifetimes of things. I skipped fresh entirely
Some things can likely still be improved, but this is a good initial implementation
This way there is no need for handles, it also makes it easier to add the `on_clause` API
|
So apparently Ubuntu ships with a version of |
The previous version half assumed there was no multithreading (no requierement for Sync), half assumed there was (it was using `ref` everywhere). This commit fully goes for the no multithreading version. - &mut where it makes sense - the UPSolver now owns the UserPropagators, to prevent potential aliasings
|
So I discovered that we can get null pointer back from z3 with my implementation of TL;DR: current lifetimes don't match Currently, it actually returns the null pointer that z3 gives back. This was done on purpose because implementing this function causes me huge lifetimes problems. To give an idea of the problem. The C++ implementation for
In practice, z3 gives a new These problems tend to cascade effects to the rest of the user propagator API. I'm switching this into a draft since I don't have an immediate solution. If you are using |
|
It may be worth revisiting this in light of #401, #404, and #417. Now that contexts are refcounted and implicit, there shouldn't be an issue dealing with arcane lifetimes. The trick would be designing the API to ensure correctness and memory safety in the face of callbacks that use Contexts we do not control. I haven't done a detailed read of the contribution you have here, but going from your description of the difficulty, there's a general approach that I think could work:
This would ensure that no |
|
Amazing! It sounds like this does indeed solve most of my issues! I'll have a try at this Weekend |
- renaming ffi types for the user propagator - some ffi bindings got duplicated during the merge somehow...
It still need some testing as the current test segfaults. But it segault in a completly incomprehesible way...
|
I have adapted the work to the new RC-based All looks good, but my example segfaults somewhere in |
| new_context: Z3_context, | ||
| ) -> *mut ::std::ffi::c_void { | ||
| if let Some(upw) = unsafe { wapper_from_user_context(uctx) } { | ||
| let ctx = unsafe { Context::from_raw(new_context) }; // hopefully it doesn't die... |
There was a problem hiding this comment.
I suspect this is the cause of the segfaults you're getting. impl Drop for Context frees the backing Z3_Context. But this Z3_Context was given to us, so I suspect Z3 might be freeing it as well, causing a double-free?
This is what I was referring to in my earlier comment: we probably want to structure this so that there's a "borrowed" variant of context that does not drop Z3_Context and then the challenge becomes ensuring that we properly quarantine instances of that type to places where we are sure Z3 hasn't dropped the context.
| s.assert( | ||
| f.apply(&[&f.apply(&[&f.apply(&[&f.apply(&[&x])])])]) | ||
| .eq(f.apply(&[&x])) | ||
| .not(), | ||
| ); |
There was a problem hiding this comment.
So the current bug is more messed up than just a double free. If I bundle with a z3 with debug enabled I get an assertion error already here which gets triggered on this line.
It doesn't seem to be a pointer problem, as z3 TRACE macro can print the term. Also requesting for the term's sort return Bool...
Commenting the register_user_propagator line out "solves" the problem, which is even more puzzling to me...
I will keep debugging this, but it might take more time than I would like..
This adds bindings and an API for the user propagator and the
on_clausecallback.I would consider this still experimental, as I'm not fully sure of what
z3might do with my objects (e.g., weird lifetimes and thread safety).This also closes #343