presentation (, annotated with notes)

The HoTT/HoTT Library in Coq
Designing for Speed
Jason Gross
Massachusetts Institute of Technology
For ICMS 2016, adapted from ITP 2014 presentation
Category theory work done with Adam Chlipala and David I. Spivak
HoTT/HoTT library additionally co-authored by Andrej Bauer, Peter LeFanu Lumsdaine, Mike
Shulman, Bas Spitters, and includes contributions from Assia Mahboubi, Marc Bezem, Kristina
Sojakova, Daniel R. Grayson, Gaetan Gilbert, Matthieu Sozeau, Jérémy Ledent, Kevin Quirin,
Steve Awodey, Cyril Cohen, Egbert, Benedikt Ahrens, Edward Z. Yang, Georgy Dunaev, Jesse C.
McKeown, Simon Boulier, Alexander Karpich, Jelle Herold, John Dougherty, MatΔ›j Grabovský,
Michael Nahas, and Yves Bertot
How should theorem provers work?
2
How theorem provers should work:
1=0
Coq, is this
correct?
No; here’s a
proof of
1 = 0 β†’ False
3
How theorem provers should work:
Theorem (currying) : π‘ͺ𝟏 β†’ π‘ͺ𝟐 β†’ 𝑫
Proof: homework ∎
Coq, is this
correct?
β‰… (π‘ͺ𝟏 × π‘ͺ𝟐 β†’ 𝑫)
Yes; here’s a
proof …
4
How theorem provers should work:
Theorem (currying) : π‘ͺ𝟏 β†’ π‘ͺ𝟐 β†’ 𝑫
Proof: homework ∎
Theorem currying : 𝐢1 β†’ 𝐢2 β†’ 𝐷
Proof.
trivial.
Qed.
β‰… (π‘ͺ𝟏 × π‘ͺ𝟐 β†’ 𝑫)
β‰… 𝐢1 × πΆ2 β†’ 𝐷 .
5
How theorem provers should work:
Theorem (currying) : π‘ͺ𝟏 β†’ π‘ͺ𝟐 β†’ 𝑫 β‰… (π‘ͺ𝟏 × π‘ͺ𝟐 β†’ 𝑫)
Proof: β†’: 𝑭 ↦ 𝝀 π’„πŸ , π’„πŸ . 𝑭 π’„πŸ π’„πŸ ; morphisms similarly
←: 𝑭 ↦ 𝝀 π’„πŸ . 𝝀 π’„πŸ . 𝑭(π’„πŸ , π’„πŸ ); morphisms similarly
Functoriality, naturality, and congruence: straightforward.
∎
Theorem currying : 𝐢1 β†’ 𝐢2 β†’ 𝐷 β‰… 𝐢1 × πΆ2 β†’ 𝐷 .
Proof.
esplit.
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐 ↦ 𝐹o 𝑐1 𝑐2 )))). }
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐1 ↦ (πœ†F (𝑐2 ↦ 𝐹o (𝑐1 , 𝑐2 ))))))). }
all: trivial.
Qed.
6
How theorem provers should work:
Theorem (currying) : π‘ͺ𝟏 β†’ π‘ͺ𝟐 β†’ 𝑫 β‰… (π‘ͺ𝟏 × π‘ͺ𝟐 β†’ 𝑫)
Proof: β†’: 𝑭 ↦ 𝝀 π’„πŸ , π’„πŸ . 𝑭 π’„πŸ π’„πŸ ; morphisms similarly
←: 𝑭 ↦ 𝝀 π’„πŸ . 𝝀 π’„πŸ . 𝑭(π’„πŸ , π’„πŸ ); morphisms similarly
Functoriality, naturality, and congruence: straightforward.
∎
Theorem currying : 𝐢1 β†’ 𝐢2 β†’ 𝐷 β‰… 𝐢1 × πΆ2 β†’ 𝐷 .
Proof.
esplit.
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐 ↦ 𝐹o 𝑐1 𝑐2 ) (𝑠 𝑑 π‘š ↦ 𝐹o 𝑑1 m π‘š2 ∘ 𝐹m π‘š1 o 𝑠2 ))
(𝐹 𝐺 𝑇 ↦ (πœ†T (𝑐 ↦ 𝑇 𝑐1 𝑐2 )))). }
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐1 ↦ (πœ†F (𝑐2 ↦ 𝐹o (𝑐1 , 𝑐2 )) (𝑠 𝑑 π‘š ↦ 𝐹m (1, π‘š))))
(𝐹 𝐺 𝑇 ↦ (πœ†T (𝑐1 ↦ (πœ†T (𝑐2 ↦ 𝑇 (𝑐1 , 𝑐2 )))))). }
all: trivial.
Qed.
7
How theorem provers do work:
Theorem (currying) : π‘ͺ𝟏 β†’ π‘ͺ𝟐 β†’ 𝑫 β‰… (π‘ͺ𝟏 × π‘ͺ𝟐 β†’ 𝑫)
Proof: β†’: 𝑭 ↦ 𝝀 π’„πŸ , π’„πŸ . 𝑭 π’„πŸ π’„πŸ ; morphisms similarly
←: 𝑭 ↦ 𝝀 π’„πŸ . 𝝀 π’„πŸ . 𝑭(π’„πŸ , π’„πŸ ); morphisms similarly
Functoriality, naturality, and congruence: straightforward.
17 s
β‰ˆ0s
∎
2m 46 s !!! (5 s, if we use UIP)
Theorem currying : 𝐢1 β†’ 𝐢2 β†’ 𝐷 β‰… 𝐢1 × πΆ2 β†’ 𝐷 .
Proof.
esplit.
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐 ↦ 𝐹o 𝑐1 𝑐2 ) (𝑠 𝑑 π‘š ↦ 𝐹o 𝑑1 m π‘š2 ∘ 𝐹m π‘š1 o 𝑠2 ))
(𝐹 𝐺 𝑇 ↦ (πœ†T (𝑐 ↦ 𝑇 𝑐1 𝑐2 )))). }
{ by refine (πœ†F (𝐹 ↦ (πœ†F (𝑐1 ↦ (πœ†F (𝑐2 ↦ 𝐹o (𝑐1 , 𝑐2 )) (𝑠 𝑑 π‘š ↦ 𝐹m (1, π‘š))))
(𝐹 𝐺 𝑇 ↦ (πœ†T (𝑐1 ↦ (πœ†T (𝑐2 ↦ 𝑇 (𝑐1 , 𝑐2 )))))). }
all: trivial.
Qed.
8
Performance is important!
If we’re not careful, obvious or trivial things can be
very, very slow.
9
Why you should listen to me
Theorem : You should listen to me.
Proof.
by experience.
Qed.
10
Why you should listen to me
Category theory in Coq: https://github.com/HoTT/HoTT
(subdirectory theories/categories):
Concepts Formalized:
β€’
1-precategories (in the sense of the HoTT Book)
β€’
univalent/saturated categories (or just categories, in the HoTT Book)
β€’
functor precategories 𝐢 β†’ 𝐷
β€’
dual functor isomorphisms Cat β†’ Cat; and 𝐢 β†’ 𝐷 op β†’ (𝐢 op β†’ 𝐷op )
β€’
the category Prop of (U-small) hProps
β€’
the category Set of (U-small) hSets
β€’
the category Cat of (U-small) strict (pre)categories (strict in the sense of the
objects being hSets)
β€’
pseudofunctors
β€’
pseudonatrual transformations
β€’
(op)lax comma categories
β€’
profunctors
β€’
identity profunctor (the hom functor 𝐢 op × πΆ β†’ Set)
β€’
adjoints
β€’
equivalences between a number of definitions:
β€’
unit-counit + zig-zag definition
β€’
unit + UMP definition
β€’
counit + UMP definition
β€’
universal morphism definition
β€’
hom-set definition
β€’
composition, identity, dual
β€’
pointwise adjunctions in the library, 𝐺 𝐸 ⊣ 𝐹 𝐢 and 𝐸 𝐹 ⊣ 𝐢 𝐺 from an
adjunction 𝐹 ⊣ 𝐺 for functors 𝐹: 𝐢 ⇆ 𝐷: 𝐺 and 𝐸 a precategory
β€’
Yoneda lemma
β€’
β€’
β€’
β€’
β€’
Exponential laws
β€’
𝐢 0 β‰… 1; 0𝐢 β‰… 0 given an object in 𝐢
β€’
𝐢 1 β‰… 𝐢; 1𝐢 β‰… 1
β€’
𝐢 𝐴+𝐡 β‰… 𝐢 𝐴 × πΆ 𝐡
β€’
(𝐴 × π΅)𝐢 β‰… 𝐴𝐢 × π΅πΆ
β€’
(𝐴𝐡 )𝐢 β‰… 𝐴𝐡×𝐢
Product laws
β€’
𝐢×𝐷 ≅𝐷×𝐢
β€’
𝐢×0β‰…0×𝐢 β‰… 0
β€’
𝐢×1β‰…1×𝐢 β‰… 𝐢
Grothendieck construction (oplax colimit) of a pseudofunctor to Cat
Category of sections (gives rise to oplax limit of a pseudofunctor to Cat when
applied to Grothendieck construction
functor composition is functorial (there's a functor Ξ”: 𝐢 β†’ 𝐷 β†’ (𝐷 β†’
11
Presentation is not mainly about:
12
Presentation is not mainly about:
β€’ category theory or diagram chasing
Cartoon from xkcd, adapted by Alan Huang
13
Presentation is not mainly about:
β€’ category theory or diagram chasing
Cartoon from xkcd, adapted by Alan Huang
β€’ the mathematical content
of the library
14
Presentation is not mainly about:
β€’ category theory or diagram chasing
Cartoon from xkcd, adapted by Alan Huang
β€’ the mathematical content
of the library
β€’ Coq
15
Presentation is not mainly about:
β€’ category theory or diagram chasing
Cartoon from xkcd, adapted by Alan Huang
β€’ the mathematical content
of the library
β€’ Coq (though what I say might not always generalize nicely)
16
Presentation is about:
β€’ performance
β€’ the design of proof assistants and type theories to
assist with performance
β€’ the kind of performance issues I encountered
β€’ an overview of the content of the HoTT/HoTT library
17
Presentation is for:
β€’ Homotopy type theorists
β€’ Who are interested in the HoTT/HoTT library
β€’ Users of proof assistants (and Coq in particular)
β€’ Who want to make their code faster
β€’ Designers of (type-theoretic) proof assistants
β€’ Who want to know where to focus their optimization efforts
18
Outline
β€’ Why should we care about performance?
β€’ Overview of the HoTT/HoTT library
β€’ What makes theorem provers (mainly Coq) slow?
β€’ Examples of particular slowness
β€’ For users (workarounds)
β€’ Arguments vs. fields and packed records
β€’ Abstraction barriers
β€’ For developers (features)
β€’ Primitive projections
19
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
HoTT/HoTT Library: Contents
β€’ Basic type formers and their identity types
β€’ h-levels, object classifier, …
β€’ Many examples of HITs from the book:
β€’ Circle, interval, suspensions, flattening, truncations,
quotients
β€’ πœ‹1 𝑆 1 = β„€
β€’ Modalities (reflective subtoposes)
β€’ Spaces: Cantor, Finite, Surreals, …
β€’ Categories
20
HoTT/HoTT Library: Diagram
21
Performance
β€’ Question: What makes programs, particularly theorem
provers or proof scripts, slow?
23
Performance
β€’ Question: What makes programs, particularly theorem
provers or proof scripts, slow?
β€’ Answer: Doing too much stuff!
24
Performance
β€’ Question: What makes programs, particularly theorem
provers or proof scripts, slow?
β€’ Answer: Doing too much stuff!
β€’ doing the same things repeatedly
25
Snail from http://naolito.deviantart.com/art/Repetitive-task-258126598
Performance
β€’ Question: What makes programs, particularly theorem
provers or proof scripts, slow?
β€’ Answer: Doing too much stuff!
β€’ doing the same things repeatedly
β€’ doing lots of stuff for no good reason
26
Running rooster from http://d.wapday.com:8080/animation/ccontennt/15545-f/mr_rooster_running.gif
Performance
β€’ Question: What makes programs, particularly theorem
provers or proof scripts, slow?
β€’ Answer: Doing too much stuff!
β€’ doing the same things repeatedly
β€’ doing lots of stuff for no good reason
β€’ using a slow language when you could be
using a quicker one
27
Proof assistant performance
β€’ What kinds of things does Coq do?
β€’ Type checking
β€’ Term building
β€’ Unification
β€’ Normalization
28
Proof assistant performance (pain)
β€’ When are these slow?
β€’ when you duplicate work
β€’ when you do work on a part of a term you end up not caring
about
β€’ when you do them too many times
β€’ when your term is large
29
Proof assistant performance (size)
β€’ How large is slow?
30
Proof assistant performance (size)
β€’ How large is slow?
β€’ Around 150,000β€”500,000 words
31
Durations of Various Tactics vs. Term Size (Coq v8.4, 2.4 GHz Intel Xeon CPU, 16 GB RAM)
100 s
destruct x (v8.4)
assert (z := true); destruct z (v8.4)
10 s
set (y := x) (v8.4)
set (y := bool) (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in apply H end (v8.4)
apply f_equal (v8.4)
generalize x (v8.4)
1s
assert (z := true); generalize z (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in exact H end (v8.4)
match goal with |- ?G => set (y := G) end (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in exact_no_check H end (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in idtac end (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b)
in idtac end (v8.4)
0.1 s
assert (z := true); revert z (v8.4)
lazymatch goal with |- ?f ?a = ?g ?b => idtac end (v8.4)
0.01 s
1.0E+0
32
1.0E+1
1.0E+2
1.0E+3
1.0E+4
1.0E+5
1.0E+6
1.0E+7
1.0E+8
Durations of Various Tactics vs. Term Size (Coq v8.6, 3.5 GHz Intel i7 CPU, 64 GB RAM)
100 s
destruct x (v8.6)
assert (z := true); destruct z (v8.6)
10 s
set (y := x) (v8.6)
set (y := bool) (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in apply H end (v8.6)
apply f_equal (v8.6)
generalize x (v8.6)
1s
assert (z := true); generalize z (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in exact H end (v8.6)
match goal with |- ?G => set (y := G) end (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in exact_no_check H end (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b
(@eq_refl bool a)) in idtac end (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => let H := constr:(@f_equal bool bool f a b)
in idtac end (v8.6)
0.1 s
assert (z := true); revert z (v8.6)
lazymatch goal with |- ?f ?a = ?g ?b => idtac end (v8.6)
0.01 s
1.0E+0
33
1.0E+1
1.0E+2
1.0E+3
1.0E+4
1.0E+5
1.0E+6
1.0E+7
1.0E+8
Proof assistant performance (size)
β€’ How large is slow?
β€’ Around 150,000β€”500,000 words
Do terms actually get this large?
34
Proof assistant performance (size)
β€’ How large is slow?
β€’ Around 150,000β€”500,000 words
Do terms actually get this large?
YES!
35
Proof assistant performance (size)
β€’ A directed graph has:
β€’ a type of vertices (points)
β€’ for every ordered pair of vertices, a type of arrows
36
Proof assistant performance (size)
β€’ A directed 2-graph has:
β€’ a type of vertices (0-arrows)
β€’ for every ordered pair of vertices, a type of arrows (1-arrows)
β€’ for every ordered pair of 1-arrows between the same vertices, a
type of 2-arrows
37
Proof assistant performance (size)
β€’ A directed arrow-graph comes from turning arrows into
vertices:
38
Proof assistant performance (pain)
β€’ When are these slow?
β€’ When your term is large
β€’ Smallish example (29 000 words): Without Proofs:
{| LCCMF ≔ _\_inducedF π‘š22 ∘ π‘š12 ;
LCCMT ≔ πœ† 𝑇 (πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ π‘š11 𝑐. 𝛽) |} =
{| LCCMF ≔ _\_inducedF π‘š12 ∘ _\_inducedF π‘š22 ;
LCCMT ≔ πœ† 𝑇 (πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽 ∘ 𝕀) |}
39
Proof assistant performance (pain)
β€’ When are these slow?
β€’ When your term is large
β€’ Smallish example (29 000 words): Without Proofs:
{| LCCMF ≔ _\_inducedF π‘š22 ∘ π‘š12 ;
LCCMT ≔ πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ π‘š11 𝑐. 𝛽
(Ξ βˆ’pf 𝑠2 (πœ† 𝑇 πœ† 𝑐 ∢ 𝐢 β‡’ π‘š21 𝑐 ∘ π‘š11 𝑐
(∘1 βˆ’pf π‘š21 π‘š11 )) (π‘š22 ∘ π‘š12 )) |} =
{| LCCMF ≔ _\_inducedF π‘š12 ∘ _\_inducedF π‘š22 ;
LCCMT ≔ πœ† 𝑇 (πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽 ∘ 𝕀)
(∘1 βˆ’pf
(πœ† 𝑇
πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 (Ξ βˆ’pf 𝑑
(πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽 ∘ 𝕀
(∘1 βˆ’pf
(πœ† 𝑇
πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ 𝑑1
(∘0 βˆ’pf (πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2 /40𝐹 β‡’
Proof assistant performance (pain)
β€’ When are these slow?
β€’ When your term is large
β€’ Smallish example (29 000 words): Without Proofs:
{| LCCMF ≔ _\_inducedF π‘š22 ∘ π‘š12 ;
LCCMT ≔ πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ π‘š11 𝑐. 𝛽
(Ξ βˆ’pf 𝑠2 (πœ† 𝑇 πœ† 𝑐 ∢ 𝐢 β‡’ π‘š21 𝑐 ∘ π‘š11 𝑐
(∘1 βˆ’pf π‘š21 π‘š11 )) (π‘š22 ∘ π‘š12 )) |} =
{| LCCMF ≔ _\_inducedF π‘š12 ∘ _\_inducedF π‘š22 ;
LCCMT ≔ πœ† 𝑇 (πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 ∘ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽 ∘ 𝕀)
(∘1 βˆ’pf (πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ π‘š21 𝑐. 𝛽 (Ξ βˆ’pf 𝑑2 π‘š21 π‘š22 )))
(πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽 ∘ 𝕀
(∘1 βˆ’pf (πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2β€² / 𝐹 β‡’ 𝑑1 1 𝕀 ∘ π‘š11 𝑐. 𝛽
(∘0 βˆ’pf (πœ† 𝑇 πœ† 𝑐 ∢ 𝑑2 / 𝐹 β‡’ π‘š11 𝑐. 𝛽
(Ξ βˆ’pf 𝑠2 π‘š11 π‘š12 )) 𝕀)) 𝕀))) |}
41
Proof assistant performance (fixes)
β€’ How do we work around this?
42
Proof assistant performance (fixes)
β€’ How do we work around this?
β€’ By hiding from the proof checker!
43
Fence from http://imgarcade.com/1/hiding-clipart/
Proof assistant performance (fixes)
β€’ How do we work around this?
β€’ By hiding from the proof checker!
β€’ How do we hide?
44
Proof assistant performance (fixes)
β€’ How do we work around this?
β€’ By hiding from the proof checker!
β€’ How do we hide?
β€’ Good engineering
β€’ Better proof assistants
45
Proof assistant performance (fixes)
Careful Engineering
46
Outline
β€’ Why should we care about performance?
β€’ Overview of the HoTT/HoTT library
β€’ What makes theorem provers (mainly Coq) slow?
β€’ Examples of particular slowness
β€’ For users (workarounds)
β€’ Arguments vs. fields and packed records
β€’ Abstraction barriers
β€’ For developers (features)
β€’ Primitive projections
47
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
β€’ How?
β€’ Avoid exponential blowup: Pack your records!
48
Proof assistant performance (fixes)
β€’ How?
β€’ Avoid exponential blowup: Pack your records!
A mapping of graphs is a mapping of vetices to vertices and
arrows to arrows
mapping
49
Proof assistant performance (fixes)
β€’ How?
β€’ Avoid exponential blowup: Pack your records!
At least two options to define graph:
Record Graph := { V : Type ; E : V β†’ V β†’ Type }.
Record IsGraph (V : Type) (E : V β†’ V β†’ Type) := { }.
50
Proof assistant performance (fixes)
Record Graph := { V : Type ; E : V β†’ V β†’ Type }.
Record IsGraph (𝑉: Type) (𝐸: 𝑉→ 𝑉→ Type) := { }.
Big difference for size of functor:
Mapping : Graph β†’ Graph β†’ Type.
vs.
IsMapping : βˆ€ (𝑉𝐺 : Type) (𝑉𝐻 : Type)
(𝐸𝐺 : 𝑉𝐺 β†’ 𝑉𝐺 β†’ Type) (𝐸𝐻 : 𝑉𝐻 β†’ 𝑉𝐻 β†’ Type),
IsGraph 𝑉𝐺 𝐸𝐺 β†’ IsGraph 𝑉𝐻 𝐸𝐻 β†’ Type.
51
Proof assistant performance (fixes)
β€’ How?
β€’ Either don’t nest constructions, or don't unfold nested
constructions
β€’ Coq only cares about unnormalized term size – β€œWhat I don't
know can't hurt me”
52
Proof assistant performance (fixes)
β€’ How?
β€’ More systematically, have good abstraction barriers
53
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Leaky abstraction barriers
generally only torture
programmers
54
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Leaky abstraction barriers
torture Coq, too!
55
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Example: Pairing (without judgmental Ξ·)
Two ways to make use of elements of a pair:
let (π‘₯, 𝑦) := 𝑝 in 𝑓 π‘₯ 𝑦. (pattern matching)
𝑓 (fst 𝑝) (snd 𝑝). (projections)
56
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Example: Pairing (without judgmental Ξ·)
Two ways to make use of elements of a pair:
let (π‘₯, 𝑦) := 𝑝 in 𝑓 π‘₯ 𝑦. (pattern matching)
𝑓 (let (π‘₯, 𝑦) := 𝑝 in π‘₯) (let (π‘₯, 𝑦) := 𝑝 in 𝑦). (projections)
These ways do not unify!
57
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Leaky abstraction barriers
torture Coq, too!
Rooster Image from
http://www.animationlibrary.com/animation/18342/Chicken_blows_up/
59
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
β€’ How?
β€’ Have good abstraction barriers
Leaky abstraction barriers
torture Coq, too!
60
Dam image from ID-L-0010, WaterArchives.org, CC by SA 2.0
Proof assistant performance (fixes)
Concrete Example (Old Version)
Local Notation mor_of π‘Œ0 π‘Œ1 𝑓:=
(let πœ‚π‘Œ1 := IsInitialMorphism_morphism (@HM π‘Œ1 ) in
(@center _ (IsInitialMorphism_property (@HM π‘Œ0) _ (πœ‚π‘Œ1 ∘ f))) 1 ) (only parsing).
Lemma composition_of π‘₯ 𝑦 𝑧 𝑔 𝑓: mor_of _ _ (𝑓 ∘ 𝑔) = mor_of 𝑦 𝑧 𝑓 ∘ mor_of π‘₯ 𝑦 𝑔.
Proof.
simpl.
match goal with | [ ⊒ ((@center ?𝐴?𝐻) 2 ) 1 = _ ] β‡’ erewrite (@contr 𝐴 𝐻 (center _; (_; _))) end.
simpl; reflexivity.
Grab Existential Variables.
simpl in βˆ—.
repeat match goal with | [ ⊒ appcontext[(?π‘₯ 2 ) 1 ] ] β‡’ generalize (π‘₯ 2 ); intro end.
rewrite ?composition_of.
repeat try_associativity_quick (idtac; match goal with | [ ⊒ appcontext[?π‘₯ 1 ] ] β‡’ simpl rewrite π‘₯ 2 end).
rewrite ?left_identity, ?right_identity, ?associativity.
reflexivity.
Qed.
Size of goal (after first simpl): 7312 words
Size of proof term: 66 264 words
Total time in file: 39 s
8s
2s
2.5 s
0.5 s
3.5 s
0.3 s
20 s
61
Proof assistant performance (fixes)
Concrete Example (New Version)
Local Notation mor_of π‘Œ0 π‘Œ1 𝑓:=
(let πœ‚π‘Œ1 := IsInitialMorphism_morphism (@HM π‘Œ1 ) in
IsInitialMorphism_property_morphism (@HM π‘Œ0) _ (πœ‚π‘Œ1 ∘ 𝑓)) (only parsing).
Lemma composition_of π‘₯ 𝑦 𝑧 𝑔 𝑓: mor_of _ _ (𝑓 ∘ 𝑔) = mor_of 𝑦 𝑧 𝑓 ∘ mor_of π‘₯ 𝑦 𝑔.
Proof.
simpl.
erewrite IsInitialMorphism_property_morphism_unique; [ reflexivity | ].
rewrite ?composition_of.
repeat try_associativity_quick rewrite IsInitialMorphism_property_morphism_property.
reflexivity.
Qed.
0.08 s
(was 10 s)
0.08 s
(was 0.5 s)
0.5 s
(was 3.5 s)
0.5 s
(was 3.5 s)
Size of goal (after first simpl): 191 words (was 7312)
Size of proof term: 3 632 words (was 66 264)
62
Total time in file: 3 s (was 39 s)
Proof assistant performance (fixes)
Concrete Example (Old Interface)
Definition IsInitialMorphism_object (𝑀 : IsInitialMorphism π΄πœ‘) : 𝐷 := CommaCategory.b π΄πœ‘.
Definition IsInitialMorphism_morphism (𝑀 : IsInitialMorphism π΄πœ‘) : morphism 𝐢 𝑋 (π‘ˆ 0 (IsInitialMorphism_object 𝑀)) := CommaCategory.f π΄πœ‘.
Definition IsInitialMorphism_property (𝑀 : IsInitialMorphism π΄πœ‘) (π‘Œ : 𝐷) (𝑓 : morphism 𝐢 𝑋 (π‘ˆ 0 π‘Œ))
: Contr { π‘š : morphism 𝐷 (IsInitialMorphism_object 𝑀) π‘Œ | π‘ˆ 1 π‘š ∘ (IsInitialMorphism_morphism 𝑀) = 𝑓 }.
Proof.
(βˆ—βˆ— We could just [rewrite right_identity], but we want to preserve judgemental computation rules. βˆ—)
pose proof (@trunc_equivβ€² _ _ (symmetry _ _ (@CommaCategory.issig_morphism _ _ _ !𝑋 π‘ˆ _ _)) -2 (𝑀 (CommaCategory.Build_object !𝑋 π‘ˆ tt π‘Œ 𝑓))) as 𝐻′.
simpl in 𝐻′.
apply contr_inhabited_hprop.
- abstract (
apply @trunc_succ in 𝐻′;
eapply @trunc_equivβ€²; [ | exact 𝐻′ ];
match goal with
| [ ⊒ appcontext[?π‘š ∘ 𝕀] ] β‡’ simpl rewrite (right_identity _ _ _ π‘š)
| [ ⊒ appcontext[𝕀 ∘ ?π‘š] ] β‡’ simpl rewrite (left_identity _ _ _ π‘š)
end;
simpl; unfold IsInitialMorphism_object, IsInitialMorphism_morphism;
let 𝐴 := match goal with ⊒ Equiv ?𝐴 ?𝐡 β‡’ constr:(𝐴) end in
let 𝐡 := match goal with ⊒ Equiv ?𝐴 ?𝐡 β‡’ constr:(𝐡) end in
apply (equiv_adjointify (πœ† π‘₯ : 𝐴 β‡’ π‘₯ 2) (πœ† π‘₯ : 𝐡 β‡’ (tt; π‘₯)));
[ intro; reflexivity | intros [[]]; reflexivity ]
).
- (exists ((@center _ 𝐻′) 2) 1).
abstract (etransitivity; [ apply ((@center _ 𝐻′) 2) 2 | auto with morphism ]).
Defined.
3s
1s
Total file time: 7 s
63
Proof assistant performance (fixes)
Concrete Example (New Interface)
Definition IsInitialMorphism_object (𝑀 : IsInitialMorphism π΄πœ‘) : 𝐷 := CommaCategory.b π΄πœ‘.
Definition IsInitialMorphism_morphism (𝑀 : IsInitialMorphism π΄πœ‘) : morphism 𝐢 𝑋 (π‘ˆ 0 (IsInitialMorphism_object 𝑀)) := CommaCategory.f π΄πœ‘.
Definition IsInitialMorphism_property_morphism (𝑀 : IsInitialMorphism π΄πœ‘) (π‘Œ : 𝐷) (f : morphism 𝐢 𝑋 (π‘ˆ 0 π‘Œ)) : morphism 𝐷 (IsInitialMorphism_object 𝑀) π‘Œ
:= CommaCategory.h (@center _ (𝑀 (CommaCategory.Build_object !𝑋 π‘ˆ tt π‘Œ 𝑓))).
Definition IsInitialMorphism_property_morphism_property (𝑀 : IsInitialMorphism π΄πœ‘) (π‘Œ : 𝐷) (𝑓 : morphism 𝐢 𝑋 (π‘ˆ 0 π‘Œ))
: π‘ˆ 1 (IsInitialMorphism_property_morphism 𝑀 π‘Œ 𝑓) ∘ (IsInitialMorphism_morphism 𝑀) = 𝑓
:= CommaCategory.p (@center _ (𝑀 (CommaCategory.Build_object !𝑋 π‘ˆ tt π‘Œ 𝑓))) @ right_identity _ _ _ _.
Definition IsInitialMorphism_property_morphism_unique (𝑀 : IsInitialMorphism π΄πœ‘) (π‘Œ : 𝐷) (f : morphism 𝐢 𝑋 (π‘ˆ 0 π‘Œ)) π‘šβ€² (𝐻 : π‘ˆ 1 π‘šβ€™ ∘ IsInitialMorphism_morphism 𝑀 = 𝑓)
: IsInitialMorphism_property_morphism 𝑀 π‘Œ 𝑓 = π‘šβ€²
:= ap (@CommaCategory.h _ _ _ _ _ _ _)
(@contr _ (𝑀 (CommaCategory.Build_object !𝑋 π‘ˆ tt π‘Œ 𝑓)) (CommaCategory.Build_morphism π΄πœ‘ (CommaCategory.Build_object !𝑋 π‘ˆ tt π‘Œ 𝑓) tt π‘šβ€² (𝐻 @ (right_identity _ _ _ _) βˆ’1))).
Definition IsInitialMorphism_property (𝑀 : IsInitialMorphism π΄πœ‘) (π‘Œ : 𝐷) (f : morphism 𝐢 𝑋 (π‘ˆ 0 π‘Œ))
: Contr { π‘š : morphism 𝐷 (IsInitialMorphism_object 𝑀) π‘Œ | π‘ˆ 1 π‘š ∘ (IsInitialMorphism_morphism 𝑀) = 𝑓 }.
:= {| center := (IsInitialMorphism_property_morphism 𝑀 π‘Œ 𝑓; IsInitialMorphism_property_morphism_property 𝑀 π‘Œ 𝑓);
contr π‘šβ€² := path_sigma _ (IsInitialMorphism_property_morphism 𝑀 π‘Œ 𝑓; IsInitialMorphism_property_morphism_property 𝑀 π‘Œ 𝑓)
π‘šβ€² (@ IsInitialMorphism_property_morphism_unique 𝑀 π‘Œ 𝑓 π‘šβ€² 1 π‘šβ€² 2) (center _) |}.
0.4 s
Total file time: 7 s
64
Proof assistant performance (fixes)
Concrete Example 2 (Generalization)
Lemma pseudofunctor_to_cat_assoc_helper {π‘₯ π‘₯0 : 𝐢} {π‘₯2 : morphism 𝐢 x x0} {x1 : 𝐢}
{π‘₯5 : morphism 𝐢 π‘₯0 π‘₯1 } {π‘₯4 : 𝐢} {π‘₯7 : morphism 𝐢 π‘₯1 π‘₯4 }
{𝑝 𝑝0 : PreCategory} {𝑓 : morphism 𝐢 π‘₯ π‘₯4 β†’ Functor 𝑝0 𝑝}
{𝑝1 𝑝2 : PreCategory} {𝑓0 : Functor 𝑝2 𝑝} {𝑓1 : Functor 𝑝1 𝑝2 } {𝑓2 : Functor 𝑝0 𝑝2 } {𝑓3 : Functor 𝑝0 𝑝1 } {𝑓4 : Functor 𝑝1 𝑝}
{π‘₯16 : morphism (_ β†’ _) (𝑓 (π‘₯7 ∘ π‘₯5 ∘ π‘₯2 )) (𝑓4 ∘ 𝑓3 )%functor}
{π‘₯15 : morphism (_ β†’ _) 𝑓2 (𝑓1 ∘ 𝑓3 )%functor} {𝐻2 : IsIsomorphism π‘₯15 }
{π‘₯11 : morphism (_ β†’ _) (𝑓 (π‘₯7 ∘ (π‘₯5 ∘ π‘₯2 ))) (𝑓0 ∘ 𝑓2 )%functor}
{𝐻1 : IsIsomorphism π‘₯11 } {π‘₯9 : morphism (_ β†’ _) 𝑓4 (𝑓0 ∘ 𝑓1 )%functor} {fst_hyp : π‘₯7 ∘ π‘₯5 ∘ π‘₯2 = π‘₯7 ∘ (π‘₯5 ∘ π‘₯2 )}
(rew_hyp : βˆ€ π‘₯3 : 𝑝0 ,
(idtoiso (𝑝0 β†’ 𝑝) (ap 𝑓 fst_hyp) : morphism_ _ _) π‘₯3 = π‘₯11 βˆ’1 π‘₯3 ∘ (𝑓0 1 (π‘₯15 βˆ’1 π‘₯3 ) ∘ (𝕀 ∘ (π‘₯9 (𝑓3 π‘₯3 ) ∘ π‘₯16 π‘₯3 ))))
{𝐻0β€² : IsIsomorphism π‘₯16 } {𝐻1β€² : IsIsomorphism π‘₯9 } {π‘₯13 : 𝑝} {π‘₯3 : 𝑝0 } {π‘₯6 : 𝑝1 } {π‘₯10 : 𝑝2 }
{π‘₯14 : morphism 𝑝 (𝑓0 π‘₯10 ) π‘₯13 } {π‘₯12 : morphism 𝑝2 (𝑓1 π‘₯6 ) π‘₯10 } {π‘₯8 : morphism 𝑝1 (𝑓3 π‘₯3 ) π‘₯6 }
: existT (πœ† 𝑓5 : morphism 𝐢 π‘₯ π‘₯4 β‡’ morphism 𝑝 ((𝑓 𝑓5 ) π‘₯3 ) π‘₯13 )
(π‘₯7 ∘ π‘₯5 ∘ π‘₯2 )
(π‘₯14 ∘ (𝑓0 1 π‘₯12 ∘ π‘₯9 π‘₯6 ) ∘ (𝑓4 1 π‘₯8 ∘ π‘₯16 π‘₯3 )) = (π‘₯7 ∘ (π‘₯5 ∘ π‘₯2 ); π‘₯14 ∘ (𝑓0 1 (π‘₯12 ∘ (𝑓1 1 π‘₯8 ∘ π‘₯15 π‘₯3 )) ∘ π‘₯11 π‘₯3 )).
Proof.
helper_t assoc_before_commutes_tac.
assoc_fin_tac.
Qed.
Speedup: 10x for the file, from 4m 53s to 28 s
Time spent: a few hours
65
Outline
β€’ Why should we care about performance?
β€’ Overview of the HoTT/HoTT library
β€’ What makes theorem provers (mainly Coq) slow?
β€’ Examples of particular slowness
β€’ For users (workarounds)
β€’ Arguments vs. fields and packed records
β€’ Abstraction barriers
β€’ For developers (features)
β€’ Primitive projections
66
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
Better Proof Assistants
67
Outline
β€’ Why should we care about performance?
β€’ Overview of the HoTT/HoTT library
β€’ What makes theorem provers (mainly Coq) slow?
β€’ Examples of particular slowness
β€’ For users (workarounds)
β€’ Arguments vs. fields and packed records
β€’ Abstraction barriers
β€’ For developers (features)
β€’ Primitive projections
68
Dam image from http://www.flickr.com/photos/gammaman/7803829282/ by Eli Christman, CC by 2.0
Proof assistant performance (fixes)
β€’ How?
β€’ Primitive projections
69
Proof assistant performance (fixes)
β€’ How?
β€’ Primitive projections
Definition 2-Graph :=
{V
: Type &
{ 1E
: V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }.
Definition V (G : 2-Graph) := pr1 (pr1 G).
Definition 1E (G : 2-Graph) := pr1 (pr2 G).
Definition 2E (G : 2-Graph) := pr2 (pr2 G).
70
Proof assistant performance (fixes)
Definition 2-Graph :=
{V
: Type &
{ 1E
: V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }.
Definition V (G : 2-Graph) := pr1 (pr1 G).
Definition 1E (G : 2-Graph) := pr1 (pr2 G).
Definition 2E (G : 2-Graph) := pr2 (pr2 G).
71
Proof assistant performance (fixes)
Definition 2-Graph :=
{V
: Type &
{ 1E
: V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }.
Definition V (G : 2-Graph) :=
@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G.
72
Proof assistant performance (fixes)
Definition 2-Graph :=
{V
: Type &
{ 1E
: V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }.
Definition V (G : 2-Graph) := pr1 (pr1 G).
Definition 1E (G : 2-Graph) := pr1 (pr2 G).
Definition 2E (G : 2-Graph) := pr2 (pr2 G).
73
Proof assistant performance (fixes)
Definition 1E (G : 2-Graph) :=
@pr1
(@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
(@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
(Type)
(πœ† 1E : @pr1 Type (πœ† V : Type β‡’
{
1E : V β†’ V β†’ Type &
74
Proof assistant performance (fixes)
Definition 1E (G : 2-Graph) :=
@pr1
(@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
(@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
(Type)
(πœ† 1E : @pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
@pr1 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type })
G→
Type β‡’
βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type)
(@pr2 Type (πœ† V : Type β‡’
{ 1E : V β†’ V β†’ Type &
: βˆ€ 𝑣1 𝑣2 , 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }
G)
75
Proof assistant performance (fixes)
Definition 1E (G : 2-Graph) :=
@pr1
(@pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
(@pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
(Type)
(πœ† 1E : @pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
@pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
Type β‡’
βˆ€(𝑣1 : @pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G)
(𝑣2 : @pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G),
1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type)
(@pr2 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G)
:@pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
@pr1 Type (πœ† V : Type β‡’ { 1E : V β†’ V β†’ Type & βˆ€ (𝑣1 : V) (𝑣2 : V), 1E 𝑣1 𝑣2 β†’ 1E 𝑣1 𝑣2 β†’ Type }) G β†’
Type
Recall: Original was:
Definition 1E (G : 2-Graph) := pr1 (pr2 G).
76
Proof assistant performance (fixes)
β€’ How?
β€’ Primitive projections
β€’ They eliminate the unnecessary arguments to projections,
cutting down the work Coq has to do.
77
Take-away messages
β€’ Performance matters
(even in proof assistants)
β€’ Term size matters for performance
β€’ Performance can be improved by
β€’ careful engineering of developments
β€’ improving the proof assistant
or the metatheory
78
The presentation will be available at
http://people.csail.mit.edu/jgross/#hott-hott-and-category-coqexperience
An extended version is available at
http://people.csail.mit.edu/jgross/#category-coq-experience
The library is available at
https://github.com/HoTT/HoTT
79