Back in the old days (ie. last year), we used to be able to use theory plugins as a hack to implement custom simplifiers. The Z3 doc even contained an example of \"procedura
The theory plugins are currently marked as deprecated in Z3 4.x. So, although they can still be used to implement custom simplifier, the user would be forced to use deprecated APIs.
In Z3 4.x, custom simplifiers should be implemented as Tactics. The new build system makes it fairly easy to extend the set of available tactics. I will try to write a tutorial on how to write tactics inside the Z3 code base. Of course, in this approach, we have to write C++ code. The main advantage is that the tactic will be available in all front-ends (C, C++, .Net, Java, Python, OCaml, SMT2). Moreover, external developers can contribute their tactics to the Z3 codebase and they will be available for all Z3 users.
We also plan to support an API for creating a simplifier tactic based on callbacks provided by the user. This API would allow users to write "custom simplifiers" in their favorite programming language. This new API is conceptually simple, but there is a lot of "hacking" needed to make it available in every front-end (C++, .Net, Java, Python, OCaml) . It would be great if some external developer is interested in implementing and maintaining this feature. I'm sure it would benefit many users.