synalog 2.4.0__tar.gz → 2.4.1__tar.gz

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 (192) hide show
  1. {synalog-2.4.0 → synalog-2.4.1}/Cargo.lock +2 -2
  2. {synalog-2.4.0 → synalog-2.4.1}/Cargo.toml +1 -1
  3. {synalog-2.4.0 → synalog-2.4.1}/PKG-INFO +1 -1
  4. {synalog-2.4.0 → synalog-2.4.1}/pyproject.toml +1 -1
  5. {synalog-2.4.0 → synalog-2.4.1}/src/python.rs +120 -98
  6. {synalog-2.4.0 → synalog-2.4.1}/uv.lock +1 -1
  7. {synalog-2.4.0 → synalog-2.4.1}/verified/Cargo.toml +1 -1
  8. {synalog-2.4.0 → synalog-2.4.1}/.gitignore +0 -0
  9. {synalog-2.4.0 → synalog-2.4.1}/LICENSE +0 -0
  10. {synalog-2.4.0 → synalog-2.4.1}/NOTICE +0 -0
  11. {synalog-2.4.0 → synalog-2.4.1}/README.md +0 -0
  12. {synalog-2.4.0 → synalog-2.4.1}/docs/assertions.md +0 -0
  13. {synalog-2.4.0 → synalog-2.4.1}/docs/assets/synalog-dark.svg +0 -0
  14. {synalog-2.4.0 → synalog-2.4.1}/docs/assets/synalog-light.svg +0 -0
  15. {synalog-2.4.0 → synalog-2.4.1}/docs/assets/synalog_favicon.png +0 -0
  16. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/results.json +0 -0
  17. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/speedup_by_engine.png +0 -0
  18. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/speedup_distribution.png +0 -0
  19. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/summary.md +0 -0
  20. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/summary.png +0 -0
  21. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/time_comparison.png +0 -0
  22. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark/verify_by_engine.png +0 -0
  23. {synalog-2.4.0 → synalog-2.4.1}/docs/benchmark.md +0 -0
  24. {synalog-2.4.0 → synalog-2.4.1}/docs/cli.md +0 -0
  25. {synalog-2.4.0 → synalog-2.4.1}/docs/development.md +0 -0
  26. {synalog-2.4.0 → synalog-2.4.1}/docs/differences-datalog.md +0 -0
  27. {synalog-2.4.0 → synalog-2.4.1}/docs/differences.md +0 -0
  28. {synalog-2.4.0 → synalog-2.4.1}/docs/engines.md +0 -0
  29. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/aggregation.l +0 -0
  30. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/aggregation.log +0 -0
  31. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/directives.l +0 -0
  32. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/directives.log +0 -0
  33. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/functions.l +0 -0
  34. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/functions.log +0 -0
  35. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/functors.l +0 -0
  36. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/functors.log +0 -0
  37. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/getting_started.l +0 -0
  38. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/getting_started.log +0 -0
  39. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/knowledge_graphs.l +0 -0
  40. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/knowledge_graphs.log +0 -0
  41. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/recursion.l +0 -0
  42. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/recursion.log +0 -0
  43. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/run.py +0 -0
  44. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/concepts/customer.l +0 -0
  45. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/concepts/order_status.l +0 -0
  46. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/data/orders.csv +0 -0
  47. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/layer.toml +0 -0
  48. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/rules/customer_revenue.l +0 -0
  49. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/rules/orders_by_status.l +0 -0
  50. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/rules/top_customers.l +0 -0
  51. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop/tables/orders.l +0 -0
  52. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/shop.log +0 -0
  53. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/concepts/device.l +0 -0
  54. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/concepts/test_status.l +0 -0
  55. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/data/smoke_tests.csv +0 -0
  56. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/layer.toml +0 -0
  57. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/rules/failures_by_device.l +0 -0
  58. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/rules/runs_per_day.l +0 -0
  59. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke/tables/smoke_tests.l +0 -0
  60. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/smoke.log +0 -0
  61. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/syntax.l +0 -0
  62. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/syntax.log +0 -0
  63. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/temporal.l +0 -0
  64. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/temporal.log +0 -0
  65. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/temporal_graph.l +0 -0
  66. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/temporal_graph.log +0 -0
  67. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/verification.l +0 -0
  68. {synalog-2.4.0 → synalog-2.4.1}/docs/examples/verification.log +0 -0
  69. {synalog-2.4.0 → synalog-2.4.1}/docs/getting-started.md +0 -0
  70. {synalog-2.4.0 → synalog-2.4.1}/docs/index.md +0 -0
  71. {synalog-2.4.0 → synalog-2.4.1}/docs/javascripts/playground.js +0 -0
  72. {synalog-2.4.0 → synalog-2.4.1}/docs/javascripts/summarize.js +0 -0
  73. {synalog-2.4.0 → synalog-2.4.1}/docs/javascripts/synalog-highlight.js +0 -0
  74. {synalog-2.4.0 → synalog-2.4.1}/docs/knowledge-graphs.md +0 -0
  75. {synalog-2.4.0 → synalog-2.4.1}/docs/language/aggregation.md +0 -0
  76. {synalog-2.4.0 → synalog-2.4.1}/docs/language/directives.md +0 -0
  77. {synalog-2.4.0 → synalog-2.4.1}/docs/language/functions.md +0 -0
  78. {synalog-2.4.0 → synalog-2.4.1}/docs/language/functors.md +0 -0
  79. {synalog-2.4.0 → synalog-2.4.1}/docs/language/index.md +0 -0
  80. {synalog-2.4.0 → synalog-2.4.1}/docs/language/recursion.md +0 -0
  81. {synalog-2.4.0 → synalog-2.4.1}/docs/language/syntax.md +0 -0
  82. {synalog-2.4.0 → synalog-2.4.1}/docs/language/temporal.md +0 -0
  83. {synalog-2.4.0 → synalog-2.4.1}/docs/playground/vendor/codemirror.js +0 -0
  84. {synalog-2.4.0 → synalog-2.4.1}/docs/playground.md +0 -0
  85. {synalog-2.4.0 → synalog-2.4.1}/docs/python-api.md +0 -0
  86. {synalog-2.4.0 → synalog-2.4.1}/docs/stylesheets/extra.css +0 -0
  87. {synalog-2.4.0 → synalog-2.4.1}/docs/verification.md +0 -0
  88. {synalog-2.4.0 → synalog-2.4.1}/docs/why.md +0 -0
  89. {synalog-2.4.0 → synalog-2.4.1}/img/synalog-dark.svg +0 -0
  90. {synalog-2.4.0 → synalog-2.4.1}/img/synalog-light.svg +0 -0
  91. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/__init__.py +0 -0
  92. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/__main__.py +0 -0
  93. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/checking.py +0 -0
  94. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/cli.py +0 -0
  95. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/config.py +0 -0
  96. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/execution.py +0 -0
  97. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/introspect.py +0 -0
  98. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/project.py +0 -0
  99. {synalog-2.4.0 → synalog-2.4.1}/python/synalog/runners.py +0 -0
  100. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/SKILL.md +0 -0
  101. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/concepts/department.l +0 -0
  102. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/concepts/person.l +0 -0
  103. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/concepts/works_in.l +0 -0
  104. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/data/departments.csv +0 -0
  105. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/data/employees.csv +0 -0
  106. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/layer.toml +0 -0
  107. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/rules/team_mate.l +0 -0
  108. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/tables/departments.l +0 -0
  109. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/company/tables/employees.l +0 -0
  110. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/org/concepts/all_managers.l +0 -0
  111. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/org/data/employees.csv +0 -0
  112. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/org/layer.toml +0 -0
  113. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/org/tables/employees.l +0 -0
  114. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/concepts/region.l +0 -0
  115. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/data/sales.csv +0 -0
  116. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/layer.toml +0 -0
  117. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/rules/monthly_sales.l +0 -0
  118. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/rules/top_region.l +0 -0
  119. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/rules/total_by_region.l +0 -0
  120. {synalog-2.4.0 → synalog-2.4.1}/skills/synalog/examples/sales/tables/sales.l +0 -0
  121. {synalog-2.4.0 → synalog-2.4.1}/src/assertion/mod.rs +0 -0
  122. {synalog-2.4.0 → synalog-2.4.1}/src/assertion/parse.rs +0 -0
  123. {synalog-2.4.0 → synalog-2.4.1}/src/assertion/report.rs +0 -0
  124. {synalog-2.4.0 → synalog-2.4.1}/src/assertion/translate.rs +0 -0
  125. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/annotations.rs +0 -0
  126. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/annotations_test.rs +0 -0
  127. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/dialects.rs +0 -0
  128. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/dialects_test.rs +0 -0
  129. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/expr_translate.rs +0 -0
  130. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/expr_translate_test.rs +0 -0
  131. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/functors.rs +0 -0
  132. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/functors_test.rs +0 -0
  133. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/mod.rs +0 -0
  134. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/rule_translate.rs +0 -0
  135. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/rule_translate_test.rs +0 -0
  136. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/builder.rs +0 -0
  137. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/built_in.rs +0 -0
  138. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/edge.rs +0 -0
  139. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/expression.rs +0 -0
  140. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/graph.rs +0 -0
  141. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/inference.rs +0 -0
  142. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/intersection.rs +0 -0
  143. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/mod.rs +0 -0
  144. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/type_inference/types.rs +0 -0
  145. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/universe.rs +0 -0
  146. {synalog-2.4.0 → synalog-2.4.1}/src/compiler/universe_test.rs +0 -0
  147. {synalog-2.4.0 → synalog-2.4.1}/src/errors.rs +0 -0
  148. {synalog-2.4.0 → synalog-2.4.1}/src/lib.rs +0 -0
  149. {synalog-2.4.0 → synalog-2.4.1}/src/parser/json.rs +0 -0
  150. {synalog-2.4.0 → synalog-2.4.1}/src/parser/json_test.rs +0 -0
  151. {synalog-2.4.0 → synalog-2.4.1}/src/parser/mod.rs +0 -0
  152. {synalog-2.4.0 → synalog-2.4.1}/src/parser/names.rs +0 -0
  153. {synalog-2.4.0 → synalog-2.4.1}/src/parser/parse.rs +0 -0
  154. {synalog-2.4.0 → synalog-2.4.1}/src/parser/parse_test.rs +0 -0
  155. {synalog-2.4.0 → synalog-2.4.1}/src/parser/rewrite.rs +0 -0
  156. {synalog-2.4.0 → synalog-2.4.1}/src/parser/rewrite_test.rs +0 -0
  157. {synalog-2.4.0 → synalog-2.4.1}/src/parser/span.rs +0 -0
  158. {synalog-2.4.0 → synalog-2.4.1}/src/parser/span_test.rs +0 -0
  159. {synalog-2.4.0 → synalog-2.4.1}/src/parser/traverse.rs +0 -0
  160. {synalog-2.4.0 → synalog-2.4.1}/src/parser/traverse_test.rs +0 -0
  161. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/arity.rs +0 -0
  162. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/assertions.rs +0 -0
  163. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/cast.rs +0 -0
  164. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/contradiction.rs +0 -0
  165. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/dependencies.rs +0 -0
  166. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/directives.rs +0 -0
  167. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/front_matter.rs +0 -0
  168. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/functors.rs +0 -0
  169. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/mod.rs +0 -0
  170. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/orderby.rs +0 -0
  171. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/positional.rs +0 -0
  172. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/recursion.rs +0 -0
  173. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/reserved.rs +0 -0
  174. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/safety.rs +0 -0
  175. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/sqlexpr.rs +0 -0
  176. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/stratification.rs +0 -0
  177. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/undefined.rs +0 -0
  178. {synalog-2.4.0 → synalog-2.4.1}/src/verifier/vars.rs +0 -0
  179. {synalog-2.4.0 → synalog-2.4.1}/src/wasm.rs +0 -0
  180. {synalog-2.4.0 → synalog-2.4.1}/verified/src/arity.rs +0 -0
  181. {synalog-2.4.0 → synalog-2.4.1}/verified/src/cast.rs +0 -0
  182. {synalog-2.4.0 → synalog-2.4.1}/verified/src/contradiction.rs +0 -0
  183. {synalog-2.4.0 → synalog-2.4.1}/verified/src/lib.rs +0 -0
  184. {synalog-2.4.0 → synalog-2.4.1}/verified/src/membership.rs +0 -0
  185. {synalog-2.4.0 → synalog-2.4.1}/verified/src/page.rs +0 -0
  186. {synalog-2.4.0 → synalog-2.4.1}/verified/src/plan.rs +0 -0
  187. {synalog-2.4.0 → synalog-2.4.1}/verified/src/quote.rs +0 -0
  188. {synalog-2.4.0 → synalog-2.4.1}/verified/src/recursion.rs +0 -0
  189. {synalog-2.4.0 → synalog-2.4.1}/verified/src/safety.rs +0 -0
  190. {synalog-2.4.0 → synalog-2.4.1}/verified/src/strata.rs +0 -0
  191. {synalog-2.4.0 → synalog-2.4.1}/verified/src/types.rs +0 -0
  192. {synalog-2.4.0 → synalog-2.4.1}/zensical.toml +0 -0
