86 #include "mdl_controller.h"
90 using namespace std::chrono;
91 using namespace r_code;
97 uint16 write_index = 0;
98 code(write_index++) = Atom::Marker(Opcodes::MkNew, 2);
99 code(write_index++) = Atom::RPointer(0);
100 code(write_index++) = Atom::Float(0);
101 set_reference(0,
object);
108 uint16 write_index = 0;
109 code(write_index++) = Atom::Marker(Opcodes::MkLowRes, 2);
110 code(write_index++) = Atom::RPointer(0);
111 code(write_index++) = Atom::Float(0);
112 set_reference(0,
object);
119 uint16 write_index = 0;
120 code(write_index++) = Atom::Marker(Opcodes::MkLowSln, 2);
121 code(write_index++) = Atom::RPointer(0);
122 code(write_index++) = Atom::Float(0);
123 set_reference(0,
object);
130 uint16 write_index = 0;
131 code(write_index++) = Atom::Marker(Opcodes::MkHighSln, 2);
132 code(write_index++) = Atom::RPointer(0);
133 code(write_index++) = Atom::Float(0);
134 set_reference(0,
object);
141 uint16 write_index = 0;
142 code(write_index++) = Atom::Marker(Opcodes::MkLowAct, 2);
143 code(write_index++) = Atom::RPointer(0);
144 code(write_index++) = Atom::Float(0);
145 set_reference(0,
object);
152 uint16 write_index = 0;
153 code(write_index++) = Atom::Marker(Opcodes::MkHighAct, 2);
154 code(write_index++) = Atom::RPointer(0);
155 code(write_index++) = Atom::Float(0);
156 set_reference(0,
object);
161 MkSlnChg::MkSlnChg(
r_code::Mem *m,
Code *
object, float32 value) : LObject(m) {
163 uint16 write_index = 0;
164 code(write_index++) = Atom::Marker(Opcodes::MkSlnChg, 3);
165 code(write_index++) = Atom::RPointer(0);
166 code(write_index++) = Atom::Float(value);
167 code(write_index++) = Atom::Float(0);
168 set_reference(0,
object);
173 MkActChg::MkActChg(
r_code::Mem *m,
Code *
object, float32 value) : LObject(m) {
175 uint16 write_index = 0;
176 code(write_index++) = Atom::Marker(Opcodes::MkActChg, 3);
177 code(write_index++) = Atom::RPointer(0);
178 code(write_index++) = Atom::Float(value);
179 code(write_index++) = Atom::Float(0);
180 set_reference(0,
object);
185 _Fact::_Fact() : LObject() {
188 _Fact::_Fact(
SysObject *source) : LObject(source) {
191 _Fact::_Fact(_Fact *f) {
193 for (uint16 i = 0; i < f->code_size(); ++i)
194 code(i) = f->code(i);
195 for (uint16 i = 0; i < f->references_size(); ++i)
196 add_reference(f->get_reference(i));
199 _Fact::_Fact(uint16 opcode,
Code *
object, Timestamp after, Timestamp before, float32 confidence, float32 psln_thr) : LObject() {
201 code(0) = Atom::Object(opcode, FACT_ARITY);
202 code(FACT_OBJ) = Atom::RPointer(0);
203 code(FACT_AFTER) = Atom::IPointer(FACT_ARITY + 1);
204 code(FACT_BEFORE) = Atom::IPointer(FACT_ARITY + 4);
205 code(FACT_CFD) = Atom::Float(confidence);
206 code(FACT_ARITY) = Atom::Float(psln_thr);
207 Utils::SetTimestamp<Code>(
this, FACT_AFTER, after);
208 Utils::SetTimestamp<Code>(
this, FACT_BEFORE, before);
209 add_reference(
object);
212 _Fact *_Fact::get_absentee()
const {
216 absentee =
new AntiFact(get_reference(0), get_after(), get_before(), 1, 1);
218 absentee =
new Fact(get_reference(0), get_after(), get_before(), 1, 1);
223 bool _Fact::is_invalidated() {
225 if (LObject::is_invalidated())
227 if (get_reference(0)->is_invalidated()) {
235 bool _Fact::match_timings_sync(
const _Fact *evidence)
const {
237 auto after = get_after();
238 auto e_after = evidence->get_after();
239 auto e_before = evidence->get_before();
241 return !(e_after > after + Utils::GetTimeTolerance() || e_before <= after);
244 bool _Fact::match_timings_overlap(
const _Fact *evidence)
const {
246 auto after = get_after();
247 auto before = get_before();
248 auto e_after = evidence->get_after();
249 auto e_before = evidence->get_before();
251 return !(e_after >= before || e_before <= after);
254 bool _Fact::match_timings_inclusive(
const _Fact *evidence)
const {
256 auto after = get_after();
257 auto before = get_before();
258 auto e_after = evidence->get_after();
259 auto e_before = evidence->get_before();
261 return (e_after <= after && e_before >= before);
264 bool _Fact::Match(
const Code *lhs, uint16 lhs_base_index, uint16 lhs_index,
const Code *rhs, uint16 rhs_index, uint16 lhs_arity,
bool same_binding_state) {
266 uint16 lhs_full_index = lhs_base_index + lhs_index;
267 Atom lhs_atom = lhs->code(lhs_full_index);
268 Atom rhs_atom = rhs->code(rhs_index);
269 uint8 lhs_descriptor = lhs_atom.getDescriptor();
270 uint8 rhs_descriptor = rhs_atom.getDescriptor();
272 if (same_binding_state) {
273 if (lhs_descriptor == Atom::T_WILDCARD || lhs_descriptor == Atom::WILDCARD ||
274 rhs_descriptor == Atom::T_WILDCARD || rhs_descriptor == Atom::WILDCARD) {
278 bool lhs_is_VL_PTR = (lhs_descriptor == Atom::VL_PTR);
279 bool rhs_is_VL_PTR = (rhs_descriptor == Atom::VL_PTR);
280 if (lhs_is_VL_PTR != rhs_is_VL_PTR)
286 switch (lhs_descriptor) {
287 case Atom::T_WILDCARD:
292 switch (rhs_descriptor) {
294 if (!MatchStructure(lhs, lhs_atom.asIndex(), 0, rhs, rhs_atom.asIndex(), same_binding_state))
297 case Atom::T_WILDCARD:
306 switch (rhs_descriptor) {
308 if (!MatchObject(lhs->get_reference(lhs_atom.asIndex()), rhs->get_reference(rhs_atom.asIndex()), same_binding_state))
311 case Atom::T_WILDCARD:
320 switch (rhs_descriptor) {
321 case Atom::T_WILDCARD:
326 if (!MatchAtom(lhs_atom, rhs_atom))
333 if (lhs_index == lhs_arity)
335 return Match(lhs, lhs_base_index, lhs_index + 1, rhs, rhs_index + 1, lhs_arity, same_binding_state);
338 bool _Fact::MatchAtom(
Atom lhs,
Atom rhs) {
343 if (lhs.isFloat() && rhs.isFloat())
344 return Utils::Equal(lhs.asFloat(), rhs.asFloat());
349 bool _Fact::MatchStructure(
const Code *lhs, uint16 lhs_base_index, uint16 lhs_index,
const Code *rhs, uint16 rhs_index,
bool same_binding_state) {
351 uint16 lhs_full_index = lhs_base_index + lhs_index;
352 Atom lhs_atom = lhs->code(lhs_full_index);
353 Atom rhs_atom = rhs->code(rhs_index);
354 if (lhs_atom != rhs_atom)
356 uint16 arity = lhs_atom.getAtomCount();
359 if (lhs_atom.getDescriptor() == Atom::TIMESTAMP)
360 return Utils::Synchronous(Utils::GetTimestamp(&lhs->code(lhs_full_index)), Utils::GetTimestamp(&rhs->code(rhs_index)));
361 return Match(lhs, lhs_base_index, lhs_index + 1, rhs, rhs_index + 1, arity, same_binding_state);
364 bool _Fact::MatchObject(
const Code *lhs,
const Code *rhs,
bool same_binding_state) {
366 if (lhs->code(0) != rhs->code(0))
368 uint16 lhs_opcode = lhs->code(0).asOpcode();
369 if (lhs_opcode == Opcodes::Ent ||
370 lhs_opcode == Opcodes::Ont ||
371 lhs_opcode == Opcodes::Mdl ||
372 lhs_opcode == Opcodes::Cst)
374 return Match(lhs, 0, 1, rhs, 1, lhs->code(0).getAtomCount(), same_binding_state);
377 bool _Fact::CounterEvidence(
const Code *lhs,
const Code *rhs) {
379 uint16 opcode = lhs->code(0).asOpcode();
380 if (opcode == Opcodes::Ent ||
381 opcode == Opcodes::Ont ||
382 opcode == Opcodes::IMdl)
384 if (lhs->code(0) != rhs->code(0))
386 if (opcode == Opcodes::MkVal) {
388 if (lhs->get_reference(lhs->code(MK_VAL_OBJ).asIndex()) == rhs->get_reference(rhs->code(MK_VAL_OBJ).asIndex()) &&
389 lhs->get_reference(lhs->code(MK_VAL_ATTR).asIndex()) == rhs->get_reference(rhs->code(MK_VAL_ATTR).asIndex())) {
391 Atom lhs_atom = lhs->code(MK_VAL_VALUE);
392 Atom rhs_atom = rhs->code(MK_VAL_VALUE);
394 if (lhs_atom.isFloat()) {
396 if (rhs_atom.isFloat())
397 return !MatchAtom(lhs_atom, rhs_atom);
400 }
else if (rhs_atom.isFloat())
403 uint16 lhs_desc = lhs_atom.getDescriptor();
404 uint16 rhs_desc = rhs_atom.getDescriptor();
406 if (lhs_desc == Atom::NIL && rhs_desc == Atom::R_PTR ||
407 lhs_desc == Atom::R_PTR && rhs_desc == Atom::NIL)
411 if (lhs_desc != rhs_desc)
414 case Atom::T_WILDCARD:
418 return !MatchObject(lhs->get_reference(lhs->code(MK_VAL_VALUE).asIndex()), rhs->get_reference(rhs->code(MK_VAL_VALUE).asIndex()));
420 return !MatchStructure(lhs, lhs_atom.asIndex(), 0, rhs, rhs_atom.asIndex(),
false);
422 return !MatchAtom(lhs_atom, rhs_atom);
425 }
else if (opcode == Opcodes::ICst) {
427 if (lhs->get_reference(0) != rhs->get_reference(0))
430 for (uint32 i = 0; i < ((ICST *)lhs)->components_.size(); ++i) {
433 if (CounterEvidence(((ICST *)lhs)->components_[i], ((ICST *)rhs)->components_[i]))
441 MatchResult _Fact::is_evidence(
const _Fact *target)
const {
443 if (MatchObject(get_reference(0), target->get_reference(0))) {
446 if (target->code(0) == code(0))
447 r = MATCH_SUCCESS_POSITIVE;
449 r = MATCH_SUCCESS_NEGATIVE;
451 if (target->match_timings_overlap(
this))
453 }
else if (is_fact()) {
455 if (target->match_timings_inclusive(
this)) {
457 if (CounterEvidence(get_reference(0), target->get_reference(0)))
459 return target->is_anti_fact() ? MATCH_SUCCESS_POSITIVE : MATCH_SUCCESS_NEGATIVE;
462 return MATCH_FAILURE;
465 MatchResult _Fact::is_timeless_evidence(
const _Fact *target)
const {
467 if (MatchObject(get_reference(0), target->get_reference(0))) {
470 if (target->code(0) == code(0))
471 r = MATCH_SUCCESS_POSITIVE;
473 r = MATCH_SUCCESS_NEGATIVE;
476 }
else if (target->code(0) == code(0)) {
478 if (CounterEvidence(get_reference(0), target->get_reference(0)))
480 return target->is_anti_fact() ? MATCH_SUCCESS_POSITIVE : MATCH_SUCCESS_NEGATIVE;
482 return MATCH_FAILURE;
485 Timestamp _Fact::get_after()
const {
487 return Utils::GetTimestamp<Code>(
this, FACT_AFTER);
490 Timestamp _Fact::get_before()
const {
492 return Utils::GetTimestamp<Code>(
this, FACT_BEFORE);
495 void _Fact::trace()
const {
497 std::cout <<
"<" << get_oid() <<
" " << Utils::RelativeTime(get_after()) <<
" " << Utils::RelativeTime(get_before()) <<
">" << std::endl;
502 void *Fact::operator
new(
size_t s) {
504 return _Mem::Get()->_build_object(Atom::Object(Opcodes::Fact, FACT_ARITY));
507 Fact::Fact() : _Fact() {
509 code(0) = Atom::Object(Opcodes::Fact, FACT_ARITY);
512 Fact::Fact(
SysObject *source) : _Fact(source) {
515 Fact::Fact(Fact *f) : _Fact(f) {
518 Fact::Fact(
Code *
object, Timestamp after, Timestamp before, float32 confidence, float32 psln_thr) : _Fact(Opcodes::Fact, object, after, before, confidence, psln_thr) {
523 void *AntiFact::operator
new(
size_t s) {
525 return _Mem::Get()->_build_object(Atom::Object(Opcodes::AntiFact, FACT_ARITY));
528 AntiFact::AntiFact() : _Fact() {
530 code(0) = Atom::Object(Opcodes::AntiFact, FACT_ARITY);
533 AntiFact::AntiFact(
SysObject *source) : _Fact(source) {
536 AntiFact::AntiFact(AntiFact *f) : _Fact(f) {
539 AntiFact::AntiFact(
Code *
object, Timestamp after, Timestamp before, float32 confidence, float32 psln_thr) : _Fact(Opcodes::AntiFact, object, after, before, confidence, psln_thr) {
544 Pred::Pred() : LObject(), is_promoted_(false) {
547 Pred::Pred(
SysObject *source) : LObject(source), is_promoted_(false) {
551 vector<P<Sim>> simulations_copy;
553 simulations_copy.push_back(simulations_source->
get_simulation(i));
554 construct(target, simulations_copy, psln_thr);
555 defeasible_validities_ = simulations_source->defeasible_validities_;
558 void Pred::construct(
_Fact *target,
const vector<
P<Sim> >& simulations, float32 psln_thr) {
560 uint16 write_index = PRED_ARITY;
561 code(0) = Atom::Object(Opcodes::Pred, PRED_ARITY);
562 code(PRED_TARGET) = Atom::RPointer(0);
563 add_reference(target);
565 code(PRED_SIMS) = Atom::IPointer(++write_index);
566 code(write_index) = Atom::Set(simulations.size());
567 for (
auto i = 0; i < simulations.size(); ++i) {
568 code(++write_index) = Atom::RPointer(references_size());
569 add_reference(simulations[i]);
572 code(PRED_ARITY) = Atom::Float(psln_thr);
573 is_promoted_ =
false;
578 if (LObject::is_invalidated())
588 for (uint32 i = 0; i < grounds_.size(); ++i) {
597 for (
auto d = defeasible_validities_.begin(); d != defeasible_validities_.end(); ++d) {
598 if ((*d)->is_invalidated()) {
612 bool Pred::grounds_invalidated(
_Fact *evidence) {
614 for (uint32 i = 0; i < grounds_.size(); ++i) {
616 switch (evidence->is_evidence(grounds_[i])) {
617 case MATCH_SUCCESS_NEGATIVE:
631 if (sim->root_ == root)
650 Goal::Goal() :
LObject(), ground_(NULL) {
653 Goal::Goal(
SysObject *source) : LObject(source), ground_(NULL) {
656 Goal::Goal(_Fact *target,
Code *actor, Sim* sim, float32 psln_thr) : LObject(), ground_(NULL) {
658 code(0) = Atom::Object(Opcodes::Goal, GOAL_ARITY);
659 code(GOAL_TARGET) = Atom::RPointer(0);
660 code(GOAL_ACTR) = Atom::RPointer(1);
661 code(GOAL_SIM) = (sim ? Atom::RPointer(2) :
Atom::Nil());
662 code(GOAL_ARITY) = Atom::Float(psln_thr);
663 add_reference(target);
664 add_reference(actor);
669 bool Goal::invalidate() {
673 return LObject::invalidate();
676 bool Goal::is_invalidated() {
678 if (LObject::is_invalidated())
680 if (
has_sim() &&
get_sim()->get_f_super_goal()->is_invalidated()) {
688 bool Goal::ground_invalidated(_Fact *evidence) {
691 return ground_->get_pred()->grounds_invalidated(evidence);
695 bool Goal::is_requirement()
const {
702 bool Goal::is_self_goal()
const {
704 return (get_actor() == _Mem::Get()->get_self());
709 Sim::Sim(Sim *s) : root_(s->root_), solution_controller_(s->solution_controller_), is_requirement_(false) {
710 for (uint16 i = 0; i < s->code_size(); ++i)
711 code(i) = s->code(i);
712 for (uint16 i = 0; i < s->references_size(); ++i)
713 add_reference(s->get_reference(i));
716 Sim::Sim(SimMode mode, microseconds thz, Fact *super_goal,
bool opposite, Controller *root, float32 psln_thr, Controller *solution_controller,
717 float32 solution_cfd, Timestamp solution_before) : root_(root), solution_controller_(solution_controller), is_requirement_(false) {
718 code(0) = Atom::Object(Opcodes::Sim, SIM_ARITY);
719 code(SIM_MODE) = Atom::Float(mode);
720 code(SIM_THZ) = Atom::IPointer(SIM_ARITY + 1);
721 code(SIM_F_SUPER_GOAL) = Atom::RPointer(0);
722 add_reference(super_goal);
723 code(SIM_OPPOSITE) = Atom::Boolean(opposite);
729 code(SIM_ROOT_MODEL) = Atom::RPointer(references_size());
730 add_reference(root->get_core_object());
733 code(SIM_ROOT_MODEL) = Atom::Nil();
734 if (solution_controller) {
735 code(SIM_SOLUTION_MODEL) = Atom::RPointer(references_size());
736 add_reference(solution_controller->get_core_object());
739 code(SIM_SOLUTION_MODEL) = Atom::Nil();
741 code(SIM_SOLUTION_CFD) = Atom::Float(solution_cfd);
742 code(SIM_SOLUTION_BEFORE) = Atom::IPointer(SIM_ARITY + 4);
743 code(SIM_ARITY) = Atom::Float(psln_thr);
745 Utils::SetDuration<Code>(
this, SIM_THZ, thz);
746 Utils::SetTimestamp<Code>(
this, SIM_SOLUTION_BEFORE, solution_before);
749 bool Sim::invalidate() {
751 if (LObject::is_invalidated())
756 return LObject::invalidate();
759 bool Sim::is_invalidated() {
761 if (LObject::is_invalidated())
775 if (result->get_mode() == SIM_ROOT)
791 uint16 opcode = f_obj->code(0).asOpcode();
792 Code* obj = f_obj->get_reference(0);
794 for (
int i = 0; i < rootSim->goalTargets_.size(); ++i) {
795 _Fact* goalTarget = rootSim->goalTargets_[i];
797 if (opcode == goalTarget->code(0).asOpcode() &&
_Fact::MatchObject(obj, goalTarget->get_reference(0),
true))
802 rootSim->goalTargets_.push_back(f_obj);
807 for (
auto d =
list.begin(); d !=
list.end(); ++d) {
808 if (original_fact == d->original_fact_)
818 MkRdx::MkRdx() :
LObject(), bindings_(NULL) {
824 MkRdx::MkRdx(
Code *imdl_fact,
Code *input,
Code *output, float32 psln_thr, BindingMap *binding_map) : LObject(), bindings_(binding_map) {
826 uint16 extent_index = MK_RDX_ARITY + 1;
827 code(0) = Atom::Marker(Opcodes::MkRdx, MK_RDX_ARITY);
828 code(MK_RDX_CODE) = Atom::RPointer(references_size());
829 add_reference(imdl_fact);
830 code(MK_RDX_INPUTS) = Atom::IPointer(extent_index);
831 code(MK_RDX_ARITY) = Atom::Float(psln_thr);
832 code(extent_index++) = Atom::Set(1);
833 code(extent_index++) = Atom::RPointer(references_size());
834 add_reference(input);
835 code(MK_RDX_PRODS) = Atom::IPointer(extent_index);
836 code(extent_index++) = Atom::Set(1);
837 code(extent_index++) = Atom::RPointer(references_size());
838 add_reference(output);
841 MkRdx::MkRdx(
Code *imdl_fact,
Code *input1,
Code *input2,
Code *output, float32 psln_thr, BindingMap *binding_map) : LObject(), bindings_(binding_map) {
843 uint16 extent_index = MK_RDX_ARITY + 1;
844 code(0) = Atom::Marker(Opcodes::MkRdx, MK_RDX_ARITY);
845 code(MK_RDX_CODE) = Atom::RPointer(references_size());
846 add_reference(imdl_fact);
847 code(MK_RDX_INPUTS) = Atom::IPointer(extent_index);
848 code(MK_RDX_ARITY) = Atom::Float(psln_thr);
849 code(extent_index++) = Atom::Set(2);
850 code(extent_index++) = Atom::RPointer(references_size());
851 add_reference(input1);
853 code(extent_index++) = Atom::RPointer(references_size());
854 add_reference(input2);
857 code(extent_index++) = Atom::Nil();
858 code(MK_RDX_PRODS) = Atom::IPointer(extent_index);
859 code(extent_index++) = Atom::Set(1);
860 code(extent_index++) = Atom::RPointer(references_size());
861 add_reference(output);
866 Success::Success() : LObject() {
869 Success::Success(_Fact *
object, _Fact *evidence,
Code* object_mk_rdx, float32 psln_thr) : LObject() {
871 code(0) = Atom::Object(Opcodes::Success, SUCCESS_ARITY);
872 code(SUCCESS_OBJ) = Atom::RPointer(references_size());
873 add_reference(
object);
876 code(SUCCESS_EVD) = Atom::RPointer(references_size());
877 add_reference(evidence);
880 code(SUCCESS_EVD) = Atom::Nil();
883 code(SUCCESS_OBJ_MK_RDX) = Atom::RPointer(references_size());
884 add_reference(object_mk_rdx);
887 code(SUCCESS_OBJ_MK_RDX) = Atom::Nil();
889 code(SUCCESS_ARITY) = Atom::Float(psln_thr);
894 Perf::Perf() : LObject() {
897 Perf::Perf(microseconds reduction_job_avg_latency, microseconds d_reduction_job_avg_latency, microseconds time_job_avg_latency, microseconds d_time_job_avg_latency) : LObject() {
899 code(0) = Atom::Object(Opcodes::Perf, PERF_ARITY);
900 code(PERF_RDX_LTCY) = Atom::Float(reduction_job_avg_latency.count());
901 code(PERF_D_RDX_LTCY) = Atom::Float(d_reduction_job_avg_latency.count());
902 code(PERF_TIME_LTCY) = Atom::Float(time_job_avg_latency.count());
903 code(PERF_D_TIME_LTCY) = Atom::Float(d_time_job_avg_latency.count());
904 code(PERF_ARITY) = Atom::Float(1);
909 ICST::ICST() : LObject() {
912 ICST::ICST(
SysObject *source) : LObject(source) {
915 bool ICST::is_invalidated() {
917 if (LObject::is_invalidated()) {
919 for (uint32 i = 0; i < components_.size(); ++i) {
921 if (components_[i]->is_invalidated()) {
932 for (uint32 i = 0; i < components_.size(); ++i) {
934 if (components_[i] == component) {
946 for (
auto i = components_.begin(); i != components_.end(); ++i) {
950 if ((*i)->get_reference(0)->code(0).asOpcode() == Opcodes::ICst &&
951 ((
ICST*)(*i)->get_reference(0))->r_contains(component))