What does HackerNews think of z3?

The Z3 Theorem Prover

Language: C++

I believe, Nim also has this functionality, although, it uses the [0]Z3Prover tool with a nim frontend [1]DrNim for proving.

[0]https://github.com/Z3Prover/z3

[1]https://nim-lang.github.io/Nim/drnim.html

> And you propose me instead to go and reverse engineer library Js code which I am not that proficient in, and rewrite all code in Java instead?..

Yes, rather than demand others cater to your whims, frankly.

Do you realise how hypocritical it sounds to complain that you are not proficient in Javascript, when others might not be proficient in ?

Go use Z3 if you need a prover in C++ (or Java), its far more robust (provided its the type you're after) than someones 700 LoC JavaScript implementation.

https://github.com/Z3Prover/z3

Microsoft developed the excellent Code Contracts[1] project. From the user's perpective, tt was a simple class called Contracts with a few methods such as Require(), Ensure() and Invariant()

Underneath the hood it used the Z3 Solver[2], which is both intuitive, flexible and fast. It validated the contracts while coding and highlighted in the Visual Studio IDE when a contract was broken.

You could write something like: Contracts.Requires(x > 5 && y > x);

Which would get translated to a compile time check as well. Unfortunately, Code Contracts has been dead for years now, and it was even removed entirely from .NET[3] due to being hard to maintain, and the verifier stopped working in newer versions of VS.

Luckily, C# developers now have a small taste of contracts due to nullability analysis[4], but even more exciting is that contracts is making its way into C# as a first-level standard[5].

[1] https://www.microsoft.com/en-us/research/project/code-contra...

[2] https://github.com/Z3Prover/z3

[3] https://github.com/dotnet/runtime/issues/20006

[4] https://docs.microsoft.com/en-us/dotnet/csharp/nullable-refe...

[5] https://github.com/dotnet/csharplang/issues/105

Here's a simple example finding a hidden seed. It takes around 1, 2, or 3 values in a row and finds the seed. You can adapt this to all sorts of breaking problems, but for some you'll have to learn more about SATs and be careful how you code things. Note the simple PRNG I chose doesn't reveal all the state, yet over time you can deduce all of it.

  // Code to demonstrate finding the hidden seed of a PRNG with Z3
  // Chris Lomont Oct 2021
  // Answering this comment on Hacker News https://news.ycombinator.com/item?id=28886698

  // Start by getting Z3, a theorem prover from Microsoft, via nuget. See https://github.com/Z3Prover/z3
  using Microsoft.Z3;
  using System;

  // get a solution
  ulong Solution(Context ctx, BoolExpr f, BitVecExpr seed)
  {
    Solver s = ctx.MkSolver();
    s.Assert(f); // assert constraint into solver
    if (s.Check() == Status.SATISFIABLE)
    {
        var m = s.Model;
        Expr e = m.Evaluate(seed);
        return ulong.Parse(e.ToString());
    }
    else
        throw new Exception("Fatal error");

  }

  // simple PRNG, used in many old C libs
  UInt32 next = 0x1234;
  UInt32 rand()
  {
    next = next \* 214013 + 2531011;
    return (next / 65536) % 32768;
  }

  void Test()
  {
    var R = new Random();
    next = (uint)R.Next();
    var start = next;
    Console.WriteLine($"Starting seed {next:X8}");

    using (var ctx = new Context())
    {
        // 32 bit vector type
        Sort bv_type = ctx.MkBitVecSort(32);

        // unknown seed - we will solve for this
        BitVecExpr seed = ctx.MkBVConst("seed", 32);

        // constants used in the PRNG
        BitVecExpr c214 = (BitVecNum)ctx.MkNumeral("214013", bv_type);
        BitVecExpr c253 = (BitVecNum)ctx.MkNumeral("2531011", bv_type);
        BitVecExpr c65536 = (BitVecNum)ctx.MkNumeral("65536", bv_type);
        BitVecExpr c32768 = (BitVecNum)ctx.MkNumeral("32768", bv_type);

        // track the boolean to satisfy
        BoolExpr be = ctx.MkTrue();

        var next = seed; // start here
        int pass = 0;
        while(true)
        {
            ++pass;
            if (pass > 10) break;
            // the sampled random
            var r = rand();
            BitVecExpr rndBV = (BitVecNum)ctx.MkNumeral(r, bv_type);

            // make this code using Z3 variables
            //next = next * 214013 + 2531011;
            //return (next / 65536) % 32768;
            next = ctx.MkBVAdd(ctx.MkBVMul(next, c214), c253);
            var ret = ctx.MkBVURem(ctx.MkBVUDiv(next, c65536), c32768);

            // add a constraint boolean for this "Z3 ret = returned value"
            be = ctx.MkAnd(be, ctx.MkEq(ret, rndBV));

            // get solution
            var val = Solution(ctx, be, seed);
            // todo - can check unique by adding "seed != soln" to the boolean and checking
            Console.WriteLine($"{pass} : 0x{val:X8}");
            if (val == start)
                break; // done - can also break when shown unique
        }
    }
  }
  Test();
1) For the "how to get started with formal verification outside academia", I'll first get the case of "in/for production" out of the way:

