itp-interface 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (485) hide show
  1. itp_interface/__init__.py +0 -0
  2. itp_interface/agent/__init__.py +0 -0
  3. itp_interface/agent/simple_proof_agent.py +100 -0
  4. itp_interface/coq_ser_api/__init__.py +165 -0
  5. itp_interface/coq_ser_api/contexts.py +283 -0
  6. itp_interface/coq_ser_api/coq_agent.py +459 -0
  7. itp_interface/coq_ser_api/coq_backend.py +135 -0
  8. itp_interface/coq_ser_api/coq_util.py +839 -0
  9. itp_interface/coq_ser_api/example.py +67 -0
  10. itp_interface/coq_ser_api/lsp_backend.py +375 -0
  11. itp_interface/coq_ser_api/py.typed +0 -0
  12. itp_interface/coq_ser_api/serapi_backend.py +841 -0
  13. itp_interface/coq_ser_api/util.py +145 -0
  14. itp_interface/coq_ser_api_old/__init__.py +2583 -0
  15. itp_interface/coq_ser_api_old/contexts.py +172 -0
  16. itp_interface/coq_ser_api_old/util.py +146 -0
  17. itp_interface/lean_server/__init__.py +0 -0
  18. itp_interface/lean_server/commands.py +484 -0
  19. itp_interface/lean_server/lean3_search_tool.py +358 -0
  20. itp_interface/lean_server/lean4_repl_interface.py +151 -0
  21. itp_interface/lean_server/lean4_utils.py +255 -0
  22. itp_interface/lean_server/lean_cmd_server.py +111 -0
  23. itp_interface/lean_server/lean_context.py +60 -0
  24. itp_interface/lean_server/lean_sync_server.py +174 -0
  25. itp_interface/lean_server/lean_utils.py +199 -0
  26. itp_interface/lean_server/py.typed +1 -0
  27. itp_interface/main/__init__.py +0 -0
  28. itp_interface/main/config/afp_data_gen.yaml +14 -0
  29. itp_interface/main/config/benchmark/CompCert.yaml +366 -0
  30. itp_interface/main/config/benchmark/GeoCoq.yaml +930 -0
  31. itp_interface/main/config/benchmark/UniMath.yaml +2690 -0
  32. itp_interface/main/config/benchmark/afp_isabelle.yaml +29200 -0
  33. itp_interface/main/config/benchmark/agent_proverbot_hard.yaml +247 -0
  34. itp_interface/main/config/benchmark/category-theory.yaml +470 -0
  35. itp_interface/main/config/benchmark/compcert_118_subset.yaml +148 -0
  36. itp_interface/main/config/benchmark/compcert_benchmark.yaml +36 -0
  37. itp_interface/main/config/benchmark/compcert_benchmark_hard.yaml +498 -0
  38. itp_interface/main/config/benchmark/compcert_benchmark_hard_1.yaml +55 -0
  39. itp_interface/main/config/benchmark/compcert_benchmark_hard_2.yaml +24 -0
  40. itp_interface/main/config/benchmark/compcert_benchmark_hard_3.yaml +95 -0
  41. itp_interface/main/config/benchmark/compcert_benchmark_hard_7_per_cent.yaml +78 -0
  42. itp_interface/main/config/benchmark/compcert_benchmark_test.yaml +38 -0
  43. itp_interface/main/config/benchmark/compcert_benchmark_train.yaml +340 -0
  44. itp_interface/main/config/benchmark/leandojo_novel_premises_test.yaml +2908 -0
  45. itp_interface/main/config/benchmark/leandojo_novel_premises_train.yaml +98645 -0
  46. itp_interface/main/config/benchmark/leandojo_novel_premises_val.yaml +2912 -0
  47. itp_interface/main/config/benchmark/leandojo_random.yaml +2889 -0
  48. itp_interface/main/config/benchmark/leandojo_random_test.yaml +2421 -0
  49. itp_interface/main/config/benchmark/leandojo_random_train.yaml +62729 -0
  50. itp_interface/main/config/benchmark/leandojo_random_val.yaml +2504 -0
  51. itp_interface/main/config/benchmark/math-comp.yaml +200 -0
  52. itp_interface/main/config/benchmark/miniF2F_test.yaml +12 -0
  53. itp_interface/main/config/benchmark/miniF2F_test_aime.yaml +27 -0
  54. itp_interface/main/config/benchmark/miniF2F_test_algebra.yaml +30 -0
  55. itp_interface/main/config/benchmark/miniF2F_test_amc12.yaml +57 -0
  56. itp_interface/main/config/benchmark/miniF2F_test_few_shot_hard.yaml +231 -0
  57. itp_interface/main/config/benchmark/miniF2F_test_imo.yaml +32 -0
  58. itp_interface/main/config/benchmark/miniF2F_test_induction.yaml +20 -0
  59. itp_interface/main/config/benchmark/miniF2F_test_mathd_algebra.yaml +82 -0
  60. itp_interface/main/config/benchmark/miniF2F_test_mathd_algebra_hard.yaml +72 -0
  61. itp_interface/main/config/benchmark/miniF2F_test_mathd_numbertheory.yaml +72 -0
  62. itp_interface/main/config/benchmark/miniF2F_test_numbertheory.yaml +20 -0
  63. itp_interface/main/config/benchmark/minicompcert_benchmark_1.yaml +14 -0
  64. itp_interface/main/config/benchmark/proverbot_hard.yaml +104 -0
  65. itp_interface/main/config/benchmark/re_prover.yaml +66 -0
  66. itp_interface/main/config/benchmark/re_prover_hard.yaml +41 -0
  67. itp_interface/main/config/benchmark/re_prover_very_hard.yaml +22 -0
  68. itp_interface/main/config/benchmark/reprover_with_retrieval.yaml +73 -0
  69. itp_interface/main/config/benchmark/reprover_with_retrieval_hard.yaml +30 -0
  70. itp_interface/main/config/benchmark/reprover_with_retrieval_neg.yaml +195 -0
  71. itp_interface/main/config/benchmark/simple_benchmark_1.yaml +24 -0
  72. itp_interface/main/config/benchmark/simple_benchmark_8.yaml +50 -0
  73. itp_interface/main/config/benchmark/simple_benchmark_9.yaml +65 -0
  74. itp_interface/main/config/benchmark/simple_benchmark_isabelle.yaml +18 -0
  75. itp_interface/main/config/benchmark/simple_benchmark_lean.yaml +12 -0
  76. itp_interface/main/config/benchmark/simple_benchmark_lean_training_data.yaml +12 -0
  77. itp_interface/main/config/benchmark/simple_rl_benchmark_lean.yaml +14 -0
  78. itp_interface/main/config/benchmark/stack_machine.yaml +13 -0
  79. itp_interface/main/config/benchmark/stack_machine_hard.yaml +15 -0
  80. itp_interface/main/config/category_theory_data_gen.yaml +14 -0
  81. itp_interface/main/config/category_theory_data_gen_random.yaml +16 -0
  82. itp_interface/main/config/compcert_data_gen_test.yaml +10 -0
  83. itp_interface/main/config/compcert_data_gen_train.yaml +7 -0
  84. itp_interface/main/config/env_settings/bm25_retrieval.yaml +2 -0
  85. itp_interface/main/config/env_settings/bm25_retrieval_no_dfns.yaml +2 -0
  86. itp_interface/main/config/env_settings/bm25_retrieval_only_local_no_dfns.yaml +2 -0
  87. itp_interface/main/config/env_settings/bm25_retrieval_with_print.yaml +2 -0
  88. itp_interface/main/config/env_settings/bm25_retrieval_with_print_only_local.yaml +2 -0
  89. itp_interface/main/config/env_settings/bm25_retrieval_with_print_only_local_no_dfns.yaml +2 -0
  90. itp_interface/main/config/env_settings/no_retrieval.yaml +2 -0
  91. itp_interface/main/config/experiments.yaml +12 -0
  92. itp_interface/main/config/geo_coq_data_gen.yaml +14 -0
  93. itp_interface/main/config/geo_coq_data_gen_random.yaml +16 -0
  94. itp_interface/main/config/leandojo_random_data_gen.yaml +16 -0
  95. itp_interface/main/config/math_comp_data_gen.yaml +14 -0
  96. itp_interface/main/config/math_comp_data_gen_random.yaml +16 -0
  97. itp_interface/main/config/mathlib_data_gen.yaml +14 -0
  98. itp_interface/main/config/repo/coq_repos.yaml +191 -0
  99. itp_interface/main/config/run_settings/default_coq_data_generation_transforms.yaml +24 -0
  100. itp_interface/main/config/run_settings/default_isabelle_data_generation_transforms.yaml +24 -0
  101. itp_interface/main/config/run_settings/default_lean4_data_generation_transforms.yaml +24 -0
  102. itp_interface/main/config/run_settings/default_lean_data_generation_transforms.yaml +24 -0
  103. itp_interface/main/config/simple_coq_data_gen.yaml +12 -0
  104. itp_interface/main/config/simple_coq_data_gen_random.yaml +17 -0
  105. itp_interface/main/config/simple_lean_data_gen.yaml +12 -0
  106. itp_interface/main/config/simple_rl_lean_data_gen.yaml +12 -0
  107. itp_interface/main/config/uni_math_data_gen.yaml +14 -0
  108. itp_interface/main/config.py +192 -0
  109. itp_interface/main/extract_benchmark_dataset.py +106 -0
  110. itp_interface/main/filter_dataset.py +107 -0
  111. itp_interface/main/install.py +92 -0
  112. itp_interface/main/merge_dataset.py +96 -0
  113. itp_interface/main/run_tool.py +444 -0
  114. itp_interface/pisa/.git +1 -0
  115. itp_interface/pisa/.gitignore +125 -0
  116. itp_interface/pisa/.idea/.gitignore +8 -0
  117. itp_interface/pisa/.idea/ClojureProjectResolveSettings.xml +6 -0
  118. itp_interface/pisa/.idea/codeStyles/Project.xml +7 -0
  119. itp_interface/pisa/.idea/codeStyles/codeStyleConfig.xml +5 -0
  120. itp_interface/pisa/.idea/inspectionProfiles/Project_Default.xml +16 -0
  121. itp_interface/pisa/.idea/libraries/sbt__com_google_android_annotations_4_1_1_4_jar.xml +13 -0
  122. itp_interface/pisa/.idea/libraries/sbt__com_google_api_grpc_proto_google_common_protos_1_17_0_jar.xml +13 -0
  123. itp_interface/pisa/.idea/libraries/sbt__com_google_code_findbugs_jsr305_3_0_2_jar.xml +13 -0
  124. itp_interface/pisa/.idea/libraries/sbt__com_google_code_gson_gson_2_8_6_jar.xml +13 -0
  125. itp_interface/pisa/.idea/libraries/sbt__com_google_errorprone_error_prone_annotations_2_3_4_jar.xml +13 -0
  126. itp_interface/pisa/.idea/libraries/sbt__com_google_guava_failureaccess_1_0_1_jar.xml +13 -0
  127. itp_interface/pisa/.idea/libraries/sbt__com_google_guava_guava_30_0_jre_jar.xml +13 -0
  128. itp_interface/pisa/.idea/libraries/sbt__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava_jar.xml +9 -0
  129. itp_interface/pisa/.idea/libraries/sbt__com_google_j2objc_j2objc_annotations_1_3_jar.xml +13 -0
  130. itp_interface/pisa/.idea/libraries/sbt__com_google_protobuf_protobuf_java_3_12_0_jar.xml +13 -0
  131. itp_interface/pisa/.idea/libraries/sbt__com_google_protobuf_protobuf_java_util_3_12_0_jar.xml +13 -0
  132. itp_interface/pisa/.idea/libraries/sbt__com_lihaoyi_fastparse_2_13_2_3_0_jar.xml +13 -0
  133. itp_interface/pisa/.idea/libraries/sbt__com_lihaoyi_geny_2_13_0_6_0_jar.xml +13 -0
  134. itp_interface/pisa/.idea/libraries/sbt__com_lihaoyi_sourcecode_2_13_0_2_1_jar.xml +13 -0
  135. itp_interface/pisa/.idea/libraries/sbt__com_thesamet_scalapb_lenses_2_13_0_10_9_jar.xml +13 -0
  136. itp_interface/pisa/.idea/libraries/sbt__com_thesamet_scalapb_scalapb_runtime_2_13_0_10_9_jar.xml +13 -0
  137. itp_interface/pisa/.idea/libraries/sbt__com_thesamet_scalapb_scalapb_runtime_grpc_2_13_0_10_9_jar.xml +13 -0
  138. itp_interface/pisa/.idea/libraries/sbt__com_thesamet_scalapb_zio_grpc_zio_grpc_core_2_13_0_4_2_jar.xml +13 -0
  139. itp_interface/pisa/.idea/libraries/sbt__com_thoughtworks_paranamer_paranamer_2_8_jar.xml +13 -0
  140. itp_interface/pisa/.idea/libraries/sbt__commons_io_commons_io_2_8_0_jar.xml +13 -0
  141. itp_interface/pisa/.idea/libraries/sbt__de_unruh_java_patterns_0_1_0_jar.xml +13 -0
  142. itp_interface/pisa/.idea/libraries/sbt__de_unruh_scala_isabelle_2_13_master_SNAPSHOT_jar.xml +13 -0
  143. itp_interface/pisa/.idea/libraries/sbt__dev_zio_izumi_reflect_2_13_1_0_0_M9_jar.xml +13 -0
  144. itp_interface/pisa/.idea/libraries/sbt__dev_zio_izumi_reflect_thirdparty_boopickle_shaded_2_13_1_0_0_M9_jar.xml +13 -0
  145. itp_interface/pisa/.idea/libraries/sbt__dev_zio_zio_2_13_1_0_3_jar.xml +13 -0
  146. itp_interface/pisa/.idea/libraries/sbt__dev_zio_zio_stacktracer_2_13_1_0_3_jar.xml +13 -0
  147. itp_interface/pisa/.idea/libraries/sbt__dev_zio_zio_streams_2_13_1_0_3_jar.xml +13 -0
  148. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_api_1_34_0_jar.xml +13 -0
  149. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_context_1_34_0_jar.xml +13 -0
  150. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_core_1_34_0_jar.xml +13 -0
  151. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_netty_1_34_0_jar.xml +13 -0
  152. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_protobuf_1_34_0_jar.xml +13 -0
  153. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_protobuf_lite_1_34_0_jar.xml +13 -0
  154. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_services_1_34_0_jar.xml +13 -0
  155. itp_interface/pisa/.idea/libraries/sbt__io_grpc_grpc_stub_1_34_0_jar.xml +13 -0
  156. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_buffer_4_1_51_Final_jar.xml +13 -0
  157. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_codec_4_1_51_Final_jar.xml +13 -0
  158. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_codec_http2_4_1_51_Final_jar.xml +13 -0
  159. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_codec_http_4_1_51_Final_jar.xml +13 -0
  160. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_codec_socks_4_1_51_Final_jar.xml +13 -0
  161. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_common_4_1_51_Final_jar.xml +13 -0
  162. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_handler_4_1_51_Final_jar.xml +13 -0
  163. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_handler_proxy_4_1_51_Final_jar.xml +13 -0
  164. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_resolver_4_1_51_Final_jar.xml +13 -0
  165. itp_interface/pisa/.idea/libraries/sbt__io_netty_netty_transport_4_1_51_Final_jar.xml +13 -0
  166. itp_interface/pisa/.idea/libraries/sbt__io_perfmark_perfmark_api_0_19_0_jar.xml +13 -0
  167. itp_interface/pisa/.idea/libraries/sbt__net_java_dev_jna_jna_5_3_1_jar.xml +13 -0
  168. itp_interface/pisa/.idea/libraries/sbt__net_liftweb_lift_json_2_13_3_4_3_jar.xml +13 -0
  169. itp_interface/pisa/.idea/libraries/sbt__org_apache_commons_commons_lang3_3_11_jar.xml +13 -0
  170. itp_interface/pisa/.idea/libraries/sbt__org_apache_commons_commons_text_1_9_jar.xml +13 -0
  171. itp_interface/pisa/.idea/libraries/sbt__org_checkerframework_checker_qual_3_5_0_jar.xml +13 -0
  172. itp_interface/pisa/.idea/libraries/sbt__org_codehaus_mojo_animal_sniffer_annotations_1_18_jar.xml +13 -0
  173. itp_interface/pisa/.idea/libraries/sbt__org_jetbrains_annotations_20_1_0_jar.xml +13 -0
  174. itp_interface/pisa/.idea/libraries/sbt__org_jline_jline_3_16_0_jar.xml +13 -0
  175. itp_interface/pisa/.idea/libraries/sbt__org_log4s_log4s_2_13_1_9_0_jar.xml +13 -0
  176. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_modules_scala_collection_compat_2_13_2_1_6_jar.xml +13 -0
  177. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_modules_scala_xml_2_13_1_3_0_jar.xml +13 -0
  178. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_scala_compiler_2_13_4_jar.xml +13 -0
  179. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_scala_library_2_13_4_jar.xml +23 -0
  180. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_scala_reflect_2_13_4_jar.xml +13 -0
  181. itp_interface/pisa/.idea/libraries/sbt__org_scala_lang_scalap_2_13_4_jar.xml +13 -0
  182. itp_interface/pisa/.idea/libraries/sbt__org_scalaz_scalaz_core_2_13_7_3_2_jar.xml +13 -0
  183. itp_interface/pisa/.idea/libraries/sbt__org_slf4j_slf4j_api_1_7_30_jar.xml +13 -0
  184. itp_interface/pisa/.idea/libraries/sbt__org_slf4j_slf4j_simple_1_7_30_jar.xml +13 -0
  185. itp_interface/pisa/.idea/misc.xml +7 -0
  186. itp_interface/pisa/.idea/modules/PISA-build.iml +127 -0
  187. itp_interface/pisa/.idea/modules/PISA.iml +94 -0
  188. itp_interface/pisa/.idea/modules.xml +9 -0
  189. itp_interface/pisa/.idea/other.xml +6 -0
  190. itp_interface/pisa/.idea/sbt.xml +20 -0
  191. itp_interface/pisa/.idea/scala_compiler.xml +6 -0
  192. itp_interface/pisa/.idea/uiDesigner.xml +124 -0
  193. itp_interface/pisa/.idea/vcs.xml +6 -0
  194. itp_interface/pisa/.scalafmt.conf +2 -0
  195. itp_interface/pisa/LICENSE +29 -0
  196. itp_interface/pisa/README.md +262 -0
  197. itp_interface/pisa/build.sbt +49 -0
  198. itp_interface/pisa/build.sh +26 -0
  199. itp_interface/pisa/command_generation/close_gaps.py +44 -0
  200. itp_interface/pisa/command_generation/conjecture_normal_order.py +62 -0
  201. itp_interface/pisa/command_generation/conjecturer_command_generator.py +36 -0
  202. itp_interface/pisa/command_generation/create_dirs.py +11 -0
  203. itp_interface/pisa/command_generation/find_std.py +67 -0
  204. itp_interface/pisa/command_generation/generate_build_commands_afp.py +15 -0
  205. itp_interface/pisa/command_generation/generate_build_commands_std.py +15 -0
  206. itp_interface/pisa/command_generation/generate_commands_afp.py +103 -0
  207. itp_interface/pisa/command_generation/generate_commands_mini.py +73 -0
  208. itp_interface/pisa/command_generation/generate_commands_std.py +69 -0
  209. itp_interface/pisa/command_generation/generate_hammer_extraction_text.py +5 -0
  210. itp_interface/pisa/command_generation/hammer_command_generator.py +40 -0
  211. itp_interface/pisa/command_generation/hp_search_command_generator.py +63 -0
  212. itp_interface/pisa/command_generation/oracle_command_generator.py +56 -0
  213. itp_interface/pisa/command_generation/search_command_generator.py +69 -0
  214. itp_interface/pisa/command_generation/summarise_problem_names.py +45 -0
  215. itp_interface/pisa/command_generation/tpu_hp_search.py +75 -0
  216. itp_interface/pisa/docker/Dockerfile +34 -0
  217. itp_interface/pisa/docker/docker_tutorial.md +64 -0
  218. itp_interface/pisa/eval_setup/copy_isabelle.py +42 -0
  219. itp_interface/pisa/eval_setup/copy_pisa_jars.py +18 -0
  220. itp_interface/pisa/mesh_transformer_utils/tokenization.py +86 -0
  221. itp_interface/pisa/project/build.properties +1 -0
  222. itp_interface/pisa/project/plugins.sbt +5 -0
  223. itp_interface/pisa/requirements.txt +4 -0
  224. itp_interface/pisa/scripts/extract_last_k_steps.py +28 -0
  225. itp_interface/pisa/scripts/extract_proof_corpus.py +26 -0
  226. itp_interface/pisa/scripts/gather_hammer_results.py +27 -0
  227. itp_interface/pisa/scripts/length_in_char_stats.py +20 -0
  228. itp_interface/pisa/scripts/mix.py +127 -0
  229. itp_interface/pisa/scripts/results_stat.py +52 -0
  230. itp_interface/pisa/scripts/test_array_job.sh +34 -0
  231. itp_interface/pisa/setup.sh +25 -0
  232. itp_interface/pisa/src/main/protobuf/server.proto +60 -0
  233. itp_interface/pisa/src/main/python/.idea/.gitignore +8 -0
  234. itp_interface/pisa/src/main/python/.idea/inspectionProfiles/Project_Default.xml +18 -0
  235. itp_interface/pisa/src/main/python/.idea/inspectionProfiles/profiles_settings.xml +6 -0
  236. itp_interface/pisa/src/main/python/.idea/misc.xml +4 -0
  237. itp_interface/pisa/src/main/python/.idea/modules.xml +8 -0
  238. itp_interface/pisa/src/main/python/.idea/python.iml +12 -0
  239. itp_interface/pisa/src/main/python/.idea/vcs.xml +6 -0
  240. itp_interface/pisa/src/main/python/conjecturing_parsing/conjecturer_postprocessing.py +59 -0
  241. itp_interface/pisa/src/main/python/data_extraction/extract_data.py +184 -0
  242. itp_interface/pisa/src/main/python/data_extraction/find_premises.py +221 -0
  243. itp_interface/pisa/src/main/python/data_extraction/process_data.py +129 -0
  244. itp_interface/pisa/src/main/python/legacy/PisaFlexibleClient.py +167 -0
  245. itp_interface/pisa/src/main/python/legacy/autof_test.py +74 -0
  246. itp_interface/pisa/src/main/python/legacy/cmd_client.py +23 -0
  247. itp_interface/pisa/src/main/python/legacy/convert_scala_dump_to_test_name_jsons.py +14 -0
  248. itp_interface/pisa/src/main/python/legacy/create_data_txt.py +72 -0
  249. itp_interface/pisa/src/main/python/legacy/create_finetune_tfrecords.py +311 -0
  250. itp_interface/pisa/src/main/python/legacy/demo.py +49 -0
  251. itp_interface/pisa/src/main/python/legacy/evaluate.py +108 -0
  252. itp_interface/pisa/src/main/python/legacy/extract_first_step.py +25 -0
  253. itp_interface/pisa/src/main/python/legacy/get_global_facts.py +35 -0
  254. itp_interface/pisa/src/main/python/legacy/mix_data.py +19 -0
  255. itp_interface/pisa/src/main/python/legacy/one_stage_extraction.py +111 -0
  256. itp_interface/pisa/src/main/python/legacy/prepare_episodic_transitions.py +137 -0
  257. itp_interface/pisa/src/main/python/legacy/prepare_translation_pairs.py +277 -0
  258. itp_interface/pisa/src/main/python/pisa_client.py +322 -0
  259. itp_interface/pisa/src/main/python/server_pb2.py +394 -0
  260. itp_interface/pisa/src/main/python/server_pb2_grpc.py +230 -0
  261. itp_interface/pisa/src/main/python/test_client.py +17 -0
  262. itp_interface/pisa/src/main/python/test_client2.py +79 -0
  263. itp_interface/pisa/src/main/python/utils/filters.py +59 -0
  264. itp_interface/pisa/src/main/python/utils/pisa_server_control.py +29 -0
  265. itp_interface/pisa/src/main/scala/pisa/agent/CheckSyntax.scala +257 -0
  266. itp_interface/pisa/src/main/scala/pisa/agent/DepThms.scala +29 -0
  267. itp_interface/pisa/src/main/scala/pisa/agent/PisaStat.scala +46 -0
  268. itp_interface/pisa/src/main/scala/pisa/agent/RefactorTest.scala +40 -0
  269. itp_interface/pisa/src/main/scala/pisa/agent/RepHammer.scala +95 -0
  270. itp_interface/pisa/src/main/scala/pisa/server/HammFacts.scala +63 -0
  271. itp_interface/pisa/src/main/scala/pisa/server/PisaOS.scala +881 -0
  272. itp_interface/pisa/src/main/scala/pisa/server/PisaOneStage.scala +540 -0
  273. itp_interface/pisa/src/main/scala/pisa/server/PisaOneStageServers.scala +1048 -0
  274. itp_interface/pisa/src/main/scala/pisa/utils/TheoryManager.scala +95 -0
  275. itp_interface/pisa/src/test/python/analyse_debug.py +33 -0
  276. itp_interface/pisa/src/test/python/extract_test_seq2seq.py +53 -0
  277. itp_interface/pisa/src/test/python/extract_test_theorem_ground_truth_indices.py +31 -0
  278. itp_interface/pisa/src/test/python/proof_originality.py +24 -0
  279. itp_interface/pisa/src/test/python/test_command_generator.py +25 -0
  280. itp_interface/pisa/src/test/python/test_model_sequence_accuracy.py +70 -0
  281. itp_interface/pisa/src/test/scala/pisa/Easy.scala +26 -0
  282. itp_interface/pisa/src/test/scala/pisa/TestCurl.scala +82 -0
  283. itp_interface/pisa/src/test/scala/pisa/TestIsa.scala +27 -0
  284. itp_interface/pisa/test.sh +19 -0
  285. itp_interface/pisa/universal_test_theorems.tar.gz +0 -0
  286. itp_interface/repo/build.py +78 -0
  287. itp_interface/repo/clone.py +79 -0
  288. itp_interface/repo/dataset_discovery.py +99 -0
  289. itp_interface/retrieval/__init__.py +0 -0
  290. itp_interface/retrieval/abstraction.py +35 -0
  291. itp_interface/retrieval/coq_bm25_reranker.py +153 -0
  292. itp_interface/retrieval/isabelle_bm25_reranker.py +86 -0
  293. itp_interface/retrieval/lean3_bm25_reranker.py +86 -0
  294. itp_interface/rl/__init__.py +0 -0
  295. itp_interface/rl/abstraction.py +168 -0
  296. itp_interface/rl/proof_action.py +172 -0
  297. itp_interface/rl/proof_state.py +149 -0
  298. itp_interface/rl/proof_tree.py +109 -0
  299. itp_interface/rl/simpl_proof_env_pool.py +16 -0
  300. itp_interface/rl/simple_proof_env.py +713 -0
  301. itp_interface/rl/simple_proof_env_pool.py +591 -0
  302. itp_interface/scripts/setup.sh +228 -0
  303. itp_interface/tools/__init__.py +0 -0
  304. itp_interface/tools/basic_utils.py +172 -0
  305. itp_interface/tools/bin_packing.py +61 -0
  306. itp_interface/tools/cache.py +93 -0
  307. itp_interface/tools/coq_build_spec.py +31 -0
  308. itp_interface/tools/coq_build_tool.py +319 -0
  309. itp_interface/tools/coq_context_helper.py +354 -0
  310. itp_interface/tools/coq_executor.py +508 -0
  311. itp_interface/tools/coq_local_data_generation_transform.py +158 -0
  312. itp_interface/tools/coq_parse_utils.py +154 -0
  313. itp_interface/tools/coq_raw_proofs.py +193 -0
  314. itp_interface/tools/coq_theorem_proof_pair_generation_transform.py +146 -0
  315. itp_interface/tools/coq_training_data_generator.py +76 -0
  316. itp_interface/tools/dynamic_coq_proof_exec.py +220 -0
  317. itp_interface/tools/dynamic_isabelle_proof_exec.py +229 -0
  318. itp_interface/tools/dynamic_lean4_proof_exec.py +236 -0
  319. itp_interface/tools/dynamic_lean_proof_exec.py +228 -0
  320. itp_interface/tools/isabelle_context_helper.py +66 -0
  321. itp_interface/tools/isabelle_executor.py +862 -0
  322. itp_interface/tools/isabelle_local_data_generation_transform.py +149 -0
  323. itp_interface/tools/isabelle_parse_utils.py +131 -0
  324. itp_interface/tools/isabelle_server.py +106 -0
  325. itp_interface/tools/lean4_context_helper.py +72 -0
  326. itp_interface/tools/lean4_local_data_generation_transform.py +122 -0
  327. itp_interface/tools/lean4_sync_executor.py +1193 -0
  328. itp_interface/tools/lean_cmd_executor.py +804 -0
  329. itp_interface/tools/lean_context_helper.py +327 -0
  330. itp_interface/tools/lean_dojo_data_generation_transform.py +206 -0
  331. itp_interface/tools/lean_executor.py +687 -0
  332. itp_interface/tools/lean_local_data_generation_transform.py +136 -0
  333. itp_interface/tools/lean_parse_utils.py +32 -0
  334. itp_interface/tools/log_utils.py +20 -0
  335. itp_interface/tools/proof_exec_callback.py +76 -0
  336. itp_interface/tools/ray_utils.py +265 -0
  337. itp_interface/tools/repl/.git +1 -0
  338. itp_interface/tools/repl/.github/workflows/ci.yml +24 -0
  339. itp_interface/tools/repl/.gitignore +7 -0
  340. itp_interface/tools/repl/.vscode/copyright.code-snippets +13 -0
  341. itp_interface/tools/repl/.vscode/extensions.json +13 -0
  342. itp_interface/tools/repl/.vscode/module-docstring.code-snippets +35 -0
  343. itp_interface/tools/repl/.vscode/settings.json +11 -0
  344. itp_interface/tools/repl/README.md +174 -0
  345. itp_interface/tools/repl/REPL/Frontend.lean +47 -0
  346. itp_interface/tools/repl/REPL/JSON.lean +186 -0
  347. itp_interface/tools/repl/REPL/Lean/ContextInfo.lean +9 -0
  348. itp_interface/tools/repl/REPL/Lean/Environment.lean +31 -0
  349. itp_interface/tools/repl/REPL/Lean/InfoTree/ToJson.lean +114 -0
  350. itp_interface/tools/repl/REPL/Lean/InfoTree.lean +272 -0
  351. itp_interface/tools/repl/REPL/Main.lean +323 -0
  352. itp_interface/tools/repl/REPL/Snapshots.lean +306 -0
  353. itp_interface/tools/repl/REPL/Util/Path.lean +36 -0
  354. itp_interface/tools/repl/REPL/Util/Pickle.lean +44 -0
  355. itp_interface/tools/repl/REPL.lean +4 -0
  356. itp_interface/tools/repl/lake-manifest.json +5 -0
  357. itp_interface/tools/repl/lakefile.lean +15 -0
  358. itp_interface/tools/repl/lean-toolchain +1 -0
  359. itp_interface/tools/repl/test/Mathlib/.gitignore +5 -0
  360. itp_interface/tools/repl/test/Mathlib/H20231110.sh +2 -0
  361. itp_interface/tools/repl/test/Mathlib/ReplMathlibTests.lean +1 -0
  362. itp_interface/tools/repl/test/Mathlib/lake-manifest.json +68 -0
  363. itp_interface/tools/repl/test/Mathlib/lakefile.lean +11 -0
  364. itp_interface/tools/repl/test/Mathlib/lean-toolchain +1 -0
  365. itp_interface/tools/repl/test/Mathlib/test/20240209.expected.out +20 -0
  366. itp_interface/tools/repl/test/Mathlib/test/20240209.in +3 -0
  367. itp_interface/tools/repl/test/Mathlib/test/20240209.lean +4 -0
  368. itp_interface/tools/repl/test/Mathlib/test/H20231020.expected.out +8 -0
  369. itp_interface/tools/repl/test/Mathlib/test/H20231020.in +8 -0
  370. itp_interface/tools/repl/test/Mathlib/test/H20231020.lean +22 -0
  371. itp_interface/tools/repl/test/Mathlib/test/H20231110.expected.out +4 -0
  372. itp_interface/tools/repl/test/Mathlib/test/H20231110.in +4 -0
  373. itp_interface/tools/repl/test/Mathlib/test/H20231115.expected.out +19 -0
  374. itp_interface/tools/repl/test/Mathlib/test/H20231115.in +5 -0
  375. itp_interface/tools/repl/test/Mathlib/test/H20231115_2.expected.out +18 -0
  376. itp_interface/tools/repl/test/Mathlib/test/H20231115_2.in +4 -0
  377. itp_interface/tools/repl/test/Mathlib/test/H20231115_3.expected.out +10 -0
  378. itp_interface/tools/repl/test/Mathlib/test/H20231115_3.in +4 -0
  379. itp_interface/tools/repl/test/Mathlib/test/H20231214.in +9 -0
  380. itp_interface/tools/repl/test/Mathlib/test/H20231214.lean +30 -0
  381. itp_interface/tools/repl/test/Mathlib/test/H20231215.expected.out +4 -0
  382. itp_interface/tools/repl/test/Mathlib/test/H20231215.in +4 -0
  383. itp_interface/tools/repl/test/Mathlib/test/H20231215_2.expected.out +14 -0
  384. itp_interface/tools/repl/test/Mathlib/test/H20231215_2.in +3 -0
  385. itp_interface/tools/repl/test/Mathlib/test/exact.expected.out +37 -0
  386. itp_interface/tools/repl/test/Mathlib/test/exact.in +10 -0
  387. itp_interface/tools/repl/test/Mathlib/test/import_Mathlib.lean +1 -0
  388. itp_interface/tools/repl/test/Mathlib/test/induction.expected.out +29 -0
  389. itp_interface/tools/repl/test/Mathlib/test/induction.in +10 -0
  390. itp_interface/tools/repl/test/Mathlib/test/induction.lean +6 -0
  391. itp_interface/tools/repl/test/Mathlib/test/on_goal.expected.out +22 -0
  392. itp_interface/tools/repl/test/Mathlib/test/on_goal.in +5 -0
  393. itp_interface/tools/repl/test/Mathlib/test/pickle.expected.out +16 -0
  394. itp_interface/tools/repl/test/Mathlib/test/pickle.in +6 -0
  395. itp_interface/tools/repl/test/Mathlib/test/pickle_2.expected.out +4 -0
  396. itp_interface/tools/repl/test/Mathlib/test/pickle_2.in +4 -0
  397. itp_interface/tools/repl/test/Mathlib/test.sh +41 -0
  398. itp_interface/tools/repl/test/all_tactics.expected.out +13 -0
  399. itp_interface/tools/repl/test/all_tactics.in +1 -0
  400. itp_interface/tools/repl/test/by_cases.expected.out +25 -0
  401. itp_interface/tools/repl/test/by_cases.in +8 -0
  402. itp_interface/tools/repl/test/by_cases.lean +4 -0
  403. itp_interface/tools/repl/test/calc.expected.out +32 -0
  404. itp_interface/tools/repl/test/calc.in +1 -0
  405. itp_interface/tools/repl/test/def_eval.expected.out +9 -0
  406. itp_interface/tools/repl/test/def_eval.in +3 -0
  407. itp_interface/tools/repl/test/enableInitializersExecution.expected.out +2 -0
  408. itp_interface/tools/repl/test/enableInitializersExecution.in +1 -0
  409. itp_interface/tools/repl/test/file.expected.out +8 -0
  410. itp_interface/tools/repl/test/file.in +1 -0
  411. itp_interface/tools/repl/test/file.lean +5 -0
  412. itp_interface/tools/repl/test/have_by_sorry.expected.out +28 -0
  413. itp_interface/tools/repl/test/have_by_sorry.in +6 -0
  414. itp_interface/tools/repl/test/import_lean.in +1 -0
  415. itp_interface/tools/repl/test/incomplete.expected.out +18 -0
  416. itp_interface/tools/repl/test/incomplete.in +3 -0
  417. itp_interface/tools/repl/test/incomplete.lean +0 -0
  418. itp_interface/tools/repl/test/infotree.expected.out +20 -0
  419. itp_interface/tools/repl/test/infotree.in +2 -0
  420. itp_interface/tools/repl/test/invalid_tactic.expected.out +20 -0
  421. itp_interface/tools/repl/test/invalid_tactic.in +3 -0
  422. itp_interface/tools/repl/test/name_generator.expected.out +53 -0
  423. itp_interface/tools/repl/test/name_generator.in +18 -0
  424. itp_interface/tools/repl/test/no_goal_sorry.expected.out +11 -0
  425. itp_interface/tools/repl/test/no_goal_sorry.in +1 -0
  426. itp_interface/tools/repl/test/no_goal_sorry_2.expected.out +12 -0
  427. itp_interface/tools/repl/test/no_goal_sorry_2.in +1 -0
  428. itp_interface/tools/repl/test/options.expected.out +17 -0
  429. itp_interface/tools/repl/test/options.in +6 -0
  430. itp_interface/tools/repl/test/pickle_environment.expected.out +8 -0
  431. itp_interface/tools/repl/test/pickle_environment.in +7 -0
  432. itp_interface/tools/repl/test/pickle_environment_with_imports.expected.out +10 -0
  433. itp_interface/tools/repl/test/pickle_environment_with_imports.in +9 -0
  434. itp_interface/tools/repl/test/pickle_open.expected.out +8 -0
  435. itp_interface/tools/repl/test/pickle_open.in +7 -0
  436. itp_interface/tools/repl/test/pickle_open_2.expected.out +4 -0
  437. itp_interface/tools/repl/test/pickle_open_2.in +3 -0
  438. itp_interface/tools/repl/test/pickle_open_scoped.expected.out +18 -0
  439. itp_interface/tools/repl/test/pickle_open_scoped.in +8 -0
  440. itp_interface/tools/repl/test/pickle_open_scoped_2.expected.out +14 -0
  441. itp_interface/tools/repl/test/pickle_open_scoped_2.in +3 -0
  442. itp_interface/tools/repl/test/pickle_proof_state_1.expected.out +26 -0
  443. itp_interface/tools/repl/test/pickle_proof_state_1.in +15 -0
  444. itp_interface/tools/repl/test/pickle_proof_state_2.expected.out +4 -0
  445. itp_interface/tools/repl/test/pickle_proof_state_2.in +3 -0
  446. itp_interface/tools/repl/test/pickle_proof_state_env.expected.out +26 -0
  447. itp_interface/tools/repl/test/pickle_proof_state_env.in +15 -0
  448. itp_interface/tools/repl/test/pickle_scoped_notation.in +16 -0
  449. itp_interface/tools/repl/test/pickle_scoped_notation_2.in +3 -0
  450. itp_interface/tools/repl/test/proof_step.expected.out +18 -0
  451. itp_interface/tools/repl/test/proof_step.in +7 -0
  452. itp_interface/tools/repl/test/readme.expected.out +16 -0
  453. itp_interface/tools/repl/test/readme.in +5 -0
  454. itp_interface/tools/repl/test/sorry_hypotheses.expected.out +16 -0
  455. itp_interface/tools/repl/test/sorry_hypotheses.in +4 -0
  456. itp_interface/tools/repl/test/synthesize_placeholder.expected.out +7 -0
  457. itp_interface/tools/repl/test/synthesize_placeholder.in +1 -0
  458. itp_interface/tools/repl/test/tactic_mode_sorry.expected.out +14 -0
  459. itp_interface/tools/repl/test/tactic_mode_sorry.in +3 -0
  460. itp_interface/tools/repl/test/tactic_sorry.expected.out +12 -0
  461. itp_interface/tools/repl/test/tactic_sorry.in +1 -0
  462. itp_interface/tools/repl/test/term_sorry.expected.out +12 -0
  463. itp_interface/tools/repl/test/term_sorry.in +1 -0
  464. itp_interface/tools/repl/test/trace_simp.expected.out +41 -0
  465. itp_interface/tools/repl/test/trace_simp.in +15 -0
  466. itp_interface/tools/repl/test/unfinished_tactic_block.expected.out +11 -0
  467. itp_interface/tools/repl/test/unfinished_tactic_block.in +1 -0
  468. itp_interface/tools/repl/test/unknown_environment.expected.out +2 -0
  469. itp_interface/tools/repl/test/unknown_environment.in +1 -0
  470. itp_interface/tools/repl/test/unknown_proof_state.expected.out +14 -0
  471. itp_interface/tools/repl/test/unknown_proof_state.in +3 -0
  472. itp_interface/tools/repl/test/unknown_tactic.expected.out +14 -0
  473. itp_interface/tools/repl/test/unknown_tactic.in +3 -0
  474. itp_interface/tools/repl/test/variables.expected.out +26 -0
  475. itp_interface/tools/repl/test/variables.in +5 -0
  476. itp_interface/tools/repl/test.sh +43 -0
  477. itp_interface/tools/run_data_generation_transforms.py +350 -0
  478. itp_interface/tools/theorem_details.py +25 -0
  479. itp_interface/tools/training_data.py +358 -0
  480. itp_interface/tools/training_data_format.py +599 -0
  481. itp_interface-1.0.0.dist-info/METADATA +78 -0
  482. itp_interface-1.0.0.dist-info/RECORD +485 -0
  483. itp_interface-1.0.0.dist-info/WHEEL +4 -0
  484. itp_interface-1.0.0.dist-info/entry_points.txt +3 -0
  485. itp_interface-1.0.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1193 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import sys
4
+ root_dir = f"{__file__.split('itp_interface')[0]}"
5
+ if root_dir not in sys.path:
6
+ sys.path.append(root_dir)
7
+ import os
8
+ import random
9
+ import logging
10
+ import re
11
+ import time
12
+ import json
13
+ import typing
14
+ import uuid
15
+ import bisect
16
+ import shutil
17
+ from itp_interface.lean_server.lean_context import ProofContext
18
+ from itp_interface.lean_server.lean4_utils import Lean4Utils
19
+ from itp_interface.tools.lean_parse_utils import LeanLineByLineReader
20
+ from itp_interface.tools.theorem_details import TheoremDetails
21
+ from itp_interface.lean_server.lean4_repl_interface import ProcessInterface
22
+ from typing import Iterator, List, Optional, Tuple, OrderedDict, Generator, Dict
23
+
24
+ class Lean4SyncExecutor:
25
+ theorem_start_regex = r"[\s]*(theorem|lemma|example)[\s]+"
26
+ # Non tactic mode support removed because of complications in parsing
27
+ # theorem_end_regex = r"(theorem|lemma|example) [\S|\s]*?(:=|\|)[\s]*?"
28
+ # theorem_regex = r"((((theorem|lemma) ([\S]*))|example)([\S|\s]*?)(:=|\|)[\s]*?)[\s]+"
29
+ # We ONLY support proofs which are written in tactic mode i.e. with := syntax
30
+ theorem_endings = r"(:=|(\|[\S|\s]*=>))"
31
+ theorem_end_regex = r"(theorem|lemma|example)([\s|\S]*?)(:=|=>)"
32
+ theorem_regex = r"((((theorem|lemma)[\s]+([\S]*))|example)([\S|\s]*?)(:=|=>)[\s]*?)[\s]+"
33
+ theorem_name_regex = r"(((theorem|lemma)[\s]+([\S]*))|example)"
34
+ remove_proof_regex = r"([\s|\S]*(:=|\|))[\s|\S]*?"
35
+ proof_context_separator = "⊢"
36
+ proof_context_regex = r"((\d+) goals)*([\s|\S]*?)\n\n"
37
+ goal_regex = rf"([\s|\S]*?){proof_context_separator}([\s|\S]*)"
38
+ theorem_match = re.compile(theorem_regex, re.MULTILINE)
39
+ theorem_name_match = re.compile(theorem_name_regex, re.MULTILINE)
40
+ proof_context_match = re.compile(proof_context_regex, re.MULTILINE)
41
+ goal_match = re.compile(goal_regex, re.MULTILINE)
42
+ theorem_start_match = re.compile(theorem_start_regex, re.MULTILINE)
43
+ theorem_end_match = re.compile(theorem_end_regex, re.MULTILINE)
44
+ remove_proof_match = re.compile(remove_proof_regex, re.MULTILINE)
45
+ proof_context_generation_tactic = "\nend"
46
+ proof_context_generation_tactic_curlies = "\n}"
47
+ proof_state_running_message = "tactic failed, there are unsolved goals\nstate:"
48
+ unsolved_message = "unsolved goals"
49
+ theorem_detection_message = "unexpected end of input; expected '{'"
50
+ extra_by = ' by\n'
51
+ def __init__(self,
52
+ project_root: Optional[str] = None,
53
+ prefix: Optional[str] = None,
54
+ main_file: Optional[str] = None,
55
+ use_hammer: bool = False,
56
+ timeout_in_sec: int = 60,
57
+ use_human_readable_proof_context: bool = True,
58
+ proof_step_iter: Optional[Iterator[str]] = None,
59
+ suppress_error_log: bool = False,
60
+ mathlib_root: Optional[str] = None,
61
+ enable_search: bool = False,
62
+ namespaces: Optional[List[str]] = None,
63
+ keep_local_context: bool = False,
64
+ logger: Optional[logging.Logger] = None):
65
+ assert proof_step_iter is None or isinstance(proof_step_iter, Iterator), \
66
+ "proof_step_iter must be an iterator"
67
+ assert main_file is not None or proof_step_iter is not None, \
68
+ "Either main_file or proof_step_iter must be provided"
69
+ assert main_file is None or proof_step_iter is None, \
70
+ "Only one of main_file or proof_step_iter must be provided"
71
+ assert main_file is None or (os.path.exists(main_file) and main_file.endswith(".lean")), \
72
+ f"main_file must be a valid path to a '.lean' file ({main_file})"
73
+ assert project_root is None or (os.path.exists(project_root) and os.path.isdir(project_root)), \
74
+ "project_root must be a valid path to a directory"
75
+ assert not use_hammer, "Hammer is not supported for Lean4"
76
+ self.use_human_readable_proof_context = use_human_readable_proof_context
77
+ self.project_root = project_root if project_root is not None else "."
78
+ self.main_file = main_file
79
+ self.ticks = str(time.time()).replace(".", "") # This ensures that the temp file name is unique and doesn't clash with other temp files
80
+ # This helps in running parallel instances of prover
81
+ self.random_num = str(random.randint(0, 100000000))
82
+ self.temp_filename_suffix = f"temptodel{self.ticks}{self.random_num}.lean"
83
+ self.temp_file = os.path.join(prefix, self.temp_filename_suffix) if prefix is not None else self.temp_filename_suffix
84
+ self.temp_file_full_path = os.path.join(self.project_root, self.temp_file)
85
+ self.temp_file_full_path = os.path.abspath(self.temp_file_full_path)
86
+ self.use_hammer = use_hammer
87
+ self.timeout_in_sec = min(timeout_in_sec, 120) # Maximum 120s timeout
88
+ self.current_stmt = None
89
+ self.line_num = 0
90
+ self.main_file_iter = proof_step_iter
91
+ self.suppress_error_log = suppress_error_log
92
+ self.process_interace : ProcessInterface = None
93
+ self.execution_complete = False
94
+ self._max_memory_in_mib = 40000 # 40 GiB is needed for mathlib to work seemlessly
95
+ self._lines_executed = []
96
+ self.proof_context : ProofContext = None
97
+ self.curr_lemma_name : Optional[str] = None
98
+ self.curr_lemma : Optional[str] = None
99
+ self.lean_error_messages : List[str] = []
100
+ self._proof_running = False
101
+ self._file_content = ""
102
+ self.local_file_lemmas: OrderedDict[str, str] = OrderedDict()
103
+ self.local_theorem_lemma_description: OrderedDict[str, str] = OrderedDict()
104
+ self._proof_start_idx: Optional[int] = None
105
+ self._import_end_idx: Optional[int] = None
106
+ self.logger = logger if logger is not None else logging.getLogger(__name__)
107
+ self.use_file = False
108
+ if mathlib_root is not None:
109
+ self._mathlib_root = mathlib_root
110
+ else:
111
+ self._mathlib_root = os.path.join(self.project_root, "_target", "deps", "mathlib")
112
+ self._mathlib_src_root = os.path.join(self._mathlib_root, "src")
113
+ self._enable_search = enable_search
114
+ self._theorem_started = False
115
+ self._content_till_last_theorem_stmt = None
116
+ self._last_theorem = None
117
+ self._last_env_idx = None
118
+ self._last_proof_state_idx = None
119
+ self._line_to_env_idx_map = {}
120
+ self._line_to_proof_state_idx_map = {}
121
+ self._anon_theorem_count = 0
122
+ self._namespaces = []
123
+ self._last_file_seek = 0
124
+ self._line_num_seek_map = {}
125
+ self._file_handle = None
126
+ self._in_tactic_mode = False
127
+ self._env_idx_last_thm = None
128
+ self._last_tactics = {}
129
+ self._last_tactic_line_idx = None
130
+ self._error_messages_so_far = set()
131
+ self._error_messages_since_last_thm = {}
132
+ self._run_exactly = False
133
+ self._lines_not_executed = []
134
+ self._extra_added: str = None
135
+ if self._enable_search:
136
+ pass
137
+ pass
138
+
139
+ def set_run_exactly(self):
140
+ self._run_exactly = True
141
+
142
+ def unset_run_exactly(self):
143
+ self._run_exactly = False
144
+
145
+ def run_exactly(self):
146
+ return self._run_exactly
147
+
148
+ def reset(self,
149
+ proof_step_iter: Optional[Iterator[str]] = None):
150
+ # Note: We CANNOT reset the main_file_iter as it is a generator
151
+ assert (proof_step_iter is not None and isinstance(proof_step_iter, Iterator)) or self.main_file is not None, \
152
+ "Either proof_step_iter must be provided or main_file must be set"
153
+ self.current_stmt = None
154
+ self.line_num = 0
155
+ self.main_file_iter = proof_step_iter if proof_step_iter is not None else self.main_file_iter
156
+ self.process_interace : ProcessInterface = None
157
+ self.execution_complete = False
158
+ self._lines_executed = []
159
+ self.proof_context : ProofContext = None
160
+ self.curr_lemma_name : Optional[str] = None
161
+ self.curr_lemma : Optional[str] = None
162
+ self.lean_error_messages : List[str] = []
163
+ self._proof_running = False
164
+ self._file_content = ""
165
+ self.local_file_lemmas: OrderedDict[str, str] = OrderedDict()
166
+ self.local_theorem_lemma_description: OrderedDict[str, str] = OrderedDict()
167
+ self._proof_start_idx: Optional[int] = None
168
+ self._import_end_idx: Optional[int] = None
169
+ self._theorem_started = False
170
+ self._content_till_last_theorem_stmt = None
171
+ self._last_theorem = None
172
+ self._last_env_idx = None
173
+ self._last_proof_state_idx = None
174
+ self._line_to_env_idx_map = {}
175
+ self._line_to_proof_state_idx_map = {}
176
+ self._anon_theorem_count = 0
177
+ self._namespaces = []
178
+ self._last_file_seek = 0
179
+ self._line_num_seek_map = {}
180
+ self._file_handle = None
181
+ self._in_tactic_mode = False
182
+ self._env_idx_last_thm = None
183
+ self._last_tactics = {}
184
+ self._last_tactic_line_idx = None
185
+ self._error_messages_so_far = set()
186
+ self._error_messages_since_last_thm = {}
187
+ if self._enable_search:
188
+ pass
189
+ pass
190
+
191
+ def __enter__(self):
192
+ tools_dir = os.path.dirname(__file__)
193
+ repl_path = os.path.join(tools_dir, "repl")
194
+ abs_path = os.path.abspath(repl_path)
195
+ path_to_repl_exec = os.path.join(abs_path, ".lake", "build", "bin", "repl")
196
+ if 'Mathlib' in self.project_root:
197
+ self.use_file = True
198
+ assert os.path.exists(path_to_repl_exec), f"Lean4 repl executable does not exist at {path_to_repl_exec}, you may need to build it"
199
+ self.process_interace = ProcessInterface(
200
+ command=f"lake env {path_to_repl_exec}",
201
+ cwd=self.project_root,
202
+ logger=self.logger,
203
+ log_level=self.logger.level)
204
+ if self.main_file_iter is None:
205
+ self.main_file_iter = LeanLineByLineReader(self.main_file, remove_comments=True, no_strip=True).instruction_step_generator()
206
+ return self
207
+
208
+ def __exit__(self, exc_type, exc_value, traceback):
209
+ if self.process_interace is not None:
210
+ self.process_interace.close()
211
+ if self.main_file_iter is not None:
212
+ try:
213
+ self.main_file_iter.close() # Close the file handle
214
+ except:
215
+ pass
216
+ # delete if the main file is a temporary file
217
+ if self._file_handle is not None:
218
+ self._file_handle.close()
219
+ if os.path.exists(self.temp_file_full_path):
220
+ os.remove(self.temp_file_full_path)
221
+
222
+ def is_in_proof_mode(self):
223
+ return True if self.proof_context else (len(self.lean_error_messages) > 0) # It is still in proof mode if we encountered a wrong proof
224
+
225
+ def dry_run(self) -> bool:
226
+ try:
227
+ stmt = next(self.main_file_iter)
228
+ except StopIteration:
229
+ self.execution_complete = True
230
+ return False
231
+ self.current_stmt = stmt
232
+ self.line_num += 1
233
+ return True
234
+
235
+ def run_next(self) -> bool:
236
+ try:
237
+ lines = []
238
+ scanned_new_line = False
239
+ if self.run_exactly():
240
+ if len(self._lines_not_executed) > 0:
241
+ lines = self._lines_not_executed
242
+ next_line = lines[-1]
243
+ self._lines_not_executed = []
244
+ else:
245
+ next_line = next(self.main_file_iter)
246
+ lines.append(next_line)
247
+ scanned_new_line = True
248
+ if self._extra_added is not None:
249
+ # Check if the nextline begines with extra added ignoring space and tabs
250
+ if next_line.strip().startswith(self._extra_added.strip()):
251
+ # Remove the extra added in the next line and replace it with spaces
252
+ next_line = next_line.replace(self._extra_added, " " * len(self._extra_added), 1)
253
+ self._extra_added = None
254
+ else:
255
+ next_line = next(self.main_file_iter)
256
+ lines.append(next_line)
257
+ stmt = "\n".join(lines)
258
+ except StopIteration:
259
+ self.execution_complete = True
260
+ return False
261
+ self.current_stmt = next_line
262
+ self.line_num += 1
263
+ try:
264
+ idx = len(self._lines_executed)
265
+ self._run_stmt_on_lean_server(idx, stmt)
266
+ except:
267
+ if not self.suppress_error_log:
268
+ self.logger.error(f"Got an exception while running '{stmt}' on lean. File name: {self.main_file}")
269
+ self.logger.exception(f"Exception Log")
270
+ raise
271
+ if scanned_new_line:
272
+ self._lines_executed.append(next_line)
273
+ else:
274
+ self._lines_executed.append("") # Add an empty line to keep the line numbers in sync
275
+ return True
276
+
277
+ def needs_qed(self):
278
+ return self.proof_context is not None and len(self.proof_context.all_goals) == 0
279
+
280
+ def needs_cut_close(self):
281
+ return self.proof_context is not None and len(self.proof_context.fg_goals) == 0 and len(self.proof_context.all_goals) > 0
282
+
283
+ def run_next_without_exec(self) -> bool:
284
+ raise NotImplementedError
285
+
286
+ def run_all_without_exec(self) -> bool:
287
+ raise NotImplementedError
288
+
289
+ def find_all_theorems_names(self) -> List[Tuple[str, str]]:
290
+ raise NotImplementedError
291
+
292
+ def get_tokens_in_given_stmt(self, stmt: str, ignore_first_token: bool = False) -> Iterator[str]:
293
+ raise NotImplementedError
294
+
295
+ def tokenize(self, stmt: str) -> Iterator[str]:
296
+ raise NotImplementedError
297
+
298
+ def search_type_matching_defns(self, name: str) -> List:
299
+ raise NotImplementedError
300
+
301
+ def get_all_type_matching_defns(self, name: str) -> Iterator:
302
+ raise NotImplementedError
303
+
304
+ def search_exact(self, name: str) -> List:
305
+ raise NotImplementedError
306
+
307
+ def search_defn(self, name: str, match_until: Tuple[str], max_search_res: Optional[int] = None) -> List[Tuple[str, str, bool]]:
308
+ raise NotImplementedError
309
+
310
+ def run_without_executing(self, stmt: str):
311
+ while True:
312
+ try:
313
+ stmt = next(self.main_file_iter)
314
+ except StopIteration:
315
+ return
316
+ idx = len(self._lines_executed)
317
+ self._set_content_to_run(stmt)
318
+ if stmt.startswith("theorem") and self._import_end_idx is None:
319
+ self._import_end_idx = idx
320
+ self.current_stmt = stmt
321
+ self.line_num += 1
322
+ self._set_content_to_run(stmt)
323
+ self._lines_executed.append(stmt)
324
+
325
+ def run_lemma_without_executing(self):
326
+ while True:
327
+ try:
328
+ stmt = next(self.main_file_iter)
329
+ self.current_stmt = stmt
330
+ self.line_num += 1
331
+ if "Qed." in stmt or "Defined." in stmt or "Admitted." in stmt:
332
+ return True
333
+ except StopIteration:
334
+ return False
335
+
336
+ def run_till_next_lemma(self) -> Tuple[bool, Optional[str]]:
337
+ # Run the coq file until the next lemma is found
338
+ next_stmt = None
339
+ in_proof_mode = self.is_in_proof_mode()
340
+ if in_proof_mode or self.execution_complete:
341
+ # If we are already in proof mode, then we have already found a lemma
342
+ return False, next_stmt
343
+ prev_stmt = self.current_stmt
344
+ ran_last_cmd = self.run_next()
345
+ next_stmt = self.current_stmt
346
+ if not ran_last_cmd:
347
+ return False, None
348
+ assigned = False
349
+ while ran_last_cmd and not in_proof_mode:
350
+ if not assigned:
351
+ prev_stmt = next_stmt
352
+ ran_last_cmd = self.run_next()
353
+ in_proof_mode = self.is_in_proof_mode()
354
+ if not assigned:
355
+ next_stmt = self.current_stmt
356
+ if in_proof_mode:
357
+ assigned = True
358
+ lemma_name = next_stmt if next_stmt.startswith("Theorem") or next_stmt.startswith("Lemma") else prev_stmt
359
+ return in_proof_mode, lemma_name
360
+
361
+ def run_till_next_lemma_return_exec_stmt(self) -> Generator[str, None, None]:
362
+ # Run the coq file until the next lemma is found
363
+ next_stmt = None
364
+ in_proof_mode = self.is_in_proof_mode()
365
+ if in_proof_mode or self.execution_complete:
366
+ # If we are already in proof mode, then we have already found a lemma
367
+ yield from []
368
+ else:
369
+ ran_last_cmd = self.run_next()
370
+ next_stmt = self.current_stmt
371
+ if not ran_last_cmd:
372
+ yield from []
373
+ else:
374
+ yield next_stmt
375
+ while ran_last_cmd and not in_proof_mode:
376
+ ran_last_cmd = self.run_next()
377
+ next_stmt = self.current_stmt
378
+ if ran_last_cmd:
379
+ yield next_stmt
380
+ in_proof_mode = self.is_in_proof_mode()
381
+
382
+ def run_to_finish_lemma_return_exec(self) -> Generator[str, None, None]:
383
+ # Run the coq file until the next lemma is found
384
+ next_stmt = None
385
+ in_proof_mode = self.is_in_proof_mode()
386
+ if not in_proof_mode or self.execution_complete:
387
+ # If we are already in proof mode, then we have already found a lemma
388
+ yield from []
389
+ else:
390
+ ran_last_cmd = self.run_next()
391
+ next_stmt = self.current_stmt
392
+ if not ran_last_cmd:
393
+ yield from []
394
+ else:
395
+ yield next_stmt
396
+ while ran_last_cmd and in_proof_mode:
397
+ ran_last_cmd = self.run_next()
398
+ next_stmt = self.current_stmt
399
+ if ran_last_cmd:
400
+ yield next_stmt
401
+ in_proof_mode = self.is_in_proof_mode()
402
+
403
+ def run_to_finish_lemma(self) -> bool:
404
+ # Run the coq file and finish the current lemma
405
+ in_proof_mode = self.is_in_proof_mode()
406
+ if not in_proof_mode or self.execution_complete:
407
+ # If we are not in proof mode, then we are not finishing a lemma
408
+ return False
409
+ ran_last_cmd = self.run_next()
410
+ if not ran_last_cmd:
411
+ return False
412
+ while ran_last_cmd and in_proof_mode:
413
+ ran_last_cmd = self.run_next()
414
+ in_proof_mode = self.is_in_proof_mode()
415
+ return not in_proof_mode
416
+
417
+ def run_till_line_num(self, line_num: int):
418
+ assert line_num >= self.line_num
419
+ ran_last_cmd = True
420
+ while ran_last_cmd and self.line_num < line_num:
421
+ ran_last_cmd = self.run_next()
422
+ return self.line_num
423
+
424
+ def run_to_finish(self):
425
+ ran_last_cmd = True
426
+ while ran_last_cmd:
427
+ ran_last_cmd = self.run_next()
428
+
429
+ def get_lemma_name_if_running(self) -> Optional[str]:
430
+ if not self.is_in_proof_mode():
431
+ return None
432
+ else:
433
+ try:
434
+ return self.curr_lemma_name
435
+ except:
436
+ return None
437
+
438
+ def get_lemma_stmt_if_running(self) -> Optional[str]:
439
+ try:
440
+ return self.local_theorem_lemma_description[self.curr_lemma_name]
441
+ except:
442
+ return None
443
+
444
+ def get_current_lemma_name(self) -> Optional[str]:
445
+ if self.curr_lemma_name is None:
446
+ return None
447
+ else:
448
+ return self.curr_lemma_name
449
+
450
+ def _check_if_thm_read(self, idx: int, full_stmt: str) -> bool:
451
+ cmd = self._get_cmd_tactic_mode(idx, full_stmt)
452
+ self.process_interace.send_command(cmd)
453
+ timeout_in_secs = self.timeout_in_sec
454
+ response = self.process_interace.read_response(timeout_in_secs * 5)
455
+ relevant_msgs = []
456
+ parse_success = self._parse_response(idx, response, relevant_msgs)
457
+ if parse_success:
458
+ self._update_proof_context(idx, response, relevant_msgs)
459
+ return parse_success
460
+
461
+ def _parse_theorem_stmt(self, idx: int, stmt: str, do_full_check: bool = False, interesting_span: typing.Tuple[int, int] = None) -> str:
462
+ if interesting_span is not None:
463
+ span_start, span_end = interesting_span
464
+ full_stmt = stmt[span_start:span_end]
465
+ thm_name_matches = list(Lean4SyncExecutor.theorem_name_match.finditer(full_stmt))
466
+ if len(thm_name_matches) == 0:
467
+ return None
468
+ thm_end_style = '=>' if stmt.strip().endswith('=>') else ':='
469
+ thm_name_match = thm_name_matches[-1]
470
+ _, nspan_end = thm_name_match.span()
471
+ theorem_name = thm_name_match.group(4)
472
+ theorem_stmt = full_stmt[nspan_end:].strip().strip(thm_end_style)
473
+ else:
474
+ matches = list(Lean4SyncExecutor.theorem_match.finditer(stmt))
475
+ if len(matches) == 0:
476
+ return None
477
+ # We are only interested in the last theorem
478
+ match = matches[-1]
479
+ span_start, _ = match.span()
480
+ full_stmt = match.group(1)
481
+ theorem_name = match.group(5)
482
+ theorem_stmt = match.group(6)
483
+ thm_end_style = match.group(7)
484
+ if thm_end_style == "=>":
485
+ # Find the last '|' in the full_stmt
486
+ thm_end_idx = full_stmt.rfind('|')
487
+ if thm_end_idx == -1:
488
+ return None
489
+ else:
490
+ full_stmt = full_stmt[:thm_end_idx] + ' :='
491
+ thm_end_idx = theorem_stmt.rfind('|')
492
+ if thm_end_idx == -1:
493
+ return None
494
+ else:
495
+ theorem_stmt = theorem_stmt[:thm_end_idx]
496
+ if do_full_check:
497
+ check_stmt = stmt[:span_start] + full_stmt + Lean4SyncExecutor.extra_by
498
+ if self.run_exactly():
499
+ self._extra_added = Lean4SyncExecutor.extra_by
500
+ if not self._check_if_thm_read(idx, check_stmt):
501
+ return None
502
+ return theorem_name, theorem_stmt, full_stmt
503
+
504
+ def _execute_till_last_theorem(self, idx: int, full_stmt: str):
505
+ self._write_lean_file(idx, full_stmt)
506
+ self._run_file_on_lean_server(self.timeout_in_sec * 5)
507
+
508
+ def _stmt_has_lemma(self, idx: int, stmt: str, do_full_check: bool = False) -> bool:
509
+ # Match the theorem regex
510
+ has_content = self._content_till_last_theorem_stmt is not None
511
+ full_stmt = (stmt if self._content_till_last_theorem_stmt is None else self._content_till_last_theorem_stmt + '\n' + stmt) + '\n'
512
+ theorem_started = list(Lean4SyncExecutor.theorem_start_match.finditer(full_stmt))
513
+ theorem_ended = Lean4SyncExecutor.theorem_end_match.findall(full_stmt)
514
+ is_theorem_started = len(theorem_started) > 0
515
+ is_theorem_ended = len(theorem_ended) > 0
516
+ # Case one where the theorem has started and ended in the same line
517
+ self._content_till_last_theorem_stmt = full_stmt[:-1]
518
+ process_namespaces(full_stmt, self._namespaces, has_content)
519
+ if is_theorem_started and is_theorem_ended:
520
+ last_span_start, last_span_end = theorem_started[-1].span()
521
+ stmt_before_theorem = full_stmt[:last_span_start]
522
+ if len(stmt_before_theorem.strip()) > 0 and do_full_check:
523
+ # We need to run the statement before the theorem
524
+ self._execute_till_last_theorem(0, stmt_before_theorem)
525
+ self._content_till_last_theorem_stmt = self._content_till_last_theorem_stmt[last_span_start:]
526
+ last_span_end -= last_span_start
527
+ full_stmt = full_stmt[last_span_start:]
528
+ last_span_start = 0
529
+ # Look for all ':=' in the full_stmt
530
+ endings = [i for i in range(last_span_end, len(full_stmt)) if full_stmt.startswith(':=', i)]
531
+ last_thm = None
532
+ for ending in endings:
533
+ interesting_stmt = full_stmt[:ending] + ' := ' # We need to add ':=' to the end
534
+ if do_full_check and self.run_exactly():
535
+ remaining_stmt = full_stmt[ending + len(':='):]
536
+ else:
537
+ remaining_stmt = ''
538
+ interesting_span = (last_span_start, len(interesting_stmt))
539
+ # Make sure to remove the last tactic ran and add it again because we are changing the statement
540
+ if do_full_check:
541
+ self._backtrack_tactic_line(idx)
542
+ last_thm = self._parse_theorem_stmt(idx, interesting_stmt, do_full_check, interesting_span)
543
+ if last_thm is not None:
544
+ if do_full_check and self.run_exactly():
545
+ self._backtrack_tactic_line(idx)
546
+ # Remove the extra added
547
+ self._extra_added: str = None
548
+ self._lines_not_executed.append(full_stmt[:last_span_start] + last_thm[2])
549
+ self._lines_not_executed.append(remaining_stmt)
550
+ self._content_till_last_theorem_stmt = full_stmt[:last_span_start] + last_thm[2] + remaining_stmt
551
+ else:
552
+ self._content_till_last_theorem_stmt = full_stmt[:last_span_start] + last_thm[2] + Lean4SyncExecutor.extra_by
553
+ break
554
+ if last_thm is None:
555
+ endings = [i for i in range(last_span_end, len(full_stmt)) if full_stmt.startswith('=> ', i)]
556
+ for ending in endings:
557
+ interesting_stmt = full_stmt[:ending] + ' => ' # We need to add '=>' to the end
558
+ interesting_span = (last_span_start, len(interesting_stmt))
559
+ last_thm = self._parse_theorem_stmt(idx, interesting_stmt, do_full_check, interesting_span)
560
+ if last_thm is not None:
561
+ self._content_till_last_theorem_stmt = full_stmt[:last_span_start] + last_thm[2] + ' by\n'
562
+ break
563
+ else:
564
+ last_thm = None
565
+ self._theorem_started = last_thm is not None
566
+ is_theorem_started = self._theorem_started
567
+ is_theorem_ended = is_theorem_started and is_theorem_ended
568
+ if last_thm is not None:
569
+ self._last_theorem = last_thm
570
+ return is_theorem_started
571
+
572
+ def _get_env(self, idx) -> Optional[int]:
573
+ env_idx = None
574
+ if idx in self._line_to_env_idx_map:
575
+ env_idx = self._line_to_env_idx_map[idx]
576
+ else:
577
+ self._line_to_env_idx_map[idx] = self._last_env_idx
578
+ env_idx = self._last_env_idx
579
+ return env_idx
580
+
581
+ def _update_env(self, idx: int):
582
+ self._last_env_idx = idx
583
+
584
+ def _update_proof_state_idx(self, idx: int):
585
+ self._last_proof_state_idx = idx
586
+
587
+ def _should_start_proof(self, stmt: str) -> bool:
588
+ return self._theorem_started
589
+
590
+ def _remove_proof_add_sorry(self) -> str:
591
+ # Find the last ':= by' and replace it with 'sorry' and remove the rest of the proof
592
+ matches = list(Lean4SyncExecutor.theorem_end_match.finditer(self._content_till_last_theorem_stmt))
593
+ if len(matches) == 0:
594
+ raise ValueError(f"Could not find the proof in the statement: {self._content_till_last_theorem_stmt}")
595
+ last_match = matches[-1]
596
+ span_start, span_end = last_match.span()
597
+ full_stmt = self._content_till_last_theorem_stmt[:span_end]
598
+ thm_end_style = last_match.group(3)
599
+ if thm_end_style == "=>":
600
+ # Find the last '|' in the full_stmt
601
+ thm_end_idx = full_stmt.rfind('|', start = span_start)
602
+ if thm_end_idx == -1:
603
+ remaining_stmt = self._content_till_last_theorem_stmt[span_end:]
604
+ thm_end_idx = remaining_stmt.find(':=')
605
+ if thm_end_idx == -1:
606
+ raise ValueError(f"Could not find the start of proof in the statement: {self._content_till_last_theorem_stmt}")
607
+ full_stmt = full_stmt + remaining_stmt[:thm_end_idx] + ' :='
608
+ new_stmt = full_stmt
609
+ else:
610
+ full_stmt = full_stmt[:thm_end_idx] + ' :='
611
+ new_stmt = full_stmt
612
+ else:
613
+ new_stmt = full_stmt
614
+ if not self.use_file:
615
+ new_stmt += " by sorry"
616
+ else:
617
+ new_stmt += " by\n"
618
+ self._content_till_last_theorem_stmt = new_stmt
619
+
620
+ def _write_lean_file(self, idx: int, file_content: str):
621
+ if self._file_handle is None:
622
+ self._file_handle = open(self.temp_file_full_path, "a+")
623
+ self._last_file_seek = self._file_handle.tell()
624
+ self._line_num_seek_map[idx] = self._last_file_seek
625
+ self._file_handle.write(file_content)
626
+ self._file_handle.flush()
627
+ pass
628
+
629
+ def _get_error_msg(self, msg_idx, msg) -> str:
630
+ line_start = msg['pos']['line'] if msg['pos'] is not None else ""
631
+ line_end = msg['endPos']['line'] if msg['endPos'] is not None else ""
632
+ full_error_msg = str(msg_idx) + ' ' + str(line_start) + " - " + str(line_end) + ": " + str(msg['data'])
633
+ return full_error_msg
634
+
635
+ def _run_file_on_lean_server(self, timeout_in_sec: int, only_env_update: bool = False):
636
+ cmd = {"path": self.temp_file_full_path}
637
+ self.process_interace.send_command(cmd)
638
+ response = self.process_interace.read_response(timeout_in_sec)
639
+ relevant_msgs = []
640
+ self._parse_response(0, response, relevant_msgs)
641
+ self._update_proof_context(0, response, relevant_msgs, only_env_update)
642
+ return response
643
+
644
+ def _add_last_tactic(self, idx: int, stmt: str):
645
+ if idx not in self._last_tactics:
646
+ self._last_tactics[idx] = stmt
647
+ self._last_tactic_line_idx = idx
648
+
649
+ def _get_cmd_tactic_mode(self, idx: int, stmt: str):
650
+ self._add_last_tactic(idx, stmt)
651
+ tactics_so_far = [(k, v) for k, v in self._last_tactics.items()]
652
+ tactics_so_far = sorted(tactics_so_far, key=lambda x: x[0])
653
+ tactics_so_far = [v for _, v in tactics_so_far]
654
+ if self._env_idx_last_thm is None:
655
+ return {"cmd": "\n".join(tactics_so_far)}
656
+ else:
657
+ return {"cmd": "\n".join(tactics_so_far), "env": self._env_idx_last_thm}
658
+
659
+ def _errors_since_last_thm(self, idx, error_message: str):
660
+ if idx not in self._error_messages_since_last_thm:
661
+ self._error_messages_since_last_thm[idx] = error_message
662
+
663
+ def _backtrack_tactic_line(self, idx: int):
664
+ # identify the keys to remove
665
+ idx_to_remove = []
666
+ backtracked = False
667
+ for k in self._last_tactics.keys():
668
+ if k >= idx:
669
+ idx_to_remove.append(k)
670
+ for k in idx_to_remove:
671
+ backtracked = True
672
+ del self._last_tactics[k]
673
+ idx_to_remove = []
674
+ for k in self._error_messages_since_last_thm.keys():
675
+ if k >= idx:
676
+ idx_to_remove.append(k)
677
+ for k in idx_to_remove:
678
+ backtracked = True
679
+ msg = self._error_messages_since_last_thm[k]
680
+ if msg in self._error_messages_so_far:
681
+ self._error_messages_so_far.remove(msg)
682
+ del self._error_messages_since_last_thm[k]
683
+ self._last_tactic_line_idx = max(self._last_tactics.keys(), default=None)
684
+ return backtracked
685
+
686
+ def _clear_tacitcs(self):
687
+ tactics_so_far = [(k, v) for k, v in self._last_tactics.items()]
688
+ tactics_so_far = sorted(tactics_so_far, key=lambda x: x[0])
689
+ tactics_so_far = [v for _, v in tactics_so_far]
690
+ self._write_lean_file(self._last_tactic_line_idx, "\n".join(tactics_so_far))
691
+ self._last_tactics = {}
692
+ self._last_tactic_line_idx = None
693
+ self._error_messages_since_last_thm = {}
694
+ pass
695
+
696
+ def get_all_proofs_in_file(self) -> Dict[str, List[Tuple[ProofContext, str]]]:
697
+ assert self.main_file is not None, "Main file is not provided"
698
+ abs_main_file = os.path.abspath(self.main_file)
699
+ assert os.path.exists(abs_main_file), f"Main file does not exist at {abs_main_file}"
700
+ assert abs_main_file.endswith(".lean"), "Main file must be a '.lean' file"
701
+ temp_file = os.path.join(self.project_root, self.temp_filename_suffix)
702
+ abs_temp_file = os.path.abspath(temp_file)
703
+ # Copy the file to a temporary file
704
+ shutil.copyfile(abs_main_file, abs_temp_file)
705
+ try:
706
+ abs_main_file = abs_temp_file
707
+ # Remove all the comments from the file
708
+ line_by_line_reader = LeanLineByLineReader(abs_main_file, remove_comments=True, no_strip=True)
709
+ all_stmts = list(line_by_line_reader.instruction_step_generator())
710
+ new_content = "\n".join(all_stmts)
711
+ with open(abs_main_file, "w") as f:
712
+ f.write(new_content)
713
+ # Run the file on the lean server
714
+ self.process_interace.send_command({"path": abs_main_file, "allTactics": True})
715
+ response = self.process_interace.read_response(self.timeout_in_sec*20)
716
+ tactics_resp = response.get('tactics', [])
717
+ # Parse all goals in these tactics
718
+ goals = [self._parse_proof_context([t['goals']]) for t in tactics_resp]
719
+ tactics = [t['tactic'] for t in tactics_resp]
720
+ line_nums = [t['pos']['line'] for t in tactics_resp]
721
+ line_num_dx = 0
722
+ result = {}
723
+ thm_id = uuid.uuid4().hex
724
+ thm_cnt = 0
725
+ all_theorems = get_all_theorems_in_file(abs_main_file, use_cache = True)
726
+ line_to_thm_map : typing.Dict[int, TheoremDetails] = {}
727
+ for thm_detail in all_theorems:
728
+ line_num = thm_detail.theorem_pos['line_start']
729
+ line_to_thm_map[line_num] = thm_detail
730
+ with open(abs_main_file, "r") as f:
731
+ lines = f.readlines()
732
+ for idx, line in enumerate(lines):
733
+ if Lean4SyncExecutor.theorem_start_match.match(line):
734
+ thm_detail = line_to_thm_map.get(idx + 1, None)
735
+ if thm_detail is not None:
736
+ thm_id = get_fully_qualified_theorem_name(thm_detail)
737
+ else:
738
+ thm_id = uuid.uuid4().hex + f"_{thm_cnt}"
739
+ thm_cnt += 1
740
+ while line_num_dx < len(line_nums) and line_nums[line_num_dx] == idx + 1:
741
+ if thm_id not in result:
742
+ result[thm_id] = [(goals[line_num_dx], tactics[line_num_dx])]
743
+ else:
744
+ result[thm_id].append((goals[line_num_dx], tactics[line_num_dx]))
745
+ line_num_dx += 1
746
+ return result
747
+ finally:
748
+ if os.path.exists(temp_file):
749
+ os.remove(temp_file)
750
+
751
+ def _theorem_started_init(self):
752
+ if self._theorem_started:
753
+ theorem_name, theorem_stmt, full_stmt = self._last_theorem
754
+ self.curr_lemma_name = theorem_name
755
+ self.curr_lemma = theorem_stmt
756
+ if len(theorem_name) == 0:
757
+ self._anon_theorem_count += 1
758
+ theorem_name = f"anon_theorem____{self._anon_theorem_count}"
759
+ self.local_file_lemmas[theorem_name] = theorem_stmt
760
+ self.local_theorem_lemma_description[theorem_name] = full_stmt
761
+
762
+ def _parse_response(self, idx, response, relevant_messages = [], dont_update_error_since_last_thm = True) -> bool:
763
+ has_cnt = 0
764
+ has_at_least_one_unfocussed_goal = 0
765
+ has_new_errors = 0
766
+ if 'messages' in response:
767
+ messages = response['messages']
768
+ # Go over all sev after the line number and check if there is an error
769
+ for msg_idx, msg in enumerate(messages):
770
+ full_error_msg = self._get_error_msg(msg_idx, msg)
771
+ unsolved_goal_never_seen_before = not (full_error_msg in self._error_messages_since_last_thm.values())
772
+ if msg['severity'] == 'error' and 'pos' in msg and 'endPos' in msg and \
773
+ ((msg['endPos'] is not None and 'line' in msg['endPos']) or \
774
+ (msg['pos'] is not None and 'line' in msg['pos'])):
775
+ if msg['data'].startswith(Lean4SyncExecutor.theorem_detection_message) and msg['endPos'] is None:
776
+ has_cnt += 1
777
+ continue # Ignore this error
778
+ saw_unsolved_goal = False
779
+ if msg['data'].startswith(Lean4SyncExecutor.unsolved_message):
780
+ has_at_least_one_unfocussed_goal += 1
781
+ saw_unsolved_goal = True
782
+ if full_error_msg in self._error_messages_so_far and (dont_update_error_since_last_thm or unsolved_goal_never_seen_before):
783
+ continue
784
+ else:
785
+ if not saw_unsolved_goal:
786
+ has_new_errors += 1
787
+ self._error_messages_so_far.add(full_error_msg)
788
+ if not dont_update_error_since_last_thm:
789
+ self._errors_since_last_thm(idx, full_error_msg)
790
+ if not unsolved_goal_never_seen_before:
791
+ msg['data'] = 'error: ' + msg['data']
792
+ relevant_messages.append(msg)
793
+ elif msg['severity'] == 'warning' and 'pos' in msg and 'endPos' in msg and 'sorry' in msg['data']:
794
+ full_error_msg = self._get_error_msg(msg_idx, msg)
795
+ if full_error_msg in self._error_messages_so_far and (dont_update_error_since_last_thm or unsolved_goal_never_seen_before):
796
+ continue
797
+ self._error_messages_so_far.add(full_error_msg)
798
+ if not dont_update_error_since_last_thm:
799
+ self._errors_since_last_thm(idx, full_error_msg)
800
+ if not unsolved_goal_never_seen_before:
801
+ msg['data'] = 'error: ' + msg['data']
802
+ relevant_messages.append(msg)
803
+ elif 'message' in response and 'proofState' not in response and 'sorries' not in response:
804
+ self.lean_error_messages = [response['message']]
805
+ # There is an irrecoverable error
806
+ if not self.process_interace.process_is_running():
807
+ raise Exception("Lean server got killed, probably due to an error in the line executed.\n" +
808
+ f"Check the error message: {self.lean_error_messages}")
809
+ return has_cnt == 1 and has_at_least_one_unfocussed_goal > 0 and has_new_errors == 0
810
+
811
+ def _update_proof_context(self, idx, response, relevant_messages, only_env_update = False):
812
+ if response is None:
813
+ raise ValueError(f"Response is None cannot update proof context for line number {idx}")
814
+ if 'env' in response:
815
+ env_idx = response['env']
816
+ else:
817
+ env_idx = None
818
+ if self._env_idx_last_thm is None and not self._proof_running:
819
+ self._env_idx_last_thm = self._last_env_idx
820
+ self._update_env(env_idx)
821
+ if self._env_idx_last_thm is None and not self._proof_running:
822
+ # This should run for the first time to set the env correctly
823
+ self._env_idx_last_thm = self._last_env_idx
824
+ if only_env_update:
825
+ self._env_idx_last_thm = self._last_env_idx
826
+ return
827
+ proof_running = 'sorries' in response or 'proofState' in response
828
+ error_messages = response.get('message', None)
829
+ goal_text = None
830
+ if error_messages is None and 'proofState' in response:
831
+ error_messages = response.get('messages', None)
832
+ elif error_messages is None:
833
+ # Go over all the relevant messages and see if there are messages other than unproved goals
834
+ error_messages = []
835
+ for msg in relevant_messages:
836
+ text_msg = msg.get('data', None)
837
+ if text_msg is not None and text_msg.startswith(Lean4SyncExecutor.unsolved_message):
838
+ goal_text = text_msg[len(Lean4SyncExecutor.unsolved_message):]
839
+ else:
840
+ error_messages.append(msg)
841
+ if len(error_messages) == 0:
842
+ error_messages = None
843
+ if len(relevant_messages) == 0:
844
+ goal_text = ''
845
+ elif error_messages is not None:
846
+ error_messages = [error_messages]
847
+ if error_messages is not None:
848
+ self.lean_error_messages = []
849
+ for error_message in error_messages:
850
+ if isinstance(error_message, dict):
851
+ error_message = error_message['severity'] + ": " + error_message['data']
852
+ else:
853
+ error_message = str(error_message)
854
+ self.lean_error_messages.append(error_message)
855
+ else:
856
+ self.lean_error_messages = []
857
+ proof_running = proof_running or goal_text is not None
858
+ if error_messages is None:
859
+ assert proof_running, f"Proof is not running but no error message is present, response:\n{response}, \nstmt: \n{stmt}, \nlemma: \n{self.curr_lemma_name}, \nlemma_stmt: \n{self.curr_lemma}, \nline_num: \n{self.line_num}"
860
+ self._proof_running = proof_running
861
+ if self._proof_running:
862
+ proof_state_idx = None
863
+ proof_goals = []
864
+ if goal_text is not None:
865
+ if len(goal_text) == 0:
866
+ proof_goals = []
867
+ else:
868
+ proof_goals = [goal_text]
869
+ elif 'sorries' in response:
870
+ sorries = response['sorries']
871
+ # TODO: Go over all the sorries and find the one which matches the line number with idx + 1
872
+ # Now we are only supporting the last sorry
873
+ proof_state = sorries[-1]
874
+ proof_state_idx = proof_state['proofState']
875
+ proof_goals = [proof_state['goal']]
876
+ elif 'proofState' in response:
877
+ proof_state = response
878
+ proof_state_idx = response['proofState']
879
+ proof_goals = response['goals']
880
+ self._update_proof_state_idx(proof_state_idx)
881
+ self.proof_context = self._parse_proof_context(proof_goals)
882
+ if self.proof_context == ProofContext.empty():
883
+ self._proof_running = False
884
+ self.proof_context = None
885
+ self.curr_lemma = None
886
+ self.curr_lemma_name = None
887
+ self._clear_tacitcs()
888
+ self._env_idx_last_thm = self._last_env_idx
889
+ else:
890
+ self.proof_context = None
891
+
892
+ def _run_stmt_on_lean_server(self, idx : int, stmt: str, theorem_started: bool = False):
893
+ if "sorry" in stmt and self._proof_running:
894
+ # We don't need to run the sorry statements. This should be treated as a failed proof step
895
+ self.lean_error_messages = ["The tactic 'sorry' was found in the statement, this is not allowed"]
896
+ return
897
+ elif len(stmt.strip()) == 0 and self._proof_running:
898
+ # We don't need to run the empty statements. This should be treated as a failed proof step
899
+ self.lean_error_messages = ["There is no tactic in the statement, it is just empty line or whitespace"]
900
+ return
901
+ proof_should_run = False
902
+ if theorem_started or (not self._proof_running and self._stmt_has_lemma(idx, stmt, do_full_check = True)):
903
+ proof_should_run = self._theorem_started
904
+ self._theorem_started_init()
905
+ if not self._proof_running and not proof_should_run:
906
+ return
907
+ env_idx = self._get_env(idx)
908
+ cmd_was_executed = False
909
+ response = None
910
+ while not cmd_was_executed:
911
+ # Run the statement in tactic mode
912
+ if self._env_idx_last_thm is None:
913
+ self._env_idx_last_thm = env_idx
914
+ if self.process_interace.is_rebooted():
915
+ self._run_file_on_lean_server(self.timeout_in_sec * 5, only_env_update=True)
916
+ cmd = self._get_cmd_tactic_mode(idx, stmt)
917
+ if env_idx is not None and 'env' not in cmd:
918
+ cmd["env"] = env_idx
919
+ self.process_interace.send_command(cmd)
920
+ self._content_till_last_theorem_stmt = None
921
+ timed_out = False
922
+ try:
923
+ timed_out_in_secs = self.timeout_in_sec
924
+ response = self.process_interace.read_response(timed_out_in_secs)
925
+ relevant_messages = []
926
+ self._parse_response(idx, response, relevant_messages, dont_update_error_since_last_thm=False)
927
+ cmd_was_executed = True
928
+ except TimeoutError:
929
+ if not self.suppress_error_log:
930
+ self.logger.error(f"Timeout error while running '{stmt}' on lean. File name: {self.main_file}")
931
+ timed_out = True
932
+ cmd_was_executed = True
933
+ except:
934
+ if not self.suppress_error_log:
935
+ self.logger.error(f"Got an exception while running '{stmt}' on lean. File name: {self.main_file}")
936
+ self.logger.exception(f"Exception Log")
937
+ cmd_was_executed = True
938
+ if cmd_was_executed:
939
+ raise
940
+ if timed_out:
941
+ self.lean_error_messages = ["The tactic timed out, probably because of repeated application of a tactic which created a very big goal."]
942
+ else:
943
+ self._update_proof_context(idx, response, relevant_messages)
944
+ pass
945
+
946
+ def _skip_to_theorem(self, theorem: str):
947
+ # Skip to the given theorem
948
+ found_theorem = False
949
+ thm_namespace, given_theorem_name = parse_thm_name(theorem)
950
+ while not found_theorem and not self.execution_complete:
951
+ try:
952
+ stmt = next(self.main_file_iter)
953
+ except StopIteration:
954
+ self.execution_complete = True
955
+ break
956
+ self.current_stmt = stmt
957
+ self.line_num += 1
958
+ if self._stmt_has_lemma(self.line_num - 1, stmt):
959
+ proof_should_run = self._should_start_proof(stmt)
960
+ if proof_should_run:
961
+ thm_name, thm_stmt, full_thm_stmt = self._last_theorem
962
+ last_namespace = ".".join(self._namespaces) if len(self._namespaces) > 0 else ""
963
+ if thm_name is not None and thm_name == given_theorem_name and (len(thm_namespace) == 0 or thm_namespace == last_namespace):
964
+ found_theorem = True
965
+ orig_thm_started = self._theorem_started
966
+ self._theorem_started = True
967
+ self._content_till_last_theorem_stmt = '\n'.join(self._lines_executed)
968
+ if self._stmt_has_lemma(self.line_num - 1, stmt, do_full_check=True):
969
+ self._theorem_started_init()
970
+ else:
971
+ found_theorem = False
972
+ self._theorem_started = orig_thm_started
973
+ else:
974
+ if thm_name is None or len(thm_name) == 0:
975
+ self._anon_theorem_count += 1
976
+ thm_name = f"anon_theorem____{self._anon_theorem_count}"
977
+ self.local_file_lemmas[thm_name] = thm_stmt
978
+ self.local_theorem_lemma_description[thm_name] = full_thm_stmt
979
+ self._content_till_last_theorem_stmt = None
980
+ self._lines_executed.append(stmt)
981
+ if not found_theorem:
982
+ raise ValueError(f"The theorem '{theorem}' was not found in the file '{self.main_file}'")
983
+
984
+ def _parse_proof_context(self, proof_goals: list) -> ProofContext:
985
+ goals = []
986
+ for proof_goal in proof_goals:
987
+ if self.use_human_readable_proof_context:
988
+ goals.extend(Lean4Utils.parse_proof_context_human_readable_as_goals(proof_goal))
989
+ else:
990
+ raise NotImplementedError("Parsing of non-human readable proof context is not implemented")
991
+ if len(goals) == 0:
992
+ return ProofContext.empty()
993
+ else:
994
+ return ProofContext(goals, [], [], [])
995
+
996
+
997
+ theorem_names_in_file_cache: Dict[str, List[TheoremDetails]] = {}
998
+ namespace_regex = r"^namespace[ ]+([\S]+)"
999
+ namespace_match = re.compile(namespace_regex, re.MULTILINE)
1000
+ namespace_end_regex = r"^end[ ]+([\S]+)*"
1001
+ namespace_end_match = re.compile(namespace_end_regex, re.MULTILINE)
1002
+
1003
+ def parse_thm_name(theorem_name: str) -> Tuple[str, str]:
1004
+ if theorem_name.startswith("{") and theorem_name.endswith("}"):
1005
+ thm_dict = json.loads(theorem_name)
1006
+ return thm_dict["namespace"], thm_dict["name"]
1007
+ else:
1008
+ return "", theorem_name
1009
+
1010
+ def process_namespaces(file_cotent: str, open_namespaces: List[str], is_full_content: bool=False):
1011
+ # Match the namespace regex
1012
+ # Break the content line by line and match the namespace and end namespace
1013
+ file_lines = file_cotent.split('\n')
1014
+ for line in file_lines:
1015
+ namespace_matches = namespace_match.findall(line)
1016
+ namespace_end_matches = namespace_end_match.findall(line)
1017
+ for ns in namespace_matches:
1018
+ if not is_full_content or ns not in open_namespaces:
1019
+ open_namespaces.append(ns)
1020
+ for ns in namespace_end_matches:
1021
+ try:
1022
+ open_namespaces.remove(ns)
1023
+ except ValueError:
1024
+ pass
1025
+
1026
+ def get_all_theorems_in_file(file_path: str, use_cache: bool=False) -> List[TheoremDetails]:
1027
+ if use_cache and file_path in theorem_names_in_file_cache:
1028
+ return theorem_names_in_file_cache[file_path]
1029
+ file_content = ""
1030
+ open_namespaces = []
1031
+ with open(file_path, "r") as f:
1032
+ file_content = f.read()
1033
+ line_by_line_reader = LeanLineByLineReader(file_content=file_content, remove_comments=True, no_strip=True)
1034
+ all_stmts = list(line_by_line_reader.instruction_step_generator())
1035
+ line_positions = [0] + [len(stmt) + 1 for stmt in all_stmts]
1036
+ # Cumulative sum of the line positions
1037
+ for i in range(1, len(line_positions)):
1038
+ line_positions[i] += line_positions[i - 1]
1039
+ full_content = '\n'.join(all_stmts)
1040
+ # all_matches = Lean4SyncExecutor.theorem_match.findall(full_content)
1041
+ all_matches = list(Lean4SyncExecutor.theorem_match.finditer(full_content))
1042
+ all_theorems = []
1043
+ last_namespace_processed_idx = 0
1044
+ for match in all_matches:
1045
+ span_start, span_end = match.span()
1046
+ process_namespaces(full_content[last_namespace_processed_idx:span_start], open_namespaces)
1047
+ theorem_name = match.group(5)
1048
+ theorem_name = theorem_name if theorem_name is not None else f"\"{match.group(6).strip(': ')}\""
1049
+ theorem_namespace = '.'.join(open_namespaces) if len(open_namespaces) > 0 else ''
1050
+ line_number_start = bisect.bisect_left(line_positions, span_start)
1051
+ line_number_end = bisect.bisect_left(line_positions, span_end)
1052
+ theorem_pos = {
1053
+ 'line_start': line_number_start + 1,
1054
+ 'line_end': line_number_end + 1,
1055
+ 'global_pos_start': span_start,
1056
+ 'global_pos_end': span_end,
1057
+ 'line_pos_start': span_start - line_positions[line_number_start] if line_number_start < len(line_positions) else 0,
1058
+ 'line_pos_end': span_end - line_positions[line_number_end] if line_number_end < len(line_positions) else 0
1059
+ }
1060
+ theorem_details = TheoremDetails(
1061
+ theorem_name=theorem_name,
1062
+ theorem_namespace=theorem_namespace,
1063
+ theorem_file_path=file_path,
1064
+ theorem_pos=theorem_pos)
1065
+ all_theorems.append(theorem_details)
1066
+ last_namespace_processed_idx = span_end
1067
+ if use_cache:
1068
+ theorem_names_in_file_cache[file_path] = all_theorems
1069
+ return all_theorems
1070
+
1071
+ def get_fully_qualified_theorem_name(theorem_details: TheoremDetails) -> str:
1072
+ if len(theorem_details.theorem_namespace) == 0:
1073
+ return theorem_details.theorem_name
1074
+ else:
1075
+ dict_thm = {"namespace": theorem_details.theorem_namespace, "name": theorem_details.theorem_name}
1076
+ return json.dumps(dict_thm)
1077
+
1078
+ def get_theorem_name_resembling(file_path: str, theorem_name: str, use_cache: bool=False) -> Optional[str]:
1079
+ all_theorems = get_all_theorems_in_file(file_path, use_cache=use_cache)
1080
+ all_theorems_name_unique_map : Dict[str, List[TheoremDetails]] = {}
1081
+ for thm in all_theorems:
1082
+ if thm.theorem_name in all_theorems_name_unique_map:
1083
+ all_theorems_name_unique_map[thm.theorem_name].append(thm)
1084
+ else:
1085
+ all_theorems_name_unique_map[thm.theorem_name] = [thm]
1086
+ all_parts = theorem_name.split('.')
1087
+ thm_start_idx = len(all_parts) - 1
1088
+ thm_found = False
1089
+ while not thm_found and thm_start_idx >= 0:
1090
+ full_name = '.'.join(all_parts[thm_start_idx:])
1091
+ # look for any theorems matching with full_name
1092
+ thm_found = full_name in all_theorems_name_unique_map
1093
+ thm_start_idx -= 1
1094
+ if not thm_found:
1095
+ full_name = '_root_.' + full_name
1096
+ # look for any theorems matching with the full_name
1097
+ thm_found = full_name in all_theorems_name_unique_map
1098
+ if not thm_found:
1099
+ raise ValueError(f"The theorem '{theorem_name}' was not found in the file '{file_path}'")
1100
+ assert thm_found, "The theorem was not found some code bug in finding the theorem names"
1101
+ theorem_name_matches = all_theorems_name_unique_map[full_name]
1102
+ if len(theorem_name_matches) == 1:
1103
+ if len(theorem_name_matches[0].theorem_namespace) == 0:
1104
+ return theorem_name_matches[0].theorem_name
1105
+ else:
1106
+ dict_thm = {"namespace": theorem_name_matches[0].theorem_namespace, "name": theorem_name_matches[0].theorem_name}
1107
+ return json.dumps(dict_thm)
1108
+ else:
1109
+ # We need to find the namespace which matches with the theorem_name
1110
+ for thm in theorem_name_matches:
1111
+ if theorem_name.endswith(thm.theorem_namespace + '.' + thm.theorem_name) or\
1112
+ (theorem_name.strip() == thm.theorem_name and len(thm.theorem_namespace) == 0):
1113
+ dict_thm = {"namespace": thm.theorem_namespace, "name": thm.theorem_name}
1114
+ return json.dumps(dict_thm)
1115
+ raise ValueError(f"The theorem '{theorem_name}' was not found in the file '{file_path}'")
1116
+
1117
+ if __name__ == "__main__":
1118
+ from itp_interface.tools.log_utils import setup_logger
1119
+ import datetime
1120
+ project_root = 'data/test/Mathlib/'
1121
+ file_path = 'data/test/Mathlib/.lake/packages/mathlib/Mathlib/Computability/TuringMachine.lean'
1122
+ os.chdir(root_dir)
1123
+ assert os.path.exists(project_root), "Project root does not exist"
1124
+ assert os.path.exists(file_path), "File path does not exist"
1125
+ print("Finding all theorems in the file")
1126
+ all_theorems = get_all_theorems_in_file(file_path, use_cache=True)
1127
+ print(all_theorems)
1128
+ theorems_similar_to_test = get_theorem_name_resembling(file_path, "Turing.TM1to1.tr_supports", use_cache=True)
1129
+ print("Theorem similar to ", "Turing.TM1to1.tr_supports", " is ", theorems_similar_to_test)
1130
+ project_root = 'data/test/lean4_proj/'
1131
+ file_path = 'data/test/lean4_proj/Lean4Proj/Basic.lean'
1132
+ theorem_name = "Lean4Proj2.test3"
1133
+ theorems_similar_to_test = get_theorem_name_resembling(file_path, theorem_name, use_cache=True)
1134
+ print("Theorem similar to ", "Lean4Proj2.test", " is ", theorems_similar_to_test)
1135
+ project_root = 'data/test/Mathlib/'
1136
+ # theorem_name = 'WeierstrassCurve.Jacobian.equiv_of_Z_eq_zero'
1137
+ # file_path = 'data/test/Mathlib/.lake/packages/mathlib/Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean'
1138
+ theorem_name = 'LieSubmodule.coe_toSubmodule_mk'
1139
+ file_path = 'data/test/Mathlib/.lake/packages/mathlib/Mathlib/Algebra/Lie/Submodule.lean'
1140
+ theorems_similar_to_test = get_theorem_name_resembling(file_path, theorem_name, use_cache=True)
1141
+ date_time = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
1142
+ lean_exec_log_folder = f'.log/lean4_sync_executor/{date_time}'
1143
+ os.makedirs(lean_exec_log_folder, exist_ok=True)
1144
+ lean_exec_log_file = os.path.join(lean_exec_log_folder, "lean4_sync_executor.log")
1145
+ logger = setup_logger("Lean4SyncExecutor", lean_exec_log_file, level=logging.DEBUG, format='')
1146
+ # with Lean4SyncExecutor(main_file=file_path, project_root=project_root, logger=logger) as executor:
1147
+ # all_proofs = executor.get_all_proofs_in_file()
1148
+ # print(all_proofs)
1149
+ with Lean4SyncExecutor(main_file=file_path, project_root=project_root, logger=logger) as executor:
1150
+ executor.set_run_exactly()
1151
+ executor._skip_to_theorem(theorems_similar_to_test)
1152
+ assert executor.proof_context is not None, "Proof context should be present"
1153
+ proof_exec = False
1154
+ while not executor.execution_complete:
1155
+ if executor.proof_context is not None:
1156
+ proof_exec = True
1157
+ for goal in executor.proof_context.all_goals:
1158
+ for hyp in goal.hypotheses:
1159
+ print(hyp)
1160
+ print('-'*10)
1161
+ print(goal.goal)
1162
+ print('-'*20)
1163
+ executor.run_next()
1164
+ print("Current statement:", executor.current_stmt)
1165
+ if executor.proof_context is None and proof_exec:
1166
+ proof_exec = False
1167
+ print("Proof finished")
1168
+ break
1169
+ if executor.lean_error_messages:
1170
+ print("Error messages:\n", executor.lean_error_messages)
1171
+
1172
+ mathlib_test_file = 'data/test/Mathlib/.lake/packages/mathlib/Mathlib/Data/Nat/Bits.lean'
1173
+ project_root = 'data/test/Mathlib'
1174
+ assert os.path.exists(mathlib_test_file), "Mathlib test file does not exist"
1175
+ assert os.path.exists(project_root), "Project root does not exist"
1176
+ with Lean4SyncExecutor(main_file=mathlib_test_file, project_root=project_root, timeout_in_sec=120) as executor:
1177
+ executor._skip_to_theorem("one_bits")
1178
+ assert executor.proof_context is not None, "Proof context should be present"
1179
+ while not executor.execution_complete:
1180
+ if executor.proof_context is not None:
1181
+ for goal in executor.proof_context.all_goals:
1182
+ for hyp in goal.hypotheses:
1183
+ print(hyp)
1184
+ print('-'*10)
1185
+ print(goal.goal)
1186
+ print('-'*20)
1187
+ executor.run_next()
1188
+ print("Current statement:", executor.current_stmt)
1189
+ if executor.proof_context is None:
1190
+ print("Proof finished")
1191
+ break
1192
+ if executor.lean_error_messages:
1193
+ print("Error messages:\n", executor.lean_error_messages)