Microsoft Z3 - How to use tactic combinators in the C# API - z3

I am currently going through following documents:
https://rise4fun.com/z3/tutorial/strategies
http://z3prover.github.io/api/html/namespace_microsoft_1_1_z3.html
In one of our academic research project, we are using Z3 for problem-solving. It is written using Z3 C# API. We want to use the concept of tactics, goals, and sub-goals. We want to give tactics using tactic combinators (aka tacticals). However, in the C# API, I could not find any way to use combinators like (then ..) (or-else ...).
Is there any API function I can use to create such combinators?
The way a single tactic can be used is as follows:
Tactic t = Context.MkTactic("simplify");
Context.MkSolver(Tactic)

The tactic combinator constructors are on the Context, e.g. AndThen.

Related

Parsing SMTLIB using the Z3 C API without losing `push`, `pop` and `check-sat` commands

I'm using the Z3_parse_smtlib2_string function from the Z3 C API (via Haskell's Z3 lib) to parse an SMTLIB file and apply some tactics to simplify its content, however I notice that any push, pop and check-sat commands appear to be swallowed by this function and do not appear in the resulting AST.
Is there anyway that I can parse this without losing these commands (and then apply the required tactics, once again without losing them)?
I don't think it's possible to do this with Z3_parse_smtlib2_string. As you can see in the documentation "It returns a formula comprising of the conjunction of assertions in the scope (up to push/pop) at the end of the string." See: https://z3prover.github.io/api/html/group__capi.html#ga7905ebec9289b9fe5debcad965f6267e
Note that the reason for this is not just mere "not-implemented" or "buggy." Look at the return type of the function you're using. It returns a Z3_ast_vector, and Z3_ast only captures "expressions" in the SMTLib language. But push/pop etc. are not considered expressions by Z3, but rather commands; i.e., they are internally represented differently. (Whether this was a conscious choice or historical is something I'm not sure about.)
I don't think there's a function to do what you're asking; i.e., can return both expressions and commands. You can ask at https://github.com/Z3Prover/z3/discussions to see if the developers can provide an alternative API, or if they already have something exposed to the users that achieves this.

HORN Clause Z3 Documentation

I am trying to encode some imperative program using HORN logic of Z3 (set-logic HORN) but getting some difficulties of defining clause (using SMT2). Could anyone tell me where can I find a good source of documentations for this feature of Z3?
Well, there's more to it when it comes to "encoding" a program in horn clauses.
First you need to check an appropriate proof rule: does the program has recursive functions, should you do function summarization? and so on.
There are a few papers on the subject, but I don't think there's any tutorial on VC gen.
You may also want to take a look to some benchmarks in Horn SMT format to draw inspiration: https://svn.sosy-lab.org/software/sv-benchmarks/trunk/clauses/
Feel free to ask if you have a specific question.

Z3: Is a custom theory extension appropriate for my application?

I have precise and validated descriptions of the behaviors of many X86 instructions in terms amenable to encoding in QF_ABV and solving directly with the standard solver (using no special solving strategies). I wrote an SMT-LIB script whose interface matches my ultimate goal perfectly:
X86State, a record sort describing x86 machine state (registers and flags as bitvectors, and memory as an array).
X86Instr, a record sort describing x86 instructions (enumerated mnemonics, operands as an ML-like discriminated union describing registers, memory expressions, etc.)
A function x86-translate taking an X86State and an X86Instr, and returning a new X86State. It decodes the X86Instr and produces a new X86State in terms of the symbolic effects of the given X86Instr on the input X86State.
It's great for prototyping: the user can write x86 easily and directly. After simplifying a formula built using the library, all functions and extraneous data types are eliminated, leaving a QF_ABV expression. I hoped that users could simply (set-logic QF_ABV) and #include my script (alas, neither the SMT-LIB standard nor Z3 support #include).
Unfortunately, by defining functions and types, the script requires theories such as uninterpreted functions, thus requiring a logic other than QF_ABV (or even QF_AUFBV due to the types). My experience with SMT solvers dictates that the lowest acceptable logic should be specified for best solving time. Also, it is unclear whether I can reuse my SMT-LIB script in a programmatic context (e.g. OCaml, Python, C) as I desire. Finally, the script is a bit verbose given the lack of higher-order functions, and my lack of access to par leading to code duplication.
Thus, despite having accomplished my technical goals, I think that SMT-LIB might be the wrong approach. Is there a more natural avenue for interacting with Z3 to implement my x86 instruction description / QF_ABV translation scheme? Is the SMT-LIB script re-usable at all in these avenues? For example, you can build "custom OCaml top-levels", i.e. interpreters with scripts "burned into them". Something like that could be nice. Or do I have to re-implement the functionality in another language, in a program that interacts with Z3 via a theory extension (C DLL)? What's the best option here?
Well, I don't think that people write .smt2 files by hand. These are usually generated automatically by some program.
I find the Z3 Python interface quite nice, so I guess you could give it a try. But you can always write a simple .smt2 dumper from any language.
BTW, do you plan releasing the specification you wrote for X86? I would be really interested!

function declaration in z3

In z3 is it possible to declare a function that takes another function as an argument? For instance, this
(declare-fun foo ( ((Int) Bool) ) Int)
doesn't quite seem to work. Thanks.
As Leonardo mentioned, SMT-Lib does not allow higher-order functions. This is not merely a syntactic restriction: Reasoning with higher-order functions is (generally) beyond what SMT solvers can deal with. (Although uninterpreted functions can be used in some special cases.)
If you do need to reason with higher-order functions, then interactive theorem provers are the main weapon of choice: Isabelle, HOL, Coq being some of the examples.
However, sometimes you want the higher-order functions not to reason about them, but rather merely to simplify programming tasks. SMT-Lib input language is not suitable for high-level programming that end-users typically need in practical situations. If that is your use case, then I'd recommend not using SMT-Lib directly, but rather working with a programming language that gives you access to Z3 (or other SMT solvers). There are several choices, depending on what host language is most suitable for your use case:
If you are a Python user, Z3Py that just shipped with Z3 4.0 is the way to go,
If you are a Scala user, then look into Scala^Z3.
If Haskell is your preferred language, then take a look at SBV.
Each binding has its own feature set, Z3Py probably being the most versatile since it's directly supported by the Z3 folks. (It also provides access to Z3 internals that remain inaccessible for the other choices, at least for the time being.)
No, this is not possible. However, you can define a function that takes an array as an argument.
(declare-fun foo ((Array Int Bool)) Int)
You can use this trick to simulate high-order functions like the one in your question.
Here is an example: http://rise4fun.com/Z3/qsED
The Z3 guide contains more information about Z3 and SMT.

how do i invoke Z3 Programmatically

Hi I am new to Z3 SMT solver. I know you can invoke Z3 programmatically by using relevant APIs. But I want to do the following things with Z3 SMT solver:
how can I feed Z3 with one input file programmatically?
how can I incrementally get the solution(s)?
For example:
while ((check-sat) returns sat)
get the assignments for all boolean vairables
Finally, how can I ask Z3 to save the results into one output file after solving the formula?
Any ideas or documents I can look at?
Thanks million!!!
The Z3 distribution contains several (programmatic API) examples.
examples/c/test_capi.c: many small examples using the C interface.
examples/dotnet/test_managed.cs: similar examples in C#
examples/maxsat/maxsat.c: MaxSAT procedures (in C) on top of the Z3 API.
examples/ocaml/test_mlapi.ml: examples in ML
examples/theory/test_user_theory.c: example showing how to implement an external theory (plugin).

Resources