a) "use Z3[0] with some binary/source-language-of-choice/LLVM -lifting to handle relatively simple situations that need to": i) guarantee some assert (often, but not always index-out-of-bounds checks, like non-trivial Rust slice indexing) statements are unreachable ii) some bit hacks compute the same thing as the non-hacked implementation

b) "use TLA+[1] to verify concurrent stuff with race conditions": i) in lock-free data structures that don't come with a proof that the algorithms do the right thing (in those cases, just verify three implementation truly matches the proven algorithm) ii) in (network, or sufficiently network-like) protocols that aren't 100% exactly transcribed ports of existing proven algorithms or so simple a finite state machine can (and will) be used

2) For doing it more for fun than short-term gains: a) For getting a handle on pure functional program design, I recommend going through the relevant track of HtdP[2] (Prologue until just before "Arithmetic and Arithmetic" -> I -> II -> III -> Intermezzo 2: Quote, Unquote -> V {-> [if you want to write remotely-performant pure functional code, follow up with:] VI}) b) For learning how to exploit a proof assistant for fun and applied computer science, I'll refer to the guidance provided by Isabelle/HOL. Please use the IRC(/Matrix ?)[3] if you are confused on how exactly to best approach Isabelle/HOL in your case.

[0]: https://github.com/Z3Prover/z3 [1]: https://lamport.azurewebsites.net/tla/tla.html [2]: https://htdp.org/2021-5-4/Book/index.html [3]: [edit: apparently it is neither IRC nor Matrix, but rather Zulip:] https://isabelle.zulipchat.com/

Don't get me wrong, Prolog is cool... but in 2021, why use a completely different language and not a SAT solver DSL (domain specific language) bound into your favorite imperative language, e.g. Python. Then you get all your favorite libraries for I/O, data transformation, UI/UX, etc.

Examples include Google OR-tools, Microsoft Z3, etc.

https://developers.google.com/optimization

https://github.com/Z3Prover/z3

You might like a Satisfiability Modulo Theories (SMT) solver such as Z3.

https://github.com/Z3Prover/z3

It has bindings for other languages and is able to make some rather sophisticated arithmetical and logical deductions in an often pretty efficient way. I've used it successfully for parts of puzzle competitions and CTFs (and I'm really only beginning to scratch the surface of what it can do).

You can read more about the options in that area at

https://en.wikipedia.org/wiki/Satisfiability_modulo_theories

which also links to the related tools in

https://en.wikipedia.org/wiki/Answer_set_programming

https://en.wikipedia.org/wiki/Constraint_programming

