Table Of ContentHERMIT: Mechanized Reasoning during Compilation in the
Glasgow Haskell Compiler
By
Andrew Farmer
SubmittedtothegraduatedegreeprograminElectricalEngineeringandComputerScienceand
theGraduateFacultyoftheUniversityofKansasinpartialfulfillmentoftherequirementsforthe
degreeofDoctorofPhilosophy.
ChairpersonDr. AndyGill
Dr. PerryAlexander
Dr. PrasadKulkarni
Dr. JamesMiller
Dr. ChristopherDepcik
DateDefended: April30,2015
TheDissertationCommitteeforAndrewFarmer
certifiesthatthisistheapprovedversionofthefollowingdissertation:
HERMIT:MechanizedReasoningduringCompilationintheGlasgowHaskellCompiler
ChairpersonDr. AndyGill
Dateapproved:
ii
Abstract
It is difficult to write programs which are both correct and fast. A promising approach, functional
programming, is based on the idea of using pure, mathematical functions to construct programs.
With effort, it is possible to establish a connection between a specification written in a functional
language,whichhasbeenprovencorrect,andafastimplementation,viaprogramtransformation.
When practiced in the functional programming community, this style of reasoning is still typ-
ically performed by hand, by either modifying the source code or using pen-and-paper. Unfortu-
nately,performingsuchsemi-formalreasoningbydirectlymodifyingthesourcecodeoftenobfus-
cates the program, and pen-and-paper reasoning becomes outdated as the program changes over
time. Even so, this semi-formal reasoning prevails because formal reasoning is time-consuming,
and requires considerable expertise. Formal reasoning tools often only work for a subset of the
targetlanguage,orrequireprogramstobeimplementedinacustomlanguageforreasoning.
This dissertation investigates a solution, called HERMIT, which mechanizes reasoning during
compilation. HERMIT can be used to prove properties about programs written in the Haskell
functional programming language, or transform them to improve their performance. Reasoning
in HERMIT proceeds in a style familiar to practitioners of pen-and-paper reasoning, and mech-
anization allows these techniques to be applied to real-world programs with greater confidence.
HERMIT can also re-check recorded reasoning steps on subsequent compilations, enforcing a
connectionwiththeprogramastheprogramisdeveloped.
HERMITisthefirstsystemcapableofdirectlyreasoningaboutthefullHaskelllanguage. The
designandimplementationofHERMIT,motivatedbothbytypicalreasoningtasksandHERMIT’s
place in the Haskell ecosystem, is presented in detail. Three case studies investigate HERMIT’s
capability to reason in practice. These case studies demonstrate that semi-formal reasoning with
HERMITlowersthebarriertowritingprogramswhicharebothcorrectandfast.
iii
Acknowledgements
Ireadsomewhere,once,thatadissertationtakesavillage. Thatiscertainlytrueinmyexperience.
Iamindebtedtoagreatmanypeople,bothprofessionallyandpersonally,overthelastsix(!) years.
Foremost, I would like to thank my advisor, Andy Gill, for providing me many opportunities
I did not even realize existed, and for tolerating my occasional divergences. I have learned an
incredible amount in my time as his student, and have always valued his guidance and support. I
definitelyowehimanon-trivialamountofbeer.
IwasfortunatetohaveNeilSculthorpeasacollaboratorformuchofHERMIT’sdevelopment.
I learned a lot from Neil, especially in regards to writing about research. Without his excellent
work,bothonKUREandHERMITitself,HERMITwouldnotexistasitdoes.
Thanks also to HERMIT’s first users: Michael Adams, Conal Elliott, and Paul Liu. Their
feedback was invaluable, and they were kind enough to put up with HERMIT’s ever-changing
APIs breaking their code. Thanks to Jim Hook for hosting me for a semester at Portland State
and enabling my collaboration with Michael Adams. To my peers and mentors, past and present,
in the CSDL lab (and elsewhere): Perry, Prasad, Garrin, Ed, Nick, Mark, Evan, Wes, Megan,
Brigid, Mike J, Nathan, Pedro, Laurence, Brent, Richard, Kevin, Tristan, Mike S, Justin, Jason,
Ryan, Bowe, and Brad. I learned something from each of you, and appreciate having been able to
work with you all at some point. Also thanks to the National Science Foundation, which partially
supportedHERMITundergrantsCCF-1117569andDGE-0742523.
I could not have accomplished a great many things in life without the support of my parents,
who are some of the most selfless people I know. Thanks Mom and Dad, for everything. Thanks
alsotomybrother,Ben,whoissomeoneIlookupto,bothliterallyandfiguratively. Tosomegreat
friends: Austin, Bob, Michael, John, Derick, Amy, Jys, Jess, Beth, and a great many others. To
Larryville, for all the shenanigans, punctuated with the occasional running. Finally, to Karen, for
putting up with my absentmindness, for making sure I ate something besides fast food, and for
cheeringmeupwhenIwasstressedout. Iloveyou.
iv
Contents
1 Introduction 1
1.1 Reasoning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 ProvingProperties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2 Domain-SpecificOptimizations . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.3 CalculationalProgramming . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Organization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2 TechnicalBackground 14
2.1 GHCPlugins. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2 GHCCore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.1 Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1.1 OccName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1.2 RdrName . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1.3 Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2.1.4 Var . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.2 Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.3 RULES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3 KURE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.1 Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
v
2.3.2 Monad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.3 MonadCatch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.4 Traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.4.1 Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.4.2 CongruenceCombinators . . . . . . . . . . . . . . . . . . . . . . 27
2.3.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3 HERMITArchitecture 32
3.1 Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.2 Kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3 PluginDSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3.1 ExamplePlugin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.3.2 PrettyPrinter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.4 Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.4.1 InterpretedCommandLanguage . . . . . . . . . . . . . . . . . . . . . . . . 42
3.4.2 Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.4.3 ExtendingHERMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.4.4 ProvingintheShell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.5 InvokingHERMIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4 Transformation 50
4.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2 KURE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.2.1 Universes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2.2 Crumbs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.2.3 TheHERMITContext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.2.3.1 RecordingBindings . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.2.3.2 AccessingBindings . . . . . . . . . . . . . . . . . . . . . . . . . 66
vi
4.2.3.3 In-scopeRULES . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2.3.4 Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2.4 CongruenceCombinators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.2.5 TheHERMITMonad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.2.6 Conventions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.3 Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.4 Folds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.4.1 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.4.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.4.2.1 Tries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.4.2.2 TrieMaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.4.2.3 α-equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.4.2.4 AddingHoles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.4.2.5 ImplementingFolds . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.4.3 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.5 Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.5.1 Fold/Unfold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.5.2 LocalTransformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.5.3 CreatingandFindingVariables . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.5.4 ConstructingExpressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.5.5 Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.5.6 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
4.5.7 CompositeTransformations . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
4.5.7.1 Simplify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
4.5.7.2 SmashandBash . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5 Proof 90
5.1 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
vii
5.2 Lemmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.3 Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
5.4 CreatingLemmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
5.5 PrimitiveOperations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.5.1 RedundantBinderElimination . . . . . . . . . . . . . . . . . . . . . . . . . 100
5.5.2 Instantiation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.6 LemmaUniverses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
5.7 Pre-conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
5.8 LemmaStrength . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
5.9 LemmaLibraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
5.10 LemmaDictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5.10.1 LemmasAsRewrites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5.10.2 Simplification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.10.3 Instantiation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
5.10.4 Strengthening . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.10.5 StructuralInduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.10.6 RememberedDefinitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6 CaseStudy: ProvingType-ClassLaws 114
6.1 Example: return-leftMonadLawforLists . . . . . . . . . . . . . . . . . . . . . . . 116
6.2 ConfiguringCabal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.3 ProvinginGHCCore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
6.3.1 Implications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
6.3.2 Newtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
6.3.3 MissingUnfoldings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
6.4 Reflections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
viii
7 CaseStudy: concatMap 124
7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
7.2 StreamFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
7.3 FusingNestedStreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
7.4 TransformingconcatMaptoflatten . . . . . . . . . . . . . . . . . . . . . . . . 132
7.4.1 Non-ConstantInnerStreams . . . . . . . . . . . . . . . . . . . . . . . . . . 133
7.4.2 MonadicStreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
7.5 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
7.5.1 MultipleInnerStreams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
7.5.2 ListComprehensions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
7.5.3 Call-PatternSpecialization . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
7.5.4 ThePlugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
7.6 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
7.6.1 Micro-benchmarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
7.6.2 NofibSuite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
7.6.3 PerformanceAdvantagesofconcatMap . . . . . . . . . . . . . . . . . . . 147
7.7 ADPfusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
7.8 ConclusionsandFutureWork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
8 CaseStudy: MakingaCentury 154
8.1 HERMITScripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
8.2 AssociativeOperators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
8.3 AssumedLemmasintheTextbook . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
8.4 ConstructiveCalculation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
8.5 CalculationSizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
8.6 Reflections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
ix
9 Applications 162
9.1 Worker/WrapperTransformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
9.2 OptimizingSYBisEasy! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
9.3 Haskell-to-Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
10 RelatedWork 170
10.1 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
10.2 AutomatedProof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
10.3 Semi-formalTools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
10.4 StreamFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
10.5 Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
11 Conclusion 177
11.1 Reflections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
11.2 FutureWork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
x
Description:and mech- anization allows these techniques to be applied to real-world programs with greater confidence. design and implementation of HERMIT, motivated both by typical reasoning tasks and HERMIT's place in the Haskell ecosystem, is presented in detail. hand, but with mechanical support.