86 #include "cst_controller.h"
88 #include "hlp_context.h"
91 using namespace std::chrono;
92 using namespace r_code;
96 CSTOverlay::CSTOverlay(Controller *c, HLPBindingMap *bindings) : HLPOverlay(c, bindings), match_deadline_(Timestamp(seconds(0))), lowest_cfd_(1) {
99 CSTOverlay::CSTOverlay(
const CSTOverlay *original) : HLPOverlay(original->controller_, original->bindings_) {
101 axiom_patterns_ = original->axiom_patterns_;
102 non_axiom_patterns_ = original->non_axiom_patterns_;
103 predictions_ = original->predictions_;
104 simulations_ = original->simulations_;
105 match_deadline_ = original->match_deadline_;
106 lowest_cfd_ = original->lowest_cfd_;
107 axiom_inputs_ = original->axiom_inputs_;
108 non_axiom_inputs_ = original->non_axiom_inputs_;
109 defeasible_validities_ = original->defeasible_validities_;
112 CSTOverlay::~CSTOverlay() {
115 void CSTOverlay::load_patterns() {
117 Code *
object = ((HLPController *)controller_)->get_unpacked_object();
118 uint16 obj_set_index =
object->code(CST_OBJS).asIndex();
119 uint16 obj_count =
object->code(obj_set_index).getAtomCount();
120 for (uint16 i = 1; i <= obj_count; ++i) {
122 _Fact *pattern = (_Fact *)object->get_reference(object->code(obj_set_index + i).asIndex());
123 if (pattern->references_size() >= 1 && _Mem::Get()->matches_axiom(pattern->get_reference(0)))
124 axiom_patterns_.push_back(pattern);
126 non_axiom_patterns_.push_back(pattern);
130 bool CSTOverlay::can_match(Timestamp now)
const {
132 if (match_deadline_.time_since_epoch().count() == 0)
134 return now <= match_deadline_;
139 Fact *f_icst = ((
CSTController *)controller_)->get_f_icst(bindings_, &axiom_inputs_, &non_axiom_inputs_);
142 for (uint32 i = 0; i < axiom_inputs_.size(); ++i)
143 inputs_info +=
" " + to_string(axiom_inputs_[i]->get_oid());
144 for (uint32 i = 0; i < non_axiom_inputs_.size(); ++i)
145 inputs_info +=
" " + to_string(non_axiom_inputs_[i]->get_oid());
147 if (!is_simulated()) {
149 auto before = bindings_->get_fwd_before();
150 Timestamp::duration time_to_live;
152 time_to_live = Timestamp::duration(seconds(0));
154 time_to_live = before - now;
155 if (predictions_.size()) {
157 Pred *prediction =
new Pred(f_icst, 1);
158 Fact *f_p_f_icst =
new Fact(prediction, now, now, 1, 1);
159 unordered_set<P<_Fact>,
PHash<_Fact> >::const_iterator pred;
160 for (pred = predictions_.begin(); pred != predictions_.end(); ++pred)
161 prediction->grounds_.push_back(*pred);
162 if (!((
CSTController *)controller_)->inject_prediction(f_p_f_icst, lowest_cfd_, time_to_live))
166 #ifdef WITH_DETAIL_OID
167 f_icst_info =
"(" + to_string(f_icst->get_detail_oid()) +
") ";
169 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(Now()) <<
" fact " << f_p_f_icst->get_oid() <<
170 " pred fact " << f_icst_info <<
"icst[" << controller_->get_object()->get_oid() <<
"][" << inputs_info <<
"]");
173 ((
CSTController *)controller_)->inject_icst(f_icst, lowest_cfd_, time_to_live);
175 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(Now()) <<
" fact " << f_icst->get_oid() <<
" icst[" << controller_->get_object()->get_oid() <<
"][" <<
182 vector<P<Sim>> simulations_copy;
183 for (
auto sim = simulations_.begin(); sim != simulations_.end(); ++sim)
184 simulations_copy.push_back(*sim);
186 Pred *prediction =
new Pred(f_icst, simulations_copy, 1);
187 if (((
_Fact*)input->object_)->get_pred())
189 prediction->defeasible_validities_ = defeasible_validities_;
190 Fact *f_p_f_icst =
new Fact(prediction, now, now, 1, 1);
191 if (!((
HLPController *)controller_)->inject_prediction(f_p_f_icst, lowest_cfd_))
193 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(Now()) <<
" cst " << get_object()->get_oid() <<
": fact " <<
194 input->object_->get_oid() <<
" -> fact " << f_p_f_icst->get_oid() <<
" simulated pred fact icst [" <<
205 axiom_patterns_.remove(bound_pattern);
207 non_axiom_patterns_.remove(bound_pattern);
209 if (match_deadline_.time_since_epoch().count() == 0)
210 match_deadline_ = map->get_fwd_before();
211 update(map, input, is_axiom);
219 axiom_inputs_.push_back(input);
221 non_axiom_inputs_.push_back(input);
223 Pred *prediction = input->get_pred();
226 last_cfd = prediction->get_target()->get_cfd();
227 if (prediction->is_simulation()) {
233 simulations_.insert(predictionSimulation);
236 predictions_.insert(input);
239 defeasible_validities_.insert(prediction->defeasible_validities_.begin(), prediction->defeasible_validities_.end());
241 last_cfd = input->get_cfd();
243 if (last_cfd < lowest_cfd_)
244 lowest_cfd_ = last_cfd;
247 bool CSTOverlay::reduce(View *input, CSTOverlay *&offspring) {
251 if (input->object_->is_invalidated())
254 for (uint16 i = 0; i < axiom_inputs_.size(); ++i) {
256 if (axiom_inputs_[i]->is_invalidated()) {
264 if (((_Fact *)input->object_) == axiom_inputs_[i])
267 for (uint16 i = 0; i < non_axiom_inputs_.size(); ++i) {
269 if (non_axiom_inputs_[i]->is_invalidated()) {
277 if (((_Fact *)input->object_) == non_axiom_inputs_[i])
281 Pred *prediction = ((_Fact *)input->object_)->get_pred();
283 Sim* predictionSimulation = NULL;
286 input_object = prediction->get_target();
287 is_simulation = prediction->is_simulation();
289 if (prediction->get_simulations_size() == 1)
290 predictionSimulation = prediction->get_simulation((uint16)0);
293 input_object = (_Fact *)input->object_;
294 is_simulation =
false;
298 if (predictionSimulation && !prediction->is_promoted_ &&
299 (simulations_.size() == 0 || simulations_.size() == 1 && *simulations_.begin() == predictionSimulation)) {
302 predictionSimulation->defeasible_promoted_facts_.CS_.enter();
304 for (
auto d = predictionSimulation->defeasible_promoted_facts_.list_.begin();
305 d != predictionSimulation->defeasible_promoted_facts_.list_.end(); ) {
306 if (input_object->is_evidence(d->promoted_fact_->get_pred()->get_target()) != MATCH_FAILURE) {
308 predictionSimulation->defeating_facts_.push_back(input_object);
309 d->defeasible_validity_->invalidate();
310 string defeasible_validity_info;
311 #ifdef WITH_DETAIL_OID
312 defeasible_validity_info =
" with DefeasibleValidity(" + to_string(d->defeasible_validity_->get_detail_oid()) +
")";
314 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(now) <<
" promoted simulated fact " << d->promoted_fact_->get_oid() <<
315 defeasible_validity_info <<
" defeated by fact " << input->object_->get_oid());
317 d = predictionSimulation->defeasible_promoted_facts_.list_.erase(d);
324 bool input_is_later = (input_object->get_before() > input_object->get_after() && bindings_->has_fwd_before() &&
325 input_object->get_after() >= bindings_->get_fwd_before());
326 if (input_is_later &&
327 find(promoted_in_sim_.begin(), promoted_in_sim_.end(), predictionSimulation) == promoted_in_sim_.end()) {
329 promoted_in_sim_.push_back(predictionSimulation);
333 for (uint32 i = 0; i < non_axiom_inputs_.size(); ++i) {
334 _Fact* saved_input = non_axiom_inputs_[i];
335 Pred* saved_input_pred = saved_input->get_pred();
336 if (saved_input_pred)
337 saved_input = saved_input_pred->get_target();
338 if (saved_input->get_reference(0)->code(0).asOpcode() == Opcodes::ICst)
347 if (saved_input->is_timeless_evidence(input_object) != MATCH_FAILURE)
352 Fact* promoted_fact =
new Fact(saved_input->get_reference(0), input_object->get_after(), input_object->get_before(),
353 saved_input->get_cfd(), saved_input->get_psln_thr());
354 if (!saved_input->is_fact())
356 promoted_fact->set_opposite();
358 bool matches_defeating_fact =
false;
359 for (
auto f = predictionSimulation->defeating_facts_.begin(); f != predictionSimulation->defeating_facts_.end(); ++f) {
360 if (promoted_fact->is_evidence(*f) != MATCH_FAILURE) {
361 matches_defeating_fact =
true;
365 if (matches_defeating_fact)
369 Pred* p_promoted_fact =
new Pred(promoted_fact, prediction, 1);
370 Fact* f_p_promoted_fact =
new Fact(p_promoted_fact, now, now, 1, 1);
374 p_promoted_fact->defeasible_validities_.insert(defeasible_validity);
375 p_promoted_fact->is_promoted_ =
true;
377 if (((HLPController *)controller_)->inject_prediction(f_p_promoted_fact, ((_Fact *)input->object_)->get_cfd())) {
379 predictionSimulation->defeasible_promoted_facts_.list_.push_front(
380 Sim::DefeasiblePromotedFact(saved_input, f_p_promoted_fact, defeasible_validity));
381 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(now) <<
" fact " << non_axiom_inputs_[i]->get_oid() <<
382 " -> promoted simulated pred fact " << f_p_promoted_fact->get_oid() <<
" w/ fact " <<
383 input->object_->get_oid() <<
" timings");
387 predictionSimulation->defeasible_promoted_facts_.CS_.leave();
391 bool bound_pattern_is_axiom;
392 _Fact *bound_pattern =
bind_pattern(input_object, bm, predictionSimulation, bound_pattern_is_axiom);
394 #if 0 // Debug: Show making overlays.
395 string debug_inputs_info;
396 for (uint32 i = 0; i < axiom_inputs_.size(); ++i)
397 debug_inputs_info +=
" " + to_string(axiom_inputs_[i]->get_oid());
398 for (uint32 i = 0; i < non_axiom_inputs_.size(); ++i)
399 debug_inputs_info +=
" " + to_string(non_axiom_inputs_[i]->get_oid());
401 if (axiom_patterns_.size() + non_axiom_patterns_.size() == 1) {
407 if (evaluate_fwd_guards()) {
408 offspring =
get_offspring(bm, (_Fact *)input->object_, bound_pattern_is_axiom);
411 store_evidence(input->object_, prediction, is_simulation);
420 offspring =
get_offspring(bm, (_Fact *)input->object_, bound_pattern_is_axiom);
421 #if 0 // Debug: Show making overlays.
422 OUTPUT_LINE((TraceLevel)0,
"Debug: For " << get_object()->get_oid() <<
423 (predictionSimulation ?
" Sim(" + to_string(predictionSimulation->get_detail_oid()) +
")" :
"") <<
": CSTOverlay(" <<
424 get_detail_oid() <<
") [" << debug_inputs_info <<
"]: Add " << input->object_->get_oid() <<
425 " (final) after making offspring CSTOverlay(" << offspring->get_detail_oid() <<
")");
429 store_evidence(input->object_, prediction, is_simulation);
433 offspring =
get_offspring(bm, (_Fact *)input->object_, bound_pattern_is_axiom, bound_pattern);
434 #if 0 // Debug: Show making overlays.
435 OUTPUT_LINE((TraceLevel)0,
"Debug: For " << get_object()->get_oid() <<
436 (predictionSimulation ?
" Sim(" + to_string(predictionSimulation->get_detail_oid()) +
")" :
"") <<
": CSTOverlay(" <<
437 get_detail_oid() <<
") [" << debug_inputs_info <<
"]: Add " << input->object_->get_oid() <<
438 " after making offspring CSTOverlay(" << offspring->get_detail_oid() <<
")");
440 store_evidence(input->object_, prediction, is_simulation);
452 bool use_input_timings = (axiom_inputs_.size() + non_axiom_inputs_.size() == 0);
453 if (predictionSimulation) {
454 if (simulations_.size() > 1)
457 if (simulations_.size() == 1) {
458 if (*simulations_.begin() != predictionSimulation)
463 if (axiom_inputs_.size() > 0 && non_axiom_inputs_.size() == 0) {
465 if (input->get_after() < bindings_->get_fwd_before() &&
466 input->get_before() > bindings_->get_fwd_after()) {
469 else if (input->get_before() <= bindings_->get_fwd_after())
475 use_input_timings =
true;
480 for (p = axiom_patterns_.begin(); p != axiom_patterns_.end(); ++p) {
482 map->load(bindings_);
483 if (use_input_timings)
484 map->reset_fwd_timings(input);
485 if (map->match_fwd_strict(input, *p)) {
490 for (p = non_axiom_patterns_.begin(); p != non_axiom_patterns_.end(); ++p) {
492 map->load(bindings_);
493 if (use_input_timings)
494 map->reset_fwd_timings(input);
495 if (map->match_fwd_strict(input, *p))
504 for (
auto sim = simulations_.begin(); sim != simulations_.end(); ++sim) {
505 if ((*sim)->root_ == root)
518 overlays_.push_back(o);
520 Group *host = get_host();
521 Code *
object = get_unpacked_object();
522 uint16 obj_set_index =
object->code(CST_OBJS).asIndex();
523 uint16 obj_count =
object->code(obj_set_index).getAtomCount();
524 for (uint16 i = 0; i < obj_count; ++i) {
526 Code *pattern =
object->get_reference(object->code(obj_set_index + 1).asIndex());
527 Code *pattern_ihlp = pattern->get_reference(0);
528 uint16 opcode = pattern_ihlp->code(0).asOpcode();
529 if (opcode == Opcodes::ICst ||
530 opcode == Opcodes::IMdl) {
532 Code *pattern_hlp = pattern_ihlp->get_reference(0);
535 controllers_.push_back((
HLPController *)pattern_hlp_v->controller_);
540 CSTController::~CSTController() {
545 if (become_invalidated())
548 if (input->object_->code(0).asOpcode() == Opcodes::Fact ||
549 input->object_->code(0).asOpcode() == Opcodes::AntiFact) {
551 OUTPUT_LINE(CST_IN, Utils::RelativeTime(Now()) <<
" cst " << get_object()->get_oid() <<
" <- " << input->object_->get_oid());
552 Controller::__take_input<CSTController>(input);
561 if (input->object_->is_invalidated())
564 Goal *goal = ((_Fact *)input->object_)->get_goal();
565 if (goal && goal->is_self_goal() && !goal->is_drive()) {
567 _Fact *goal_target = goal->get_target();
568 Code *target_ihlp = goal_target->get_reference(0);
569 if (target_ihlp->code(0).asOpcode() == Opcodes::ICst && target_ihlp->get_reference(0) == get_object()) {
571 if (!get_requirement_count()) {
574 bm->init_from_f_ihlp(goal_target);
576 if (goal->is_simulation())
577 abduce_simulated(bm, input->object_);
579 abduce(bm, input->object_);
585 CSTOverlay *offspring;
587 reductionCS_.enter();
589 for (o = overlays_.begin(); o != overlays_.end();) {
591 if (!((CSTOverlay *)*o)->can_match(now)) {
593 o = overlays_.erase(o);
595 else if ((*o)->is_invalidated())
596 o = overlays_.erase(o);
599 match = (((CSTOverlay *)*o)->reduce(input, offspring) || match);
601 overlays_.push_front(offspring);
606 reductionCS_.leave();
608 check_last_match_time(match);
612 void CSTController::abduce_simulated(HLPBindingMap *bm, Fact *f_super_goal) {
613 Goal *g = f_super_goal->get_goal();
614 _Fact *super_goal_target = g->get_target();
615 Fact* remade_f_icst = get_f_ihlp(bm,
false);
617 for (
auto o = overlays_.begin(); o != overlays_.end(); ++o) {
618 if (((CSTOverlay*)(*o))->is_simulated())
621 #if 0 // Debug: Don't use inputs.
622 if (!(((CSTOverlay*)(*o))->non_axiom_inputs_.size() == 0 && ((CSTOverlay*)(*o))->axiom_patterns_.size() == 0))
626 HLPBindingMap bm_copy(bm);
628 Fact* overlay_f_icst = get_f_ihlp(((HLPOverlay*)(*o))->bindings_,
false);
629 if (bm_copy.match_object(overlay_f_icst->get_reference(0), remade_f_icst->get_reference(0)))
630 abduce(&bm_copy, f_super_goal);
634 void CSTController::abduce(HLPBindingMap *bm, Fact *f_super_goal) {
636 Goal *g = f_super_goal->get_goal();
637 _Fact *super_goal_target = g->get_target();
638 bool opposite = (super_goal_target->is_anti_fact());
640 float32 confidence = super_goal_target->get_cfd();
642 Sim *sim = g->get_sim();
645 if (sim->get_mode() == SIM_ROOT)
646 sub_sim =
new Sim(opposite ? SIM_MANDATORY : SIM_OPTIONAL, sim->get_thz(), f_super_goal, opposite, sim->root_, 1, sim->solution_controller_, sim->get_solution_cfd(), now + sim->get_thz());
648 sub_sim =
new Sim(sim->get_mode(), sim->get_thz(), f_super_goal, opposite, sim->root_, 1, sim->solution_controller_, sim->get_solution_cfd(), sim->get_solution_before());
650 Code *cst = get_unpacked_object();
651 uint16 obj_set_index = cst->code(CST_OBJS).asIndex();
652 uint16 obj_count = cst->code(obj_set_index).getAtomCount();
653 Group *host = get_host();
654 for (uint16 i = 1; i <= obj_count; ++i) {
656 _Fact *pattern = (_Fact *)cst->get_reference(cst->code(obj_set_index + i).asIndex());
657 _Fact *bound_pattern = (_Fact *)bm->bind_pattern(pattern);
658 if (_Mem::Get()->matches_axiom(bound_pattern->get_reference(0)))
664 bound_pattern->set_opposite();
665 #if 0 // Debug: Don't check evidences for simulated goals.
666 if (f_super_goal->get_goal()->is_simulation()) {
667 inject_goal(bm, f_super_goal, bound_pattern, sub_sim, now, confidence, host);
671 switch (check_evidences(bound_pattern, evidence)) {
672 case MATCH_SUCCESS_POSITIVE:
674 case MATCH_SUCCESS_NEGATIVE:
677 switch (check_predicted_evidences(bound_pattern, evidence)) {
678 case MATCH_SUCCESS_POSITIVE:
680 case MATCH_SUCCESS_NEGATIVE:
682 inject_goal(bm, f_super_goal, bound_pattern, sub_sim, now, confidence, host);
689 void CSTController::inject_goal(HLPBindingMap *bm,
691 _Fact *sub_goal_target,
697 if (sim && !sim->register_goal_target(sub_goal_target))
701 sub_goal_target->set_cfd(confidence);
703 Goal *sub_goal =
new Goal(sub_goal_target, f_super_goal->get_goal()->get_actor(), sim, 1);
705 _Fact *f_icst = f_super_goal->get_goal()->get_target();
706 _Fact *sub_goal_f =
new Fact(sub_goal, now, now, 1, 1);
708 View *view =
new View(View::SYNC_ONCE, now, confidence, 1, group, group, sub_goal_f);
709 _Mem::Get()->inject(view);
710 OUTPUT_LINE(CST_OUT, Utils::RelativeTime(Now()) <<
" cst " << get_object()->get_oid() <<
": fact " <<
711 f_super_goal->get_oid() <<
" super_goal -> fact " << sub_goal_f->get_oid() <<
" simulated goal");
714 if (sim->get_mode() == SIM_ROOT)
718 Fact *CSTController::get_f_ihlp(HLPBindingMap *bindings,
bool wr_enabled)
const {
720 return bindings->build_f_ihlp(get_object(), Opcodes::ICst,
false);
723 Fact *CSTController::get_f_icst(HLPBindingMap *bindings, vector<
P<_Fact> > *axiom_inputs, vector<
P<_Fact> > *non_axiom_inputs)
const {
725 Fact *f_icst = get_f_ihlp(bindings,
false);
726 ICST* icst = (ICST *)f_icst->get_reference(0);
727 icst->bindings_ = bindings;
728 icst->components_ = *axiom_inputs;
729 icst->components_.insert(icst->components_.end(), non_axiom_inputs->begin(), non_axiom_inputs->end());
733 bool CSTController::inject_prediction(Fact *prediction, float32 confidence, microseconds time_to_live)
const {
736 Group *primary_host = get_host();
737 float32 sln_thr = primary_host->code(GRP_SLN_THR).asFloat();
738 if (confidence > sln_thr) {
740 int32 resilience = _Mem::Get()->get_goal_pred_success_res(primary_host, now, time_to_live);
741 View *view =
new View(View::SYNC_ONCE, now, confidence, resilience, primary_host, primary_host, prediction);
742 _Mem::Get()->inject(view);
748 void CSTController::inject_icst(Fact *production, float32 confidence, microseconds time_to_live)
const {
751 Group *primary_host = get_host();
752 float32 sln_thr = primary_host->code(GRP_SLN_THR).asFloat();
753 if (confidence > sln_thr) {
755 View *view =
new View(View::SYNC_ONCE, now, 1, Utils::GetResilience(now, time_to_live, primary_host->get_upr() * Utils::GetBasePeriod().count()), primary_host, primary_host, production);
756 _Mem::Get()->inject(view);
757 uint16 out_group_count = get_out_group_count();
758 for (uint16 i = 0; i < out_group_count; ++i) {
760 Group *out_group = (Group *)get_out_group(i);
761 View *view =
new View(View::SYNC_ONCE, now, 1, 1, out_group, primary_host, production);
762 _Mem::Get()->inject(view);
766 sln_thr = secondary_host_->code(GRP_SLN_THR).asFloat();
767 if (confidence > sln_thr) {
769 View *view =
new View(View::SYNC_ONCE, now, 1, Utils::GetResilience(now, time_to_live, secondary_host_->get_upr() * Utils::GetBasePeriod().count()), secondary_host_, primary_host, production);
770 _Mem::Get()->inject(view);
774 void CSTController::set_secondary_host(Group *host) {
776 secondary_host_ = host;
779 Group *CSTController::get_secondary_host()
const {
781 return secondary_host_;
784 void CSTController::kill_views() {
787 get_view()->force_res(0);
790 void CSTController::check_last_match_time(
bool match) {
794 last_match_time_ = now;
795 else if (now - last_match_time_ > _Mem::Get()->get_primary_thz())