@@ -206,38 +206,70 @@ void ContainerBasePrivate::copyState(Interface::iterator external, const Interfa
206206void ContainerBasePrivate::liftSolution (const SolutionBasePtr& solution, const InterfaceState* internal_from,
207207 const InterfaceState* internal_to, InterfaceState* new_from,
208208 InterfaceState* new_to) {
209- const bool create_from{ requiredInterface ().testFlag (WRITES_PREV_END) };
210- const bool create_to{ requiredInterface ().testFlag (WRITES_NEXT_START) };
209+ // NOLINTNEXTLINE(readability-identifier-naming)
210+ auto findExternal = [this ](const InterfaceState* internal,
211+ const InterfaceState* replacement) -> const InterfaceState* {
212+ auto it = internalToExternalMap ().find (internal);
213+ if (it != internalToExternalMap ().end () && (!replacement || &*it->second == replacement)) {
214+ return &*it->second ;
215+ }
216+
217+ return nullptr ;
218+ };
211219
212220 // external states, nullptr if they don't exist yet
213- const InterfaceState* external_from{ create_from ? new_from : internalToExternalMap (). at ( internal_from) };
214- const InterfaceState* external_to{ create_to ? new_to : internalToExternalMap (). at ( internal_to) };
221+ const InterfaceState* external_from{ findExternal ( internal_from, new_from ) };
222+ const InterfaceState* external_to{ findExternal ( internal_to, new_to ) };
215223
216224 // computeCost
217- // we can pass intern_{from/to} here because in this case the lifted states that might be created later
225+ // If there are no external states known yet, we can pass internal_{from/to} here
226+ // because in this case the lifted states that will be created later
218227 // are equivalent up to the connected Solutions (which are not relevant for CostTerms)
219- computeCost (external_from ? *external_from : *internal_from, external_to ? *external_to : *internal_to, *solution);
228+ {
229+ auto getPreliminaryState = [](const InterfaceState* external, const InterfaceState* new_state,
230+ const InterfaceState* internal) -> const InterfaceState& {
231+ if (external)
232+ return *external;
233+ if (new_state)
234+ return *new_state;
235+ else
236+ return *internal;
237+ };
238+ computeCost (getPreliminaryState (external_from, new_from, internal_from),
239+ getPreliminaryState (external_to, new_to, internal_to), *solution);
240+ }
220241
221242 // storeSolution
243+ // only pass stored external states here (others are not relevant for pruning)
222244 if (!storeSolution (solution, external_from, external_to)) {
223245 return ;
224246 }
225247
226- auto create_state = [this ](const InterfaceState& internal, InterfaceState* new_external) {
248+ // store unstored states in stage-internal storage
249+
250+ // NOLINTNEXTLINE(readability-identifier-naming)
251+ auto createState = [this ](const InterfaceState& internal, InterfaceState* new_external) {
227252 InterfaceState* external{ storeState (new_external ? std::move (*new_external) : InterfaceState{ internal }) };
228253 internalToExternalMap ().insert (std::make_pair (&internal, external));
229254 return external;
230255 };
231256
232- if (create_from)
233- external_from = create_state (*internal_from, new_from);
234- if (create_to)
235- external_to = create_state (*internal_to, new_to);
257+ const bool create_from{ external_from == nullptr };
258+ const bool create_to{ external_to == nullptr };
259+
260+ if (create_from) {
261+ assert (requiredInterface ().testFlag (WRITES_PREV_END));
262+ external_from = createState (*internal_from, new_from);
263+ }
264+ if (create_to) {
265+ assert (requiredInterface ().testFlag (WRITES_NEXT_START));
266+ external_to = createState (*internal_to, new_to);
267+ }
236268
237269 assert (external_from);
238270 assert (external_to);
239271
240- // connect solution to states
272+ // connect solution to stored states
241273 solution->setStartState (*external_from);
242274 solution->setEndState (*external_to);
243275
0 commit comments