{"record":{"id":"daa671f9d0cb3aa8","repo":"datawhalechina/hello-agents","slug":"theorem-parameters-must-be-uppercase-letters-and","errorCode":null,"errorMessage":"Theorem parameters must be uppercase letters and , only. The current theorem contains invalid characters '{str(error_paras)}'.","messagePattern":"Theorem parameters must be uppercase letters and , only\\. The current theorem contains invalid characters '(.+?)'\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py","lineNumber":1267,"sourceCode":"        return '\\n'.join(result)\n\n    def _parse_theorem(self, theorem):\n        try:\n            theorem_name, theorem_paras = parse_fact(theorem.replace(' ', ''))\n        except Exception as e:\n            e_msg = (f\"Error '{repr(e)}' occurred while parsing the theorem '{theorem}'. \"\n                     f\"The theorem format is incorrect.\")\n            raise Exception(e_msg)\n\n        if theorem_name not in self.parsed_gdl[\"Theorems\"]:\n            e_msg = f\"Unknown theorem name: '{theorem_name}'.\"\n            raise Exception(e_msg)\n\n        error_paras = set([char for char in theorem_paras if not char.isupper()])\n        if len(error_paras) > 0:\n            e_msg = (f\"Theorem parameters must be uppercase letters and , only. \"\n                     f\"The current theorem contains invalid characters '{str(error_paras)}'.\")\n            raise Exception(e_msg)\n\n        if len(theorem_paras) != 0 and len(theorem_paras) != len(self.parsed_gdl[\"Theorems\"][theorem_name]['paras']):\n            e_msg = (f\"'{theorem}' has wrong number of parameters \"\n                     f\"(expected {len(self.parsed_gdl[\"Theorems\"][theorem_name]['paras'])}).\")\n            raise Exception(e_msg)\n\n        if len(theorem_paras) == 0:\n            theorem_paras = None\n\n        return theorem_name, theorem_paras\n\n    def apply(self, theorem):\n        old_fact_id = len(self.facts)\n        old_goal_id = len(self.goals)\n        old_goal_status = self.status_of_goal.copy()\n        theorem_name, theorem_paras = self._parse_theorem(theorem)\n\n        if theorem_paras is not None:","sourceCodeStart":1249,"sourceCodeEnd":1285,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py#L1249-L1285","documentation":"Raised in _parse_theorem when the parameter segment returned by parse_fact() contains any character that fails str.isupper() (lowercase letters, digits, parentheses remnants, non-ASCII characters). The solver's theorem format only allows uppercase single-letter parameters separated by commas, because each character is treated as one parameter variable. Any other character makes substitution into the GPL premises impossible, so parsing is aborted.","triggerScenarios":"Passing a theorem whose parameters contain lowercase point names ('triangle(a,b,c)'), multi-character identifiers ('triangle(AB,CD)'), digits, or leftover formatting like underscores. Note the whole parameter string is iterated character-by-character, so commas are the only accepted separator and every other char must be A-Z.","commonSituations":"LLM agents generating lowercase or multi-letter point labels; users accustomed to 'point P1' style naming; parameter strings that still contain brackets after parse_fact.","solutions":["Rewrite all parameters as single uppercase letters separated by commas: 'midline(ABC)' not 'midline(a,b,c1)'.","If multi-character identifiers are required, they are unsupported by this format — map them to single uppercase letters and keep the mapping outside the solver.","Sanitize the theorem string before calling apply/decompose: re.sub(r'[^A-Z,]', '', paras)."],"exampleFix":"# before\nsolver.apply('similar_triangle(tri1, tri2)')  # digits + lowercase\n\n# after\nsolver.apply('similar_triangle(A,B,C,D,E,F)')  # single uppercase letters only","handlingStrategy":"validation","validationCode":"import re\ndef valid_theorem_params(theorem):\n    paras = theorem.split('(', 1)[1].rsplit(')', 1)[0] if '(' in theorem else ''\n    return re.fullmatch(r'[A-Z,]*', paras) is not None","typeGuard":null,"tryCatchPattern":"try:\n    solver.apply(theorem)\nexcept Exception as e:\n    if 'uppercase letters' in str(e):\n        theorem = re.sub(r'[^A-Z,(]', '', theorem)  # sanitize and retry once","preventionTips":["Generate theorem calls programmatically from uppercase point labels only.","Add a regex gate (^[A-Z,]*$ on the param segment) in agent tool wrappers before the solver sees input.","Tell the LLM in the tool description that parameters are single uppercase letters, comma-separated."],"tags":["geometry","symbolic-solver","validation","input-format"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}