3333# while the second represents attributes for manual reconstruction.
3434TYPESPEC_ATTRS = {'SoEq' : (['tokens_for_eq' , 'tokens_supp' , 'latex_form' ], ['vals' ]),
3535 'Factor' : (['latex_form' , '_ann_repr' , '_latex_constructor' , '_evaluator' ], []),
36- 'Equation' : (['pool' , 'latex_form' , '_history' ], ['structure' ]), # , '_features', '_target'
36+ 'Equation' : (['pool' , 'latex_form' , '_history' , '_target_term' ], ['structure' ]), # _target_term re-linked by index, see attrs_from_dict
3737 'Term' : (['pool' , 'latex_form' ], ['structure' ]), 'TFPool' : ([], []), 'cache' : ([], []),
3838 'ParetoLevels' : (['levels' ], ['population' ]), 'Population' : ([], [])}
3939
@@ -145,7 +145,16 @@ def obj_to_pickle(obj, not_to_pickle: list = [], manual_pickle: list = []):
145145 get_typespec_attrs (elem )[1 ])}
146146 else :
147147 dict_to_pickle [slot ] = elem
148-
148+
149+ # Persist the identity-tracked right-part target as a plain integer
150+ # position. The ``_target_term`` Term itself is excluded from pickling
151+ # (TYPESPEC_ATTRS) to avoid an identity break with the freshly
152+ # reconstructed structure; ``attrs_from_dict`` re-links it by index once
153+ # ``structure`` is rebuilt. Stored under the legacy ``'target_idx'`` key so
154+ # pre-rename pickles (which saved the int slot) load unchanged.
155+ if parse_obj_type (obj ) == 'Equation' :
156+ dict_to_pickle ['target_idx' ] = obj .target_idx
157+
149158 return dict_to_pickle
150159
151160def attrs_from_dict (obj , attributes , except_attrs : dict = {}):
@@ -174,6 +183,22 @@ def attrs_from_dict(obj, attributes, except_attrs: dict = {}):
174183
175184 obj .manual_reconst (man_attr , attributes [man_attr ]['elements' ], except_attrs )
176185
186+ # Re-link the identity-tracked right-part target from the saved integer
187+ # position, AFTER ``structure`` was rebuilt by manual_reconst above. The
188+ # ``'target_idx'`` key covers both post-rename pickles (saved by
189+ # obj_to_pickle) and legacy pre-rename pickles (which stored the old int
190+ # slot under the same key). The ``target_idx`` property setter resolves the
191+ # int against the reconstructed structure into ``_target_term``.
192+ if parse_obj_type (obj ) == 'Equation' :
193+ ti = attributes .get ('target_idx' , None )
194+ if ti is not None and getattr (obj , 'structure' , None ):
195+ try :
196+ obj .target_idx = int (ti )
197+ except (IndexError , ValueError , TypeError ):
198+ obj ._target_term = None
199+ else :
200+ obj ._target_term = None
201+
177202
178203def temp_pickle_save (obj : Union [SoEq , Cache , TFPool , ParetoLevels , Population ],
179204 not_to_pickle = [], manual_pickle = []):
@@ -194,14 +219,15 @@ def system_preset(pool: TFPool): # Validate correctness of attribute definitions
194219 return {'SoEq' : {'tokens_for_eq' : TFPool (pool .families_demand_equation ),
195220 'tokens_supp' : TFPool (pool .families_equationless ),
196221 'latex_form' : None },
197- 'Equation' : {'pool' : pool ,
222+ 'Equation' : {'pool' : pool ,
198223 'latex_form' : None ,
199- '_history' : None },
200- 'Term' : {'pool' : pool ,
224+ '_history' : None ,
225+ '_target_term' : None },
226+ 'Term' : {'pool' : pool ,
201227 'latex_form' : None },
202- 'Factor' : {'_latex_constructor' : None ,
203- '_evaluator' : None }}
204-
228+ 'Factor' : {'_latex_constructor' : None ,
229+ '_evaluator' : None }}
230+
205231 @staticmethod
206232 def pool_preset ():
207233 return {'TFPool' : {}}
@@ -216,12 +242,13 @@ def population_preset(pool: TFPool):
216242 'SoEq' : {'tokens_for_eq' : TFPool (pool .families_demand_equation ),
217243 'tokens_supp' : TFPool (pool .families_equationless ),
218244 'latex_form' : None },
219- 'Equation' : {'pool' : pool ,
245+ 'Equation' : {'pool' : pool ,
220246 'latex_form' : None ,
221- '_history' : None },
222- 'Term' : {'pool' : pool ,
247+ '_history' : None ,
248+ '_target_term' : None },
249+ 'Term' : {'pool' : pool ,
223250 'latex_form' : None },
224- 'Factor' : {'_latex_constructor' : None ,
251+ 'Factor' : {'_latex_constructor' : None ,
225252 '_evaluator' : None }}
226253
227254 @staticmethod
@@ -230,12 +257,13 @@ def pareto_levels_preset(pool: TFPool):
230257 'SoEq' : {'tokens_for_eq' : TFPool (pool .families_demand_equation ),
231258 'tokens_supp' : TFPool (pool .families_equationless ),
232259 'latex_form' : None },
233- 'Equation' : {'pool' : pool ,
260+ 'Equation' : {'pool' : pool ,
234261 'latex_form' : None ,
235- '_history' : None },
236- 'Term' : {'pool' : pool ,
262+ '_history' : None ,
263+ '_target_term' : None },
264+ 'Term' : {'pool' : pool ,
237265 'latex_form' : None },
238- 'Factor' : {'_latex_constructor' : None ,
266+ 'Factor' : {'_latex_constructor' : None ,
239267 '_evaluator' : None }}
240268
241269
0 commit comments