rbx.cp 0.5.2__tar.gz → 0.5.4__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 (163) hide show
  1. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/PKG-INFO +1 -1
  2. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/pyproject.toml +1 -1
  3. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/environment.py +1 -0
  4. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/presets/__init__.py +1 -0
  5. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/stresses.py +5 -12
  6. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/stressing/finder_parser.py +83 -24
  7. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/problem.rbx.yml +1 -1
  8. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/LICENSE +0 -0
  9. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/README.md +0 -0
  10. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/__init__.py +0 -0
  11. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/annotations.py +0 -0
  12. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/autoenum.py +0 -0
  13. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/__init__.py +0 -0
  14. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/builder.py +0 -0
  15. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/cd.py +0 -0
  16. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/checkers.py +0 -0
  17. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/code.py +0 -0
  18. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/compile.py +0 -0
  19. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/conftest.py +0 -0
  20. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/__init__.py +0 -0
  21. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/build_contest_statements.py +0 -0
  22. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/contest_package.py +0 -0
  23. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/contest_utils.py +0 -0
  24. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/main.py +0 -0
  25. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/schema.py +0 -0
  26. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/contest/statements.py +0 -0
  27. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/creation.py +0 -0
  28. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/download.py +0 -0
  29. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/extensions.py +0 -0
  30. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/generators.py +0 -0
  31. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/generators_test.py +0 -0
  32. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/main.py +0 -0
  33. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/package.py +0 -0
  34. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/boca/extension.py +0 -0
  35. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/boca/packager.py +0 -0
  36. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/contest_main.py +0 -0
  37. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/main.py +0 -0
  38. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/packager.py +0 -0
  39. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/polygon/packager.py +0 -0
  40. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/polygon/test.py +0 -0
  41. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/packaging/polygon/xml_schema.py +0 -0
  42. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/presets/fetch.py +0 -0
  43. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/presets/lock_schema.py +0 -0
  44. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/presets/schema.py +0 -0
  45. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/schema.py +0 -0
  46. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/solutions.py +0 -0
  47. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/solutions_test.py +0 -0
  48. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/__init__.py +0 -0
  49. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/build_statements.py +0 -0
  50. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/builders.py +0 -0
  51. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/joiners.py +0 -0
  52. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/latex.py +0 -0
  53. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/latex_jinja.py +0 -0
  54. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/statements/schema.py +0 -0
  55. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/stressing/__init__.py +0 -0
  56. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/stressing/generator_parser.py +0 -0
  57. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/testcases.py +0 -0
  58. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/ui/__init__.py +0 -0
  59. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/ui/captured_log.py +0 -0
  60. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/ui/css/app.tcss +0 -0
  61. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/ui/main.py +0 -0
  62. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/ui/run.py +0 -0
  63. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/validators.py +0 -0
  64. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/box/validators_test.py +0 -0
  65. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/checker.py +0 -0
  66. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/clone.py +0 -0
  67. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/config.py +0 -0
  68. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/conftest.py +0 -0
  69. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/console.py +0 -0
  70. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/create.py +0 -0
  71. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/edit.py +0 -0
  72. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/__init__.py +0 -0
  73. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/caching.py +0 -0
  74. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/conftest.py +0 -0
  75. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/__init__.py +0 -0
  76. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/cacher.py +0 -0
  77. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/digester.py +0 -0
  78. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/sandbox.py +0 -0
  79. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/sandboxes/__init__.py +0 -0
  80. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/sandboxes/isolate.py +0 -0
  81. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -0
  82. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/sandboxes/timeit.py +0 -0
  83. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/storage.py +0 -0
  84. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/test.py +0 -0
  85. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/judge/testiso.py +0 -0
  86. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/steps.py +0 -0
  87. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/steps_with_caching.py +0 -0
  88. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading/steps_with_caching_run_test.py +0 -0
  89. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/grading_utils.py +0 -0
  90. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/hydration.py +0 -0
  91. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/main.py +0 -0
  92. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/metadata.py +0 -0
  93. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/providers/__init__.py +0 -0
  94. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/providers/codeforces.py +0 -0
  95. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/providers/provider.py +0 -0
  96. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/checkers/boilerplate.cpp +0 -0
  97. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/default_config.json +0 -0
  98. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/envs/default.rbx.yml +0 -0
  99. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/envs/isolate.rbx.yml +0 -0
  100. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/checker.sh +0 -0
  101. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compare +0 -0
  102. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/c +0 -0
  103. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/cc +0 -0
  104. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/cpp +0 -0
  105. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/java +0 -0
  106. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/kt +0 -0
  107. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/pas +0 -0
  108. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/py2 +0 -0
  109. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/compile/py3 +0 -0
  110. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/c +0 -0
  111. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/cc +0 -0
  112. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/cpp +0 -0
  113. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/java +0 -0
  114. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/kt +0 -0
  115. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/py2 +0 -0
  116. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/packagers/boca/run/py3 +0 -0
  117. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
  118. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
  119. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
  120. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
  121. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/preset.rbx.yml +0 -0
  122. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/.gitignore +0 -0
  123. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/gen.cpp +0 -0
  124. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/random.py +0 -0
  125. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/random.txt +0 -0
  126. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
  127. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
  128. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
  129. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
  130. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
  131. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
  132. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
  133. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
  134. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
  135. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/validator.cpp +0 -0
  136. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
  137. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/resources/templates/template.cpp +0 -0
  138. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/run.py +0 -0
  139. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/schema.py +0 -0
  140. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/submit.py +0 -0
  141. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/submitors/__init__.py +0 -0
  142. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/submitors/codeforces.py +0 -0
  143. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/submitors/submitor.py +0 -0
  144. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/test.py +0 -0
  145. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testcase.py +0 -0
  146. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testcase_rendering.py +0 -0
  147. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/gen1.cpp +0 -0
  148. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/gen2.cpp +0 -0
  149. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/genScript.py +0 -0
  150. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
  151. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/ole.cpp +0 -0
  152. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/problem.rbx.yml +0 -0
  153. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/re.sol.cpp +0 -0
  154. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/sol.cpp +0 -0
  155. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/tests/1.in +0 -0
  156. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
  157. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/tle.sol.cpp +0 -0
  158. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/validator.cpp +0 -0
  159. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/box1/wa.sol.cpp +0 -0
  160. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/caching/executable.py +0 -0
  161. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testdata/compatible +0 -0
  162. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/testing_utils.py +0 -0
  163. {rbx_cp-0.5.2 → rbx_cp-0.5.4}/rbx/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rbx.cp
