summaryrefslogtreecommitdiff
path: root/src/gap_pipeline/surface.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/gap_pipeline/surface.py')
-rw-r--r--src/gap_pipeline/surface.py29
1 files changed, 27 insertions, 2 deletions
diff --git a/src/gap_pipeline/surface.py b/src/gap_pipeline/surface.py
index 914d847..aae34a8 100644
--- a/src/gap_pipeline/surface.py
+++ b/src/gap_pipeline/surface.py
@@ -29,6 +29,24 @@ SURFACE_FAMILIES: tuple[SurfaceFamily, ...] = (
IDENTIFIER_RE = re.compile(r"^[a-z]{8,}$")
+def apply_rename_map(text: str, rename_map: dict[str, str]) -> str:
+ """Apply symbol renames without replacing letters inside other tokens."""
+
+ rendered = text
+ for source in sorted(rename_map, key=len, reverse=True):
+ pattern = re.escape(source)
+ if source[0].isalnum():
+ pattern = rf"(?<![A-Za-z0-9_]){pattern}"
+ if source[-1].isalnum():
+ pattern = rf"{pattern}(?![A-Za-z0-9_])"
+ rendered = re.sub(
+ pattern,
+ lambda _match, replacement=rename_map[source]: replacement,
+ rendered,
+ )
+ return rendered
+
+
@dataclass(frozen=True)
class SurfaceVariant:
family: SurfaceFamily
@@ -69,6 +87,13 @@ def validate_surface_variant(
)
if not question.strip() or not solution.strip():
raise ValueError("surface question and solution must be non-empty")
+ expected_question = apply_rename_map(item.problem, rename_map)
+ expected_solution = apply_rename_map(item.solution, rename_map)
+ if question != expected_question or solution != expected_solution:
+ raise ValueError(
+ "surface text must be the exact deterministic rename of the "
+ "canonical question and solution"
+ )
class SurfacePipeline:
@@ -105,8 +130,8 @@ class SurfacePipeline:
str(old): str(new)
for old, new in dict(response.data["map"]).items()
}
- question = str(response.data["question"])
- solution = str(response.data["solution"])
+ question = apply_rename_map(item.problem, rename_map)
+ solution = apply_rename_map(item.solution, rename_map)
validate_surface_variant(
item,
rename_map=rename_map,