Skip to content

Commit e674589

Browse files
feat: well-founded recursion (#250)
Closes #57 --------- Co-authored-by: David Thrane Christiansen <[email protected]>
1 parent 58e8015 commit e674589

File tree

15 files changed

+860
-32
lines changed

15 files changed

+860
-32
lines changed

.vale/styles/config/ignore/terms.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,4 @@ uninstantiated
151151
unparenthesized
152152
upvote
153153
walkthrough
154+
Ackermann

Manual.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Manual.Intro
99
import Manual.Elaboration
1010
import Manual.Types
1111
import Manual.Language
12+
import Manual.RecursiveDefs
1213
import Manual.Classes
1314
import Manual.Terms
1415
import Manual.Tactics
@@ -62,6 +63,8 @@ Additionally, we will be adding missing API reference documentation and revising
6263

6364
{include 0 Manual.Language}
6465

66+
{include 0 Manual.RecursiveDefs}
67+
6568
{include 0 Manual.Terms}
6669

6770
{include 0 Manual.Classes}
@@ -275,6 +278,7 @@ Quot
275278
Setoid
276279
Squash
277280
Subsingleton
281+
WellFoundedRelation
278282
```
279283

280284
```exceptions

Manual/Language.lean

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import VersoManual
88

99
import Manual.Meta
1010
import Manual.Language.Files
11-
import Manual.Language.RecursiveDefs
1211

1312
import Lean.Parser.Command
1413

@@ -580,9 +579,6 @@ scoped
580579
Describe {deftech}_axioms_ in detail
581580
:::
582581

583-
{include 0 Manual.Language.RecursiveDefs}
584-
585-
586582
# Attributes
587583
%%%
588584
tag := "attributes"

Manual/Meta/Bibliography.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def Citable.bibHtml (go : Doc.Inline Genre.Manual → HtmlT Manual (ReaderT Exte
146146
match c with
147147
| .inProceedings p =>
148148
let authors ← andList <$> p.authors.mapM go
149-
return {{ {{authors}} s!", {p.year}. " {{ link {{"“" {{← go p.title}} "”"}} }} ". In " <em>{{← go p.booktitle}}"."</em>{{(← p.series.mapM go).map ({{"(" {{·}} ")" }}) |>.getD .empty}} }}
149+
return {{ {{authors}} s!", {p.year}. " {{ link {{"“" {{← go p.title}} "”"}} }} ". In " <em>{{← go p.booktitle}}"."</em>{{(← p.series.mapM go).map ({{" (" {{·}} ")" }}) |>.getD .empty}} }}
150150
| .thesis p =>
151151
return {{ {{← go p.author}} s!", {p.year}. " <em>{{link (← go p.title)}}</em> ". " {{← go p.degree}} ", " {{← go p.university}} }}
152152
| .arXiv p =>

Manual/Meta/Example.lean

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,12 @@ r#".example {
113113
border-radius: 0.5em;
114114
margin-bottom: 0.75em;
115115
margin-top: 0.75em;
116-
clear: both; /* Don't overlap margin notes with examples */
116+
}
117+
/* 1400 px is the cutoff for when the margin notes move out of the margin and into floated elements. */
118+
@media screen and (700px < width <= 1400px) {
119+
.example {
120+
clear: both; /* Don't overlap margin notes with examples */
121+
}
117122
}
118123
.example p:last-child {margin-bottom:0;}
119124
.example .description::before {

Manual/Papers.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,19 @@ def launchbury94 : InProceedings where
5454
authors := #[.concat (inlines! "John Launchbury"), .concat (inlines!"Simon L Peyton Jones")]
5555
year := 1994
5656
booktitle := .concat (inlines!"Proceedings of the ACM SIGPLAN 1994 Conference on Programming Language Design and Implementation")
57+
58+
def manolios2006 : InProceedings where
59+
title := .concat (inlines!"Termination Analysis with Calling Context Graphs")
60+
authors := #[.concat (inlines!"Panagiotis Manolios"), .concat (inlines!"Daron Vroon")]
61+
year := 2006
62+
booktitle := .concat (inlines!"Proceedings of the International Conference on Computer Aided Verification (CAV 2006)")
63+
series := some <| .concat (inlines!"LNCS 4144")
64+
url := "https://doi.org/10.1007/11817963_36"
65+
66+
def bulwahn2007 : InProceedings where
67+
title := .concat (inlines!"Finding Lexicographic Orders for Termination Proofs in Isabelle/HOL")
68+
authors := #[.concat (inlines!"Lukas Bulwahn"), .concat (inlines!"Alexander Krauss"), .concat (inlines!"Tobias Nipkow")]
69+
year := 2007
70+
booktitle := .concat (inlines!"Proceedings of the International Conference on Theorem Proving in Higher Order Logics (TPHOLS 2007)")
71+
series := some <| .concat (inlines!"LNTCS 4732")
72+
url := "https://doi.org/10.1007/978-3-540-74591-4_5"

Manual/Language/RecursiveDefs.lean renamed to Manual/RecursiveDefs.lean

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import VersoManual
88

99
import Manual.Meta
1010

11-
import Manual.Language.RecursiveDefs.Structural
11+
import Manual.RecursiveDefs.Structural
12+
import Manual.RecursiveDefs.WF
1213

1314
open Verso.Genre Manual
1415
open Lean.Elab.Tactic.GuardMsgs.WhitespaceMode
@@ -151,16 +152,9 @@ Thus, helpers defined in a {keywordOf Lean.Parser.Command.declaration}`where` bl
151152

152153
After the first step of elaboration, in which definitions are still recursive, and before translating recursion using the techniques above, Lean identifies the actually (mutually) recursive cliques{TODO}[define this term, it's useful] among the definitions in the mutual block and processes them separately and in dependency order.
153154

154-
{include 0 Manual.Language.RecursiveDefs.Structural}
155+
{include 0 Manual.RecursiveDefs.Structural}
155156

156-
# Well-Founded Recursion
157-
%%%
158-
tag := "well-founded-recursion"
159-
%%%
160-
161-
::: planned 57
162-
This section will describe the translation of {deftech}[well-founded recursion].
163-
:::
157+
{include 0 Manual.RecursiveDefs.WF}
164158

165159
# Partial and Unsafe Recursive Definitions
166160
%%%

Manual/Language/RecursiveDefs/Structural.lean renamed to Manual/RecursiveDefs/Structural.lean

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/-
22
Copyright (c) 2024 Lean FRO LLC. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Author: David Thrane Christiansen
4+
Author: David Thrane Christiansen, Joachim Breitner
55
-/
66

77
import VersoManual
8-
import Manual.Language.RecursiveDefs.Structural.RecursorExample
9-
import Manual.Language.RecursiveDefs.Structural.CourseOfValuesExample
8+
import Manual.RecursiveDefs.Structural.RecursorExample
9+
import Manual.RecursiveDefs.Structural.CourseOfValuesExample
1010

1111
import Manual.Meta
1212

@@ -481,6 +481,10 @@ Describe mutual structural recursion over {ref "nested-inductive-types"}[nested
481481

482482

483483
# Inferring Structural Recursion
484+
%%%
485+
tag := "inferring-structural-recursion"
486+
%%%
487+
484488

485489
If no {keyword}`termination_by` clauses are present in a recursive or mutually recursive function definition, then Lean attempts to infer a suitable structurally decreasing argument, effectively by trying all suitable parameters in sequence.
486490
If this search fails, Lean then attempts to infer {tech}[well-founded recursion].
@@ -511,13 +515,13 @@ Try this: termination_by structural x => x
511515
In this section, the construction used to elaborate structurally recursive functions is explained in more detail.
512516
This elaboration uses the {ref "recursor-elaboration-helpers"}[`below` and `brecOn` constructions] that are automatically generated from inductive types' recursors.
513517

514-
{spliceContents Manual.Language.RecursiveDefs.Structural.RecursorExample}
518+
{spliceContents Manual.RecursiveDefs.Structural.RecursorExample}
515519

516520
The structural recursion analysis attempts to translate the recursive pre-definition into a use of the appropriate structural recursion constructions.
517521
At this step, pattern matching has already been translated into the use of matcher functions; these are treated specially by the termination checker.
518522
Next, for each group of parameters, a translation using `brecOn` is attempted.
519523

520-
{spliceContents Manual.Language.RecursiveDefs.Structural.CourseOfValuesExample}
524+
{spliceContents Manual.RecursiveDefs.Structural.CourseOfValuesExample}
521525

522526
The `below` construction is a mapping from each value of a type to the results of some function call on _all_ smaller values; it can be understood as a memoization table that already contains the results for all smaller values.
523527
The notion of “smaller value” that is expressed in the `below` construction corresponds directly to the definition of {tech}[strict sub-terms].

0 commit comments

Comments
 (0)