These systems can feel pretty magical and are getting more powerful all the time. (Of course there are cases where there is a better algorithm that you could find, perhaps a much more efficient one, and using these solvers will be asymptotically or worst-case slower than it had to be given more human insight.)

Some of these could be overkill for your application, and Z3 doesn't have a Javascript binding, so I guess it's not as helpful for web forms.

Alternatively using z3 [0]:

  (declare-const a1 Bool)
  (declare-const a2 Bool)
  (declare-const a3 Bool)
  (declare-const a4 Bool)
  (declare-const a5 Bool)
  (declare-const a6 Bool)

  (assert (= a1 (and a2 (and a3 (and a4 (and a5 a6))))))
  (assert (= a2 (not (or a3 (or a4 (or a5 a6))))))
  (assert (= a3 (and a1 a2)))
  (assert (= a4 (or a1 (or a2 a3))))
  (assert (= a5 (not (or a1 (or a2 (or a3 a4))))))
  (assert (= a6 (not (or a1 (or a2 (or a3 (or a4 a5)))))))
  (assert (or a1 (or a2 (or a3 (or a4 (or a5 a6))))))

  (check-sat)
  (get-model)
  (exit)
The model is satisfiable where only a5 is true, anyone can run it themselves and play with it [1].

Additionally forcing a5 to be false by adding the following to the list of assertions:

  (assert (not a5))
And the model becomes unsatisfiable.

Edit: Finally, to make sure there's not some possible solution where a5 is true as well as another assertion you could alternatively add this assertion:

  (assert (and a5 (or a1 (or a2 (or a3 (or a4 (or a6)))))))
And the model also becomes unsatisfiable. So 5 only seems to be the correct answer.

[0] https://github.com/Z3Prover/z3

[1] https://rise4fun.com/Z3/1DMW