3
- Version: 0.5.2
3
+ Version: 0.5.4
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "rbx.cp"
3
- version = "0.5.2"
3
+ version = "0.5.4"
4
4
  description = ""
5
5
  packages = [
6
6
  {include = "rbx"}
@@ -212,6 +212,7 @@ def install_environment(name: str, file: pathlib.Path):
212
212
  )
213
213
  raise typer.Exit(1)
214
214
 
215
+ get_environment_path(name).parent.mkdir(parents=True, exist_ok=True)
215
216
  get_environment_path(name).write_bytes(file.read_bytes())
216
217
  console.console.print(
217
218
  f'[success]Environment [item]{name}[/item] was installed from [item]{file}[/item].'
@@ -316,6 +316,7 @@ def _install(root: pathlib.Path = pathlib.Path(), force: bool = False):
316
316
  should_copy_env = False
317
317
 
318
318
  if should_copy_env:
319
+ get_environment_path(preset.name).parent.mkdir(parents=True, exist_ok=True)
319
320
  shutil.rmtree(get_environment_path(preset.name), ignore_errors=True)
320
321
  shutil.copyfile(str(root / preset.env), get_environment_path(preset.name))
321
322
 
@@ -1,4 +1,3 @@
1
- import dataclasses
2
1
  import functools
3
2
  import time
4
3
  from shutil import rmtree
@@ -175,11 +174,13 @@ def run_stress(
175
174
 
176
175
  @functools.cache
177
176
  def run_solution_and_checker_fn(
178
- solution: str,
179
- checker: Optional[finder_parser.FinderChecker],
177
+ call: finder_parser.FinderCall,
180
178
  input_path=input_path,
181
179
  expected_output_path=expected_output_path,
182
180
  ) -> finder_parser.FinderResult:
181
+ solution = call.solution
182
+ checker = call.checker
183
+
183
184
  solution_result = run_solution_fn(solution)
184
185
 
185
186
  if checker is None:
@@ -196,19 +197,11 @@ def run_stress(
196
197
  solution=solution,
197
198
  outcome=checker_result.outcome,
198
199
  checker=checker,
199
- truth_value=True,
200
200
  solution_result=solution_result,
201
201
  checker_result=checker_result,
202
202
  )
203
203
 
204
- def run_fn(
205
- call: finder_parser.FinderCall,
206
- ) -> finder_parser.FinderResult:
207
- finder_result = run_solution_and_checker_fn(call.solution, call.checker)
208
- truth_value = call.expected_outcome.match(finder_result.outcome)
209
- return dataclasses.replace(finder_result, truth_value=truth_value)
210
-
211
- runner = finder_parser.FinderTreeRunner(runner=run_fn)
204
+ runner = finder_parser.FinderTreeRunner(runner=run_solution_and_checker_fn)
212
205
  finder_outcome: finder_parser.FinderOutcome = runner.transform(parsed_finder)
213
206
 
214
207
  internal_error_results = [
@@ -2,7 +2,7 @@ import dataclasses
2
2
  import pathlib
3
3
  import typing
4
4
  from enum import Enum
5
- from typing import Callable, List, Optional
5
+ from typing import Callable, List, Optional, Union
6
6
 
7
7
  import lark
8
8
  import typer
@@ -20,23 +20,34 @@ disjunction: conjunction | disjunction _OR conjunction
20
20
 
21
21
  conjunction: _atom | conjunction _AND _atom
22
22
 
23
- _atom: statement | "(" disjunction ")" | negation
23
+ _atom: logical | "(" disjunction ")" | negation
24
24
  negation: _NOT "(" disjunction ")"
25
25
 
26
- statement: solution matcher outcome checking?
26
+ // Expressions
27
+ logical: eval matcher expected_outcome -> matching
28
+ | eval equality (eval | outcome) -> equating
27
29
 
30
+ eval: "[" solution checking? "]"
31
+
32
+ // Eval
28
33
  solution: _filename | WILDCARD
29
- outcome: CNAME
30
34
  checking: "ON"i (checking_mode? checker | ":nil")
31
35
  checking_mode: MODE ":"
32
36
  MODE: "2" | "3"
33
37
  checker: _filename | WILDCARD
34
38
 
39
+ // Outcomes
40
+ expected_outcome: CNAME
41
+ outcome: CNAME
42
+
35
43
  // Operators
36
44
  matcher: MATCHES | NOT_MATCHES
45
+ equality: EQUALS | NOT_EQUALS
37
46
 
38
47
  MATCHES: "~"
39
48
  NOT_MATCHES: "!~"
49
+ EQUALS: "=="
50
+ NOT_EQUALS: "!="
40
51
  _OR: "||"
41
52
  _AND: "&&"
42
53
  _NOT: "!"
@@ -46,7 +57,14 @@ WILDCARD: "$"
46
57
  _filename: FILENAME | "\"" FILENAME "\""
47
58
  FILENAME: /[\/A-Za-z0-9\-_\.]/+
48
59
 
49
- %import common.CNAME
60
+ // Names (Variables)
61
+ LCASE_LETTER: "a".."z"
62
+ UCASE_LETTER: "A".."Z"
63
+ DIGIT: "0".."9"
64
+ LETTER: UCASE_LETTER | LCASE_LETTER
65
+ WORD: LETTER+
66
+ CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT|"+")*
67
+
50
68
  %ignore " "
51
69
  """
52
70
 
@@ -67,7 +85,6 @@ class FinderChecker:
67
85
  @dataclasses.dataclass(frozen=True)
68
86
  class FinderCall:
69
87
  solution: str
70
- expected_outcome: ExpectedOutcome
71
88
  checker: Optional[FinderChecker]
72
89
 
73
90
 
@@ -83,7 +100,6 @@ class FinderResult:
83
100
  solution: str
84
101
  outcome: Outcome
85
102
  checker: Optional[FinderChecker]
86
- truth_value: bool
87
103
 
88
104
  # Auxiliary information.
89
105
  solution_result: Optional[FinderSolutionResult] = None
@@ -155,8 +171,8 @@ def _get_checker_from_token(token: lark.Token) -> str:
155
171
  return path
156
172
 
157
173
 
158
- def _get_statement_checker(statement: lark.ParseTree) -> Optional[FinderChecker]:
159
- checking_nodes = list(statement.find_data('checking'))
174
+ def _get_eval_checker(eval: lark.ParseTree) -> Optional[FinderChecker]:
175
+ checking_nodes = list(eval.find_data('checking'))
160
176
  if not checking_nodes:
161
177
  return _get_default_checker_for_finder()
162
178
  (checking,) = checking_nodes
@@ -227,11 +243,11 @@ def get_all_solution_items(tree: lark.ParseTree) -> List[CodeItem]:
227
243
 
228
244
 
229
245
  def _get_all_finder_checkers(tree: lark.ParseTree) -> List[FinderChecker]:
230
- statement_nodes = tree.find_data('statement')
246
+ eval_nodes = tree.find_data('eval')
231
247
  res = []
232
248
 
233
- for statement_node in statement_nodes:
234
- finder_checker = _get_statement_checker(statement_node)
249
+ for eval_node in eval_nodes:
250
+ finder_checker = _get_eval_checker(eval_node)
235
251
  if finder_checker is not None:
236
252
  res.append(finder_checker)
237
253
 
@@ -299,8 +315,6 @@ def validate(tree: lark.ParseTree):
299
315
 
300
316
  @lark.v_args(inline=True)
301
317
  class FinderTreeRunner(lark.Transformer):
302
- outcome = ExpectedOutcome
303
-
304
318
  def __init__(
305
319
  self,
306
320
  runner: Callable[[FinderCall], FinderResult],
@@ -310,27 +324,72 @@ class FinderTreeRunner(lark.Transformer):
310
324
  def solution(self, token: lark.Token) -> str:
311
325
  return _get_solution_from_token(token)
312
326
 
327
+ def outcome(self, token: lark.Token) -> Outcome:
328
+ try:
329
+ outcome = Outcome(token.value)
330
+ except ValueError:
331
+ try:
332
+ expected_outcome = self.expected_outcome(token)
333
+ except ValueError:
334
+ raise ValueError(f'"{token.value}" is not a valid Outcome.') from None
335
+ outcomes = expected_outcome.get_matches()
336
+ if len(outcomes) != 1:
337
+ raise ValueError(
338
+ f'"{token.value}" is not a valid Outcome. You are trying to specify an ExpectedOutcome, instead of a single Outcome.'
339
+ ) from None
340
+ return outcomes[0]
341
+ return outcome
342
+
343
+ def expected_outcome(self, token: lark.Token) -> ExpectedOutcome:
344
+ return ExpectedOutcome(token.value)
345
+
313
346
  def matcher(self, op: lark.Token) -> bool:
314
347
  return op.value == '~'
315
348
 
349
+ def equality(self, op: lark.Token) -> bool:
350
+ return op.value == '=='
351
+
316
352
  @lark.v_args(inline=False, tree=True)
317
- def statement(
353
+ def eval(self, tree: lark.ParseTree) -> FinderResult:
354
+ solution = typing.cast(str, tree.children[0])
355
+ checker: Optional[FinderChecker] = _get_eval_checker(tree)
356
+
357
+ call = FinderCall(solution, checker=checker)
358
+ return self.run_fn(call)
359
+
360
+ def matching(
318
361
  self,
319
- tree: lark.ParseTree,
362
+ eval_result: FinderResult,
363
+ is_positive: bool,
364
+ expected_outcome: ExpectedOutcome,
320
365
  ) -> FinderOutcome:
321
- solution = typing.cast(str, tree.children[0])
322
- is_positive = typing.cast(bool, tree.children[1])
323
- expected_outcome = typing.cast(ExpectedOutcome, tree.children[2])
366
+ truth_value = expected_outcome.match(eval_result.outcome)
367
+ if not is_positive:
368
+ truth_value = not truth_value
369
+
370
+ return FinderOutcome(truth_value=truth_value, results=[eval_result])
371
+
372
+ def equating(
373
+ self,
374
+ eval_result: FinderResult,
375
+ is_positive: bool,
376
+ result_or_outcome: Union[FinderResult, Outcome],
377
+ ) -> FinderOutcome:
378
+ results = [eval_result]
379
+ truth_value = True
324
380
 
325
- checker: Optional[FinderChecker] = _get_statement_checker(tree)
381
+ if isinstance(result_or_outcome, Outcome):
382
+ outcome: Outcome = result_or_outcome
383
+ truth_value = eval_result.outcome == outcome
384
+ else:
385
+ result: FinderResult = result_or_outcome
386
+ truth_value = eval_result.outcome == result.outcome
387
+ results.append(result)
326
388
 
327
- call = FinderCall(solution, expected_outcome=expected_outcome, checker=checker)
328
- result = self.run_fn(call)
329
- truth_value = result.truth_value
330
389
  if not is_positive:
331
390
  truth_value = not truth_value
332
391
 
333
- return FinderOutcome(truth_value=truth_value, results=[result])
392
+ return FinderOutcome(truth_value=truth_value, results=results)
334
393
 
335
394
  def negation(self, value: FinderOutcome) -> FinderOutcome:
336
395
  return dataclasses.replace(value, truth_value=not value.truth_value)
@@ -38,7 +38,7 @@ stresses:
38
38
  generator:
39
39
  name: 'gen'
40
40
  args: '[1..<MAX_N>] @' # `@` generates a random string
41
- finder: 'sols/wa.cpp ~ INCORRECT'
41
+ finder: '[sols/wa.cpp] ~ INCORRECT'
42
42
  vars:
43
43
  "MAX_N": 1000000000 # Can be used in the validator, in stress tests and in the statement.
44
44
 
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
File without changes
File without changes
File without changes
File without changes