{"record":{"id":"ddbb6303cdd33839","repo":"datawhalechina/hello-agents","slug":"theorem-has-wrong-number-of-parameters-expect","errorCode":null,"errorMessage":"'{theorem}' has wrong number of parameters (expected {len(self.parsed_gdl[\"Theorems\"][theorem_name]['paras'])}).","messagePattern":"'(.+?)' has wrong number of parameters \\(expected (.+?)\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py","lineNumber":1272,"sourceCode":"        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:\n            theorem_gdl = self.parsed_gdl['Theorems'][theorem_name]\n            replace = dict(zip(theorem_gdl['paras'], theorem_paras))\n            premise_ids = set()\n            for gpl_one_term in theorem_gdl['premises_gpl']:  # run gdl with theorem parameter\n                product = gpl_one_term['product']","sourceCodeStart":1254,"sourceCodeEnd":1290,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py#L1254-L1290","documentation":"Raised in _parse_theorem when the theorem string supplies a non-zero number of parameters that does not equal len(parsed_gdl['Theorems'][name]['paras']) — the arity declared in the GDL theorem definition. The solver needs an exact positional mapping between supplied parameters and the theorem's declared parameters to build the substitution dict for premises and conclusion, so any arity mismatch is fatal. Supplying zero parameters is allowed and defers to other checks (errors 123/124).","triggerScenarios":"Calling apply('midsegment(A,B)') when the GDL defines midsegment with 6 parameters; passing 3 of 4 points of a quadrilateral theorem; counting commas incorrectly because multi-letter tokens were collapsed to per-character params.","commonSituations":"LLM agents guessing parameter counts instead of reading the theorem's declared signature; GDL files updated to add a parameter while prompts still show the old count.","solutions":["Read the expected count from solver.parsed_gdl['Theorems'][name]['paras'] and supply exactly that many uppercase letters.","If unsure of the signature, call apply with no parameters (when the theorem is not in special_theorem and its name avoids perimeter/area/similar/congruent) and let the solver enumerate instances.","Check for accidentally merged/split parameters (e.g. 'AB' counts as two params A and B)."],"exampleFix":"# before\nsolver.apply('congruent_triangle(A,B,C)')  # GDL expects 6 params\n\n# after\nn = len(solver.parsed_gdl['Theorems']['congruent_triangle']['paras'])\n# n == 6\nsolver.apply('congruent_triangle(A,B,C,D,E,F)')","handlingStrategy":"validation","validationCode":"def check_theorem_arity(solver, theorem):\n    name = theorem.replace(' ', '').split('(')[0]\n    expected = len(solver.parsed_gdl['Theorems'][name]['paras'])\n    paras = theorem.split('(', 1)[1].rsplit(')', 1)[0] if '(' in theorem else ''\n    actual = len([c for c in paras if c.isupper()])\n    assert actual == 0 or actual == expected, f'expected {expected}, got {actual}'","typeGuard":null,"tryCatchPattern":"try:\n    solver.apply(theorem)\nexcept Exception as e:\n    if 'wrong number of parameters' in str(e):\n        # re-emit with the arity printed in the message and retry","preventionTips":["Always read arity from parsed_gdl['Theorems'][name]['paras'] instead of guessing.","Include the parameter count in each theorem's tool description given to the LLM.","Wrap apply() in a helper that formats 'name(' + ','.join(points[:n]) + ')'."],"tags":["geometry","symbolic-solver","arity","validation"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}