I have used the Z3 solver(https://github.com/Z3Prover/z3) to optimize a job scheduling problem. Roughly, I have ~20k jobs, defined by N tasks (~1-50). A job is complete only if M tasks (typically 2-3) per job are done. Every task takes some variable amount of time to complete and can only be run during specific windows. Given the equipment can only perform P tasks in parallel, what is the optimal configuration of tasks (~500k) that will allow us to complete the most jobs?

The search space for this problem is enormous, but Z3 will produce an impressive result within a few minutes.

Synthetic Minds (YC S18) | SF + Seattle | $120k+ | First 5 engineers: commensurate equity | ONSITE, Full Time

The ideal candidate has a master/phd in systems, compilers, programming languages, or distributed systems. Synthetic Minds will allow you to leverage your technical chops.

Synthetic Minds is building program synthesizers, i.e., automation that can write code. We have a system in production that reads/writes smart contracts in Ethereum's Solidity language, and we use it to ensure our customer's code is secure and correct. Eventually, we plan on going far beyond smart contracts. Think of what we are building as a compiler that takes code and translates it to theorem proving, so that we can build automation that can understand code almost as close to a human. If it can understand code, with sufficient compute it can “synthesize” it.

In Oct 2018, we raised $5.6M from Y Combinator, Khosla Ventures and Pantera Capital [6]. We have a backlog of customers waiting to be on-boarded. The team is experienced. This is my 2nd YC startup and I have a PhD in Program Synthesis. The 1st employee was the first hire at Parse (YC S11) and spent 10 yrs at Google. We aim to be a 10-15 person all-engineering team in 2019.

Roles/Openings (see [1]):

# Software engineer: Systems/infrastructure — You’ll be working on distributing heavy CPU processes on AWS. Making sure processes run reliably over many days. Ensure robustness of the infrastructure across node/process/memory/algorithm failures.

# Software engineer: Compilers/verification/synthesis — You’ll be working on developing new algorithms that analyze and generate code [2]. You’ll identify when an engineering solution is needed (i.e., throw across a cluster of machines), or when an algorithmic improvement is required. You might even play with the Z3 theorem prover [3]. And if you’re really into it, you can improve Z3.

# Software engineer: Smart contracts — You’ll be working on the “front-end of the compiler”, which reads in smart contracts languages (e.g., Solidity) and makes it accessible to the backend (the part that does semantic analysis). Desire to work at the compiler level of smart contracts is required, e.g., see [4] — experience in writing smart contracts is easily acquired as a side effect.

Contact: [email protected] - Saurabh, Founder

[1] Synthetic Minds Jobs: https://synthetic-minds.com/pages/jobs.html

[2] Program synthesis: https://medium.com/@vidiborskiy/software-writes-software-pro...

[3] Z3 Theorem Prover: https://github.com/Z3Prover/z3

[4] Solidity AST: https://github.com/ethereum/solidity/blob/develop/libsolidit...

[5] Solidity smart contracts: https://solidity.readthedocs.io/en/v0.4.21/solidity-by-examp...

[6] Forbes funding article: https://www.forbes.com/sites/darrynpollock/2018/10/22/invest...

Synthetic Minds (YC S18) | SF + Seattle | $120k+ | First 5 engineers: commensurate equity | ONSITE, Full Time

The ideal candidate has a master/phd in systems, compilers, programming languages, or distributed systems; but never gets to use it in their day job. Synthetic Minds will allow you to leverage your technical chops.

Synthetic Minds is building program synthesizers, i.e., automation that can write code. We have a system in production that reads/writes smart contracts in Ethereum's Solidity language, and we use it to ensure our customer's code is secure and correct. Eventually, we plan on going far beyond smart contracts. Think of what we are building as a compiler that takes code and translates it to theorem proving, so that we can build automation that can understand code almost as close to a human. If it can understand code, with sufficient compute it can even “synthesize” it.

In Oct 2018, we raised a $5.6M seed round from Y Combinator, Khosla Ventures and Pantera Capital [6]. We have paying customers and a backlog waiting to be on-boarded. The team is heavily experienced. This is the founder’s second startup and they have a PhD in the area. The 1st employee was the first hire at Parse (YC S11) and has 10 yrs at Google. We aim to be a 10-15 person all-engineering team in 2019.

Roles/Openings (see [1]): # Software engineer: Systems/infrastructure — You’ll be working on distributing heavy CPU processes on AWS. Making sure processes run reliably over many days. Ensure robustness of the infrastructure across node/process/memory/algorithm failures.

# Software engineer: Compilers/verification/synthesis — You’ll be working on developing new algorithms that analyze and generate code [2]. You’ll identify when an engineering solution is needed (i.e., throw across a cluster of machines), or when an algorithmic improvement is required. You might even play with the Z3 theorem prover [3]. And if you’re really into it, you can improve Z3.

# Software engineer: Smart contracts — You’ll be working on the “front-end of the compiler”, which reads in smart contracts languages (e.g., Solidity) and makes it accessible to the backend (the part that does semantic analysis). Desire to work at the compiler level of smart contracts is required, e.g., see [4] — experience in writing smart contracts is easily acquired as a side effect.

Contact: [email protected] - Saurabh, Founder

[1] Synthetic Minds Jobs: https://synthetic-minds.com/pages/jobs.html

[2] Program synthesis: https://medium.com/@vidiborskiy/software-writes-software-pro...

[3] Z3 Theorem Prover: https://github.com/Z3Prover/z3

[4] Solidity AST: https://github.com/ethereum/solidity/blob/develop/libsolidit...

[5] Solidity smart contracts: https://solidity.readthedocs.io/en/v0.4.21/solidity-by-examp...

[6] Forbes funding article: https://www.forbes.com/sites/darrynpollock/2018/10/22/invest...

I fundamentally disagree with the author's thesis. I don't think dependent types are the future of development, but instead I'd bet on refined types (or contracts - see my experiment [0], Liquid Haskell [1] by Ranjit Jhala, and languages Dafny [2] and F* [3] developed by Microsoft on top of Z3 SMT theorem prover [4]), where constraints are explicit yet simple, and proven automatically by an automated theorem prover.

  lookup : (a : array) -> (n : int if 0 <= n < length(a)) -> whatever
[0] https://github.com/tomprimozic/type-systems/tree/master/refi...

[1] https://ucsd-progsys.github.io/liquidhaskell-blog/

[2] https://rise4fun.com/Dafny/tutorial/guide

[3] https://fstar-lang.org/tutorial - see e.g. section 3 "First proofs about functions on integers"

[4] https://github.com/Z3Prover/z3

This article represents an ongoing trend that we've seen over the last 3 years as a resurgence in optimization techniques for directly modeling tasks which historically were considered "not amenable to optimization techniques." We saw this last year as well with the landmark, "The Case for Learned Index Structures" [0] and in prior years with Coda Hale's "usl4j And You" [1], which can easily be woven in realtime into modern container control planes.

We've also seen research in using search and strategy based optimization techniques [2] (such as Microsoft's Z3 SMT prover[3]) to validate security models. Some folks are even using Clojure's core.logic at request time to validate requests against JWTs for query construction!

