In "normal" programming languages such as C++ we regularly use design by contract.
The absolute bare minimum for this is to define:
- pre-conditions (expects)
- post-conditions (ensures) &
- invariants
These are typically checked by unit tests and at run time. They do not count as proofs except perhaps for the weakest proof by construction case.
What else, if anything, is needed to go from "design by contract" to using a more advanced prover?
The first improvement we can make is to try and get the compiler to check if our assertions would hold. Now the compiler is helping with formal verification. It requires a least a minimal prover of some kind.
Design by contract is typically a very simple framework whereas something like Coq has a whole host of extra features to help its users write mathematical proofs.
What are some of these features and what do they bring to the table?
These might be basic to a user of a proof assistant but may seem novel to someone from an engineering background used to DbC but with less practical exposure to formal verification or mathematic proofs.
Is there some higher level analogue to "turing completeness" suggesting a minimal number of features a proof assistent needs? or put another way what are basic tools a mathematician would want to see (maybe just for a given branch of maths).
I asked a related question on programming langauge design https://languagedesign.stackexchange.com/questions/1436/what-options-are-there-for-adding-formal-verification-to-a-general-purpose-progr and the most popular answer so far is refinement types
Examples
The paper "can c++ be made as safe as spark?" from eschertech suggests several additional things (listed in the paper) including:
- exists
- forall
- old (to refer to a value of an expression when a function was entered)
In addition to improving our "language for proofs" there may also be aspects to how they are used.
For instance I hear "tactics" mentioned in the context of proof assistants.
Sticking with the c++ theme. The standard recently added:
Plans to add
are in the works. And
- 'full' concepts including
concept maps
andaxioms
were put on hold.
Concepts and contracts elevate design by contract from something typically added via library functions to part of the language that would in theory allow the compiler to use a solver like Z3.
Example contracts syntax:
int mul(int x, int y)
[[expects: x > 0]] // implicit default
[[expects default: y > 0]]
[[ensures audit res: res > 0]]{
return x * y;
}
For concepts see for example https://en.cppreference.com/w/cpp/language/constraints
Would this be sufficient to qualify as a prover or proof assistant?
Possibly this should be a separate question but:
Does Z3 qualify as a proof assistant?
Related: