cpp-pd-code-simplify-interface 0.1.2__tar.gz → 0.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cpp-pd-code-simplify-interface
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Python interface for cpp-pd-code-simplify with runtime C++ compilation.
5
5
  License-Expression: MIT
6
6
  Author: GGN_2015
@@ -35,7 +35,7 @@ use, the package compiles a cached local dynamic library through
35
35
  compiler compatible with `g++` must be available at runtime.
36
36
 
37
37
  Calls use the C++ library's default preprocessing pipeline: R1-move removal
38
- followed by nugatory-crossing removal.
38
+ followed by nugatory-crossing removal, then iterative mid-simplification.
39
39
 
40
40
  ## Example
41
41
 
@@ -44,12 +44,14 @@ import cpp_pd_code_simplify_interface as simplify
44
44
 
45
45
  pd_code = "PD[X[1,5,2,4],X[3,1,4,6],X[5,3,6,2]]"
46
46
  result = simplify.simplify(pd_code)
47
- print(result["simplification_found"])
47
+ print(result["final_pd_code"])
48
48
  ```
49
49
 
50
50
  The default `max_paths=-1` uses deterministic heuristic green-path sampling in
51
51
  the C++ backend. Use `ban_heuristic=True` to request exhaustive green-path
52
- enumeration for a manageable input.
52
+ enumeration for a manageable input. Use `reduction_round=K` to cap applied
53
+ mid-simplification rounds; the default `-1` runs until stable. Use
54
+ `verbose=True` to forward C++ progress logs to stderr.
53
55
 
54
56
  Batch use:
55
57
 
@@ -76,7 +78,7 @@ Python process needs a 64-bit compiler target.
76
78
  Command-line use also supports multi-line PD-code files:
77
79
 
78
80
  ```sh
79
- python -m cpp_pd_code_simplify_interface --pd-file inputs.pd --max-paths -1
81
+ python -m cpp_pd_code_simplify_interface --pd-file inputs.pd --max-paths -1 --verbose
80
82
  ```
81
83
 
82
84
  ## Build And Publish
@@ -15,7 +15,7 @@ use, the package compiles a cached local dynamic library through
15
15
  compiler compatible with `g++` must be available at runtime.
16
16
 
17
17
  Calls use the C++ library's default preprocessing pipeline: R1-move removal
18
- followed by nugatory-crossing removal.
18
+ followed by nugatory-crossing removal, then iterative mid-simplification.
19
19
 
20
20
  ## Example
21
21
 
@@ -24,12 +24,14 @@ import cpp_pd_code_simplify_interface as simplify
24
24
 
25
25
  pd_code = "PD[X[1,5,2,4],X[3,1,4,6],X[5,3,6,2]]"
26
26
  result = simplify.simplify(pd_code)
27
- print(result["simplification_found"])
27
+ print(result["final_pd_code"])
28
28
  ```
29
29
 
30
30
  The default `max_paths=-1` uses deterministic heuristic green-path sampling in
31
31
  the C++ backend. Use `ban_heuristic=True` to request exhaustive green-path
32
- enumeration for a manageable input.
32
+ enumeration for a manageable input. Use `reduction_round=K` to cap applied
33
+ mid-simplification rounds; the default `-1` runs until stable. Use
34
+ `verbose=True` to forward C++ progress logs to stderr.
33
35
 
34
36
  Batch use:
35
37
 
@@ -56,7 +58,7 @@ Python process needs a 64-bit compiler target.
56
58
  Command-line use also supports multi-line PD-code files:
57
59
 
58
60
  ```sh
59
- python -m cpp_pd_code_simplify_interface --pd-file inputs.pd --max-paths -1
61
+ python -m cpp_pd_code_simplify_interface --pd-file inputs.pd --max-paths -1 --verbose
60
62
  ```
61
63
 
62
64
  ## Build And Publish
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <array>
4
4
  #include <cstddef>
5
+ #include <functional>
5
6
  #include <iosfwd>
6
7
  #include <string>
7
8
  #include <vector>
@@ -49,7 +50,11 @@ struct GreenCrossing {
49
50
 
50
51
  struct SimplifierOptions {
51
52
  int max_paths = -1;
53
+ int max_threads = -1;
52
54
  bool ban_heuristic = false;
55
+ bool require_applicable = false;
56
+ bool verbose = false;
57
+ std::function<void(const std::string&)> progress;
53
58
  };
54
59
 
55
60
  struct LinkComponentSummary {
@@ -107,6 +112,24 @@ struct SimplificationResult {
107
112
  std::size_t tested_green_paths = 0;
108
113
  };
109
114
 
115
+ struct MidSimplificationApplyResult {
116
+ PDCode code;
117
+ std::size_t crossingless_components = 0;
118
+ };
119
+
120
+ struct ReductionResult {
121
+ PDCode code;
122
+ std::size_t crossingless_components = 0;
123
+ int mid_simplification_rounds = 0;
124
+ int heuristic_failover_rounds = 0;
125
+ int reidemeister_i_moves = 0;
126
+ int nugatory_crossing_moves = 0;
127
+ std::size_t tested_red_paths = 0;
128
+ std::size_t tested_green_paths = 0;
129
+ std::string last_path_search_mode;
130
+ bool stopped_by_round_limit = false;
131
+ };
132
+
110
133
  PDCODE_SIMPLIFY_API PDCode parse_pd_code(const std::string& text);
111
134
  PDCODE_SIMPLIFY_API std::string format_pd_code(const PDCode& code);
112
135
  PDCODE_SIMPLIFY_API std::string format_endpoint(const Endpoint& endpoint);
@@ -142,6 +165,17 @@ PDCODE_SIMPLIFY_API SimplificationResult find_simplification(
142
165
  const PDCode& code,
143
166
  const SimplifierOptions& options = SimplifierOptions{});
144
167
 
168
+ PDCODE_SIMPLIFY_API MidSimplificationApplyResult apply_simplification_witness(
169
+ const PDCode& code,
170
+ const SimplificationResult& result,
171
+ std::size_t known_crossingless_components = 0);
172
+
173
+ PDCODE_SIMPLIFY_API ReductionResult reduce_pd_code(
174
+ const PDCode& code,
175
+ std::size_t known_crossingless_components = 0,
176
+ const SimplifierOptions& options = SimplifierOptions{},
177
+ int reduction_round = -1);
178
+
145
179
  PDCODE_SIMPLIFY_API std::ostream& operator<<(std::ostream& out, const Endpoint& endpoint);
146
180
 
147
181
  } // namespace pdcode_simplify
@@ -3,6 +3,7 @@
3
3
  #include <cstdlib>
4
4
  #include <cstring>
5
5
  #include <exception>
6
+ #include <iostream>
6
7
  #include <sstream>
7
8
  #include <string>
8
9
  #include <vector>
@@ -55,14 +56,14 @@ void append_component_counts(
55
56
  }
56
57
 
57
58
  std::string result_to_json(
58
- const pdcode_simplify::SimplificationResult& result,
59
+ const pdcode_simplify::ReductionResult& result,
59
60
  const pdcode_simplify::ComponentAnalysis& input_components,
60
- const pdcode_simplify::ComponentAnalysis* after_removal_components,
61
- const pdcode_simplify::PDSimplificationResult& pd_simplification,
62
- const pdcode_simplify::ComponentAnalysis& search_components) {
61
+ const pdcode_simplify::ComponentAnalysis& final_components,
62
+ const pdcode_simplify::ComponentAnalysis* after_removal_components) {
63
63
  std::ostringstream out;
64
64
  out << "{";
65
- out << "\"simplification_found\":" << (result.found ? "true" : "false") << ",";
65
+ out << "\"simplification_found\":"
66
+ << (result.mid_simplification_rounds > 0 ? "true" : "false") << ",";
66
67
  out << "\"input_components\":{";
67
68
  append_component_counts(out, input_components);
68
69
  out << "},";
@@ -71,50 +72,21 @@ std::string result_to_json(
71
72
  append_component_counts(out, *after_removal_components);
72
73
  out << "},";
73
74
  }
74
- out << "\"pd_simplification\":{"
75
- << "\"enabled\":true,"
76
- << "\"reidemeister_i_moves\":" << pd_simplification.reidemeister_i_moves << ","
77
- << "\"nugatory_crossing_moves\":" << pd_simplification.nugatory_crossing_moves << ","
78
- << "\"output_crossings\":" << pd_simplification.code.size()
79
- << "},";
80
- out << "\"search_components\":{";
81
- append_component_counts(out, search_components);
75
+ out << "\"final_pd_code\":\"" << json_escape(pdcode_simplify::format_pd_code(result.code))
76
+ << "\",";
77
+ out << "\"final_crossings\":" << result.code.size() << ",";
78
+ out << "\"final_components\":{";
79
+ append_component_counts(out, final_components);
82
80
  out << "},";
81
+ out << "\"mid_simplification_rounds\":" << result.mid_simplification_rounds << ",";
82
+ out << "\"heuristic_failover_rounds\":" << result.heuristic_failover_rounds << ",";
83
+ out << "\"reidemeister_i_moves\":" << result.reidemeister_i_moves << ",";
84
+ out << "\"nugatory_crossing_moves\":" << result.nugatory_crossing_moves << ",";
83
85
  out << "\"tested_red_paths\":" << result.tested_red_paths << ",";
84
86
  out << "\"tested_green_paths\":" << result.tested_green_paths << ",";
85
- out << "\"path_search_mode\":\"" << json_escape(result.path_search_mode) << "\"";
86
- if (result.found) {
87
- out << ",";
88
- out << "\"direction\":\"" << pdcode_simplify::format_direction(result.direction) << "\",";
89
- out << "\"red_path\":[";
90
- for (std::size_t i = 0; i < result.red_path.size(); ++i) {
91
- if (i != 0) {
92
- out << ",";
93
- }
94
- out << "{\"crossing\":" << result.red_path[i].crossing
95
- << ",\"strand\":" << result.red_path[i].strand << "}";
96
- }
97
- out << "],";
98
- out << "\"green_path\":[";
99
- for (std::size_t i = 0; i < result.green_path.size(); ++i) {
100
- if (i != 0) {
101
- out << ",";
102
- }
103
- out << result.green_path[i];
104
- }
105
- out << "],";
106
- out << "\"green_crossings\":[";
107
- for (std::size_t i = 0; i < result.green_crossings.size(); ++i) {
108
- if (i != 0) {
109
- out << ",";
110
- }
111
- const auto& crossing = result.green_crossings[i];
112
- out << "{\"from_face\":" << crossing.from_face
113
- << ",\"to_face\":" << crossing.to_face
114
- << ",\"strand_level\":\"" << json_escape(crossing.strand_level) << "\"}";
115
- }
116
- out << "]";
117
- }
87
+ out << "\"last_path_search_mode\":\"" << json_escape(result.last_path_search_mode) << "\",";
88
+ out << "\"stopped_by_round_limit\":"
89
+ << (result.stopped_by_round_limit ? "true" : "false");
118
90
  out << "}";
119
91
  return out.str();
120
92
  }
@@ -139,6 +111,9 @@ char* pdcode_simplify_run_json(
139
111
  const char* pd_text,
140
112
  int max_paths,
141
113
  int ban_heuristic,
114
+ int reduction_round,
115
+ int max_thread,
116
+ int verbose,
142
117
  unsigned long long known_crossingless_components,
143
118
  const int* removed_crossings,
144
119
  unsigned long long removed_crossing_count) {
@@ -150,7 +125,12 @@ char* pdcode_simplify_run_json(
150
125
  const std::string text(pd_text);
151
126
  pdcode_simplify::SimplifierOptions options;
152
127
  options.max_paths = max_paths;
128
+ options.max_threads = max_thread;
153
129
  options.ban_heuristic = ban_heuristic != 0;
130
+ options.verbose = verbose != 0;
131
+ options.progress = [](const std::string& message) {
132
+ std::cerr << "[pdcode-simplify] " << message << '\n';
133
+ };
154
134
 
155
135
  const pdcode_simplify::PDCode code = pdcode_simplify::parse_pd_code(text);
156
136
  std::size_t crossingless = static_cast<std::size_t>(known_crossingless_components);
@@ -170,17 +150,15 @@ char* pdcode_simplify_run_json(
170
150
  code, removed, crossingless);
171
151
  }
172
152
 
173
- const auto pd_simplification = pdcode_simplify::simplify_pd_code(code, crossingless);
174
- const auto search_components = pdcode_simplify::analyze_components(
175
- pd_simplification.code,
176
- pd_simplification.crossingless_components);
177
- const auto result = pdcode_simplify::find_simplification(pd_simplification.code, options);
153
+ const auto result =
154
+ pdcode_simplify::reduce_pd_code(code, crossingless, options, reduction_round);
155
+ const auto final_components =
156
+ pdcode_simplify::analyze_components(result.code, result.crossingless_components);
178
157
  return copy_string(result_to_json(
179
158
  result,
180
159
  input_components,
181
- has_removal ? &after_removal_components : nullptr,
182
- pd_simplification,
183
- search_components));
160
+ final_components,
161
+ has_removal ? &after_removal_components : nullptr));
184
162
  } catch (const std::exception& error) {
185
163
  return copy_string(std::string("{\"error\":\"") + json_escape(error.what()) + "\"}");
186
164
  } catch (...) {