@@ -300,7 +300,7 @@ dependencies = [
300
300
 
301
301
  [[package]]
302
302
  name = "synalog"
303
- version = "2.4.0"
303
+ version = "2.4.1"
304
304
  dependencies = [
305
305
  "anyhow",
306
306
  "indexmap",
@@ -316,7 +316,7 @@ dependencies = [
316
316
 
317
317
  [[package]]
318
318
  name = "synalog-verified"
319
- version = "2.4.0"
319
+ version = "2.4.1"
320
320
  dependencies = [
321
321
  "vstd",
322
322
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "synalog"
3
- version = "2.4.0"
3
+ version = "2.4.1"
4
4
  edition = "2024"
5
5
  description = "Logic programming for AI agents: Datalog-family language compiling to optimized SQL"
6
6
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synalog
3
- Version: 2.4.0
3
+ Version: 2.4.1
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: 3
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "synalog"
7
- version = "2.4.0"
7
+ version = "2.4.1"
8
8
  description = "Logic programming for AI agents: Datalog-family language compiling to optimized SQL"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -195,22 +195,25 @@ fn search(
195
195
  #[pyfunction]
196
196
  #[pyo3(signature = (source, engine=None, import_root=None))]
197
197
  fn compile_all(
198
+ py: Python<'_>,
198
199
  source: &str,
199
200
  engine: Option<&str>,
200
201
  import_root: Option<Vec<String>>,
201
202
  ) -> PyResult<HashMap<String, String>> {
202
- check_engine(engine)?;
203
- let parsed = parse_source(source, None, import_root)?;
204
- let program = build_program(&parsed, engine)?;
205
- let mut out = HashMap::new();
206
- let pagination = Pagination { limit: None, offset: None };
207
- for name in program.user_defined_predicates() {
208
- let sql = program
209
- .formatted_predicate_sql_with_pagination(&name, &pagination)
210
- .map_err(map_err)?;
211
- out.insert(name, sql);
212
- }
213
- Ok(out)
203
+ py.detach(|| {
204
+ check_engine(engine)?;
205
+ let parsed = parse_source(source, None, import_root)?;
206
+ let program = build_program(&parsed, engine)?;
207
+ let mut out = HashMap::new();
208
+ let pagination = Pagination { limit: None, offset: None };
209
+ for name in program.user_defined_predicates() {
210
+ let sql = program
211
+ .formatted_predicate_sql_with_pagination(&name, &pagination)
212
+ .map_err(map_err)?;
213
+ out.insert(name, sql);
214
+ }
215
+ Ok(out)
216
+ })
214
217
  }
215
218
 
216
219
  /// Validate a Synalog program; returns `(errors, warnings)`, two lists of
@@ -225,17 +228,20 @@ fn compile_all(
225
228
  #[pyfunction]
226
229
  #[pyo3(signature = (source, engine=None, import_root=None))]
227
230
  fn check(
231
+ py: Python<'_>,
228
232
  source: &str,
229
233
  engine: Option<&str>,
230
234
  import_root: Option<Vec<String>>,
231
235
  ) -> PyResult<(Vec<String>, Vec<String>)> {
232
- check_engine(engine)?;
233
- let parsed = parse_source(source, None, import_root)?;
234
- let names = PredicateNames::of(&parsed);
235
- let result = validate(&parsed);
236
- let errors = result.errors.iter().map(|e| names.written(&e.to_string())).collect();
237
- let warnings = result.warnings.iter().map(|w| names.written(w)).collect();
238
- Ok((errors, warnings))
236
+ py.detach(|| {
237
+ check_engine(engine)?;
238
+ let parsed = parse_source(source, None, import_root)?;
239
+ let names = PredicateNames::of(&parsed);
240
+ let result = validate(&parsed);
241
+ let errors = result.errors.iter().map(|e| names.written(&e.to_string())).collect();
242
+ let warnings = result.warnings.iter().map(|w| names.written(w)).collect();
243
+ Ok((errors, warnings))
244
+ })
239
245
  }
240
246
 
241
247
  /// Every `@Assert` of a program and where it stands.
@@ -261,11 +267,12 @@ fn assertions(
261
267
  engine: Option<&str>,
262
268
  import_root: Option<Vec<String>>,
263
269
  ) -> PyResult<Vec<Py<PyAny>>> {
264
- check_engine(engine)?;
265
- let parsed = parse_source(source, None, import_root)?;
266
- let names = PredicateNames::of(&parsed);
267
- validate(&parsed)
268
- .assertions
270
+ let (names, found) = py.detach(|| {
271
+ check_engine(engine)?;
272
+ let parsed = parse_source(source, None, import_root)?;
273
+ PyResult::Ok((PredicateNames::of(&parsed), validate(&parsed).assertions))
274
+ })?;
275
+ found
269
276
  .into_iter()
270
277
  .map(|assertion| {
271
278
  let dict = pyo3::types::PyDict::new(py);
@@ -291,18 +298,24 @@ fn assertions(
291
298
  /// from here. Raises ValueError on syntax errors.
292
299
  #[pyfunction]
293
300
  #[pyo3(signature = (source, import_root=None))]
294
- fn dependencies(source: &str, import_root: Option<Vec<String>>) -> PyResult<BTreeMap<String, Vec<String>>> {
295
- let parsed = parse_source(source, None, import_root)?;
296
- let names = PredicateNames::of(&parsed);
297
- let rules: Vec<&Json> = parsed.as_object().get("rule").map(|r| r.as_array().iter().collect()).unwrap_or_default();
298
- Ok(program_dependencies(&rules)
299
- .into_iter()
300
- .map(|(name, refs)| {
301
- let mut refs: Vec<String> = refs.iter().map(|r| names.written(r)).collect();
302
- refs.sort();
303
- (names.written(&name), refs)
304
- })
305
- .collect())
301
+ fn dependencies(
302
+ py: Python<'_>,
303
+ source: &str,
304
+ import_root: Option<Vec<String>>,
305
+ ) -> PyResult<BTreeMap<String, Vec<String>>> {
306
+ py.detach(|| {
307
+ let parsed = parse_source(source, None, import_root)?;
308
+ let names = PredicateNames::of(&parsed);
309
+ let rules: Vec<&Json> = parsed.as_object().get("rule").map(|r| r.as_array().iter().collect()).unwrap_or_default();
310
+ Ok(program_dependencies(&rules)
311
+ .into_iter()
312
+ .map(|(name, refs)| {
313
+ let mut refs: Vec<String> = refs.iter().map(|r| names.written(r)).collect();
314
+ refs.sort();
315
+ (names.written(&name), refs)
316
+ })
317
+ .collect())
318
+ })
306
319
  }
307
320
 
308
321
  /// Compile the search for the counterexamples of an assertion to SQL.
@@ -316,7 +329,9 @@ fn dependencies(source: &str, import_root: Option<Vec<String>>) -> PyResult<BTre
316
329
  /// checked, and on syntax or compilation errors.
317
330
  #[pyfunction]
318
331
  #[pyo3(signature = (source, predicate, name, limit=None, offset=None, engine=None, import_root=None))]
332
+ #[allow(clippy::too_many_arguments)]
319
333
  fn counterexamples(
334
+ py: Python<'_>,
320
335
  source: &str,
321
336
  predicate: &str,
322
337
  name: &str,
@@ -325,19 +340,21 @@ fn counterexamples(
325
340
  engine: Option<&str>,
326
341
  import_root: Option<Vec<String>>,
327
342
  ) -> PyResult<String> {
328
- check_engine(engine)?;
329
- let parsed = parse_source(source, None, import_root.clone())?;
330
- let names = PredicateNames::of(&parsed);
331
- let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
332
- let translation = assertion_check(&rules, &names.internal(predicate), name).map_err(written_err(&names))?;
333
- // The counterexamples are a predicate of the program like any other.
334
- let extended = format!("{}\n{}\n", source, translation.rules);
335
- let parsed = parse_source(&extended, None, import_root)?;
336
- let program = build_program(&parsed, engine)?;
337
- let pagination = Pagination { limit, offset };
338
- program
339
- .formatted_predicate_sql_with_pagination(&translation.predicate, &pagination)
340
- .map_err(map_err)
343
+ py.detach(|| {
344
+ check_engine(engine)?;
345
+ let parsed = parse_source(source, None, import_root.clone())?;
346
+ let names = PredicateNames::of(&parsed);
347
+ let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
348
+ let translation = assertion_check(&rules, &names.internal(predicate), name).map_err(written_err(&names))?;
349
+ // The counterexamples are a predicate of the program like any other.
350
+ let extended = format!("{}\n{}\n", source, translation.rules);
351
+ let parsed = parse_source(&extended, None, import_root)?;
352
+ let program = build_program(&parsed, engine)?;
353
+ let pagination = Pagination { limit, offset };
354
+ program
355
+ .formatted_predicate_sql_with_pagination(&translation.predicate, &pagination)
356
+ .map_err(map_err)
357
+ })
341
358
  }
342
359
 
343
360
  /// Compile the search for the counterexamples of several assertions to SQL;
@@ -353,6 +370,7 @@ fn counterexamples(
353
370
  #[pyfunction]
354
371
  #[pyo3(signature = (source, assertions=None, limit=None, offset=None, engine=None, import_root=None))]
355
372
  fn counterexamples_all(
373
+ py: Python<'_>,
356
374
  source: &str,
357
375
  assertions: Option<Vec<(String, String)>>,
358
376
  limit: Option<u64>,
@@ -360,37 +378,39 @@ fn counterexamples_all(
360
378
  engine: Option<&str>,
361
379
  import_root: Option<Vec<String>>,
362
380
  ) -> PyResult<HashMap<(String, String), String>> {
363
- check_engine(engine)?;
364
- let parsed = parse_source(source, None, import_root.clone())?;
365
- let names = PredicateNames::of(&parsed);
366
- let assertions = match assertions {
367
- Some(assertions) => assertions,
368
- None => validate(&parsed)
369
- .assertions
381
+ py.detach(|| {
382
+ check_engine(engine)?;
383
+ let parsed = parse_source(source, None, import_root.clone())?;
384
+ let names = PredicateNames::of(&parsed);
385
+ let assertions = match assertions {
386
+ Some(assertions) => assertions,
387
+ None => validate(&parsed)
388
+ .assertions
389
+ .into_iter()
390
+ .filter(|assertion| assertion.status == AssertionStatus::Unchecked)
391
+ .map(|assertion| (names.written(&assertion.predicate), assertion.name))
392
+ .collect(),
393
+ };
394
+ let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
395
+ let mut extended = format!("{}\n", source);
396
+ let mut checks = Vec::new();
397
+ for (predicate, name) in assertions {
398
+ let translation = assertion_check(&rules, &names.internal(&predicate), &name).map_err(written_err(&names))?;
399
+ extended.push_str(&translation.rules);
400
+ extended.push('\n');
401
+ checks.push(((predicate, name), translation.predicate));
402
+ }
403
+ let parsed = parse_source(&extended, None, import_root)?;
404
+ let program = build_program(&parsed, engine)?;
405
+ let pagination = Pagination { limit, offset };
406
+ checks
370
407
  .into_iter()
371
- .filter(|assertion| assertion.status == AssertionStatus::Unchecked)
372
- .map(|assertion| (names.written(&assertion.predicate), assertion.name))
373
- .collect(),
374
- };
375
- let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
376
- let mut extended = format!("{}\n", source);
377
- let mut checks = Vec::new();
378
- for (predicate, name) in assertions {
379
- let translation = assertion_check(&rules, &names.internal(&predicate), &name).map_err(written_err(&names))?;
380
- extended.push_str(&translation.rules);
381
- extended.push('\n');
382
- checks.push(((predicate, name), translation.predicate));
383
- }
384
- let parsed = parse_source(&extended, None, import_root)?;
385
- let program = build_program(&parsed, engine)?;
386
- let pagination = Pagination { limit, offset };
387
- checks
388
- .into_iter()
389
- .map(|(key, predicate)| {
390
- let sql = program.formatted_predicate_sql_with_pagination(&predicate, &pagination).map_err(map_err)?;
391
- Ok((key, sql))
392
- })
393
- .collect()
408
+ .map(|(key, predicate)| {
409
+ let sql = program.formatted_predicate_sql_with_pagination(&predicate, &pagination).map_err(map_err)?;
410
+ Ok((key, sql))
411
+ })
412
+ .collect()
413
+ })
394
414
  }
395
415
 
396
416
  /// The steps that compute a predicate, for a runner that executes them.
@@ -419,25 +439,27 @@ fn plan(
419
439
  pattern: Option<&str>,
420
440
  assertion: Option<&str>,
421
441
  ) -> PyResult<Vec<Py<PyAny>>> {
422
- check_engine(engine)?;
423
- let (source, predicate) = match assertion {
424
- Some(name) => {
425
- let parsed = parse_source(source, None, import_root.clone())?;
426
- let names = PredicateNames::of(&parsed);
427
- let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
428
- let translation =
429
- assertion_check(&rules, &names.internal(predicate), name).map_err(written_err(&names))?;
430
- (format!("{}\n{}\n", source, translation.rules), translation.predicate)
431
- }
432
- None => (source.to_string(), predicate.to_string()),
433
- };
434
- let parsed = parse_source(&source, None, import_root)?;
435
- let names = PredicateNames::of(&parsed);
436
- let program = build_program(&parsed, engine)?;
437
- let pagination = Pagination { limit, offset };
438
- let steps = program
439
- .formatted_predicate_plan(&names.internal(&predicate), Some(&pagination), pattern)
440
- .map_err(written_err(&names))?;
442
+ let steps = py.detach(|| {
443
+ check_engine(engine)?;
444
+ let (source, predicate) = match assertion {
445
+ Some(name) => {
446
+ let parsed = parse_source(source, None, import_root.clone())?;
447
+ let names = PredicateNames::of(&parsed);
448
+ let rules: Vec<&Json> = parsed.as_object()["rule"].as_array().iter().collect();
449
+ let translation =
450
+ assertion_check(&rules, &names.internal(predicate), name).map_err(written_err(&names))?;
451
+ (format!("{}\n{}\n", source, translation.rules), translation.predicate)
452
+ }
453
+ None => (source.to_string(), predicate.to_string()),
454
+ };
455
+ let parsed = parse_source(&source, None, import_root)?;
456
+ let names = PredicateNames::of(&parsed);
457
+ let program = build_program(&parsed, engine)?;
458
+ let pagination = Pagination { limit, offset };
459
+ program
460
+ .formatted_predicate_plan(&names.internal(&predicate), Some(&pagination), pattern)
461
+ .map_err(written_err(&names))
462
+ })?;
441
463
  steps
442
464
  .into_iter()
443
465
  .map(|step| {
@@ -3032,7 +3032,7 @@ wheels = [
3032
3032
 
3033
3033
  [[package]]
3034
3034
  name = "synalog"
3035
- version = "2.4.0"
3035
+ version = "2.4.1"
3036
3036
  source = { editable = "." }
3037
3037
  dependencies = [
3038
3038
  { name = "click" },
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "synalog-verified"
3
- version = "2.4.0"
3
+ version = "2.4.1"
4
4
  edition = "2024"
5
5
  description = "Synalog's graph algorithms, proved correct with Verus"
6
6
  license = "Apache-2.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes