Types in mathematical proofs
Types in mathematical proofs
Types in mathematical proofs
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Types</strong> <strong>in</strong><br />
<strong>mathematical</strong> <strong>proofs</strong><br />
Georges Gonthier
Legacy<br />
• Interactive theorem prov<strong>in</strong>g<br />
• Parametric polymorphism<br />
• Type <strong>in</strong>ference
Some Context<br />
I’m <strong>in</strong>terested <strong>in</strong><br />
• <strong>in</strong>terac6ve <strong>proofs</strong><br />
• of mathema6cal theorems<br />
F<strong>in</strong>ite Group Theory
computa6onal<br />
reflec6on<br />
The “library” problem<br />
client<br />
adapter<br />
meta<br />
data<br />
Library<br />
Component<br />
C (v : T)<br />
C mT(v : a mT)<br />
provider<br />
type<br />
<strong>in</strong>ference<br />
dependent<br />
type<br />
Mathema6cal<br />
Component
Methodology<br />
• Formalize <strong>in</strong> the Logic rather than <strong>in</strong> the<br />
Proof Assistant<br />
• Use both type and form to represent <strong>in</strong>tent<br />
• Formalize dynamics (simplification and<br />
proof rules) as well as the statics of a<br />
theory.
Who does what<br />
• The logic/type theory: CiC<br />
– Propositions as types: programs as proof<br />
– Reflection: programs <strong>in</strong> <strong>proofs</strong><br />
• The system: Coq/ssreflect<br />
– Type reconstruction, term reconstruction<br />
– Notation / elision<br />
– Proof script<strong>in</strong>g : ssreflect<br />
• The library : Ssreflect<br />
– Components
Tool review<br />
• Data (<strong>in</strong>ductive) types / propositions<br />
• Computational reflection<br />
– compute values, types, and propositions<br />
• Dependent types<br />
– first-class Structures<br />
• Type / value <strong>in</strong>ference<br />
– controlled by Coercion / Canonical / Structure<br />
• User notations
Math vs. Computer Math<br />
\beg<strong>in</strong>{eqnarray*}<br />
\det AB Lemma & = determ<strong>in</strong>antM & \sum_{\sigma : forall \<strong>in</strong> S_n} n (A (-1)^\sigma B : M_(n)), \prod_i \det (A *m B) = \det A * \det B.<br />
Proof. \left(\sum_j A_{ij} B_{j\sigma(i)}\right)\\<br />
move=> & = & n \sum_{\phi A B; rewrite :\; big_distrl [1, n] \rightarrow /=. [1, n]}<br />
pose F := {ffun \sum_{\sigma 'I_n -> 'I_n}; \<strong>in</strong> S_n} pose AB s i j := A i j * B j (s i).<br />
transitivity (-1)^\sigma (\sum_(f : \prod_i F) \sum_(s A_{i\phi(i)} : 'S_n) (-1) B_{\phi(i)\sigma(i)}\\<br />
^+ s * \prod_i AB s i (f i)).<br />
& rewrite = & \sum_{\phi exchange_big; \not<strong>in</strong> apply: S_n} eq_bigr \sum_{\sigma => /= \<strong>in</strong> s _; S_n} rewrite -big_distrr /=.<br />
congr (_ * (-1)^\sigma _); rewrite \prod_i -(bigA_distr_bigA A_{i\phi(i)} (AB B_{\phi(i)\sigma(i)}<br />
s)) /=.<br />
by apply: eq_bigr + \sum_{\phi => x _; \<strong>in</strong> rewrite S_n} \sum_{\sigma mxE.<br />
\<strong>in</strong> S_n}<br />
rewrite (bigID (-1)^\sigma (fun f : F => \prod_i <strong>in</strong>jectiveb A_{i\phi(i)} f)) /= addrC B_{\phi(i)\sigma(i)}\\<br />
big1 ?add0r => [|f Uf].<br />
& rewrite = & \sum_{\phi (re<strong>in</strong>dex (@pval \not<strong>in</strong> _)) S_n} /=; \left(\prod_i last first. A_{i\phi(i)}\right)<br />
pose <strong>in</strong>_Sn \sum_{\sigma f : ‘S_n := \<strong>in</strong> <strong>in</strong>subd S_n} 1%g f.<br />
by exists <strong>in</strong>_Sn (-1)^\sigma => /= f \prod_i Uf; first B_{\phi(i)\sigma(i)}\\<br />
apply: val_<strong>in</strong>j; exact: <strong>in</strong>subdK.<br />
first & & {} + apply: \sum_{\phi \<strong>in</strong> val_<strong>in</strong>j; S_n} exact: <strong>in</strong>subdK.<br />
apply: eq_big => /= [s | s _]; rewrite ?(valP s) // big_distrr /=.<br />
rewrite (re<strong>in</strong>dex_<strong>in</strong>j (-1)^\phi (mulgI \left(\prod_i s)); apply: eq_bigr A_{i\phi(i)}\right)<br />
=> t _ /=.<br />
rewrite big_split \sum_{\sigma /= mulrA mulrCA \<strong>in</strong> S_n} mulrA mulrCA mulrA.<br />
rewrite -signr_addb<br />
(-1)^{\phi^{-1}\sigma}<br />
odd_permM !pvalE; congr (_ * _); symmetry.<br />
by rewrite (re<strong>in</strong>dex_<strong>in</strong>j (@perm_<strong>in</strong>j \prod_k B_{k\sigma(\phi^{-1}(k))}\\<br />
_ s)); apply: eq_bigr => i; rewrite permM.<br />
transitivity & = & \sum_{\phi (\det (\matrix_(i, \not<strong>in</strong> S_n} \left(\prod_i j) B (f i) j) A_{i\phi(i)}\right)<br />
* \prod_i A i (f i)).<br />
rewrite mulrC \det big_distrr \left(B_{\phi(i)j}\right)_{ij}<br />
/=; apply: eq_bigr => s _.<br />
rewrite =(∑ + (\det mulrCA (-1) A)\sum_{\tau big_split //=; \<strong>in</strong> S_n}(-1)^\tau congr (_ * (_ \prod_k * _)). B_{k\tau(k)}\\<br />
by apply: & = & eq_bigr 0 + (\det => x A)(\det _; rewrite B)\\ mxE.<br />
\end{eqnarray*}<br />
case/<strong>in</strong>jectivePn: Uf => i1 [i2 Di12 Ef12].<br />
The first by rewrite step swaps (alternate_determ<strong>in</strong>ant the iterated product Di12) of the ?simp Leibnitz //= => formula j; rewrite with !mxE Ef12.<br />
the sum Qed. <strong>in</strong> the general term of the matrix product, generat<strong>in</strong>g a sum over<br />
all functions from <strong>in</strong>dices to <strong>in</strong>dices. This is split <strong>in</strong>to a sum over<br />
non-<strong>in</strong>jective functions and a sum over permutations. The former is rearranged<br />
<strong>in</strong>to a weighted sum of determ<strong>in</strong>ants of matrices with repeated rows,<br />
while the latter is re<strong>in</strong>dexed, us<strong>in</strong>g the group properties<br />
of permutations, to become the desired product of determ<strong>in</strong>ants.<br />
ρ ∏i Ai,iρ) ( ∑ (-1)τ + ∑ ∏i Ai,iρ ∑ (-1)<br />
ρ∉Sn<br />
∏j Bj,jτ )<br />
ρ∈Sn τ∈Sn<br />
+ ∑ ∏i Ai,iρ |(Biρ,j)|<br />
ρ∉Sn<br />
σ = ∑ ∏i Ai,iρ ∑ (-1)<br />
∏i Biρ,iσ<br />
σ ∏i Biρ,iσ<br />
σ∈Sn<br />
= ∑ ∏i Ai,iρ ∑ (-1) σ ∏j Bj,jρ-1 |AB| = ∑ (-1)<br />
σ<br />
σ∈Sn<br />
σ ∏i (∑j Ai,j Bj,iσ)<br />
σ∈Sn<br />
ρ<br />
ρ∈Sn<br />
σ∈Sn<br />
= |A| |B|<br />
rewrite (re<strong>in</strong>dex (@pval _)) /=; last first.<br />
pose <strong>in</strong>_Sn f : ‘S_n := <strong>in</strong>subd 1%g f.<br />
by exists <strong>in</strong>_Sn => /= f Uf;<br />
i = jρ -1<br />
σ = ρτ
∑ai X i<br />
i < n<br />
Big Operators<br />
∑ (-1) σ ∏ i Ai,iσ<br />
σ∈Sn<br />
∑Φ(n/d) m d<br />
d | n<br />
∩ H<br />
H < G<br />
H maximal<br />
n<br />
⋀GCD Qi(X)<br />
i = 1<br />
\bigcap_{H < G \atop H {\rm\ maximal}} H<br />
⊕ Vi<br />
Vi ≈ W<br />
Def<strong>in</strong>ition determ<strong>in</strong>ant n (A : 'M_n) : R :=<br />
\sum_(s : 'S_n) (-1) ^+ s * \prod_i A i (s i).
• Present the options<br />
Notation<br />
Def<strong>in</strong>ition bigop R I op idx r P (F : I -> R) : R :=<br />
foldr (fun i x => if P i then op (F i) x else x) idx r.<br />
Notation "\big[ op / idx ]_ ( i
• Polymorphism with dependent records<br />
Variable I : f<strong>in</strong>Type.<br />
Inferred Notation<br />
Module F<strong>in</strong>ite.<br />
Structure type :=<br />
Pack { sort :> Type; enum : seq sort; ... }.<br />
End F<strong>in</strong>ite.<br />
Variable F : I -> nat.<br />
sort I -> nat.<br />
Lemma null_sum : \sum_i F i = 0 -> forall i, F i = 0.<br />
@bigop nat I _ addn 0 (enum I _) .. (fun i : I _ => F i)<br />
seq(sort _)<br />
=<br />
seq(sort I)
Canonical Notation<br />
• Use ad hoc <strong>in</strong>terpretation<br />
Inductive ord<strong>in</strong>al n := Ord<strong>in</strong>al i of i < n.<br />
Notation "‘I_ n" := (ord<strong>in</strong>al n).<br />
Def<strong>in</strong>ition ord_enum n : seq ‘I_n := …<br />
Canonical ord<strong>in</strong>al_f<strong>in</strong>Type n :=<br />
F<strong>in</strong>Type ‘I_n (ord_enum n) …<br />
Variable V : ‘I_10 -> nat.<br />
Hypothesis normV : \sum_i V i * V i V i)<br />
seq seq (sort I_(_) _) =<br />
ord<strong>in</strong>al_f<strong>in</strong>Type 10<br />
_<br />
seq I_10
Generic Lemmas<br />
• Pull, split, re<strong>in</strong>dex, exchange …<br />
Lemma bigD1 : forall (I : f<strong>in</strong>Type) (j : I) P F,<br />
P j -> \big[*%M/1]_(i | P i) F i<br />
= F j * \big[*%M/1]_(i | P i && (i != j)) F i.<br />
Lemma big_split : forall I (r : list I) P F1 F2,<br />
\big[*%M/1]_(i J}) \big[*%M/1]_(i) F i (f i).
Interfac<strong>in</strong>g big ops<br />
Equality<br />
F<strong>in</strong>ite<br />
bool<br />
nat<br />
'I_n<br />
seq<br />
bigop<br />
⊕ Ei<br />
i ←r & P(i)<br />
Monoid.law<br />
Monoid.com_law<br />
Monoid.add_law
Operator structures<br />
• Polymorphism for values!<br />
Structure law : Type :=<br />
Law {<br />
operator :> T -> T -> T;<br />
_ : associative operator;<br />
_ : left_id idx operator;<br />
_ : right_id idx operator<br />
}.<br />
Canonical addn_monoid := Monoid.Law addnA add0n addn0.<br />
Canonical addn_abeloid := Monoid.ComLaw addnC.<br />
Canonical muln_monoid := Monoid.Law mulnA mul1n muln1.<br />
…<br />
Structure com_law : Type :=<br />
AbelianLaw {<br />
com_operator :> law;<br />
_ : commutative com_operator<br />
}.<br />
Canonical r<strong>in</strong>g_add_monoid := Monoid.Law addrA add0r addr0.<br />
Canonical r<strong>in</strong>g_add_abeloid := Monoid.ComLaw addrC.<br />
…
The Equality <strong>in</strong>terface<br />
Module Equality.<br />
Def<strong>in</strong>ition axiom T op := forall x y : T, reflect (x = y) (op<br />
x y).<br />
Record mix<strong>in</strong>_of T :=<br />
Mix<strong>in</strong> {op : rel T; _ : axiom T op}.<br />
Structure type :=<br />
Pack {sort :> Type; class : mix<strong>in</strong>_of sort}.<br />
End Equality.<br />
Def<strong>in</strong>ition eq_op T := Equality.op (Equality.class T).<br />
Notation eqType := Equality.type.<br />
Notation “x == y” := (eq_op x y).
Build<strong>in</strong>g up (telescopes)<br />
• F<strong>in</strong>ite (enumerable) types:<br />
Structure f<strong>in</strong>Type := F<strong>in</strong>Type {<br />
f<strong>in</strong>Carrier : eqType;<br />
enum : seq f<strong>in</strong>Carrier; _ : ...}<br />
#|T|, #|A|, A \subset B, ...<br />
• F<strong>in</strong>ite functions<br />
Inductive f<strong>in</strong>fun (aT : f<strong>in</strong>Type) rT :=<br />
F<strong>in</strong>fun of #|aT|.-tuple rT.
Packed classes<br />
• Telescopes are easy to code, but...<br />
– S<strong>in</strong>gle <strong>in</strong>heritance only<br />
– Coercion cha<strong>in</strong>s: aT ≡ eqSort (f<strong>in</strong>Carrier aT)<br />
– Wrong head constructor eqSort (f<strong>in</strong>Carrier aT)<br />
• Solution: use classes (dictionaries) and<br />
mix<strong>in</strong>s.
ComR<strong>in</strong>g<br />
Inheritance graph<br />
Equality<br />
Choice<br />
Zmodule<br />
R<strong>in</strong>g<br />
ComUnitR<strong>in</strong>g<br />
UnitR<strong>in</strong>g<br />
Lmodule<br />
Algebra<br />
Addidive<br />
Rmorphism L<strong>in</strong>ear<br />
LRmorphism<br />
Vector<br />
Falgebra
L<strong>in</strong>ear operator <strong>in</strong>terface<br />
• Encapsulate f (λv) = λ(f v)<br />
Module L<strong>in</strong>ear.<br />
Section ClassDef.<br />
Variables (R : r<strong>in</strong>gType) (U V : lmodType R).<br />
Def<strong>in</strong>ition mix<strong>in</strong>_of (f : U -> V) :=<br />
forall a, {morph f : u / a *: u}.<br />
Record class_of f : Prop :=<br />
Class {base : additive f; mix<strong>in</strong> : mix<strong>in</strong>_of f}.<br />
Structure map :=<br />
Pack {apply :> U -> V; class : class_of apply}.<br />
Structure additive cT := Additive (base (class cT)).<br />
End L<strong>in</strong>ear.
General l<strong>in</strong>ear operators<br />
• Encapsulate f (λv) = λ σ (f v)<br />
Module L<strong>in</strong>ear….<br />
Variables (R : r<strong>in</strong>gType) (U : lmodType R) (V : zmodType).<br />
Variable (s : R -> V -> V).<br />
Def<strong>in</strong>ition mix<strong>in</strong>_of (f : U -> V) :=<br />
forall a, {morph f : u / a *: u >-> s a u}.<br />
Record class_of f : Prop :=<br />
Class {base : additive f; mix<strong>in</strong> : mix<strong>in</strong>_of f}.<br />
Structure map := Pack {apply :> Type; class : class_of apply}.<br />
…<br />
(* horner_morph mulCx_nu P := (map nu P).[x] *)<br />
Fact …: scalable_for (nu \; *%R) (horner_morph mulCx_nu).
General l<strong>in</strong>earity<br />
• Rewrite f (λv) = λ σ (f v) <strong>in</strong> both directions<br />
Variables (R : r<strong>in</strong>gType) (U : lmodType R) (V : zmodType).<br />
Variables (s : R -> V -> V) (S : r<strong>in</strong>gType) (h : S -> V -> V).<br />
Variable h_law : Scale.law h.<br />
Lemma l<strong>in</strong>earZ c a (h_c := Scale.op h_law c)<br />
(f : L<strong>in</strong>ear.map_for U s a h_c) u :<br />
f (a *: u) = h_c (L<strong>in</strong>ear.wrap f u).
Deep match<strong>in</strong>g<br />
• Adjo<strong>in</strong> a unification constra<strong>in</strong>t to L<strong>in</strong>ear<br />
Module L<strong>in</strong>ear. …<br />
Def<strong>in</strong>ition map_class := map.<br />
Def<strong>in</strong>ition map_at (a : R) := map.<br />
Structure map_for a s_a :=<br />
MapFor {map_for_map : map; _ : s a = s_a}.<br />
Canonical unify_map_at a (f : map_at a) :=<br />
MapFor f (erefl (s a)).<br />
Structure wrapped := Wrap {unwrap : map}.<br />
Coercion wrap (f : map_class) := Wrap f.<br />
Canonical wrap.
Interfac<strong>in</strong>g groups<br />
Equality<br />
F<strong>in</strong>ite<br />
BaseF<strong>in</strong>Group<br />
1, x * y, x -‐1<br />
F<strong>in</strong>Group<br />
x -‐1 x=1<br />
bool<br />
f<strong>in</strong>set<br />
{x 1, x 2, … x n}<br />
group<br />
coset<br />
Hx, G/H<br />
predType<br />
subType<br />
morphism<br />
ac6on
• Matrices from<br />
Phantom <strong>Types</strong><br />
Inductive ord<strong>in</strong>al n := Ord<strong>in</strong>al i & i < n.<br />
• ?? matrix T m n := f<strong>in</strong>fun<br />
(pair_f<strong>in</strong>Type (ord<strong>in</strong>al_f<strong>in</strong>Type m) (ord<strong>in</strong>al_f<strong>in</strong>Type n))<br />
T<br />
• Use Inductive phantom T (x : T) := Phantom.<br />
f<strong>in</strong>fun_of aT rT of phantom (aT -> rT) := f<strong>in</strong>fun aT rT<br />
Notation “{ ‘ffun’ fT }” := (f<strong>in</strong>fun_of (Phantom fT)).<br />
• Now matrix T m n := {ffun ‘I_m * ‘I_n -> T}
Property <strong>in</strong>ference<br />
• The statements only conta<strong>in</strong> sets.<br />
Theorem third_iso : isog ((G / K) / (H / K)) (G / H).<br />
• The group properties are <strong>in</strong>ferred.<br />
Canonical Structure setI_group G H :=<br />
Group (setI_closed G H : group_set (G∩H)).<br />
G, H <strong>in</strong>st group H <strong>in</strong>st group<br />
G∩H <strong>in</strong>st group ./H <strong>in</strong>st morphism<br />
G <strong>in</strong>st group φ <strong>in</strong>st morphism<br />
φ(G) <strong>in</strong>st group
Circular <strong>in</strong>equalities<br />
rankEP Bfree_if rankEP Lemma leqif_trans : \rank : forall 1%:M ZxH : forall = : (\sum_(ZxH {set m1 m2 coset_of m3 c1 \<strong>in</strong> c2, Z}, clPqH) ZxH #|ZxH|)%N<br />
\<strong>in</strong> #|ZxH|)%N<br />
clPqH^# -><br />
m1 m2 m1 <br />
\rank
Conclusions<br />
• Advanced mathematics is also a<br />
Software Eng<strong>in</strong>eer<strong>in</strong>g challenge.<br />
• Higher-order type theory provides a rich<br />
language for organis<strong>in</strong>g formalisations.<br />
• Dependent type reconstruction is userprogrammable