99 of theorems. The order of these files is important.)
1010
1111"""
12+
1213from typing import Dict , Mapping , Optional , Union , Tuple , List
1314from dataclasses import dataclass
1415import yaml
1516import json
1617import sys
1718
18- TieredDict = Dict [str , Union [Optional [str ], 'TieredDict' ]]
19+ TieredDict = Dict [str , Union [Optional [str ], "TieredDict" ]]
20+
1921
2022def tiered_extract (db : TieredDict ) -> List [Tuple [List [str ], str ]]:
21- """From a nested dictionary, return a list of (key_path, values)
22- of the deepest level."""
23- out = []
24- for name , entry in db .items ():
25- if isinstance (entry , dict ):
26- for subname , value in tiered_extract (entry ):
27- out .append (([name ] + subname , value ))
28- else :
29- if entry and '/' not in entry :
30- out .append (([name ], entry ))
31- return out
23+ """From a nested dictionary, return a list of (key_path, values)
24+ of the deepest level."""
25+ out = []
26+ for name , entry in db .items ():
27+ if isinstance (entry , dict ):
28+ for subname , value in tiered_extract (entry ):
29+ out .append (([name ] + subname , value ))
30+ else :
31+ if entry and "/" not in entry :
32+ out .append (([name ], entry ))
33+ return out
34+
3235
3336def flatten_names (data : List [Tuple [List [str ], str ]]) -> List [Tuple [str , str ]]:
34- return [(' :: ' .join (id ), v ) for id , v in data ]
37+ return [(" :: " .join (id ), v ) for id , v in data ]
3538
36- def print_list (fn : str , pairs : List [Tuple [str , str ]]) -> None :
37- with open (fn , 'w' , encoding = 'utf8' ) as out :
38- for (id , val ) in pairs :
39- out .write (f'{ id } \n { val .strip ()} \n \n ' )
4039
40+ def print_list (fn : str , pairs : List [Tuple [str , str ]]) -> None :
41+ with open (fn , "w" , encoding = "utf8" ) as out :
42+ for id , val in pairs :
43+ out .write (f"{ id } \n { val .strip ()} \n \n " )
4144
4245
4346# keep in sync with make_site.py in the leanprover-community.github.io repo
@@ -59,6 +62,7 @@ class HundredTheorem:
5962 links : Optional [Mapping [str , str ]] = None
6063 note : Optional [str ] = None
6164
65+
6266# keep in sync with make_site.py in the leanprover-community.github.io repo!
6367# These field names match the names in the data files of the 1000+ theorems project upstream.
6468# See https://github.com/1000-plus/1000-plus.github.io/blob/main/README.md#file-format
@@ -87,67 +91,74 @@ class ThousandPlusTheorem:
8791 # any additional notes or comments
8892 comment : Optional [str ] = None
8993
94+
9095hundred_yaml = sys .argv [1 ]
9196thousand_yaml = sys .argv [2 ]
9297overview_yaml = sys .argv [3 ]
9398undergrad_yaml = sys .argv [4 ]
9499
95- with open (hundred_yaml , 'r' , encoding = ' utf8' ) as hy :
96- hundred = yaml .safe_load (hy )
97- with open (thousand_yaml , 'r' , encoding = ' utf8' ) as hy :
98- thousand = yaml .safe_load (hy )
99- with open (overview_yaml , 'r' , encoding = ' utf8' ) as hy :
100- overview = yaml .safe_load (hy )
101- with open (undergrad_yaml , 'r' , encoding = ' utf8' ) as hy :
102- undergrad = yaml .safe_load (hy )
100+ with open (hundred_yaml , "r" , encoding = " utf8" ) as hy :
101+ hundred = yaml .safe_load (hy )
102+ with open (thousand_yaml , "r" , encoding = " utf8" ) as hy :
103+ thousand = yaml .safe_load (hy )
104+ with open (overview_yaml , "r" , encoding = " utf8" ) as hy :
105+ overview = yaml .safe_load (hy )
106+ with open (undergrad_yaml , "r" , encoding = " utf8" ) as hy :
107+ undergrad = yaml .safe_load (hy )
103108
104109hundred_decls : List [Tuple [str , str ]] = []
105110
106111errors = 0
107112for index , entry in hundred .items ():
108- # Check that the YAML fits the dataclass used in the website.
109- try :
110- _thm = HundredTheorem (index , ** entry )
111- except TypeError as e :
112- print (f"error: entry for theorem { index } is invalid: { e } " )
113- errors += 1
114- # Also verify that the |decl| and |decls| fields are not *both* provided.
115- if _thm .decl and _thm .decls :
116- print (f"warning: entry for theorem { index } has both a decl and a decls field; "
117- "please only provide one of these" , file = sys .stderr )
118- errors += 1
119-
120- title = entry ['title' ]
121- if 'decl' in entry :
122- hundred_decls .append ((f'{ index } { title } ' , entry ['decl' ]))
123- elif 'decls' in entry :
124- if not isinstance (entry ['decls' ], list ):
125- print (f"For key { index } ({ title } ): did you mean `decl` instead of `decls`?" )
126- errors += 1
127- hundred_decls = hundred_decls + [(f'{ index } { title } ' , d ) for d in entry ['decls' ]]
113+ # Check that the YAML fits the dataclass used in the website.
114+ try :
115+ _thm = HundredTheorem (index , ** entry )
116+ except TypeError as e :
117+ print (f"error: entry for theorem { index } is invalid: { e } " )
118+ errors += 1
119+ # Also verify that the |decl| and |decls| fields are not *both* provided.
120+ if _thm .decl and _thm .decls :
121+ print (
122+ f"warning: entry for theorem { index } has both a decl and a decls field; "
123+ "please only provide one of these" ,
124+ file = sys .stderr ,
125+ )
126+ errors += 1
127+
128+ title = entry ["title" ]
129+ if "decl" in entry :
130+ hundred_decls .append ((f"{ index } { title } " , entry ["decl" ]))
131+ elif "decls" in entry :
132+ if not isinstance (entry ["decls" ], list ):
133+ print (f"For key { index } ({ title } ): did you mean `decl` instead of `decls`?" )
134+ errors += 1
135+ hundred_decls = hundred_decls + [(f"{ index } { title } " , d ) for d in entry ["decls" ]]
128136
129137thousand_decls : List [Tuple [str , str ]] = []
130138for index , entry in thousand .items ():
131- # Check that the YAML fits the dataclass used in the website.
132- try :
133- _thm = ThousandPlusTheorem (index , ** entry )
134- except TypeError as e :
135- print (f"error: entry for theorem { index } is invalid: { e } " )
136- errors += 1
137- # Also verify that the |decl| and |decls| fields are not *both* provided.
138- if _thm .decl and _thm .decls :
139- print (f"warning: entry for theorem { index } has both a decl and a decls field; "
140- "please only provide one of these" , file = sys .stderr )
141- errors += 1
142-
143- title = entry ['title' ]
144- if 'decl' in entry :
145- thousand_decls .append ((f'{ index } { title } ' , entry ['decl' ]))
146- elif 'decls' in entry :
147- if not isinstance (entry ['decls' ], list ):
148- print (f"For key { index } ({ title } ): did you mean `decl` instead of `decls`?" )
149- errors += 1
150- thousand_decls = thousand_decls + [(f'{ index } { title } ' , d ) for d in entry ['decls' ]]
139+ # Check that the YAML fits the dataclass used in the website.
140+ try :
141+ _thm = ThousandPlusTheorem (index , ** entry )
142+ except TypeError as e :
143+ print (f"error: entry for theorem { index } is invalid: { e } " )
144+ errors += 1
145+ # Also verify that the |decl| and |decls| fields are not *both* provided.
146+ if _thm .decl and _thm .decls :
147+ print (
148+ f"warning: entry for theorem { index } has both a decl and a decls field; "
149+ "please only provide one of these" ,
150+ file = sys .stderr ,
151+ )
152+ errors += 1
153+
154+ title = entry ["title" ]
155+ if "decl" in entry :
156+ thousand_decls .append ((f"{ index } { title } " , entry ["decl" ]))
157+ elif "decls" in entry :
158+ if not isinstance (entry ["decls" ], list ):
159+ print (f"For key { index } ({ title } ): did you mean `decl` instead of `decls`?" )
160+ errors += 1
161+ thousand_decls = thousand_decls + [(f"{ index } { title } " , d ) for d in entry ["decls" ]]
151162
152163overview_decls = tiered_extract (overview )
153164assert all (len (n ) == 3 for n , _ in overview_decls )
@@ -157,15 +168,15 @@ class ThousandPlusTheorem:
157168assert all (len (n ) >= 3 for n , _ in undergrad_decls )
158169undergrad_decls = flatten_names (undergrad_decls )
159170
160- with open (' 100.json' , 'w' , encoding = ' utf8' ) as f :
161- json .dump (hundred_decls , f )
162- with open (' 1000.json' , 'w' , encoding = ' utf8' ) as f :
163- json .dump (thousand_decls , f )
164- with open (' overview.json' , 'w' , encoding = ' utf8' ) as f :
165- json .dump (overview_decls , f )
166- with open (' undergrad.json' , 'w' , encoding = ' utf8' ) as f :
167- json .dump (undergrad_decls , f )
171+ with open (" 100.json" , "w" , encoding = " utf8" ) as f :
172+ json .dump (hundred_decls , f )
173+ with open (" 1000.json" , "w" , encoding = " utf8" ) as f :
174+ json .dump (thousand_decls , f )
175+ with open (" overview.json" , "w" , encoding = " utf8" ) as f :
176+ json .dump (overview_decls , f )
177+ with open (" undergrad.json" , "w" , encoding = " utf8" ) as f :
178+ json .dump (undergrad_decls , f )
168179
169180if errors :
170- # Return an error code of at most 125 so this return value can be used further in shell scripts.
171- sys .exit (min (errors , 125 ))
181+ # Return an error code of at most 125 so this return value can be used further in shell scripts.
182+ sys .exit (min (errors , 125 ))
0 commit comments