35 std::cout <<
"== Deep dependency graph TORTURE test ==\n";
46 auto A = std::make_shared<Block>(); A->blockname =
"SRC_A";
47 auto B = std::make_shared<Block>();
B->blockname =
"SRC_B";
52 auto acc = std::make_shared<BlockAccessor>();
57 auto depSUM = std::make_shared<DependentBlock>(
58 std::unordered_map<std::string, std::shared_ptr<Block>>{{
"SRC_A", A}, {
"SRC_B",
B}},
59 [=](
const auto& blocks, std::shared_ptr<DependentBlock> self){
60 double v = blocks.get_val(
"SRC_A", ID_X) + blocks.get_val(
"SRC_B", ID_X);
61 if (!self->contains(ID_SUM)) self->store(ID_SUM, mkp(
ParameterType::SM,
"SUM", 300, 0.0));
62 self->assign(ID_SUM, v);
65 depSUM->blockname =
"SUM";
70 auto DER = std::make_shared<Block>(); DER->blockname =
"DERIVED";
74 auto make_P1 = [&](
double factor){
76 std::unordered_map<ParamId, std::shared_ptr<Parameter>> srcs;
79 auto P1 = std::make_shared<DependentParameter>(
81 [=](
const ParamSrc& s, std::shared_ptr<DependentParameter> self){
83 self->set_expected(factor * a);
93 std::unordered_map<ParamId, std::shared_ptr<Parameter>> srcs;
98 auto P2 = std::make_shared<DependentParameter>(
100 [=](
const ParamSrc& s, std::shared_ptr<DependentParameter> self){
104 self->set_expected(sumv + p1v + by);
111 DER->store_or_assign(ID_P1, make_P1(10.0));
112 DER->store_or_assign(ID_P2, make_P2());
115 auto depPOST = std::make_shared<DependentBlock>(
116 std::unordered_map<std::string, std::shared_ptr<Block>>{{
"SUM", depSUM}, {
"DERIVED", DER}},
117 [=](
const auto& blocks, std::shared_ptr<DependentBlock> self){
118 double sumv = blocks.get_val(
"SUM", ID_SUM);
119 double p2v = blocks.get_val(
"DERIVED", ID_P2);
120 double v = 3.0 * sumv + p2v;
121 if (!self->contains(ID_POST)) self->store(ID_POST, mkp(
ParameterType::SM,
"POST", 400, 0.0));
122 self->assign(ID_POST, v);
125 depPOST->blockname =
"POST";
132 std::cout <<
"\n[1] Basic sanity\n";
135 assert(acc->
at(
"SUM")->contains(ID_SUM));
136 assert(acc->
at(
"POST")->contains(ID_POST));
138 double sum0 = acc->
getValue(
"SUM", ID_SUM);
139 double p1_0 = acc->
getValue(
"DERIVED", ID_P1);
140 double p2_0 = acc->
getValue(
"DERIVED", ID_P2);
141 double post0= acc->
getValue(
"POST", ID_POST);
142 std::cout <<
"sum0=" << sum0 <<
" p1_0=" << p1_0 <<
" p2_0=" << p2_0 <<
" post0=" << post0 <<
"\n";
143 assert(std::abs(sum0-3.0) < 1e-12);
144 assert(std::abs(p1_0-10.0) < 1e-12);
145 assert(std::abs(p2_0-18.0) < 1e-12);
146 assert(std::abs(post0-27.0) < 1e-12);
151 std::cout <<
"\n[2] Freeze/unfreeze behavior\n";
152 acc->
at(
"POST")->freeze();
154 double post_frozen = acc->
getValue(
"POST", ID_POST);
155 std::cout <<
"post_frozen=" << post_frozen <<
" (expected still 27)\n";
156 assert(std::abs(post_frozen-27.0) < 1e-12);
158 acc->
at(
"POST")->unfreeze();
159 double post1 = acc->
getValue(
"POST", ID_POST);
160 std::cout <<
"post1=" << post1 <<
" (expected 111)\n";
161 assert(std::abs(post1-111.0) < 1e-12);
164 auto p1ptr = std::dynamic_pointer_cast<DependentParameter>(DER->retrieve(ID_P1));
168 double p1_f = acc->
getValue(
"DERIVED", ID_P1);
169 double p2_f = acc->
getValue(
"DERIVED", ID_P2);
170 double post_f = acc->
getValue(
"POST", ID_POST);
171 std::cout <<
"p1_f=" << p1_f <<
" (expected still 70)\n";
172 std::cout <<
"p2_f=" << p2_f <<
" (expected SUM(12)+70+5=87)\n";
173 std::cout <<
"post_f=" << post_f <<
" (expected 3*12+87=123)\n";
174 assert(std::abs(p1_f-70.0) < 1e-12);
175 assert(std::abs(p2_f-87.0) < 1e-12);
176 assert(std::abs(post_f-123.0) < 1e-12);
179 double p1_u = acc->
getValue(
"DERIVED", ID_P1);
180 double post_u = acc->
getValue(
"POST", ID_POST);
181 std::cout <<
"p1_u=" << p1_u <<
" (expected 100), post_u=" << post_u <<
" (expected 153)\n";
182 assert(std::abs(p1_u-100.0) < 1e-12);
183 assert(std::abs(post_u-153.0) < 1e-12);
188 std::cout <<
"\n[3] remove_item source + recovery\n";
192 expect_throw_get(*acc,
"SUM", ID_SUM);
193 expect_throw_get(*acc,
"DERIVED", ID_P1);
194 expect_throw_get(*acc,
"POST", ID_POST);
196 std::cout <<
"here " << std::endl;
207 std::cout <<
"\n[4] Rebind DependentParameter (store_or_assign overwrite)\n";
209 DER->store_or_assign(ID_P1, make_P1(100.0));
213 double p1_new = acc->
getValue(
"DERIVED", ID_P1);
214 double p2_new = acc->
getValue(
"DERIVED", ID_P2);
215 double post_new= acc->
getValue(
"POST", ID_POST);
216 std::cout <<
"p1_new=" << p1_new <<
" p2_new=" << p2_new <<
" post_new=" << post_new <<
"\n";
217 assert(std::abs(p1_new-100.0) < 1e-12);
218 assert(std::abs(p2_new-108.0) < 1e-12);
219 assert(std::abs(post_new-117.0) < 1e-12);
224 std::cout <<
"\n[5] erase_block\n";
230 expect_throw_get(*acc,
"SUM", ID_SUM);
233 auto B2 = std::make_shared<Block>(); B2->blockname =
"SRC_B";
242 bool throws = !acc->
at(
"SUM")->contains(ID_SUM);
245 std::cout <<
"After erase/re-add SRC_B, SUM getValue throws? " <<
throws <<
" (expected TRUE unless you rebuild dependencies)\n";
250 std::cout <<
"\n[6] operator[] / + / >>\n";
252 auto EXTRA = std::make_shared<Block>(); EXTRA->blockname =
"EXTRA";
254 auto acc2 = std::make_shared<BlockAccessor>();
255 acc2->emplace(
"EXTRA", EXTRA);
258 auto merged = (acc + acc2);
259 assert(merged->contains(
"EXTRA"));
260 assert(std::abs(merged->getValue(
"EXTRA",
LhaID(1)) - 42.0) < 1e-12);
263 auto acc_override = std::make_shared<BlockAccessor>();
264 auto DER2 = std::make_shared<Block>(); DER2->blockname =
"DERIVED";
266 acc_override->emplace(
"DERIVED", DER2);
268 auto prio = (acc >> acc_override);
269 assert(prio->contains(
"DERIVED"));
270 assert(prio->at(
"DERIVED")->contains(
LhaID(999)));
273 auto sub = (*prio)[ std::unordered_set<BlockName>{
"SRC_A",
"DERIVED"} ];
274 assert(sub->contains(
"SRC_A"));
275 assert(sub->contains(
"DERIVED"));
276 assert(!sub->contains(
"POST"));
283 dump(*acc,
"DERIVED");
285 dump(*merged,
"EXTRA");
287 std::cout <<
"\n✅ TORTURE test finished (some checks intentionally demonstrate expected failures).\n";