Skip to content

Commit a5a35fb

Browse files
committed
find external states also in writing-interfaces
Essential for SerialContainer that spawns multiple solutions with the same end state.
1 parent 9209c45 commit a5a35fb

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

core/src/container.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,26 @@ void ContainerBasePrivate::copyState(Interface::iterator external, const Interfa
206206
void 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](InterfaceState* replacement, const InterfaceState* internal) -> const InterfaceState* {
211+
auto it = internalToExternalMap().find(internal);
212+
if (it != internalToExternalMap().end()) {
213+
return &*it->second;
214+
}
215+
216+
// if replacement has been created before it was returned above already
217+
if (replacement)
218+
return replacement;
219+
220+
return nullptr;
221+
};
211222

212223
// 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) };
224+
const InterfaceState* external_from{ findExternal(new_from, internal_from) };
225+
const InterfaceState* external_to{ findExternal(new_to, internal_to) };
215226

216227
// computeCost
217-
// we can pass intern_{from/to} here because in this case the lifted states that might be created later
228+
// we can pass internal_{from/to} here because in this case the lifted states that might be created later
218229
// are equivalent up to the connected Solutions (which are not relevant for CostTerms)
219230
computeCost(external_from ? *external_from : *internal_from, external_to ? *external_to : *internal_to, *solution);
220231

@@ -223,21 +234,31 @@ void ContainerBasePrivate::liftSolution(const SolutionBasePtr& solution, const I
223234
return;
224235
}
225236

226-
auto create_state = [this](const InterfaceState& internal, InterfaceState* new_external) {
237+
// create unstored states in stage-internal storage
238+
239+
// NOLINTNEXTLINE(readability-identifier-naming)
240+
auto createState = [this](const InterfaceState& internal, InterfaceState* new_external) {
227241
InterfaceState* external{ storeState(new_external ? std::move(*new_external) : InterfaceState{ internal }) };
228242
internalToExternalMap().insert(std::make_pair(&internal, external));
229243
return external;
230244
};
231245

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);
246+
const bool create_from{ new_from != nullptr || external_from == nullptr };
247+
const bool create_to{ new_to != nullptr || external_to == nullptr };
248+
249+
if (create_from) {
250+
assert(requiredInterface().testFlag(WRITES_PREV_END));
251+
external_from = createState(*internal_from, new_from);
252+
}
253+
if (create_to) {
254+
assert(requiredInterface().testFlag(WRITES_NEXT_START));
255+
external_to = createState(*internal_to, new_to);
256+
}
236257

237258
assert(external_from);
238259
assert(external_to);
239260

240-
// connect solution to states
261+
// connect solution to stored states
241262
solution->setStartState(*external_from);
242263
solution->setEndState(*external_to);
243264

0 commit comments

Comments
 (0)