datawhalechina/hello-agents · error · Exception

Error when add init fact {(predicate, instance)}.

Error message

Error when add init fact {(predicate, instance)}.

What it means

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.

Source

Thrown at Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py:390

                    self.sym_to_sym[multiple_sym] = sym
                    self.sym_to_syms[sym].add(multiple_sym)

        # 4.9 add extended constructions
        operation_id = self._add_operation(('Preset', 'extend_construction', None))
        for predicate in extend_constructions:
            for instance in extend_constructions[predicate]:
                self._add_fact(predicate, instance, premise_ids, operation_id)

        # 5.Add facts
        operation_id = self._add_operation(('Preset', 'init_fact', None))
        for predicate, instance in self.parsed_cdl['relation_cdl']:
            if not self._pass_geometric_constraints(predicate, instance):
                raise Exception(f'EE check not passed when add init fact {(predicate, instance)}.')
            if (predicate, instance) in self.fact_id:
                continue
            fact_id, _ = self._add_fact(predicate, instance, (), operation_id)
            if fact_id is None:
                raise Exception(f'Error when add init fact {(predicate, instance)}.')

        # 6.Set goal
        init_goal_operation_id = self._add_operation(('Preset', 'init_goal', None))
        goal_ids = self._add_goals([self.parsed_cdl['goal_cdl']], None, init_goal_operation_id)
        if goal_ids is None:
            raise Exception(f"Error when set init goal {self.parsed_cdl['goal_cdl']}.")
        self._check_goals(goal_ids)

    def _add_fact(self, predicate, instance, premise_ids, operation_id):
        if predicate == 'Eq':
            instance = self._adjust_expr(instance)
            if instance is None or len(instance.free_symbols) == 0:
                return None, set()

        if (predicate, instance) in self.fact_id:
            return None, set()

        fact_id = len(self.facts)

View on GitHub (pinned to 606a07d341)

Solutions

  1. 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
  2. If the trivial equality is intentional documentation, remove it from relation_cdl
  3. Check _adjust_expr for the supported expression grammar and normalize your Eq syntax to it
  4. Add a pre-solve lint pass that flags Eq facts with zero free symbols before the solver runs

Example fix

# before (CDL relation)
# Eq(Add(LengthOfLine(AB), LengthOfLine(CD)), Add(LengthOfLine(CD), LengthOfLine(AB)))  # tautology -> fact_id None

# after
# replace with a meaningful constraint, e.g.
# Eq(LengthOfLine(AB), 5)
Defensive patterns

Strategy: validation

Validate before calling

from sympy import sympify
# reject Eq facts that carry no free symbols before solving
for predicate, instance in parse_relations(relation_cdl):
    if predicate == 'Eq':
        expr = adjust(instance)
        if expr is None or not expr.free_symbols:
            raise ValueError(f'vacuous Eq fact: {(predicate, instance)}')

Try / catch

try:
    solver.solve(problem_cdl)
except Exception as e:
    if 'Error when add init fact' in str(e):
        flag_fact_as_malformed(str(e))  # inspect the printed (predicate, instance)
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/218f39ed67dbca1f. Report an issue: GitHub.