[0]: https://arxiv.org/abs/1712.01208

[1]: https://codahale.com/usl4j-and-you/

[2]: http://www0.cs.ucl.ac.uk/staff/b.cook/FMCAD18.pdf (and by the way, this made it to prod last year, so an SMT solver is validating all your S3 security policies for public access!)

[3]: https://github.com/Z3Prover/z3

I wonder if it uses Z3 under the hood for solving constraints. Very nice of MSFT to MIT license Z3. It's super useful for problems that result in circular dependencies when modeled in Excel, and require iterative solvers (e.g., goal seek). I use the python bindings, but unfortunately it's not as simple as `pip install` and requires a lengthy build/compilation. Well worth the effort, though.

https://github.com/Z3Prover/z3

https://github.com/Z3Prover/z3/issues/288

what about this?

https://github.com/Z3Prover/z3

Is it comparable with prolog or just a subset of prolog?

Not the parent, but indeed like you said, writing unit tests doesn't show absence of bugs, but can only show their presence.

To be able to state that a piece of software is bug-free and formally correct, we first need a notion of correctness: that the algorithm follows a [formal] specification.

The first step would be to formally specify what the software/algorithm should do. Then, the next step would be to use formal methods and mathematical tools (e.g. set theory and logic) to prove that your algorithm does exactly as the specification says.

TLA+ is a formal method that can be used for writing specifications and model-checking them. While a big step forward from testing, model-checking still doesn't "prove" anything.

For proving, you can use theorem provers like the Z3 [0] SMT solver (or a formal framework that uses theorem provers) to do proof checking.

The Event-B [1] method is one such formal method that uses SMT solvers and allows you to model systems starting with a very abstract and high-level model, state invariants about your system, and prove that those invariants hold as you refine your models and make them more concrete.

Feel free to shoot me an email if you like to talk more about formal methods :)

[0]: https://github.com/Z3Prover/z3

[1]: http://www.event-b.org/

Other people are already flooding you with counterexamples, but I'll add to the pileup:

Z3 (https://github.com/Z3Prover/z3) is the Satisfiability Modulo Theories (SMT) solver to use. It is such a quality piece of software and it's amazingly easy to find help on StackOverflow from the main developers. Z3 really is the default choice for an SMT solver these days (i.e. you only reach for other solvers when you really have to).

Roslyn (https://github.com/dotnet/roslyn) is the C# (and VB) compiler as a library. Useful for doing code analysis and code generation for a modern imperative language. Roslyn is a whole lot easier to get started with than integrating Clang/LLVM into a project, so it really lowers the barrier of entry for lightweight program analysis projects.