cpp-pd-code-simplify-interface 0.1.13__py3-none-any.whl → 0.1.14__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.
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import sys
5
+ from pathlib import Path
5
6
  from typing import Any
6
7
 
7
8
  from .main import _run_one_direct
@@ -18,28 +19,48 @@ def main() -> int:
18
19
  max_thread=int(request.get("max_thread", -1)),
19
20
  timeout=int(request.get("timeout", -1)),
20
21
  verbose=bool(request.get("verbose", False)),
22
+ show_step_pd=bool(request.get("show_step_pd", False)),
21
23
  known_crossingless_components=int(
22
24
  request.get("known_crossingless_components", 0)
23
25
  ),
24
26
  remove_crossings=request.get("remove_crossings") or [],
25
27
  )
26
- print(json.dumps({"ok": True, "result": result}, separators=(",", ":")))
28
+ output = json.dumps({"ok": True, "result": result}, separators=(",", ":"))
29
+ protocol_output_path = request.get("protocol_output_path")
30
+ if protocol_output_path:
31
+ Path(str(protocol_output_path)).write_text(output, encoding="utf-8")
32
+ else:
33
+ print(output)
27
34
  return 0
28
35
  except KeyboardInterrupt:
29
- print(
30
- json.dumps(
31
- {"ok": False, "error": "interrupted by Ctrl+C"},
32
- separators=(",", ":"),
33
- )
36
+ output = json.dumps(
37
+ {"ok": False, "error": "interrupted by Ctrl+C"},
38
+ separators=(",", ":"),
34
39
  )
40
+ try:
41
+ request
42
+ except NameError:
43
+ request = {}
44
+ protocol_output_path = request.get("protocol_output_path")
45
+ if protocol_output_path:
46
+ Path(str(protocol_output_path)).write_text(output, encoding="utf-8")
47
+ else:
48
+ print(output)
35
49
  return 130
36
50
  except BaseException as exc: # noqa: BLE001 - return errors through JSON.
37
- print(
38
- json.dumps(
39
- {"ok": False, "error": str(exc)},
40
- separators=(",", ":"),
41
- )
51
+ output = json.dumps(
52
+ {"ok": False, "error": str(exc)},
53
+ separators=(",", ":"),
42
54
  )
55
+ try:
56
+ request
57
+ except NameError:
58
+ request = {}
59
+ protocol_output_path = request.get("protocol_output_path")
60
+ if protocol_output_path:
61
+ Path(str(protocol_output_path)).write_text(output, encoding="utf-8")
62
+ else:
63
+ print(output)
43
64
  return 0
44
65
 
45
66
 
@@ -59,6 +59,7 @@ struct SimplifierOptions {
59
59
  bool require_applicable = false;
60
60
  bool verbose = false;
61
61
  std::function<void(const std::string&)> progress;
62
+ std::function<void(int, const PDCode&)> step_pd_output;
62
63
  std::function<bool()> should_cancel;
63
64
  };
64
65
 
@@ -136,6 +136,7 @@ char* pdcode_simplify_run_json(
136
136
  int max_thread,
137
137
  int timeout_seconds,
138
138
  int verbose,
139
+ int show_step_pd,
139
140
  unsigned long long known_crossingless_components,
140
141
  const int* removed_crossings,
141
142
  unsigned long long removed_crossing_count) {
@@ -154,6 +155,14 @@ char* pdcode_simplify_run_json(
154
155
  options.progress = [](const std::string& message) {
155
156
  print_progress_log(message);
156
157
  };
158
+ if (show_step_pd != 0) {
159
+ options.step_pd_output = [](int round, const pdcode_simplify::PDCode& step_code) {
160
+ std::cout << "step_pd_code[" << round << "]: "
161
+ << pdcode_simplify::format_final_pd_code(step_code)
162
+ << '\n';
163
+ std::cout.flush();
164
+ };
165
+ }
157
166
 
158
167
  const pdcode_simplify::PDCode code = pdcode_simplify::parse_pd_code(text);
159
168
  std::size_t crossingless = static_cast<std::size_t>(known_crossingless_components);
@@ -1836,6 +1836,12 @@ void emit_progress(const SimplifierOptions& options, const std::string& message)
1836
1836
  }
1837
1837
  }
1838
1838
 
1839
+ void emit_step_pd(const SimplifierOptions& options, int round, const PDCode& code) {
1840
+ if (options.step_pd_output) {
1841
+ options.step_pd_output(round, code);
1842
+ }
1843
+ }
1844
+
1839
1845
  std::string search_mode_for_options(const SimplifierOptions& options) {
1840
1846
  if (options.max_paths == -1 && !options.ban_heuristic) {
1841
1847
  return "heuristic";
@@ -2639,6 +2645,7 @@ ReductionResult reduce_pd_code(
2639
2645
  const MidSimplificationApplyResult applied =
2640
2646
  apply_simplification_witness(output.code, search, output.crossingless_components);
2641
2647
  ++output.mid_simplification_rounds;
2648
+ emit_step_pd(run_options, round, applied.code);
2642
2649
  output.code = applied.code;
2643
2650
  output.crossingless_components = applied.crossingless_components;
2644
2651
  check_timeout(run_options);
@@ -15,6 +15,7 @@ import shutil
15
15
  import struct
16
16
  import subprocess
17
17
  import sys
18
+ import tempfile
18
19
  from importlib import resources
19
20
  from typing import Any, Optional, Sequence, Union
20
21
 
@@ -763,6 +764,7 @@ def _load_library() -> ctypes.CDLL:
763
764
  ctypes.c_int,
764
765
  ctypes.c_int,
765
766
  ctypes.c_int,
767
+ ctypes.c_int,
766
768
  ctypes.c_ulonglong,
767
769
  ctypes.POINTER(ctypes.c_int),
768
770
  ctypes.c_ulonglong,
@@ -784,6 +786,7 @@ def _run_one_direct(
784
786
  max_thread: int = -1,
785
787
  timeout: int = -1,
786
788
  verbose: bool = False,
789
+ show_step_pd: bool = False,
787
790
  known_crossingless_components: int = 0,
788
791
  remove_crossings: Optional[Sequence[int]] = None,
789
792
  ) -> dict[str, Any]:
@@ -807,6 +810,7 @@ def _run_one_direct(
807
810
  int(max_thread),
808
811
  int(timeout),
809
812
  1 if verbose else 0,
813
+ 1 if show_step_pd else 0,
810
814
  int(known_crossingless_components),
811
815
  removed_array,
812
816
  int(removed_count),
@@ -847,6 +851,7 @@ def _run_one(
847
851
  max_thread: int = -1,
848
852
  timeout: int = -1,
849
853
  verbose: bool = False,
854
+ show_step_pd: bool = False,
850
855
  known_crossingless_components: int = 0,
851
856
  remove_crossings: Optional[Sequence[int]] = None,
852
857
  ) -> dict[str, Any]:
@@ -865,43 +870,62 @@ def _run_one(
865
870
  "max_thread": int(max_thread),
866
871
  "timeout": int(timeout),
867
872
  "verbose": bool(verbose),
873
+ "show_step_pd": bool(show_step_pd),
868
874
  "known_crossingless_components": int(known_crossingless_components),
869
875
  "remove_crossings": [int(value) for value in remove_crossings or []],
870
876
  }
877
+ protocol_output_path: Optional[pathlib.Path] = None
878
+ if show_step_pd:
879
+ fd, protocol_name = tempfile.mkstemp(
880
+ prefix="cpp-pd-code-simplify-interface-",
881
+ suffix=".json",
882
+ )
883
+ os.close(fd)
884
+ protocol_output_path = pathlib.Path(protocol_name)
885
+ request["protocol_output_path"] = str(protocol_output_path)
871
886
  env = os.environ.copy()
872
887
  project_root = str(pathlib.Path(__file__).resolve().parents[1])
873
888
  env["PYTHONPATH"] = project_root + os.pathsep + env.get("PYTHONPATH", "")
874
- proc = subprocess.Popen(
875
- [
876
- sys.executable,
877
- "-m",
878
- "cpp_pd_code_simplify_interface._worker",
879
- ],
880
- cwd=str(pathlib.Path.cwd()),
881
- text=True,
882
- stdin=subprocess.PIPE,
883
- stdout=subprocess.PIPE,
884
- stderr=None if verbose else subprocess.PIPE,
885
- env=env,
886
- )
887
889
  try:
888
- stdout, stderr = proc.communicate(json.dumps(request))
889
- except KeyboardInterrupt:
890
- _terminate_process(proc)
891
- raise
892
-
893
- if proc.returncode != 0:
894
- detail = (stderr or "").strip()
895
- raise PdCodeSimplifyInterfaceError(
896
- f"C++ interface worker failed with exit code {proc.returncode}"
897
- + (f": {detail}" if detail else "")
890
+ proc = subprocess.Popen(
891
+ [
892
+ sys.executable,
893
+ "-m",
894
+ "cpp_pd_code_simplify_interface._worker",
895
+ ],
896
+ cwd=str(pathlib.Path.cwd()),
897
+ text=True,
898
+ stdin=subprocess.PIPE,
899
+ stdout=None if show_step_pd else subprocess.PIPE,
900
+ stderr=None if verbose else subprocess.PIPE,
901
+ env=env,
898
902
  )
899
- try:
900
- envelope = json.loads(stdout)
901
- except json.JSONDecodeError as exc:
902
- raise PdCodeSimplifyInterfaceError(
903
- f"invalid interface worker JSON output: {stdout!r}"
904
- ) from exc
903
+ try:
904
+ stdout, stderr = proc.communicate(json.dumps(request))
905
+ except KeyboardInterrupt:
906
+ _terminate_process(proc)
907
+ raise
908
+
909
+ if proc.returncode != 0:
910
+ detail = (stderr or "").strip()
911
+ raise PdCodeSimplifyInterfaceError(
912
+ f"C++ interface worker failed with exit code {proc.returncode}"
913
+ + (f": {detail}" if detail else "")
914
+ )
915
+ if protocol_output_path is not None:
916
+ stdout = protocol_output_path.read_text(encoding="utf-8")
917
+ try:
918
+ envelope = json.loads(stdout or "")
919
+ except json.JSONDecodeError as exc:
920
+ raise PdCodeSimplifyInterfaceError(
921
+ f"invalid interface worker JSON output: {stdout!r}"
922
+ ) from exc
923
+ finally:
924
+ if protocol_output_path is not None:
925
+ try:
926
+ protocol_output_path.unlink()
927
+ except FileNotFoundError:
928
+ pass
905
929
  if not isinstance(envelope, dict):
906
930
  raise PdCodeSimplifyInterfaceError(
907
931
  f"invalid interface worker response type: {type(envelope)!r}"
@@ -923,6 +947,7 @@ def simplify(
923
947
  max_thread: int = -1,
924
948
  timeout: int = -1,
925
949
  verbose: bool = False,
950
+ show_step_pd: bool = False,
926
951
  known_crossingless_components: int = 0,
927
952
  remove_crossings: Optional[Sequence[int]] = None,
928
953
  ) -> dict[str, Any]:
@@ -936,6 +961,7 @@ def simplify(
936
961
  max_thread=max_thread,
937
962
  timeout=timeout,
938
963
  verbose=verbose,
964
+ show_step_pd=show_step_pd,
939
965
  known_crossingless_components=known_crossingless_components,
940
966
  remove_crossings=remove_crossings,
941
967
  )
@@ -950,6 +976,7 @@ def simplify_many(
950
976
  max_thread: int = -1,
951
977
  timeout: int = -1,
952
978
  verbose: bool = False,
979
+ show_step_pd: bool = False,
953
980
  known_crossingless_components: int = 0,
954
981
  remove_crossings: Optional[Sequence[int]] = None,
955
982
  ) -> list[dict[str, Any]]:
@@ -964,6 +991,7 @@ def simplify_many(
964
991
  max_thread=max_thread,
965
992
  timeout=timeout,
966
993
  verbose=verbose,
994
+ show_step_pd=show_step_pd,
967
995
  known_crossingless_components=known_crossingless_components,
968
996
  remove_crossings=remove_crossings,
969
997
  )
@@ -982,6 +1010,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
982
1010
  parser.add_argument("--max-thread", type=int, default=-1)
983
1011
  parser.add_argument("--timeout", type=int, default=-1)
984
1012
  parser.add_argument("--verbose", action="store_true")
1013
+ parser.add_argument("--show-step-pd", action="store_true")
985
1014
  parser.add_argument("--known-crossingless-components", type=int, default=0)
986
1015
  parser.add_argument("--remove-crossings", help="comma-separated zero-based crossing indices")
987
1016
  args = parser.parse_args(argv)
@@ -1017,6 +1046,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
1017
1046
  max_thread=args.max_thread,
1018
1047
  timeout=args.timeout,
1019
1048
  verbose=args.verbose,
1049
+ show_step_pd=args.show_step_pd,
1020
1050
  known_crossingless_components=args.known_crossingless_components,
1021
1051
  remove_crossings=remove_crossings,
1022
1052
  )
@@ -1049,6 +1079,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
1049
1079
  max_thread=args.max_thread,
1050
1080
  timeout=args.timeout,
1051
1081
  verbose=args.verbose,
1082
+ show_step_pd=args.show_step_pd,
1052
1083
  known_crossingless_components=args.known_crossingless_components,
1053
1084
  remove_crossings=remove_crossings,
1054
1085
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cpp-pd-code-simplify-interface
3
- Version: 0.1.13
3
+ Version: 0.1.14
4
4
  Summary: Python interface for cpp-pd-code-simplify with runtime C++ compilation.
5
5
  License-Expression: MIT
6
6
  Author: GGN_2015
@@ -77,6 +77,9 @@ and sets `timed_out` to `True`. Verbose log lines use local wall-clock time in
77
77
  phase, verbose logs also include `actual_threads`, the worker count selected by
78
78
  the C++ backend for that phase. The backend call runs in a helper process, so
79
79
  `Ctrl+C` can terminate active C++ work and its worker threads cleanly.
80
+ Use `show_step_pd=True`, or CLI flag `--show-step-pd`, to print
81
+ `step_pd_code[ROUND]: PD[...]` to stdout after each mid-simplification witness
82
+ is applied and before that round's automatic R1/nugatory cleanup.
80
83
 
81
84
  Batch use:
82
85
 
@@ -0,0 +1,12 @@
1
+ cpp_pd_code_simplify_interface/__init__.py,sha256=aaNwD--zgQX13xiU1hpuvgXy8vVTFGRk-r5zLm8zIRY,447
2
+ cpp_pd_code_simplify_interface/__main__.py,sha256=fdA1QWBe5LNX0fbtaJXa1-dwEhrg_4sS_5UnjaajcMo,80
3
+ cpp_pd_code_simplify_interface/_worker.py,sha256=RPLUE-4amjh78C1fmFolmSIM2_s8AXWk-2fWvASq7A0,2338
4
+ cpp_pd_code_simplify_interface/main.py,sha256=yVWv0zmsJGT3pHhruwK4QaHl3Dn4rJ6spr_fqMMm1Dk,38307
5
+ cpp_pd_code_simplify_interface/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
+ cpp_pd_code_simplify_interface-0.1.14.dist-info/entry_points.txt,sha256=ThorC4Enxp317TKITsXm9pE0gUp7pt-pP6Dl5mEPUR8,91
7
+ cpp_pd_code_simplify_interface-0.1.14.dist-info/METADATA,sha256=InpkotMDzumP-fnGzGTHVcpk-LKV0-gvmf8w-wvFYIM,4762
8
+ cpp_pd_code_simplify_interface-0.1.14.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
9
+ cpp_pd_code_simplify_interface/data/include/pdcode_simplify/pdcode_simplify.hpp,sha256=U49Urs6bMXwkygJsVTnXp-q7y_aWkfRfGimy8mxHoms,5195
10
+ cpp_pd_code_simplify_interface/data/src/native_interface.cpp,sha256=YiYlbGyWTM_FA0V_XzjHtnb9sD4eqMGQmdom6ivm0f0,7094
11
+ cpp_pd_code_simplify_interface/data/src/pdcode_simplify.cpp,sha256=A9ozSFzD_bkgrSl_9tIxH6PVAceUix76nRceEO6Ymho,96021
12
+ cpp_pd_code_simplify_interface-0.1.14.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- cpp_pd_code_simplify_interface/__init__.py,sha256=aaNwD--zgQX13xiU1hpuvgXy8vVTFGRk-r5zLm8zIRY,447
2
- cpp_pd_code_simplify_interface/__main__.py,sha256=fdA1QWBe5LNX0fbtaJXa1-dwEhrg_4sS_5UnjaajcMo,80
3
- cpp_pd_code_simplify_interface/_worker.py,sha256=pgvL3zlAZkUVM033YKAT1geXxcI8TxTUXLp83sgrZgw,1477
4
- cpp_pd_code_simplify_interface/main.py,sha256=QkhR_2Cq9Ep_8hT5qpFKML7bhq99SuQSKO0jePJHp3U,37007
5
- cpp_pd_code_simplify_interface/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
6
- cpp_pd_code_simplify_interface-0.1.13.dist-info/entry_points.txt,sha256=ThorC4Enxp317TKITsXm9pE0gUp7pt-pP6Dl5mEPUR8,91
7
- cpp_pd_code_simplify_interface-0.1.13.dist-info/METADATA,sha256=-uQyhNQjhrKxBj2_HaRqkrWhF50ojY878shH3kafxaE,4553
8
- cpp_pd_code_simplify_interface-0.1.13.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
9
- cpp_pd_code_simplify_interface/data/include/pdcode_simplify/pdcode_simplify.hpp,sha256=ZWZVWuSXN9HgCYd88pfURgLqs-3_0xGDi_ZEPZrYUyY,5135
10
- cpp_pd_code_simplify_interface/data/src/native_interface.cpp,sha256=-X9ztIyCl5y27Yhj2vCyC4bHCeDpFlcKm6ACPMDoxHs,6708
11
- cpp_pd_code_simplify_interface/data/src/pdcode_simplify.cpp,sha256=xQd5-tirH-Mk4dLZpXAAZo6qHP4mpAFO94Z8GFCPJbg,95788
12
- cpp_pd_code_simplify_interface-0.1.13.dist-info/RECORD,,