lesson_3

Lesson 3: Mathematics Verification

From mathcomp Require Import all_ssreflect all_algebra.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Definition sorry {T} : T. Admitted.

Advanced Topics

Some possible topics for Friday are:
  • deep specification
  • user interfaces, notations, interactive books
  • collaborative development / ecosystem / impact
  • proof automation / Machine Learning
  • higher mathematical structures / HoTT (Homotophy Type Theory)
  • proof by refinement
  • advanced program logics
  • models, axioms, proof relevance

The Mathematical Components Library

  • https://math-comp.github.io/
  • Developed first for the 4 color theorem, then for the Feit-Thompsom proof.
  • High-quality, large set of advanced techniques and theorems
  • Large development effort, co-development with Coq, refactoring very costly
  • Powerful but lacking documentation thus it feels hard to use
  • Indeed, it is not a straightforward step for a mathematician.

Lean's mathlib

  • https://leanprover-community.github.io/mathlib_docs/
  • Lean is a recent re-implementation of Coq's type theory by Leo de Moura and collaborators
  • Type theories almost compatible, front-ends follow the same spirit, but significant differences.
  • Built on many ideas from math-comp
  • Made very popular for mathematicians thanks to great communication and community.
  • Math marketing effort mainly led by Kevin Buzzard
  • New version (Lean 4) vs mathlib (Lean 3)
  • It is also not a straightforward step for a mathematician.
  • https://xenaproject.wordpress.com/2021/06/05/half-a-year-of-the-liquid-tensor-experiment-amazing-developments/

Challenges of doing mathematics in type theory

  • general usability: search, tactics, documentation, notations
  • organization of mathematical structures: base type theory is not well-suited for encoding complex mathematical

Plan + an example:

In today's brief introduction we will cover some examples and structures from the mathematical components library, in particular, we will present the basic algebraic structures (commutative groups, rings), matrices, and polynomials. The library includes many more structures and results, including a new library on analysis.
We start by explaining an example on numbers:
Lemma prime_above m : {p | m < p & prime p}.
have /pdivP[p pr_p p_dv_m1]: 1 < m`! + 1 by rewrite addn1 ltnS fact_gt0.
p ⇒ //; rewrite ltnNge; apply: contraL p_dv_m1p_le_m.
by rewrite dvdn_addr ?dvdn_fact ?prime_gt0 // gtnNdvd ?prime_gt1.
Qed.

Base useful libraries

In this lesson, we will use a large number of "basic" data structures and theories which are by no means trivial, and play an essential role in the developments. In particular:
  • eqType, choiceType: types with choice and decidable equality
  • nat: mathcomp's Peano numbers + their large theory, including modular arithmetic, prime numbers, etc...
  • seq A: mathcomp's lists (or sequences) + their large theory
  • finType: finite types
  • orderType: types with different orders
  • subType P A: subTypes of A convertibles to A. For example the set of all even natural numbers: { x : nat | even x }.
Using subtypes we can define:
  • ordinals 'I_n, in particular 'I_n := { x : nat | x < n }
  • tuples n-tuple A, lists of size n, or tuples
  • {ffun T U} finitely supported functions (a tuple of cardinality #|T| .
Of particular interest are the finitely supported functions. Similarly to other "classical" principles, Coq's logic doesn't prove the principle of functional extensionality for all functions:
Axiom funext : T U (f g : TU), ( x, f x = g x) → f = g.
However, a lot of reasoning in mathematics depends on this being true. mathcomp is pretty careful as to use datatypes that validate this principle, for example finitely supported functions are implemented in a way such that we can prove extensionality
Section ExtIntro.
Variable (T : finType) (U : Type).

Lemma ffun_ext_show (f g : {ffun TU}) : f = g.
Proof. apply/ffunP. movex. Abort.

Finite sets do validate this principle too
Lemma fset_ext_show (A B : {set T}) : A = B.
Proof. apply/setP. movex. Abort.

End ExtIntro.

Mathematical Structures

While type theory does provide us a convenient way to write low-level proofs and check them, when doing mathematics formally we need to organize and validate a large ontology of mathematical object with complex relations among them. For example, a ring may be a group, and it may be so in more than one. Similarly subgroups are groups, and some particular instances of objects, like matrices, may form structures only in some cases.
Good support for inference and synthesis of these relations is essential, as you will find that stating a theorem often involves the same object but viewed from several different points of view.
Thus, in order to keep definitions and statement manageable, the meta information about objects must be used by Coq automatically.
A lot of research has been put into building good support for such structures.
Math-comp provides great support by using a Coq inference feature called "Canonical Structures", and automatic (safe) type castings. Both features live at the level of elaboration and not in the kernel.

Canonical Structures

As we have seen, it is customary to pack the definition of an structure and its properties into a record. For example, types with decidable equality are packed as `eqType`, which thanks to a coercion can be used a `Type`.
However, it is very common that we will have the following situation:
( {T : eqType}, (x y : T), ...) 3 4
That is to say, x y have type ?T.(type) (due to the coercion), as ?T is implicit and just a meta-variable at this point.
Thus, we got a unification problem ?T.(type) = nat, which is hard to solve as it would mean we need to synthesize an implementation de eqType for nat on on the fly.
Instead, we can tell Coq to consider a hint when this kind of unification problem appears. What we can say to Coq is that indeed, every unification problem that that has the shape of ?T : eqType |- ?T.(type) = nat , should be solved by using the existing nat_eqP instance.
"Canonical" structures provides us the way to indicate this.

Coercions

Coercions allow the type inference to relate to different types by inserting (or synthesising) a type casting from a type to another. A good example is just the above equation. We have T : eqType and we need in (x : T) that T is a Type however it is an eqType. But Coq knows how to repair this, and will insert the .(type) projection so we now have (x : T.(type), with this correctly typing.

Status in Coq

As of today, defining our own structures requires too much boiler-plate. Lean has better support for this (with trade-offs) , whereas Coq has an experimental plugin called hierarchy builder that greatly helps.

Algebra

Equipped with this, we proceed to present some of the core algebraic structures of math comp: Abelian groups, rings, and commutative rings.
Open Scope ring_scope.
Import GRing.Theory.

Section AEx.

Variable (A : zmodType).
zmodType is the type of Abelian groups over choiceTypes:

Record mixin_of (V : Type) : Type := Mixin {
  zero : V;
  opp : VV;
  add : VVV;
  _ : associative add;
  _ : commutative add;
  _ : left_id zero add;
  _ : left_inverse zero opp add
}.

- The operators exported are [0] [x + y] [- x] , a few derived ones are defined too, like [x *+ n].
- Suffix for theory is [r], so [addr0], [addrA], etc...

Lemma demo_A (x y : A) : x + y + 0 = y + 0 + x.
Proof. Admitted.

Variable (R : ringType).
ringType: (non-commutative) rings over a commutative abelian group

Lemma demo_R (x y : R) : x + y + 0 = y + 0 + x.
Proof. Admitted.

Variable (C : comRingType).
Lemma demo_C (x y : C) : x + y + 0 = y + 0 + x.
Proof. Admitted.

Variable (L : lmodType R).
Lemma demo_l (a : R) (x y : L) : a *: (x + y) = a *: x + a *:y.
Proof. Admitted.

End AEx.

Big Operators

Another very important tool is the one of "big operators", which are usually operators such as sum or max but applied over a collection of objects. They will appear in many places as for example matrix multiplication is defined that way, etc...
Lemma big_swap_(A : zmodType) (x y : AA) i l : \sum_(i <- l) x i + y i = \sum_(i <- l) y i + x i.
Proof. Admitted.

Matrices

Matrices in math-comp are implemented by a finitely supported finitely-supported function from their indexes to the value.
Matrices will inherit some of the algebraic properties iff
Matrices are extensional so that allows to do many proofs easily! The down side is due to locking these matrices don't computer well.

Lemma matrix_1 :
  let A : 'M[nat]_(2,2) := \matrix_(i < 2, j < 2) (i + j)%nat in
  let B : 'M[nat]_(2,2) := \matrix_(i < 2, j < 2) (i + j)%nat in
  A = B.
Proof. Admitted.

Lemma matrix_struct_1 (T : zmodType) n m (A B : 'M[T]_(n,m)) : A + B = B + A.
Proof. Admitted.

Lemma matrix_struct_1' (T : zmodType) n m (A B : 'M[T]_(n,m)) : A + B = B + A.
Proof. Admitted.

Lemma matrix_struct_2 (T : ringType) n (A B C : 'M[T]_(n.+1,n.+1)) : A × B × C = A × (B × C).
Proof. Admitted.

Lemma tr_tr (T : zmodType) m n (A : 'M[T]_(n,m)) : A = A^T^T.
Proof. Admitted.

Polynomials

Last, we will explore a bit {poly R} the type of polynomials with coefficients in R
  • 'X^i is the variable
  • p.i is evaluation (Horner scheme)
  • polynomials have the corresponding ring structure
Lemma poly_1 (A : ringType) (x y z : A) :
  (Poly [:: x; y; z])`_1 = y.
Proof. by rewrite coef_Poly. Admitted.

Lemma poly_2 (A : ringType) (p q : {poly A}) : p + q = q + p.
Proof. Admitted.