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,862 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import signal
4
+ import sys
5
+ root_dir = f"{__file__.split('itp_interface')[0]}"
6
+ if root_dir not in sys.path:
7
+ sys.path.append(root_dir)
8
+ import os
9
+ import subprocess
10
+ import logging
11
+ import typing
12
+ import functools
13
+ import re
14
+ import time
15
+ import threading
16
+ from collections import OrderedDict
17
+ from pathlib import Path
18
+ from enum import Enum
19
+ from itp_interface.pisa.src.main.python.pisa_client import PisaEnv, initialise_env, IsabelleLemma
20
+ from itp_interface.tools.isabelle_parse_utils import IsabelleLineByLineReader, IsabelleStepByStepStdInReader
21
+ logger = logging.getLogger()
22
+
23
+ class Obligation(typing.NamedTuple):
24
+ hypotheses: typing.List[str]
25
+ goal: str
26
+
27
+ @classmethod
28
+ def from_dict(cls, data):
29
+ return cls(**data)
30
+
31
+ def to_dict(self) -> typing.Dict[str, typing.Any]:
32
+ return {"hypotheses": self.hypotheses,
33
+ "goal": self.goal}
34
+
35
+
36
+ class ProofContext(typing.NamedTuple):
37
+ fg_goals: typing.List[Obligation]
38
+ bg_goals: typing.List[Obligation]
39
+ shelved_goals: typing.List[Obligation]
40
+ given_up_goals: typing.List[Obligation]
41
+
42
+ @classmethod
43
+ def empty(cls: typing.Type['ProofContext']):
44
+ return ProofContext([], [], [], [])
45
+
46
+ @classmethod
47
+ def from_dict(cls, data):
48
+ fg_goals = list(map(Obligation.from_dict, data["fg_goals"]))
49
+ bg_goals = list(map(Obligation.from_dict, data["bg_goals"]))
50
+ shelved_goals = list(map(Obligation.from_dict, data["shelved_goals"]))
51
+ given_up_goals = list(map(Obligation.from_dict,
52
+ data["given_up_goals"]))
53
+ return cls(fg_goals, bg_goals, shelved_goals, given_up_goals)
54
+
55
+ def to_dict(self) -> typing.Dict[str, typing.Any]:
56
+ return {"fg_goals": list(map(Obligation.to_dict, self.fg_goals)),
57
+ "bg_goals": list(map(Obligation.to_dict, self.bg_goals)),
58
+ "shelved_goals": list(map(Obligation.to_dict,
59
+ self.shelved_goals)),
60
+ "given_up_goals": list(map(Obligation.to_dict,
61
+ self.given_up_goals))}
62
+
63
+ @property
64
+ def all_goals(self) -> typing.List[Obligation]:
65
+ return self.fg_goals + self.bg_goals + \
66
+ self.shelved_goals + self.given_up_goals
67
+
68
+ @property
69
+ def focused_goal(self) -> str:
70
+ if self.fg_goals:
71
+ return self.fg_goals[0].goal
72
+ else:
73
+ return ""
74
+
75
+ @property
76
+ def focused_hyps(self) -> typing.List[str]:
77
+ if self.fg_goals:
78
+ return self.fg_goals[0].hypotheses
79
+ else:
80
+ return []
81
+
82
+ class HammerMode(Enum):
83
+ NONE = 'NONE' # Prohibit hammer
84
+ ALLOW = 'ALLOW' # Allow agent to query hammer
85
+ AUTO = 'AUTO' # Automatically apply hammer to individual tactics (heuristically)
86
+ ONESHOT = 'ONESHOT' # Proof attempt in one shot using hammer
87
+ ALWAYS = 'ALWAYS' # Always use hammer on thesis after a successful proof attempt
88
+
89
+ def __str__(self):
90
+ return self.name
91
+
92
+ class IsabelleExecutor:
93
+ # This doesn't do the best job of capturing each state changing
94
+ # tactic separately. It relies on the fact the tactics are usually written in an
95
+ # atomic way on separate lines. However for a simple REPL, we can just assume that
96
+ # the user writes tactics in an atomic way.
97
+
98
+ # Keywords list may not be complete
99
+ keywords = {
100
+ "section", "theory", "imports", "begin", "end", "text", "lemma", "theorem", "assume", "assumes", "proof", "have",
101
+ "fix", "show", "shows", "then", "with", "qed", "next", "obtain", "by", "for", "?thesis", "contradiction",
102
+ "datatype", "fun", "where", "subsection", "term", "value", "declare", "using", "case"
103
+ }
104
+
105
+ # Matches theorem declarations
106
+ theorem_regex = r"((((theorem\s+|lemma\s+)([\w+|\d+'_]*)))(\s*:\s*)?([\S|\s]*))"
107
+ theorem_match = re.compile(theorem_regex, re.MULTILINE)
108
+
109
+ # Matches proof context returned by Isabelle engine
110
+ proof_context_regex = r"\s*proof \((state|prove|chain)\)\s*((using )?this:([\s|\S]*?))?goal([\s|\S]*?):\s*([\s|\S]*)"
111
+ proof_context_match = re.compile(proof_context_regex, re.MULTILINE)
112
+
113
+ # Matches theory initialization
114
+ begin_theory_regex = r"theory([\s\S]*)imports([\s\S]*)begin"
115
+ begin_theory_match = re.compile(begin_theory_regex, re.MULTILINE)
116
+
117
+ # Matches 'assms_x:' in hypotheses
118
+ assms_regex = r"assms_(\d+):"
119
+ assms_regex_match = re.compile(assms_regex)
120
+
121
+ # Proof automation tactics: [tactics from LYRA] + `algebra`
122
+ auto_tactics = ["auto", "simp", "blast", "fastforce", "force", "eval", "presburger", "sos", "arith", "linarith", "(auto simp: field_simps)", "algebra"]
123
+
124
+ def __init__(self, project_root: str = None, main_file: str = None, use_hammer: HammerMode = HammerMode.AUTO, timeout_in_sec: int = 60,
125
+ use_human_readable_proof_context: bool = False, proof_step_iter: typing.Iterator[str] = None,
126
+ suppress_error_log: bool = False, port: int = 8000):
127
+ assert proof_step_iter is None or isinstance(proof_step_iter, typing.Iterator), \
128
+ "proof_step_iter must be an iterator"
129
+ assert main_file is not None or proof_step_iter is not None, \
130
+ "Either main_file or proof_step_iter must be provided"
131
+ assert (main_file is None) or (project_root is not None), \
132
+ "Project root must be provided for Isabelle, if main file is provided"
133
+ assert main_file is None or (os.path.exists(main_file) and main_file.endswith(".thy")), \
134
+ "main_file must be a valid path to a '.thy' file"
135
+ assert project_root is None or (os.path.exists(project_root) and os.path.isdir(project_root)), \
136
+ "project_root must be a valid path to a directory"
137
+ self.use_human_readable_proof_context = use_human_readable_proof_context
138
+ self.project_root = project_root if project_root is not None else "."
139
+ self.main_file = main_file
140
+ self.use_hammer = use_hammer
141
+ self.timeout_in_sec = min(timeout_in_sec, 120) # Maximum 120s timeout
142
+ self.current_stmt = None
143
+ self.line_num = 0
144
+ self.current_state = 0
145
+ self.line_num_to_state = {}
146
+ self.main_file_iter = proof_step_iter
147
+ self.buffer = ""
148
+ self.suppress_error_log = suppress_error_log
149
+ self.pisa_env : PisaEnv = None
150
+ self.proof_context : ProofContext = None
151
+ self.curr_lemma_name : typing.Optional[str] = None
152
+ self.curr_lemma : typing.Optional[str] = ""
153
+ self._proof_running = False
154
+ self._top_level = True
155
+ self.local_theorem_lemma_description: typing.OrderedDict[str, str] = OrderedDict()
156
+ self.execution_complete = False
157
+ self.global_lemmas = []
158
+ self.port = int(os.environ.get("PISA_PORT", port))
159
+ self._seldgehammer_cache : typing.Dict[int,typing.Dict[str, str]] = {}
160
+ home_dir = str(Path.home())
161
+ if os.path.exists(os.path.join(home_dir, "Isabelle2022")):
162
+ self.isa_install_dir = os.path.join(home_dir, "Isabelle2022")
163
+ else:
164
+ raise Exception("Isabelle2022 installation not found. Please install Isabelle2022 and set the path to the installation directory in the environment variable 'ISABELLE_HOME'")
165
+
166
+ def __enter__(self):
167
+ self._all_dep_handles = []
168
+
169
+ if self.main_file_iter is None:
170
+ self.main_file_iter = IsabelleLineByLineReader(self.main_file).instruction_step_generator()
171
+
172
+ # PISA clients must provide a file and working directory. If these are not provided,
173
+ # or if the file path is not supported by PISA, use the default header, which may or may not be sufficient.
174
+ if self.main_file is None:
175
+ logger.warning("Initialising Isabelle environment with default theory header and imports (Complex_Main). Pass in a file and project root to import additional theories")
176
+ default_theory_file_path = os.path.join(self.isa_install_dir, "src/HOL/Library/Discrete.thy")
177
+ default_working_directory = os.path.join(self.isa_install_dir, "src/HOL/Library")
178
+ self.pisa_env = initialise_env(port=self.port, isa_path=self.isa_install_dir, theory_file_path=default_theory_file_path, working_directory=default_working_directory)
179
+ self.pisa_env.initialise()
180
+ else:
181
+ try:
182
+ self.pisa_env = initialise_env(port=self.port, theory_file_path=self.main_file, working_directory=self.project_root)
183
+ self.pisa_env.initialise()
184
+ except:
185
+ logger.warning("Theory initialization failed. Most likely this file path is not supported by PISA.")
186
+ logger.warning("Initialising Isabelle environment with default theory header and imports (Complex_Main).")
187
+ self.pisa_env = initialise_env(port=self.port)
188
+ self.pisa_env.initialise()
189
+
190
+
191
+ return self
192
+
193
+ def __exit__(self, exc_type, exc_value, traceback):
194
+ try:
195
+ self.main_file_iter.close() # Close the file handle
196
+ except:
197
+ pass
198
+
199
+ def start_server(logger : logging.Logger = None, port: int = 8000):
200
+ if "PISA_PORT" in os.environ:
201
+ port = int(os.environ["PISA_PORT"])
202
+ else:
203
+ os.environ["PISA_PORT"] = str(port)
204
+ assert port > 0, "Port number must be greater than 0"
205
+ assert port < 65536, "Port number must be less than 65536"
206
+ jar_path = "itp_interface/pisa/target/scala-2.13/PISA-assembly-0.1.jar"
207
+ assert os.path.exists(jar_path), "PISA jar file not found. Please build the project using 'sbt assembly' commnad"
208
+ logger = logger if logger is not None else logging.getLogger('isabelle_pisa_executor')
209
+ cmd = f"java -cp {jar_path} pisa.server.PisaOneStageServer{port}"
210
+ # Start the server in a separate process
211
+ cwd = os.getcwd()
212
+ server_process = subprocess.Popen(
213
+ cmd,
214
+ cwd=cwd,
215
+ shell=True,
216
+ stdout=subprocess.PIPE,
217
+ stderr=subprocess.PIPE,
218
+ preexec_fn=os.setsid) # Create a new process group so that we can kill the process and all its children
219
+ pid = server_process.pid
220
+ os.environ["PISA_SERVER_PID"] = str(pid)
221
+ # Log the process id
222
+ logger.info(f"Server process id: {pid}")
223
+ # Log the port number
224
+ logger.info(f"Server port: {port}")
225
+ logger.info("Waiting for server to start")
226
+ time.sleep(5)
227
+ server_running = IsabelleExecutor.check_server_running(logger)
228
+ if not server_running:
229
+ logger.error(f"Server is not running on port {port}")
230
+ else:
231
+ thread = threading.Thread(target=IsabelleExecutor._server_loggening_thread, args=(logger, server_process))
232
+ thread.start()
233
+ thread_id = thread.ident
234
+ os.environ["PISA_SERVER_THREAD_ID"] = str(thread_id)
235
+ pass
236
+
237
+ def check_server_running(logger : logging.Logger):
238
+ assert "PISA_PORT" in os.environ, "PISA_PORT environment variable is not set"
239
+ port = int(os.environ["PISA_PORT"])
240
+ # log the netsat result netstat -nlp | grep :{port}
241
+ netstat_cmd = f"netstat -nlp | grep :{port}"
242
+ logger.info(f"Netstat command: {netstat_cmd}")
243
+ output = subprocess.run(netstat_cmd, shell=True, capture_output=True)
244
+ logger.info(f"Netstat output: {output}")
245
+ output_str = output.stdout.decode("utf-8")
246
+ logger.info(f"Netstat output stdout: {output_str}")
247
+ server_running = "tcp" in output_str
248
+ return server_running
249
+
250
+ def _server_loggening_thread(logger : logging.Logger, process: subprocess.Popen):
251
+ # Keep checking the server is running
252
+ process_killed = False
253
+ while not process_killed:
254
+ try:
255
+ line = process.stdout.readline()
256
+ if not line:
257
+ break
258
+ logger.info(line)
259
+ except:
260
+ logger.info("Stdout is closed")
261
+ time.sleep(1)
262
+ # Reload the environment variables as they are shared across threads (not processes)
263
+ process_killed = os.environ.get("PISA_PROCESS_KILLED", "False") == "True"
264
+ logger.info("Server is shut down")
265
+ # Print the environment variables
266
+ logger.info(f"Environment variables at shutdown time: {os.environ}")
267
+ time.sleep(1)
268
+ pass
269
+
270
+ def stop_server():
271
+ os.environ["PISA_PROCESS_KILLED"] = "True"
272
+ pisa_pid = int(os.environ["PISA_SERVER_PID"])
273
+ try:
274
+ # Kill the server process
275
+ os.killpg(pisa_pid, signal.SIGTERM)
276
+ except:
277
+ pass
278
+ if "PISA_SERVER_THREAD_ID" in os.environ:
279
+ thread_id = int(os.environ["PISA_SERVER_THREAD_ID"])
280
+ # Find the right thread object
281
+ for thread in threading.enumerate():
282
+ if thread.ident == thread_id:
283
+ thread.join(5)
284
+ break
285
+ os.unsetenv("PISA_SERVER_THREAD_ID")
286
+ # Reset the environment variables
287
+ os.unsetenv("PISA_PROCESS_KILLED")
288
+ os.unsetenv("PISA_SERVER_PID")
289
+ pass
290
+
291
+ # The following token separators may not be completely correct
292
+
293
+ @property
294
+ def token_separator_set(self):
295
+ return set(" ()[]{}.,;:+-*/=<>!~?@#$%^&|`\"\\")
296
+
297
+ @property
298
+ def token_separator(self):
299
+ return " ()[]{}.,;:+-*/=<>!~?@#$%^&|`\"\\"
300
+
301
+ @property
302
+ def token_separator_regex(self):
303
+ return "\s+|\(|\)|\[|\]|\{|\}|\.|,|;|:|\?|@|#|\$|%|\^|&|\||`|\"|\\\\" +\
304
+ ""#"|\+|-|\*|/|=|<|>|!|~"
305
+
306
+ @staticmethod
307
+ def get_token_separator_set():
308
+ return set(" ()[]{}.,;:+-*/=<>!~?@#$%^&|`\"\\")
309
+
310
+ @staticmethod
311
+ def get_token_separators():
312
+ return " ()[]{}.,;:+-*/=<>!~?@#$%^&|`\"\\"
313
+
314
+ @staticmethod
315
+ def get_token_separator_regex():
316
+ return "\s+|\(|\)|\[|\]|\{|\}|\.|,|;|:|\?|@|#|\$|%|\^|&|\||`|\"|\\\\" +\
317
+ ""#"|\+|-|\*|/|=|<|>|!|~"
318
+
319
+ def is_in_proof_mode(self):
320
+ return True if self.proof_context else False
321
+
322
+ def needs_qed(self):
323
+ return self.proof_context is not None and len(self.proof_context.all_goals) == 0
324
+
325
+ def needs_cut_close(self):
326
+ # Not supported. Even if there is a nested proof, we still can use `qed` to close the proof
327
+ return False
328
+
329
+ def get_state_str(self, state_num):
330
+ if state_num == 0:
331
+ return 'default'
332
+ return 'state' + str(state_num)
333
+
334
+ def run_next(self, proof_search_mode=True) -> str:
335
+ try:
336
+ stmt = next(self.main_file_iter)
337
+ except StopIteration:
338
+ self.execution_complete = True
339
+ return ""
340
+ self.current_stmt = stmt
341
+ self.line_num += 1
342
+ try:
343
+ stmt = self._run_stmt_on_isabelle_server(stmt, proof_search_mode)
344
+ except:
345
+ if proof_search_mode:
346
+ if not self.suppress_error_log:
347
+ logger.error(f"Got an exception while running '{stmt}' on isabelle. File name: {self.main_file}")
348
+ logger.exception(f"Exception Log")
349
+ raise
350
+ else:
351
+ # If we're not in proof search mode, we can assume any errors are expected
352
+ pass
353
+ return stmt
354
+
355
+ def get_tokens_in_given_stmt(self, stmt: str, ignore_first_token: bool = False) -> typing.Generator[str, None, None]:
356
+ idx = -1
357
+ for tok in re.split(self.token_separator_regex, stmt):
358
+ idx += 1
359
+ # skip the first token as it is usually a keyword
360
+ if idx == 0 and ignore_first_token:
361
+ continue
362
+ tok1 = tok.strip()
363
+ if len(tok1) > 0:
364
+ yield tok1
365
+
366
+ def tokenize(stmt: str) -> typing.Generator[str, None, None]:
367
+ for tok in re.split(IsabelleExecutor.get_token_separator_regex(), stmt):
368
+ tok1 = tok.strip()
369
+ if len(tok1) > 0:
370
+ yield tok1
371
+
372
+ # Make this chacheable
373
+ # @functools.lru_cache(maxsize=10000)
374
+ def search_type_matching_defns(self, name: str) -> typing.List[IsabelleLemma]:
375
+ if name in IsabelleExecutor.keywords:
376
+ return []
377
+ if not self.global_lemmas:
378
+ assert not self.current_state == 0, 'Search tool cannot be used in top level state (before imports)'
379
+ self.global_lemmas = self.pisa_env.get_global_lemmas(self.get_state_str(self.current_state))
380
+ return self.global_lemmas
381
+
382
+ def get_all_type_matching_defns(self, name: str) -> typing.Generator[IsabelleLemma, None, None]:
383
+ return self.search_type_matching_defns(name)
384
+
385
+ def search_exact(self, name: str) -> typing.List[IsabelleLemma]:
386
+ return self.search_type_matching_defns(name)
387
+
388
+ def search_defn(self, name: str, match_until: typing.Tuple[str], max_search_res: typing.Optional[int] = None) -> typing.List[IsabelleLemma]:
389
+ return self.search_type_matching_defns(name)
390
+
391
+ def run_without_executing(self, stmt: str):
392
+ while True:
393
+ try:
394
+ stmt = next(self.main_file_iter)
395
+ except StopIteration:
396
+ return
397
+ self.current_stmt = stmt
398
+ self.line_num += 1
399
+
400
+ def run_lemma_without_executing(self):
401
+ while True:
402
+ try:
403
+ stmt = next(self.main_file_iter)
404
+ self.current_stmt = stmt
405
+ self.line_num += 1
406
+ if "qed" in stmt or "sorry" in stmt or "oops" in stmt:
407
+ return True
408
+ except StopIteration:
409
+ return False
410
+
411
+ def rewind_proof_steps(self) -> str:
412
+ raise NotImplementedError("rewind_proof_steps is not implemented")
413
+
414
+ def run_till_next_lemma(self) -> typing.Tuple[bool, typing.Optional[str]]:
415
+ # Run the file until the next lemma is found
416
+ next_stmt = None
417
+ in_proof_mode = self.is_in_proof_mode()
418
+ if in_proof_mode or self.execution_complete:
419
+ # If we are already in proof mode, then we have already found a lemma
420
+ return False, next_stmt
421
+ prev_stmt = self.current_stmt
422
+ ran_last_cmd = self.run_next(proof_search_mode=False)
423
+ next_stmt = self.current_stmt
424
+ if not ran_last_cmd:
425
+ return False, None
426
+ assigned = False
427
+ in_proof_mode = self.is_in_proof_mode()
428
+ while ran_last_cmd and not in_proof_mode:
429
+ if not assigned:
430
+ prev_stmt = next_stmt
431
+ ran_last_cmd = self.run_next(proof_search_mode=False)
432
+ in_proof_mode = self.is_in_proof_mode()
433
+ if not assigned:
434
+ next_stmt = self.current_stmt
435
+ if in_proof_mode:
436
+ assigned = True
437
+ lemma_name = next_stmt if next_stmt.startswith("theorem") or next_stmt.startswith("lemma") else prev_stmt
438
+ return in_proof_mode, lemma_name
439
+
440
+ def run_till_next_lemma_return_exec_stmt(self) -> typing.Generator[str, None, None]:
441
+ # Run the file until the next lemma is found
442
+ next_stmt = None
443
+ in_proof_mode = self.is_in_proof_mode()
444
+ if in_proof_mode or self.execution_complete:
445
+ # If we are already in proof mode, then we have already found a lemma
446
+ yield from []
447
+ else:
448
+ ran_last_cmd = self.run_next(proof_search_mode=False)
449
+ next_stmt = self.current_stmt
450
+ if not ran_last_cmd:
451
+ yield from []
452
+ else:
453
+ yield next_stmt
454
+ in_proof_mode = self.is_in_proof_mode()
455
+ while ran_last_cmd and not in_proof_mode:
456
+ ran_last_cmd = self.run_next(proof_search_mode=False)
457
+ next_stmt = self.current_stmt
458
+ if ran_last_cmd:
459
+ yield next_stmt
460
+ in_proof_mode = self.is_in_proof_mode()
461
+
462
+ def run_to_finish_lemma_return_exec(self) -> typing.Generator[str, None, None]:
463
+ # Run the file until the next lemma is found
464
+ next_stmt = None
465
+ in_proof_mode = self.is_in_proof_mode()
466
+ if not in_proof_mode or self.execution_complete:
467
+ # If we are already in proof mode, then we have already found a lemma
468
+ yield from []
469
+ else:
470
+ ran_last_cmd = self.run_next(proof_search_mode=False)
471
+ next_stmt = self.current_stmt
472
+ if not ran_last_cmd:
473
+ yield from []
474
+ else:
475
+ yield next_stmt
476
+ in_proof_mode = self.is_in_proof_mode()
477
+ while ran_last_cmd and in_proof_mode:
478
+ ran_last_cmd = self.run_next(proof_search_mode=False)
479
+ next_stmt = self.current_stmt
480
+ if ran_last_cmd:
481
+ yield next_stmt
482
+ in_proof_mode = self.is_in_proof_mode()
483
+
484
+ def run_to_finish_lemma(self) -> bool:
485
+ # Run the file and finish the current lemma
486
+ in_proof_mode = self.is_in_proof_mode()
487
+ if not in_proof_mode or self.execution_complete:
488
+ # If we are not in proof mode, then we are not finishing a lemma
489
+ return False
490
+ ran_last_cmd = self.run_next(proof_search_mode=False)
491
+ if not ran_last_cmd:
492
+ return False
493
+ in_proof_mode = self.is_in_proof_mode()
494
+ while ran_last_cmd and in_proof_mode:
495
+ ran_last_cmd = self.run_next(proof_search_mode=False)
496
+ in_proof_mode = self.is_in_proof_mode()
497
+ return not in_proof_mode
498
+
499
+ def run_till_line_num(self, line_num: int):
500
+ assert line_num >= self.line_num
501
+ ran_last_cmd = True
502
+ while ran_last_cmd and self.line_num < line_num:
503
+ ran_last_cmd = self.run_next(proof_search_mode=False)
504
+ return self.line_num
505
+
506
+ def run_to_finish(self):
507
+ ran_last_cmd = True
508
+ while ran_last_cmd:
509
+ ran_last_cmd = self.run_next(proof_search_mode=False)
510
+
511
+ def get_lemma_name_if_running(self) -> typing.Optional[str]:
512
+ if not self.is_in_proof_mode():
513
+ return None
514
+ else:
515
+ try:
516
+ return self.curr_lemma_name
517
+ except:
518
+ return None
519
+
520
+ def get_lemma_stmt_if_running(self) -> typing.Optional[str]:
521
+ if not self.is_in_proof_mode():
522
+ return None
523
+ else:
524
+ try:
525
+ return self.local_theorem_lemma_description[self.curr_lemma_name]
526
+ except:
527
+ return None
528
+
529
+ def get_current_lemma_name(self) -> typing.Optional[str]:
530
+ if self.curr_lemma_name is None:
531
+ return None
532
+ else:
533
+ return self.curr_lemma_name
534
+
535
+ def _run_stmt_on_isabelle_server(self, stmt: str, proof_search_mode=True) -> str:
536
+ begin_clause = []
537
+ last_thm_details = []
538
+ start_state = self.get_state_str(self.current_state)
539
+ end_state = self.get_state_str(self.current_state + 1)
540
+ found_lemma = False
541
+
542
+ # Deal with multi-line statements:
543
+ # 1. theory initialization (theory... imports... begin)
544
+ # 2. lemma declarations over multiple lines
545
+ if self._top_level:
546
+ self.buffer += stmt + '\n' # Add current line to buffer
547
+ begin_clause = IsabelleExecutor.begin_theory_match.findall(self.buffer)
548
+ elif not self._proof_running:
549
+ self.buffer += stmt + '\n' # Add current line to buffer
550
+ # If the action succeeds, we have a new lemma
551
+ description = self.pisa_env.step(start_state, self.buffer, end_state)
552
+ if not description.startswith('Step error:'):
553
+ last_thm_details = IsabelleExecutor.theorem_match.findall(self.buffer)
554
+
555
+ # Complete initialization transitions found! Exit top-level mode
556
+ if begin_clause:
557
+ # Perform initialization
558
+ stmt = self.buffer
559
+ self.buffer = ""
560
+ self._top_level = False
561
+
562
+ start_state = self.get_state_str(0)
563
+ end_state = self.get_state_str(1)
564
+
565
+ # Complete lemma found! Enter proof mode
566
+ if last_thm_details:
567
+ found_lemma = True
568
+ # Extract lemma name and declaration
569
+ stmt = self.buffer
570
+ self.buffer = ""
571
+ full_thm_stmt, _, _, _, thm_name, _, thm_value = last_thm_details[-1]
572
+ full_thm_stmt, thm_name, thm_value = full_thm_stmt.strip(), thm_name.strip(), thm_value.strip()
573
+
574
+ # Some lemmas don't have names
575
+ if not thm_name:
576
+ thm_name = thm_value
577
+
578
+ self.local_theorem_lemma_description[thm_name] = full_thm_stmt
579
+ self.curr_lemma_name, self.curr_lemma = thm_name, thm_value
580
+ self._proof_running = True # Set proof mode
581
+
582
+ # In proof mode. Execute tactics
583
+ if self._proof_running or begin_clause:
584
+ stmt = f"{self.buffer}{stmt.strip()}"
585
+
586
+ # Throw an error if "sorry" is used, which is not allowed
587
+ # Note that this is a fairly simple/optimistic way of handling it
588
+ if proof_search_mode and "sorry" in stmt:
589
+ raise Exception('Error: expected tactic, got "sorry". Do not use "sorry" in your proof.')
590
+
591
+ try:
592
+ # Run statement. TODO: pass in timeout
593
+ stmt = self._handle_sledgehammer(start_state, stmt, end_state, proof_search_mode)
594
+ # Parse proof context
595
+ local_hypotheses = self.pisa_env.get_local_lemmas(self.get_state_str(self.current_state + 1))
596
+ proof_state = self.pisa_env.get_state(self.get_state_str(self.current_state + 1))
597
+ self.proof_context = self._parse_proof_context(proof_state, local_hypotheses, found_lemma)
598
+ except Exception as e:
599
+ # If we're not in proof search mode, we assume the file compiles correctly
600
+ # Then this error is likely the result of a tactic split between multiple lines
601
+ # To fix, we'll simply fill a buffer until the tactic compiles correctly
602
+ if not proof_search_mode:
603
+ self.buffer = stmt + '\n'
604
+ raise
605
+
606
+ self.current_state += 1
607
+ self.line_num_to_state[self.line_num] = self.current_state
608
+ self.buffer = ""
609
+ # print(repr(stmt) + "\n -> \n" + repr(description))
610
+
611
+ if not begin_clause:
612
+ is_proof_done = self.pisa_env.is_finished(end_state)
613
+ if is_proof_done: # Proof finished
614
+ self.buffer = ""
615
+ self._proof_running = False
616
+ self.curr_lemma_name, self.curr_lemma = None, ""
617
+ self.proof_context = None
618
+ return stmt
619
+ return "-"
620
+
621
+ # PISA only supports sledgehammer as an atomic operation. So we must split any tactic which uses it
622
+ def _handle_sledgehammer(self, start_state: str, step: str, end_state: str, proof_search_mode=True) -> str:
623
+ if step is None or len(step) == 0:
624
+ return None
625
+
626
+ if self.current_state in self._seldgehammer_cache and step in self._seldgehammer_cache[self.current_state]:
627
+ # We've already tried this tactic, so just return the cached result
628
+ stmt_or_description = self._seldgehammer_cache[self.current_state][step]
629
+ if stmt_or_description.startswith('Step error:'):
630
+ raise Exception(stmt_or_description)
631
+ return stmt_or_description
632
+
633
+
634
+ tactics = re.split(r'(sledgehammer)', step)
635
+ tactics = list(filter(None, tactics))
636
+
637
+ description = None
638
+ stmt = ""
639
+ for idx, tactic in enumerate(tactics):
640
+ temp_start = end_state
641
+ temp_end = end_state
642
+ if idx == 0:
643
+ temp_start = start_state
644
+
645
+ if tactic == 'sledgehammer':
646
+ if proof_search_mode and self.use_hammer == HammerMode.NONE:
647
+ raise Exception('Error: got "sledgehammer" query with hammer turned off. To use hammer, toggle "use_hammer"')
648
+
649
+ # Attempt to solve proof with sledgehammer
650
+ description = self._handle_auto_tactics(stmt, temp_start, temp_end)
651
+ stmt += description # Replace with hammer-provided tactic, not 'sledgehammer' literally
652
+ else:
653
+ # Run tactic normally
654
+ description = self._handle_reg_tactic(temp_start, tactic, temp_end, proof_search_mode)
655
+ stmt += description # Replace with a potentially modified tactic
656
+
657
+ return stmt
658
+
659
+ def _handle_auto_tactics(self, step: str, start_state: str, end_state: str) -> str:
660
+ # First we'll try easier tactics, e.g. "simp", "auto", "blast", etc.
661
+ for tactic in IsabelleExecutor.auto_tactics:
662
+ stmt = 'by ' + tactic
663
+ full_stmt = step + stmt
664
+ # Check if we've already tried this tactic
665
+ if self.current_state in self._seldgehammer_cache and full_stmt in self._seldgehammer_cache[self.current_state]:
666
+ description = self._seldgehammer_cache[self.current_state][full_stmt]
667
+ else:
668
+ description = self.pisa_env.step(start_state, stmt, end_state)
669
+ if self.current_state not in self._seldgehammer_cache:
670
+ self._seldgehammer_cache[self.current_state] = {}
671
+ self._seldgehammer_cache[self.current_state][full_stmt] = description
672
+ auto_tactic_succeeded = not description.startswith('Step error:')
673
+ if auto_tactic_succeeded:
674
+ # If the tactic succeeded, return it
675
+ return stmt + ' <auto tactic>'
676
+
677
+ # If those fail, run sledgehammer (more powerful but slower)
678
+ full_stmt = step + 'sledgehammer'
679
+ # Check if we've already tried this tactic
680
+ if self.current_state in self._seldgehammer_cache and full_stmt in self._seldgehammer_cache[self.current_state]:
681
+ description = self._seldgehammer_cache[self.current_state][full_stmt]
682
+ else:
683
+ description = self.pisa_env.apply_hammer(start_state, end_state)
684
+ if self.current_state not in self._seldgehammer_cache:
685
+ self._seldgehammer_cache[self.current_state] = {}
686
+ self._seldgehammer_cache[self.current_state][full_stmt] = description
687
+ sledgehammer_succeeded = not description.startswith('Step error:')
688
+ if sledgehammer_succeeded:
689
+ # If the tactic succeeded, return it
690
+ return description.split('<hammer>')[0] + '<hammer>'
691
+ else:
692
+ raise Exception(description)
693
+
694
+ def _handle_reg_tactic(self, start_state: str, step: str, end_state: str, proof_search_mode=True) -> str:
695
+ description = self.pisa_env.step(start_state, step, end_state)
696
+ # Check if the tactic succeeded
697
+ tactic_succeeded = not description.startswith('Step error:')
698
+ if tactic_succeeded:
699
+ return step
700
+ else:
701
+ # Use auto tactics correction heuristics by changing it to sledehammer
702
+ tactics = re.split(r'\susing\s|\sby\s', step, maxsplit=1)
703
+ if len(tactics) > 1 and \
704
+ (self.use_hammer == HammerMode.AUTO or self.use_hammer == HammerMode.ALWAYS) and \
705
+ proof_search_mode:
706
+ # Try applying sledgehammer. We do some awkward parsing to apply it to the correct portion
707
+ # This will not always work, but because this is a heuristic and not mission-critical, it is ok
708
+ new_tactic = tactics[0] + ' sledgehammer'
709
+ try:
710
+ step = self._handle_sledgehammer(start_state, new_tactic, end_state, proof_search_mode)
711
+ return step
712
+ except:
713
+ # Don't throw an error here -- we want to throw the original error
714
+ pass
715
+ raise Exception(description)
716
+
717
+ def _parse_proof_context(self, proof_context_str: str, local_hypotheses: typing.List[IsabelleLemma], found_lemma: bool) -> ProofContext:
718
+ if proof_context_str is None or len(proof_context_str) == 0:
719
+ return None
720
+
721
+ # Parse proof context and find 1. last proved statement (this) and 2. goals
722
+ all_matches = self.proof_context_match.findall(proof_context_str)
723
+ if len(all_matches) == 0:
724
+ return None
725
+
726
+ context_type, _, _, this_hyps_str, _, goals_str = all_matches[0]
727
+ this_hyps_str, goals_str = this_hyps_str.strip(), goals_str.strip()
728
+ if(goals_str == "No subgoals!"):
729
+ return ProofContext.empty()
730
+
731
+ if not found_lemma and not context_type == 'state':
732
+ raise Exception(f'Error: please provide a full tactic. This step ends in "{context_type}" mode but it should end in "state" mode')
733
+
734
+ hypotheses = []
735
+ for hyp in local_hypotheses:
736
+ # Replace assms_x with assms(x)
737
+ hypotheses.append(IsabelleExecutor.assms_regex_match.sub(r'assms(\1):', hyp.dfn))
738
+
739
+ goals_list = list(filter(None, goals_str.split("\n")))
740
+ goals = []
741
+ for i, goal_str in enumerate(goals_list):
742
+ goal_str = re.sub("\d+.", "", goal_str, 1).strip() # Remove numbering
743
+ if i == 0:
744
+ goal = Obligation(hypotheses, goal_str)
745
+ else:
746
+ goal = Obligation([], goal_str)
747
+ goals.append(goal)
748
+
749
+ return ProofContext(goals, [], [], [])
750
+
751
+ def get_all_lemmas_in_file(isabelle_executor: IsabelleExecutor, logger: logging.Logger) -> typing.List[str]:
752
+ lemmas_to_prove = []
753
+ while not isabelle_executor.execution_complete:
754
+ assert not isabelle_executor.is_in_proof_mode(), "main_executor must not be in proof mode"
755
+ _ = list(isabelle_executor.run_till_next_lemma_return_exec_stmt())
756
+ if isabelle_executor.execution_complete:
757
+ break
758
+ lemma_name = isabelle_executor.get_lemma_name_if_running()
759
+ if lemma_name is None:
760
+ _ = list(isabelle_executor.run_to_finish_lemma_return_exec())
761
+ if isabelle_executor.execution_complete:
762
+ break
763
+ else:
764
+ logger.info(f"Discovered lemma: {lemma_name}")
765
+ lemmas_to_prove.append(lemma_name)
766
+ isabelle_executor.run_to_finish_lemma()
767
+ return lemmas_to_prove
768
+
769
+ class IsabelleStdInOutExecutor:
770
+ def __init__(self):
771
+ self.isabelle_stdin_reader = IsabelleStepByStepStdInReader()
772
+ self.isabelle_exec : IsabelleExecutor = IsabelleExecutor(
773
+ use_human_readable_proof_context=True,
774
+ proof_step_iter=self.isabelle_stdin_reader.instruction_step_generator())
775
+
776
+ def __enter__(self):
777
+ self.isabelle_exec.__enter__()
778
+ return self
779
+
780
+ def __exit__(self, exc_type, exc_value, traceback):
781
+ self.isabelle_exec.__exit__(exc_type, exc_value, traceback)
782
+
783
+ def run_in_loop(self):
784
+ print("In> ", end="")
785
+ while True:
786
+ try:
787
+ cmd_ran = self.isabelle_exec.run_next()
788
+ if not cmd_ran:
789
+ break
790
+ print(f"Isabelle> {cmd_ran}")
791
+ print(f"{self.isabelle_exec.proof_context}")
792
+ print("In> ", end="")
793
+ except Exception as e:
794
+ print(e)
795
+ pass
796
+ pass
797
+
798
+ class IsabelleCustomFileExec:
799
+ def __init__(self, file_path: str, project_root: str):
800
+ self.isabelle_exec : IsabelleExecutor = IsabelleExecutor(
801
+ use_human_readable_proof_context=True,
802
+ main_file=file_path,
803
+ project_root=project_root)
804
+
805
+ def __enter__(self):
806
+ self.isabelle_exec.__enter__()
807
+ return self
808
+
809
+ def __exit__(self, exc_type, exc_value, traceback):
810
+ self.isabelle_exec.__exit__(exc_type, exc_value, traceback)
811
+
812
+ def run_in_loop(self):
813
+ print("In> Press 'Enter' for running next line and 'c' + 'Enter' to cancel the last command and 're-run'.", end="")
814
+ cmd_ran = None
815
+ while True:
816
+ try:
817
+ opt = input()
818
+ if opt == "c" and cmd_ran is not None:
819
+ if self.isabelle_exec.is_in_proof_mode():
820
+ print(f"Goals before cancelling")
821
+ print(self.isabelle_exec.proof_context.all_goals)
822
+ else:
823
+ print("No goals before cancelling")
824
+ print("cancel_last() not implemented")
825
+ if self.isabelle_exec.is_in_proof_mode():
826
+ print(f"Goals after cancelling")
827
+ print(self.isabelle_exec.proof_context.all_goals)
828
+ else:
829
+ print("No goals after cancelling")
830
+ print(f"Canceled last statement: {cmd_ran}")
831
+ print(f"Re-running: {cmd_ran}")
832
+ print("re-running not implemented")
833
+ print(f"Isabelle> Ran {cmd_ran} again")
834
+ continue
835
+ cmd_ran = self.isabelle_exec.run_next(proof_search_mode=False)
836
+ if not cmd_ran:
837
+ break
838
+ print(f"Isabelle> {self.isabelle_exec.current_stmt}")
839
+ print(f"Parsed Tactic> {cmd_ran}")
840
+ print(f"{self.isabelle_exec.proof_context}")
841
+ print("In> ", end="")
842
+ except Exception as e:
843
+ print(e)
844
+ pass
845
+ pass
846
+
847
+ if __name__ == "__main__":
848
+ logging.basicConfig(filename='isabelle_executor.log', filemode='w', level=logging.INFO)
849
+ # with IsabelleStdInOutExecutor() as isabelle_exec:
850
+ # isabelle_exec.run_in_loop()
851
+
852
+ # os.chdir(root_dir)
853
+ # with IsabelleCustomFileExec("data/benchmarks/miniF2F/isabelle/test/aime_1983_p1.thy", "data/benchmarks/miniF2F") as isabelle_exec:
854
+ # isabelle_exec.run_in_loop()
855
+
856
+ os.chdir(root_dir)
857
+ IsabelleExecutor.start_server(port=13000)
858
+ try:
859
+ with IsabelleCustomFileExec("data/test/isabelle/custom_hol/Basic_Logic.thy", "data/test/isabelle/custom_hol") as isabelle_exec:
860
+ isabelle_exec.run_in_loop()
861
+ finally:
862
+ IsabelleExecutor.stop_server()