The difficulty and verbosity of formal proofs is huge even with the very concise mathematical notation. And learning the notation itself is a very small stumbling block compared to learning the actual theorems and logic that you need to use.
So while I am not a fan of mathematical notation for general programming (which is often quite un-mathematical in fact) formal proofs are a place where this notation absolutely shines. I can't even imagine how much uglier the proof above would become if you had to replace `∀ (n : ℕ)` with something like `for any natural number n`.
Is perfectly reasonable.
If conciseness was that important theorem provers would have syntax like APL.
I can still do theorem proving in Idris excluding the mathematical notation and still learn concepts such as totality, covering, equality etc
Second, it makes it harder to identify patterns. Writing things out in a formalism lets you identify syntactic patterns and employ techniques like factoring, cancelling, seeing symmetries and other purely syntactic properties. When you write things out in natural language you lose the ability to see these things clearly. Being able to see purely formal syntactic properties helps reinforce your confidence in a proof or can help you identify potential flaws in it. It's like with programming styles and conventions, one thing I tell developers is an important reason for choosing one style over another is if it makes wrong code look wrong visually.
Third, and this is just a personal matter... it results in a type of culture of writing that I find is often pretentious and full of unnecessary baggage. When I read an academic paper I cringe at how bad most writing is and try my best to skip to the formal part of the paper.
Who is this we? The people who understand mashed with the ignorant who put in no work?
> to democratise
So that those in the know can be further diluted with dabblers who contribute nothing and complain about their ignorance?
also why tools like chatGPT have gained so much popularity
Then someone had to come along and invent the printing press.
Greek (or koine, for that matter) was pretty much street vernacular in the Roman/Byzantine empire during that period you're likely talking about.
lemma nat.add_comm : ∀ n m : ℕ, n + m = m + n
| n 0 := eq.symm (nat.zero_add n)
| n (m+1) :=
suffices succ (n + m) = succ (m + n), from
eq.symm (succ_add m n) ▸ this,
congr_arg succ (add_comm n m)
Also, this example proof is explicitly about math (the commutativity of addition on natural numbers), so it's appropriate and not surprising that it uses mathematical notation.Here is a closer approximation to how someone would actually write the proof in Lean:
lemma add_comm (a b : ℕ) : a + b = b + a :=
begin
induction a with a IH,
rw (add_zero b),
rw (zero_add b),
trivial,
rw (add_succ b a),
rw (succ_add a b),
rw IH,
trivial
end /*@
// There is a partial match of the needle at location loc in the
// haystack, of length len.
predicate partial_match_at(char *needle, char *haystack, int loc, int len) =
\forall int i; 0 <= i < len ==> needle[i] == haystack[loc + i];
*/
/*@
// There is a complete match of the needle at location loc in the
// haystack.
predicate match_at(char *needle, int n, char *haystack, int h, int loc) =
\valid(needle + (0 .. n-1)) && 0 <= n < INT_MAX &&
\valid(haystack + (0 .. h-1)) && 0 <= h < INT_MAX &&
n <= h && loc <= h - n &&
partial_match_at(needle, haystack, loc, n);
*/
/*@
requires \valid(needle + (0 .. n-1)) && 0 <= n < INT_MAX;
requires \valid(haystack + (0 .. h-1)) && 0 <= h < INT_MAX;
requires n <= h;
assigns \nothing;
ensures -1 <= \result <= (h-n);
behavior success:
ensures \result >= 0 ==> match_at(needle, n, haystack, h, \result);
behavior failure:
ensures \result == -1 ==>
\forall int i; 0 <= i < h ==>
!match_at(needle, n, haystack, h, i);
*/
int
brute_force (char *needle, int n, char *haystack, int h)
{
int i, j;
/*@
loop assigns i, j;
loop invariant 0 <= i <= (h-n) + 1;
loop invariant \forall int k; 0 <= k < i ==>
!match_at(needle, n, haystack, h, k);
*/
for (i = 0; i <= h - n; ++i) {
/*@
loop assigns j;
loop invariant 0 <= j <= n;
loop invariant partial_match_at(needle, haystack, i, j);
*/
for (j = 0; j < n && needle[j] == haystack[j + i]; ++j);
if (j >= n) {
return i;
}
}
return -1;
}
Lean to me is not only obscure but unapproachable by someone from a non-mathematical background.
Take this snippet for instance
If we want to democratise formal methods and theorem proving, we should lean towards natural language expressions of proof and not mathematical expressions and greek characters.This is the path that languages such as Idris https://www.idris-lang.org/ have taken