87 #include "auto_focus.h"
88 #include "ast_controller.h"
91 using namespace r_code;
95 AutoFocusController::AutoFocusController(
_View *view) : Controller(view) {
98 Code *icpp_pgm = get_object();
99 uint16 arg_set_index = icpp_pgm->code(ICPP_PGM_ARGS).asIndex();
100 uint16 arg_count = icpp_pgm->code(arg_set_index).getAtomCount();
102 pass_through_ = icpp_pgm->code(arg_set_index + i++).asBoolean();
103 ctpx_on_ = icpp_pgm->code(arg_set_index + i++).asBoolean();
104 gtpx_on_ = icpp_pgm->code(arg_set_index + i++).asBoolean();
105 ptpx_on_ = icpp_pgm->code(arg_set_index + i++).asBoolean();
106 trace_injections_ = icpp_pgm->code(arg_set_index + i++).asBoolean();
107 decompile_models_ = icpp_pgm->code(arg_set_index + i).asBoolean();
108 for (uint16 j = i; j < arg_count; ++j)
109 output_groups_.push_back((Group *)icpp_pgm->get_reference(j - i));
111 cross_buffer_.set_thz(_Mem::Get()->get_tpx_time_horizon());
112 cross_buffer_.reserve(CrossBufferInitialSize);
113 auto thz = 2 * ((
r_exec::View*)view)->get_host()->get_upr()*Utils::GetBasePeriod();
115 cache_.reserve(CacheInitialSize);
117 #ifdef WITH_DETAIL_OID
118 OUTPUT_LINE(AUTO_FOCUS,
"new controller(" << get_detail_oid() <<
") for auto_focus " << view->object_->get_oid());
122 AutoFocusController::~AutoFocusController() {
125 Code *AutoFocusController::get_core_object()
const {
130 inline void AutoFocusController::inject_input(View *input, uint32 start) {
132 Group *origin = input->get_host();
133 for (uint16 i = start; i < output_groups_.size(); ++i) {
135 Group *output_group = output_groups_[i];
136 View *view =
new View(input,
true);
137 view->references_[0] = output_group;
138 view->code(VIEW_RES) = Atom::Float(Utils::GetResilience(view->code(VIEW_RES).asFloat(), origin->get_upr(), output_group->get_upr()));
139 _Mem::Get()->inject(view);
143 inline void AutoFocusController::inject_input(View *input, _Fact *abstract_input, BindingMap *bm) {
145 View *primary_view = inject_input(input);
146 cross_buffer_.push_back(Input(primary_view, abstract_input, bm));
149 inline View *AutoFocusController::inject_input(View *input) {
151 _Fact *input_fact = (_Fact *)input->object_;
153 Group *origin = input->get_host();
154 Group *ref_group = output_groups_[0];
160 switch (input->get_sync()) {
161 case View::SYNC_ONCE:
162 for (uint16 i = 0; i < output_groups_.size(); ++i) {
164 Group *output_group = output_groups_[i];
165 View *view =
new View(input,
true);
166 view->references_[0] = output_group;
167 view->references_[1] = input->references_[0];
168 view->code(VIEW_RES) = Atom::Float(Utils::GetResilience(view->code(VIEW_RES).asFloat(), origin->get_upr(), output_group->get_upr()));
169 _Mem::Get()->inject(view);
174 case View::SYNC_PERIODIC:
175 if (input_fact->is_anti_fact())
176 copy =
new AntiFact(input_fact->get_reference(0), ref_group->get_prev_upr_time(now), ref_group->get_next_upr_time(now), 1, 1);
178 copy =
new Fact(input_fact->get_reference(0), ref_group->get_prev_upr_time(now), ref_group->get_next_upr_time(now), 1, 1);
179 for (uint16 i = 0; i < output_groups_.size(); ++i) {
181 Group *output_group = output_groups_[i];
182 View *view =
new View(input,
true);
183 view->references_[0] = output_group;
184 view->references_[1] = input->references_[0];
185 view->code(VIEW_RES) = Atom::Float(Utils::GetResilience(view->code(VIEW_RES).asFloat(), origin->get_upr(), output_group->get_upr()));
186 view->object_ = copy;
187 _Mem::Get()->inject(view);
192 if (ctpx_on_ && input_fact->is_fact())
194 _Mem::Get()->inject_null_program(
new PASTController(
this, view), output_group, 2 * output_group->get_upr()*Utils::GetBasePeriod(),
true);
198 case View::SYNC_HOLD: {
199 auto offset = 2 * Utils::GetTimeTolerance();
200 if (input_fact->is_anti_fact())
201 copy =
new AntiFact(input_fact->get_reference(0), now + offset, now + ref_group->get_upr()*Utils::GetBasePeriod(), 1, 1);
203 copy =
new Fact(input_fact->get_reference(0), now + offset, now + ref_group->get_upr()*Utils::GetBasePeriod(), 1, 1);
204 for (uint16 i = 0; i < output_groups_.size(); ++i) {
206 Group *output_group = output_groups_[i];
207 View *view =
new View(input,
true);
208 view->references_[0] = output_group;
209 view->references_[1] = input->references_[0];
210 view->code(VIEW_SYNC) = Atom::Float(View::SYNC_ONCE);
211 view->code(VIEW_RES) = Atom::Float(Utils::GetResilience(view->code(VIEW_RES).asFloat(), origin->get_upr(), output_group->get_upr()));
212 view->object_ = copy;
213 _Mem::Get()->inject(view);
218 _Mem::Get()->inject_null_program(
new HASTController(
this, view, input_fact), output_group, output_group->get_upr()*Utils::GetBasePeriod(),
true);
222 }
case View::SYNC_AXIOM:
223 if (input_fact->is_anti_fact())
224 copy =
new AntiFact(input_fact->get_reference(0), ref_group->get_prev_upr_time(now), ref_group->get_next_upr_time(now), 1, 1);
226 copy =
new Fact(input_fact->get_reference(0), ref_group->get_prev_upr_time(now), ref_group->get_next_upr_time(now), 1, 1);
227 for (uint16 i = 0; i < output_groups_.size(); ++i) {
229 Group *output_group = output_groups_[i];
230 View *view =
new View(input,
true);
231 view->references_[0] = output_group;
232 view->references_[1] = input->references_[0];
233 view->code(VIEW_SYNC) = Atom::Float(View::SYNC_ONCE_AXIOM);
234 view->code(VIEW_RES) = Atom::Float(1);
235 view->object_ = copy;
236 _Mem::Get()->inject(view);
243 if (trace_injections_) {
245 const char* syncString =
"";
246 switch (input->get_sync()) {
247 case View::SYNC_HOLD: syncString =
"(HOLD)";
break;
248 case View::SYNC_ONCE: syncString =
"(ONCE)";
break;
249 case View::SYNC_PERIODIC: syncString =
"(PERIODIC)";
break;
250 case View::SYNC_AXIOM: syncString =
"(AXIOM)";
break;
252 OUTPUT_LINE(AUTO_FOCUS, Utils::RelativeTime(Now()) <<
" A/F -> " << input->object_->get_oid() <<
"|" <<
253 primary_view->object_->get_oid() <<
" " << syncString);
259 inline void AutoFocusController::notify(_Fact *target, View *input, TPXMap &map) {
261 TPXMap::const_iterator m = map.find(target);
262 if (m != map.end()) {
264 m->second->signal(input);
269 inline void AutoFocusController::dispatch_pred_success(Success* success, TPXMap &map) {
271 TPXMap::const_iterator m;
272 for (m = map.begin(); m != map.end(); ++m)
273 m->second->ack_pred_success(success);
276 inline void AutoFocusController::dispatch(View *input, _Fact *abstract_input, BindingMap *bm,
bool &injected, TPXMap &map) {
278 TPXMap::const_iterator m;
279 for (m = map.begin(); m != map.end(); ++m) {
281 if (m->second->take_input(input, abstract_input, bm)) {
286 inject_input(input, abstract_input, bm);
292 inline void AutoFocusController::dispatch_no_inject(View *input, _Fact *abstract_input, BindingMap *bm, TPXMap &map) {
294 TPXMap::const_iterator m;
295 for (m = map.begin(); m != map.end(); ++m)
296 m->second->take_input(input, abstract_input, bm);
299 void AutoFocusController::take_input(
r_exec::View *input) {
301 if (is_invalidated())
303 if (input->object_->code(0).asOpcode() == Opcodes::Fact ||
304 input->object_->code(0).asOpcode() == Opcodes::AntiFact ||
305 input->object_->code(0).asOpcode() == Opcodes::MkRdx)
306 Controller::__take_input<AutoFocusController>(input);
311 Code *input_object = input->object_;
312 uint16 opcode = input_object->code(0).asOpcode();
314 reductionCS_.enter();
316 if (opcode == Opcodes::MkRdx) {
318 Fact *f_ihlp = (Fact *)input_object->get_reference(MK_RDX_IHLP_REF);
319 BindingMap *bm = ((MkRdx *)input_object)->bindings_;
320 if (f_ihlp->get_reference(0)->code(0).asOpcode() == Opcodes::IMdl) {
322 Code *mdl = f_ihlp->get_reference(0)->get_reference(0);
323 Code *unpacked_mdl = mdl->get_reference(mdl->references_size() - MDL_HIDDEN_REFS);
324 uint16 obj_set_index = unpacked_mdl->code(MDL_OBJS).asIndex();
327 uint16 production_set_index = input_object->code(MK_RDX_PRODS).asIndex();
328 uint16 production_reference_index = input_object->code(production_set_index + 1).asIndex();
329 Code *production = input_object->get_reference(production_reference_index);
333 Goal *goal = ((_Fact *)production)->get_goal();
336 pattern = (_Fact *)unpacked_mdl->get_reference(unpacked_mdl->code(obj_set_index + 1).asIndex());
337 tpx = build_tpx<GTPX>((_Fact *)production, pattern, bm, goal_ratings_, f_ihlp, f_ihlp->get_reference(0)->code(I_HLP_WEAK_REQUIREMENT_ENABLED).asBoolean());
338 goals_.insert(std::make_pair((_Fact *)production, tpx));
341 Pred *pred = ((_Fact *)production)->get_pred();
344 pattern = (_Fact *)unpacked_mdl->get_reference(unpacked_mdl->code(obj_set_index + 2).asIndex());
345 tpx = build_tpx<PTPX>((_Fact *)production, pattern, bm, prediction_ratings_, f_ihlp, f_ihlp->get_reference(0)->code(I_HLP_WEAK_REQUIREMENT_ENABLED).asBoolean());
346 predictions_.insert(std::make_pair((_Fact *)production, tpx));
352 bool success = (opcode == Opcodes::Fact);
353 if (success || opcode == Opcodes::AntiFact) {
355 Code *payload = input_object->get_reference(0);
356 uint16 opcode = payload->code(0).asOpcode();
357 if (opcode == Opcodes::Success) {
359 _Fact *target = (_Fact *)payload->get_reference(0);
360 Goal *goal = target->get_goal();
363 notify(target, input, goals_);
366 notify(target, input, predictions_);
368 dispatch_pred_success((Success*)payload, goals_);
370 }
else if (opcode == Opcodes::Perf)
371 inject_input(input, 2);
376 View* primary_view = NULL;
377 if (opcode != Opcodes::ICst)
378 primary_view = inject_input(input);
382 if (opcode == Opcodes::ICst) {
384 _Fact *abstract_f_ihlp = bm->abstract_f_ihlp((_Fact *)input_object);
385 cross_buffer_.push_back(Input(input, abstract_f_ihlp, bm));
389 P<_Fact> abstract_input = (_Fact *)bm->abstract_object(input_object,
false);
390 cross_buffer_.push_back(Input(primary_view, abstract_input, bm));
396 if (opcode == Opcodes::ICst) {
398 bm = ((ICST *)payload)->bindings_;
399 _Fact *abstract_f_ihlp = bm->abstract_f_ihlp((_Fact *)input_object);
400 dispatch_no_inject(input, abstract_f_ihlp, bm, goals_);
401 dispatch_no_inject(input, abstract_f_ihlp, bm, predictions_);
402 cross_buffer_.push_back(Input(input, abstract_f_ihlp, bm));
405 P<_Fact> abstract_input = (_Fact *)bm->abstract_object(input_object,
false);
406 bool injected =
false;
407 dispatch(input, abstract_input, bm, injected, goals_);
408 dispatch(input, abstract_input, bm, injected, predictions_);
415 reductionCS_.leave();
418 void AutoFocusController::inject_hlps(
const vector<
P<Code> > &hlps)
const {
420 vector<View *> views;
424 vector<P<Code> >::const_iterator hlp;
425 for (hlp = hlps.begin(); hlp != hlps.end(); ++hlp) {
427 View *view =
new View(View::SYNC_ONCE, now, 0, -1, output_groups_[0], NULL, *hlp, 1);
428 view->references_[0] = output_groups_[0];
429 views.push_back(view);
432 _Mem::Get()->inject_hlps(views, output_groups_[0]);
437 reductionCS_.enter();
439 for (i = cross_buffer_.begin(Now()); i != cross_buffer_.end(); ++i)
440 destination.push_back(Input(*i));
441 reductionCS_.leave();