{"record":{"id":"218f39ed67dbca1f","repo":"datawhalechina/hello-agents","slug":"error-when-add-init-fact-predicate-instance","errorCode":null,"errorMessage":"Error when add init fact {(predicate, instance)}.","messagePattern":"Error when add init fact (.+?)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py","lineNumber":390,"sourceCode":"                    self.sym_to_sym[multiple_sym] = sym\n                    self.sym_to_syms[sym].add(multiple_sym)\n\n        # 4.9 add extended constructions\n        operation_id = self._add_operation(('Preset', 'extend_construction', None))\n        for predicate in extend_constructions:\n            for instance in extend_constructions[predicate]:\n                self._add_fact(predicate, instance, premise_ids, operation_id)\n\n        # 5.Add facts\n        operation_id = self._add_operation(('Preset', 'init_fact', None))\n        for predicate, instance in self.parsed_cdl['relation_cdl']:\n            if not self._pass_geometric_constraints(predicate, instance):\n                raise Exception(f'EE check not passed when add init fact {(predicate, instance)}.')\n            if (predicate, instance) in self.fact_id:\n                continue\n            fact_id, _ = self._add_fact(predicate, instance, (), operation_id)\n            if fact_id is None:\n                raise Exception(f'Error when add init fact {(predicate, instance)}.')\n\n        # 6.Set goal\n        init_goal_operation_id = self._add_operation(('Preset', 'init_goal', None))\n        goal_ids = self._add_goals([self.parsed_cdl['goal_cdl']], None, init_goal_operation_id)\n        if goal_ids is None:\n            raise Exception(f\"Error when set init goal {self.parsed_cdl['goal_cdl']}.\")\n        self._check_goals(goal_ids)\n\n    def _add_fact(self, predicate, instance, premise_ids, operation_id):\n        if predicate == 'Eq':\n            instance = self._adjust_expr(instance)\n            if instance is None or len(instance.free_symbols) == 0:\n                return None, set()\n\n        if (predicate, instance) in self.fact_id:\n            return None, set()\n\n        fact_id = len(self.facts)","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py#L372-L408","documentation":"An exception raised by the symbolic geometry solver's initialization (src/gps/symbolic_solver.py) when _add_fact returns None for an initial relation fact. Reading _add_fact, None is returned when the predicate is 'Eq' and the adjusted expression is degenerate — instance is None or has no free symbols (e.g. an equation like Eq(0) or one fully solved to a constant) — so the fact adds no information and the solver treats it as an error at init time. It signals a semantically vacuous or malformed initial equality in the problem's relation_cdl.","triggerScenarios":"Feeding the solver a CDL whose relation section includes an Eq fact whose expression simplifies to a constant (no free symbols) or fails _adjust_expr (returns None), such as 'Eq(AB+CD, AB+CD)' or 'Eq(3, 3)'. Non-Eq predicates take the normal fact-creation path and cannot produce this specific error. The raise fires on the first such fact during init.","commonSituations":"Auto-generated problems containing trivial identities; unit tests with placeholder Eq statements; expressions written in a form _adjust_expr cannot normalize (unsupported operators), yielding None; refactoring _adjust_expr to be stricter, retroactively breaking old problem files.","solutions":["Locate the printed (predicate, instance) pair — it names the exact offending Eq fact — and rewrite it to include at least one free symbol tied to the diagram","If the trivial equality is intentional documentation, remove it from relation_cdl","Check _adjust_expr for the supported expression grammar and normalize your Eq syntax to it","Add a pre-solve lint pass that flags Eq facts with zero free symbols before the solver runs"],"exampleFix":"# before (CDL relation)\n# Eq(Add(LengthOfLine(AB), LengthOfLine(CD)), Add(LengthOfLine(CD), LengthOfLine(AB)))  # tautology -> fact_id None\n\n# after\n# replace with a meaningful constraint, e.g.\n# Eq(LengthOfLine(AB), 5)","handlingStrategy":"validation","validationCode":"from sympy import sympify\n# reject Eq facts that carry no free symbols before solving\nfor predicate, instance in parse_relations(relation_cdl):\n    if predicate == 'Eq':\n        expr = adjust(instance)\n        if expr is None or not expr.free_symbols:\n            raise ValueError(f'vacuous Eq fact: {(predicate, instance)}')","typeGuard":null,"tryCatchPattern":"try:\n    solver.solve(problem_cdl)\nexcept Exception as e:\n    if 'Error when add init fact' in str(e):\n        flag_fact_as_malformed(str(e))  # inspect the printed (predicate, instance)\n    raise","preventionTips":["Avoid trivial/tautological Eq statements in relation_cdl","Follow the expression grammar _adjust_expr normalizes (verify with a small script)","Lint generated CDL for Eq facts with zero free symbols"],"tags":["geometry","solver","cdl","validation","domain-error"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}