YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
kbase.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
9
10#include <cstdio>
11#include <cctype>
12#include <string>
13#include <cstring>
14
15
16using namespace yarp::manager;
17
18
20 AppLoader* _apploader, ResourceLoader* _resloader)
21{
22 modloader = _mloader;
23 apploader = _apploader;
24 resloader = _resloader;
25
29 kbGraph.clear();
30 tmpGraph.clear();
31 selconnections.clear();
32 selmodules.clear();
33 selapplications.clear();
34 selresources.clear();
35
36 /*
37 * Loading resources
38 */
39 if(resloader)
40 {
41 GenericResource* resource;
42 resloader->reset();
43 while ((resource = resloader->getNextResource())) {
44 addResource(resource);
45 }
46 }
47
51 if(modloader)
52 {
53 Module* module;
54 modloader->reset();
55 while ((module = modloader->getNextModule())) {
56 addModule(module);
57 }
58 }
59
63 if(apploader)
64 {
65 Application* application;
66 apploader->reset();
67 while ((application = apploader->getNextApplication())) {
68 addApplication(application);
69 }
70 }
71
72 return true;
73}
74
75
76bool KnowledgeBase::addApplication(Application* app, char** szAppName_, bool modifyName)
77{
78 __CHECK_NULLPTR(app);
80 static std::map<std::string, int> mapId;
81 app->setLabel(app->getName());
82 if(kbGraph.hasNode(app))
83 {
84 if (mapId.find(std::string(app->getName())) == mapId.end()) {
85 mapId[app->getName()] = 1;
86 } else {
87 mapId[app->getName()] = mapId[app->getName()] + 1;
88 }
89 OSTRINGSTREAM newlable;
90 newlable<<app->getLabel()<<"("<<mapId[app->getName()]<<")";
91 OSTRINGSTREAM msg;
92 msg<<app->getName()<<" from "<<app->getXmlFile()<<" already exists.";
93 logger->addWarning(msg);
94 app->setName(newlable.str().c_str());
95 app->setLabel(newlable.str().c_str());
96 }
97
98 if(modifyName){
99 if (*szAppName_)
100 {
101 delete [] *szAppName_;
102 *szAppName_ = nullptr;
103 }
104 size_t len = app->getNameLenght();
105 *szAppName_ = new char[len + 1];
106 strncpy(*szAppName_, app->getName(), len);
107 (*szAppName_)[len] = '\0';
108 }
109 if(!kbGraph.addNode(app))
110 {
111 OSTRINGSTREAM msg;
112 msg<<"Application "<<app->getName()<<" cannot be added to the graph.";
113 logger->addError(msg);
114 return false;
115 }
116 return true;
117}
118
119
121{
122 __CHECK_NULLPTR(mod);
123
125 mod->setLabel(mod->getName());
126 if(kbGraph.hasNode(mod))
127 {
128 OSTRINGSTREAM msg;
129 msg<<"Module "<<mod->getName()<<" already exists.";
130 logger->addWarning(msg);
131 return false;
132 }
133 if(!addModuleToGraph(kbGraph, mod))
134 {
135 OSTRINGSTREAM msg;
136 msg<<"Module "<<mod->getName()<<" cannot be added to the graph.";
137 logger->addError(msg);
138 return false;
139 }
140 return true;
141}
142
143
145{
146 __CHECK_NULLPTR(res);
147
148 // a disabled resource should not be used.
149 //if(res->getDisable())
150 // return true;
151
153 res->setLabel(res->getName());
154 if(kbGraph.hasNode(res))
155 {
156 OSTRINGSTREAM msg;
157 msg<<"Resource "<<res->getName()<<" already exists.";
158 logger->addWarning(msg);
159 return false;
160 }
161 if(!kbGraph.addNode(res))
162 {
163 OSTRINGSTREAM msg;
164 msg<<"Resource "<<res->getName()<<" cannot be added to the graph.";
165 logger->addError(msg);
166 return false;
167 }
168 return true;
169}
170
171
173{
174 return kbGraph.removeNode(app);
175}
176
178{
179 return removeModuleFromGraph(kbGraph, mod);
180}
181
183{
184 return kbGraph.removeNode(res);
185}
186
187
189{
190 dummyApplications.clear();
191 if(parent)
192 {
193 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
194 {
195 auto* app = dynamic_cast<Application*>(*itr);
196 if (app && (app->owner() == parent)) {
197 dummyApplications.push_back(app);
198 }
199 }
200 }
201 else
202 {
203 for(GraphIterator itr=kbGraph.begin(); itr!=kbGraph.end(); itr++)
204 {
205 auto* app = dynamic_cast<Application*>(*itr);
206 if (app) {
207 dummyApplications.push_back(app);
208 }
209 }
210 }
211
212 sort(dummyApplications.begin(), dummyApplications.end(), sortApplication());
213 return dummyApplications;
214}
215
216
218{
219 dummyModules.clear();
220 if(parent)
221 {
222 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
223 {
224 auto* mod = dynamic_cast<Module*>(*itr);
225 if (mod && (mod->owner() == parent)) {
226 dummyModules.push_back(mod);
227 }
228 }
229 }
230 else
231 {
232 for(GraphIterator itr=kbGraph.begin(); itr!=kbGraph.end(); itr++)
233 {
234 auto* mod = dynamic_cast<Module*>(*itr);
235 if (mod) {
236 dummyModules.push_back(mod);
237 }
238 }
239 }
240 sort(dummyModules.begin(), dummyModules.end(), sortModules());
241 return dummyModules;
242}
243
244//TODO: dummyConnections should be changed to return connections from all
245// nested applications recursively
247{
248 dummyConnections.clear();
249 if(parent)
250 {
251 for (int i = 0; i < parent->connectionCount(); i++) {
252 dummyConnections.push_back(parent->getConnectionAt(i));
253 }
254 } else {
255 dummyConnections = selconnections;
256 }
257 //sort(dummyConnections.begin(), dummyConnections.end(), sortConnections());
258 return dummyConnections;
259}
260
262{
263 dummyResources.clear();
264 for(GraphIterator itr=kbGraph.begin(); itr!=kbGraph.end(); itr++)
265 {
266 auto* res = dynamic_cast<Computer*>(*itr);
267 if(res)
268 {
269 bool bHas = false;
270 for (auto& dummyResource : dummyResources) {
271 if(std::string(dummyResource->getName()) == std::string(res->getName()))
272 {
273 bHas = true;
274 break;
275 }
276 }
277 if (!bHas) {
278 dummyResources.push_back(res);
279 }
280 }
281 }
282
283 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
284 {
285 auto* res = dynamic_cast<Computer*>(*itr);
286 if(res)
287 {
288 bool bHas = false;
289 for (auto& dummyResource : dummyResources) {
290 if(std::string(dummyResource->getName()) == std::string(res->getName()))
291 {
292 bHas = true;
293 break;
294 }
295 }
296 if (!bHas) {
297 dummyResources.push_back(res);
298 }
299 }
300 }
301 sort(dummyResources.begin(), dummyResources.end(), sortResources());
302 return dummyResources;
303}
304
306{
307 dummyArbitrators.clear();
308 if(parent)
309 {
310 for (int i = 0; i < parent->arbitratorCount(); i++) {
311 dummyArbitrators.push_back(parent->getArbitratorAt(i));
312 }
313 }
314 return dummyArbitrators;
315}
316
317
319{
320 static InputContainer inputs;
321 inputs.clear();
322 for (GraphIterator itr = kbGraph.begin(); itr != kbGraph.end(); itr++) {
323 if ((*itr)->getType() == INPUTD && (*itr)->hasSuc(output)) {
324 inputs.push_back(*((InputData*)(*itr)));
325 }
326 }
327 return inputs;
328}
329
330
332{
333 static OutputContainer outputs;
334 outputs.clear();
335 for (int i = 0; i < input->sucCount(); i++) {
336 outputs.push_back(*((OutputData*)input->getLinkAt(i).to()));
337 }
338 return outputs;
339}
340
341
345bool KnowledgeBase::makeupApplication(Application* application)
346{
348 if (!application) {
349 return false;
350 }
354 for(int i=0; i<application->iapplicationCount(); i++)
355 {
356 ApplicationInterface interfaceApp = application->getIapplicationAt(i);
357 if(std::string(interfaceApp.getName()) == std::string(application->getName()))
358 {
359 OSTRINGSTREAM msg;
360 msg<<"Application "<<interfaceApp.getName()<<" cannot be called from itself.";
361 logger->addWarning(msg);
362 }
363 else
364 {
365 auto* repapp = dynamic_cast<Application*>(kbGraph.getNode(interfaceApp.getName()));
366 if(!repapp)
367 {
368 OSTRINGSTREAM msg;
369 msg<<"Application "<<interfaceApp.getName()<<" not found.";
370 logger->addWarning(msg);
371 }
372 else
373 {
374
375 if (appList.find(std::string(interfaceApp.getName())) == appList.end()) {
376 appList[interfaceApp.getName()] = 1;
377 }
378 OSTRINGSTREAM newname;
379 newname<<application->getName()<<":";
380 newname<<interfaceApp.getName()<<":"<<appList[interfaceApp.getName()];
381
382 repapp = replicateApplication(tmpGraph, repapp, newname.str().c_str());
383
384 // setting application base prefix
385 repapp->setBasePrefix(interfaceApp.getPrefix());
386
387 // adding applicattion prefix to child application
388 if( strlen(application->getPrefix()) )
389 {
390 std::string strPrefix = std::string(application->getPrefix()) +
391 std::string(interfaceApp.getPrefix());
392 interfaceApp.setPrefix(strPrefix.c_str());
393 }
394
395 // updating Application with ApplicationInterface
396 updateApplication(repapp, &interfaceApp);
397 appList[interfaceApp.getName()] = appList[interfaceApp.getName()] + 1;
398
399 //Adding child application as an successor to the application
400 tmpGraph.addLink(application, repapp, 0, false);
401 repapp->setOwner(application);
402 // recursive call to make up child application
403 makeupApplication(repapp);
404 }
405 }
406 }
407
408
412 //std::map<std::string, int> modList;
413 for(int i=0; i<application->imoduleCount(); i++)
414 {
415 ModuleInterface &mod = application->getImoduleAt(i);
416 addIModuleToApplication(application, mod);
417 } // end of for loop
418
419
420 /*
421 * updating extera connections with application prefix
422 * and connections owner
423 */
424 for(int i=0; i<application->connectionCount(); i++)
425 {
426 Connection* cnn = &application->getConnectionAt(i);
427 cnn->setOwner(application);
428 if(!cnn->isExternalFrom())
429 {
430 std::string strPort = std::string(application->getPrefix()) + std::string(cnn->from());
431 cnn->setFrom(strPort.c_str());
432 }
433
434 if(!cnn->isExternalTo())
435 {
436 std::string strPort = std::string(application->getPrefix()) + std::string(cnn->to());
437 cnn->setTo(strPort.c_str());
438 }
439 }
440
449 if(application->resourcesCount())
450 {
451 MultiResource mres;
452 OSTRINGSTREAM strLabel;
453 strLabel<<application->getLabel()<<":MultipleResource";
454 mres.setLabel(strLabel.str().c_str());
455 mres.setName("MultipleResource");
456 mres.setOwner(application);
457 for (int i = 0; i < application->resourcesCount(); i++) {
458 mres.addResource(application->getResourceAt(i));
459 }
460 Node* node = tmpGraph.addNode(&mres);
461 tmpGraph.addLink(application, node, 0);
462 }
463
464 return true;
465}
466
467bool KnowledgeBase::setModulePrefix(Module* module, const char* szPrefix, bool updateBasePrefix)
468{
469 __CHECK_NULLPTR(module);
470 __CHECK_NULLPTR(szPrefix);
471
472 module->setPrefix(szPrefix);
473 if (updateBasePrefix) {
474 module->setBasePrefix(szPrefix);
475 }
476
477 // updating port's prefix
478 // TODO: check if this is required anymore
479 /*
480 for(int i=0; i<module->sucCount(); i++)
481 {
482 InputData* input = dynamic_cast<InputData*>(module->getLinkAt(i).to());
483 if(input)
484 {
485 std::string strPort = std::string(szPrefix) + std::string(input->getPort());
486 input->setPort(strPort.c_str());
487 }
488 }
489
490 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
491 {
492 if((*itr)->getType() == OUTPUTD)
493 {
494 OutputData* output = (OutputData*)(*itr);
495 Module* producer = dynamic_cast<Module*>(output->getLinkAt(0).to());
496 if(producer == module)
497 {
498 std::string strPort = std::string(szPrefix) + std::string(output->getPort());
499 output->setPort(strPort.c_str());
500 }
501 }
502 }
503 */
504 return true;
505}
506
507bool KnowledgeBase::setApplicationPrefix(Application* application, const char* szPrefix, bool updateBasePrefix)
508{
509 __CHECK_NULLPTR(application);
510 __CHECK_NULLPTR(szPrefix);
511
512 application->setPrefix(szPrefix);
513 if (updateBasePrefix) {
514 application->setBasePrefix(szPrefix);
515 }
516
520 for(int i=0; i<application->sucCount(); i++)
521 {
522 auto* nestedApp = dynamic_cast<Application*>(application->getLinkAt(i).to());
523 if(nestedApp)
524 {
525 std::string strPrefix = std::string(szPrefix) + std::string(nestedApp->getBasePrefix());
526 setApplicationPrefix(nestedApp, strPrefix.c_str(), false);
527 }
528 else
529 {
530 auto* module = dynamic_cast<Module*>(application->getLinkAt(i).to());
531 if(module)
532 {
533 std::string strPrefix = std::string(szPrefix) + std::string(module->getBasePrefix());
534 setModulePrefix(module, strPrefix.c_str(), false);
535 }
536 }
537 }
538
542 /*
543 for(int i=0; i<application->connectionCount(); i++)
544 {
545 Connection* cnn = &application->getConnectionAt(i);
546 if(!cnn->isExternalFrom())
547 {
548 std::string strPort = std::string(szPrefix) + std::string(cnn->from());
549 cnn->setFrom(strPort.c_str());
550 }
551
552 if(!cnn->isExternalTo())
553 {
554 std::string strPort = std::string(szPrefix) + std::string(cnn->to());
555 cnn->setTo(strPort.c_str());
556 }
557 }
558 */
559 return true;
560}
561
563 Connection &cnn)
564{
565 cnn.setOwner(application);
566 for(int i=0; i<application->connectionCount(); i++)
567 {
568 Connection* con = &application->getConnectionAt(i);
569 if(*con == cnn)
570 {
571 *con = cnn;
572 return *con;
573 }
574 }
575
576 selconnections.push_back(cnn);
577 return application->addConnection(cnn);
578}
579
581 Arbitrator &arb)
582{
583 arb.setOwner(application);
584 for(int i=0; i<application->arbitratorCount(); i++)
585 {
586 Arbitrator* parb = &application->getArbitratorAt(i);
587 if(*parb == arb)
588 {
589 *parb = arb;
590 return *parb;
591 }
592 }
593 return application->addArbitrator(arb);
594}
595
596
597
599 Connection& prev, Connection& con )
600{
601 __CHECK_NULLPTR(application);
602
603 for(int i=0; i<application->connectionCount(); i++)
604 {
605 Connection* pcon = &application->getConnectionAt(i);
606 if(*pcon == prev)
607 {
608 *pcon = con;
609 break;
610 }
611 }
612
613 CnnIterator citr;
614 for(citr=selconnections.begin(); citr<selconnections.end(); citr++)
615 {
616 if((*citr) == prev)
617 {
618 (*citr) = con;
619 break;
620 }
621 }
622
623 return true;
624}
625
627{
628 //printf("[%d] %s\n",__LINE__, __PRETTY_FUNCTION__ );
629 __CHECK_NULLPTR(application);
630 return application->removeArbitrator(arb);
631}
632
633
635{
636 __CHECK_NULLPTR(application);
637
638 CnnIterator citr;
639 for(citr=selconnections.begin(); citr<selconnections.end(); citr++)
640 {
641 if((*citr) == cnn)
642 {
643 selconnections.erase(citr);
644 break;
645 }
646 }
647 return application->removeConnection(cnn);
648}
649
650const std::string KnowledgeBase::getUniqueAppID(Application* parent, const char* szAppName)
651{
652 if (appList.find(std::string(szAppName)) == appList.end()) {
653 appList[szAppName] = 1;
654 }
655 OSTRINGSTREAM newname;
656 newname<<parent->getName()<<":";
657 newname<<szAppName<<":"<<appList[szAppName];
658 return newname.str();
659}
660
662 ApplicationInterface &interfaceApp, bool isNew)
663{
664 __CHECK_NULLPTR(application);
665
666 Application* repapp = nullptr;
667
669 if(std::string(interfaceApp.getName()) == std::string(application->getName()))
670 {
671 OSTRINGSTREAM msg;
672 msg<<"Application "<<interfaceApp.getName()<<" cannot be called from itself.";
673 logger->addWarning(msg);
674 }
675 else
676 {
677 repapp = dynamic_cast<Application*>(kbGraph.getNode(interfaceApp.getName()));
678 if(!repapp)
679 {
680 OSTRINGSTREAM msg;
681 msg<<"Application "<<interfaceApp.getName()<<" not found.";
682 logger->addWarning(msg);
683 }
684 else
685 {
686 if (appList.find(std::string(interfaceApp.getName())) == appList.end()) {
687 appList[interfaceApp.getName()] = 1;
688 }
689 OSTRINGSTREAM newname;
690 newname<<application->getName()<<":";
691 newname<<interfaceApp.getName()<<":"<<appList[interfaceApp.getName()];
692 repapp = replicateApplication(tmpGraph, repapp, newname.str().c_str());
693 // setting application base prefix
694 repapp->setBasePrefix(interfaceApp.getPrefix());
695
696 // adding application prefix to child application
697 if( strlen(application->getPrefix()) )
698 {
699 std::string strPrefix = std::string(application->getPrefix()) +
700 std::string(interfaceApp.getPrefix());
701 interfaceApp.setPrefix(strPrefix.c_str());
702 }
703
704 // updating Application with ApplicationInterface
705 updateApplication(repapp, &interfaceApp);
706 appList[interfaceApp.getName()] = appList[interfaceApp.getName()] + 1;
707
708 //Adding child application as an successor to the application
709 tmpGraph.addLink(application, repapp, 0, false);
710 repapp->setOwner(application);
711 // recursive call to make up child application
712 makeupApplication(repapp);
713 }
714 }
715 return repapp;
716}
717
718
720 ModuleInterface &mod, bool isNew)
721{
722 __CHECK_NULLPTR(application);
723
724 Module* module;
725
726 if (application->modList.find(std::string(mod.getName())) == application->modList.end()) {
727 application->modList[mod.getName()] = 1;
728 }
729 OSTRINGSTREAM newname;
730 newname<<application->getLabel()<<":"<<mod.getName()<<":"<<application->modList[mod.getName()];
731
732 auto* repmod = dynamic_cast<Module*>(kbGraph.getNode(mod.getName()));
733 if (repmod) {
734 module = replicateModule(tmpGraph, repmod, newname.str().c_str());
735 } else {
736 Module newmod(mod.getName());
737 newmod.setLabel(newname.str().c_str());
738 module = addModuleToGraph(tmpGraph, &newmod);
739 }
740
741 mod.setTag(newname.str().c_str());
742
743 // setting module base prefix
744 module->setBasePrefix(mod.getPrefix());
745
746 // adding application prefix to module prefix
747 if( strlen(application->getPrefix()) )
748 {
749 std::string strPrefix = std::string(application->getPrefix()) +
750 std::string(mod.getPrefix());
751 mod.setPrefix(strPrefix.c_str());
752 }
753
754 //updating Module with ModuleInterface
755 updateModule(module, &mod);
756 application->modList[mod.getName()] = application->modList[mod.getName()] + 1;
757
758 // adding module's resources to application resource list
760 for(itr=mod.getResources().begin();
761 itr!=mod.getResources().end(); itr++)
762 {
763 (*itr).setOwner(module);
764 application->addResource(*itr);
765 }
766
767 //Adding the module as an successor to the application
768 tmpGraph.addLink(application, module, 0, false);
769 module->setOwner(application);
770
771 if (isNew) {
772 application->addImodule(mod);
773 }
774 return module;
775}
776
777
778
779bool KnowledgeBase::removeIModuleFromApplication(Application* application, const char* szModTag)
780{
781 __CHECK_NULLPTR(application);
782
783 auto* module = dynamic_cast<Module*>(tmpGraph.getNode(szModTag));
784 if (module) {
785 removeModuleFromGraph(tmpGraph, module);
786 }
787 for(int i=0; i<application->imoduleCount(); i++)
788 {
789 if(strcmp(application->getImoduleAt(i).getTag(), szModTag) == 0)
790 {
791 application->removeImodule(application->getImoduleAt(i));
792 return true;
793 }
794 }
795 return false;
796}
797
798//TODO: check if we should free application memory
799//
800bool KnowledgeBase::removeIApplicationFromApplication(Application* application, const char* szAppTag)
801{
802 __CHECK_NULLPTR(application);
803 auto* app = dynamic_cast<Application*>(tmpGraph.getNode(szAppTag));
804 if (!app) {
805 return false;
806 }
807
808 // removing all nested applications recursively
809 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
810 {
811 auto* nestedApp = dynamic_cast<Application*>(*itr);
812 if (nestedApp && (nestedApp->owner() == app)) {
813 removeIApplicationFromApplication(app, nestedApp->getLabel());
814 }
815 }
816
817 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
818 {
819 auto* mod = dynamic_cast<Module*>(*itr);
820 if (mod && (mod->owner() == app)) {
821 removeModuleFromGraph(tmpGraph, mod);
822 } else {
823 auto* res = dynamic_cast<MultiResource*>(*itr);
824 if(res && (res->owner() == app))
825 {
826 tmpGraph.removeLink(app, res);
827 tmpGraph.removeNode(res);
828 }
829 }
830 }
831
832 for(int i=0; i<application->iapplicationCount(); i++)
833 {
834 if(strcmp(application->getIapplicationAt(i).getName(), szAppTag) == 0)
835 {
836 application->removeIapplication(application->getIapplicationAt(i));
837 break;
838 }
839 }
840
841 tmpGraph.removeLink(application, app);
842 tmpGraph.removeNode(app);
843 return true;
844}
845
846
847
848GenericResource* KnowledgeBase::findResByName(Graph& graph, const char* szName)
849{
850 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
851 {
852 auto* res = dynamic_cast<GenericResource*>(*itr);
853 if (res) {
854 if (std::string(res->getName()) == std::string(szName)) {
855 return res;
856 }
857 }
858 }
859 return nullptr;
860}
861
862
863InputData* KnowledgeBase::findInputByPort(Graph& graph, const char* szPort)
864{
865 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
866 {
867 if((*itr)->getType() == INPUTD )
868 {
869 auto* input = (InputData*)(*itr);
870 if (compareString(input->getPort(), szPort)) {
871 return input;
872 }
873 }
874 }
875 return nullptr;
876}
877
878
879OutputData* KnowledgeBase::findOutputByPort(Graph& graph, const char* szPort)
880{
881 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
882 {
883 if((*itr)->getType() == OUTPUTD)
884 {
885 auto* output = (OutputData*)(*itr);
886 if (compareString(output->getPort(), szPort)) {
887 return output;
888 }
889 }
890 }
891 return nullptr;
892}
893
894bool KnowledgeBase::reasolveDependency(const char* szAppName,
895 bool bAutoDependancy, bool bSilent)
896{
898 auto* app = dynamic_cast<Application*>(kbGraph.getNode(szAppName));
899 if(!app)
900 {
901 OSTRINGSTREAM msg;
902 msg<<"Application "<<std::string(szAppName)<<" not found.";
903 logger->addError(msg.str().c_str());
904 mainApplication = nullptr;
905 return false;
906 }
907
908 return reasolveDependency(app, bAutoDependancy, bSilent);
909}
910
912 bool bAutoDependancy, bool bSilent)
913{
915
916 if(!kbGraph.hasNode(app))
917 {
918 OSTRINGSTREAM msg;
919 msg<<"Application "<<app->getName()<<" not found.";
920 logger->addError(msg.str().c_str());
921 mainApplication = nullptr;
922 return false;
923 }
924
925 tmpGraph.clear();
926 // Adding application to tmpGraph
927 mainApplication = replicateApplication(tmpGraph,
928 app,
929 app->getLabel());
930
931 //internally used by makeup application and addIApplicationToApplication
932 appList.clear();
933 // extend application to its child applications and modules
934 if(!makeupApplication(mainApplication))
935 {
936 mainApplication = nullptr;
937 return false;
938 }
939
940 // Adding all resources which are providers to tmpGraph
941 // providers are those with no owner.
942 for (GraphIterator itr = kbGraph.begin(); itr != kbGraph.end(); itr++) {
943 if(dynamic_cast<GenericResource*>(*itr))
944 {
945
946 if (!dynamic_cast<GenericResource*>(*itr)->owner()) {
947 replicateResource(tmpGraph,
948 (GenericResource*)(*itr),
949 (*itr)->getLabel());
950 }
951 }
952 }
953
954 // make resources links
955 makeResourceLinks(tmpGraph);
956
957 ResourcePContainer resources;
958 ModulePContainer modules;
959 ApplicaitonPContainer applications;
960 CnnContainer connections;
961 tmpGraph.setSatisfied(false);
962 bool ret = reason(&tmpGraph, mainApplication,
963 applications, modules, resources, connections,
964 bAutoDependancy, bSilent);
965
966 // removing double nodes
967 selconnections.clear();
968 selmodules.clear();
969 selapplications.clear();
970 selresources.clear();
971
972 for(auto& resource : resources)
973 {
974 auto* mres = dynamic_cast<MultiResource*>(resource);
975 if(mres)
976 {
977 for(int i=0; i<mres->resourceCount(); i++)
978 {
979 auto* yres = dynamic_cast<ResYarpPort*>(&mres->getResourceAt(i));
980 if (yres && (find(selresources.begin(), selresources.end(), yres) == selresources.end())) {
981 selresources.push_back(yres);
982 }
983
984 // adding ResYarpPort from modules dependencies
985 /*
986 Computer* comp = dynamic_cast<Computer*>(&mres->getResourceAt(i));
987 if(comp)
988 {
989 for(int j=0; j<comp->peripheralCount(); j++)
990 {
991 ResYarpPort* yres = dynamic_cast<ResYarpPort*>(&comp->getPeripheralAt(j));
992 if(yres && (find(selresources.begin(), selresources.end(), yres)
993 == selresources.end()))
994 selresources.push_back(yres);
995 }
996
997 }*/
998 }
999 }
1000 else
1001 {
1002 if (find(selresources.begin(), selresources.end(), resource)
1003 == selresources.end()) {
1004 selresources.push_back(resource);
1005 }
1006 }
1007 }
1008
1009 for(auto& module : modules)
1010 {
1011 if (find(selmodules.begin(), selmodules.end(), module)
1012 == selmodules.end()) {
1013 selmodules.push_back(module);
1014 }
1015 }
1016
1017 for(auto& application : applications)
1018 {
1019 if (find(selapplications.begin(), selapplications.end(), application)
1020 == selapplications.end()) {
1021 selapplications.push_back(application);
1022 }
1023 }
1024
1025
1026 selconnections = connections;
1027
1028 /*
1029 cout<<"Modules: "<<endl;
1030 for(ModulePIterator mod = selmodules.begin(); mod != selmodules.end(); mod++)
1031 cout<<(*mod)->getName()<<" on "<<(*mod)->getHost()<<endl;
1032
1033 cout<<"Resources: "<<endl;
1034 for(ResourcePIterator res = selresources.begin(); res != selresources.end(); res++)
1035 cout<<(*res)->getName()<<endl;
1036
1037 cout<<"Connections: "<<endl;
1038 for(CnnIterator con = selconnections.begin(); con != selconnections.end(); con++)
1039 cout<<(*con).from()<<", "<<(*con).to()<<endl;
1040 */
1041
1042 /*
1043 if(bAutoDependancy)
1044 {
1045 updateNodesLink(tmpGraph, NODELINK_DEEP);
1046
1047 if(!checkConsistency())
1048 {
1049 logger->addError("Knowledge base is not consistent.");
1050 return false;
1051 }
1052 }
1053 else
1054 updateNodesLink(tmpGraph, NODELINK_SUPERFICIAL);
1055
1056
1057 // updating extra node links
1058 updateExtraLink(tmpGraph, &selconnections);
1059
1060 tmpGraph.setSatisfied(false);
1061 if(!bestDependancyPath(application, &selnodes, bAutoDependancy))
1062 {
1063 logger->addError("No solution found.");
1064 return false;
1065 }
1066
1067 NodePVIterator itr;
1068 for(itr=selnodes.begin(); itr!=selnodes.end(); itr++)
1069 {
1070 if((*itr)->getType() == MODULE)
1071 {
1072 if(find(selmodules.begin(), selmodules.end(),
1073 (Module*)(*itr)) == selmodules.end())
1074 selmodules.push_back((Module*)(*itr));
1075 }
1076 }
1077
1078 OutputData* from = NULL;
1079 InputData* to = NULL;
1080 for(itr=selnodes.begin(); itr!=selnodes.end(); itr++)
1081 {
1082 if((*itr)->getType() == INPUTD)
1083 to = (InputData*)(*itr);
1084 if((*itr)->getType() == OUTPUTD)
1085 from = (OutputData*)(*itr);
1086 if(from && to)
1087 {
1088 Connection cnn(from->getPort(), to->getPort(),
1089 from->getCarrier());
1090 if(find(selconnections.begin(), selconnections.end(),
1091 cnn) == selconnections.end())
1092 {
1093 cnn.setPriority(to->withPriority());
1094 cnn.setOwner(findOwner(tmpGraph, to));
1095 selconnections.push_back(cnn);
1096 }
1097 from = NULL;
1098 to = NULL;
1099 }
1100 }
1101
1102 for(itr=selnodes.begin(); itr!=selnodes.end(); itr++)
1103 {
1104 if((*itr)->getType() == RESOURCE)
1105 {
1106 if(find(selresources.begin(), selresources.end(),
1107 (ResYarpPort*)(*itr)) == selresources.end())
1108 selresources.push_back((ResYarpPort*)(*itr));
1109 }
1110 }
1111 */
1112 return ret;
1113}
1114
1115
1116bool KnowledgeBase::updateApplication(Application* app,
1117 ApplicationInterface* iapp )
1118{
1119 __CHECK_NULLPTR(app);
1120 __CHECK_NULLPTR(iapp);
1121
1122 if (strlen(iapp->getPrefix())) {
1123 app->setPrefix(iapp->getPrefix());
1124 }
1125 app->setModelBase(iapp->getModelBase());
1126 return true;
1127}
1128
1129bool KnowledgeBase::updateModule(Module* module, ModuleInterface* imod )
1130{
1131 __CHECK_NULLPTR(module);
1132 __CHECK_NULLPTR(imod);
1133
1134 if(strlen(imod->getHost()))
1135 {
1136 module->setHost(imod->getHost());
1137 module->setForced(true);
1138 }
1139
1140 if (strlen(imod->getParam())) {
1141 module->setParam(imod->getParam());
1142 }
1143 if (imod->getRank() > 0) {
1144 module->setRank(imod->getRank());
1145 }
1146 if (strlen(imod->getBroker())) {
1147 module->setBroker(imod->getBroker());
1148 }
1149 if (strlen(imod->getStdio())) {
1150 module->setStdio(imod->getStdio());
1151 }
1152 if (strlen(imod->getWorkDir())) {
1153 module->setWorkDir(imod->getWorkDir());
1154 }
1155 if (strlen(imod->getDisplay())) {
1156 module->setDisplay(imod->getDisplay());
1157 }
1158 if (strlen(imod->getEnvironment())) {
1159 module->setEnvironment(imod->getEnvironment());
1160 }
1161 module->setPostExecWait(imod->getPostExecWait());
1162 module->setPostStopWait(imod->getPostStopWait());
1163 module->setModelBase(imod->getModelBase());
1164
1165
1166 // updating module prefix
1167 if (strlen(imod->getPrefix())) {
1168 setModulePrefix(module, imod->getPrefix(), false);
1169 }
1170 return true;
1171}
1172
1173/*
1174 * Replicate a module from graph to tmpgraph
1175 */
1176Module* KnowledgeBase::replicateModule(Graph& graph,
1177 Module* module, const char* szLabel)
1178{
1179 __CHECK_NULLPTR(module);
1180 auto* newmod = (Module*) module->clone();
1181 newmod->setLabel(szLabel);
1182 newmod->setBasePrefix(module->getPrefix());
1183 newmod->removeAllSuc();
1184 if(!addModuleToGraph(graph, newmod))
1185 {
1186 delete newmod;
1187 return nullptr;
1188 }
1189
1190 delete newmod;
1191 return (Module*)graph.getNode(szLabel);
1192}
1193
1194
1195/*
1196 * Replicate an application from graph to tmpgraph
1197 */
1198Application* KnowledgeBase::replicateApplication(Graph& graph,
1199 Application* app, const char* szLabel)
1200{
1201 __CHECK_NULLPTR(app);
1202 auto* newapp = (Application*) app->clone();
1203 newapp->setLabel(szLabel);
1204 newapp->setBasePrefix(app->getPrefix());
1205 newapp->removeAllSuc();
1206 /*Adding new application to the graph */
1207 auto* application = (Application*)graph.addNode(newapp);
1208 delete newapp;
1209 return application;
1210}
1211
1212
1213/*
1214 * Replicate a resource from graph to tmpgraph
1215 */
1216GenericResource* KnowledgeBase::replicateResource(Graph& graph,
1217 GenericResource* res, const char* szLabel)
1218{
1219 __CHECK_NULLPTR(res);
1220 auto* newres = (GenericResource*) res->clone();
1221 newres->setLabel(szLabel);
1222 newres->removeAllSuc();
1223 /*Adding new resource to the graph */
1224 auto* resource = (GenericResource*)graph.addNode(newres);
1225 delete newres;
1226 return resource;
1227}
1228
1229
1230Module* KnowledgeBase::addModuleToGraph(Graph& graph, Module* module)
1231{
1233
1234 if (!moduleCompleteness(module)) {
1235 return nullptr;
1236 }
1237
1238 /*Adding module to the graph */
1239 if (!(module = (Module*)graph.addNode(module))) {
1240 return nullptr;
1241 }
1242
1243 /* Adding inputs nodes to the graph*/
1244 for(int i=0; i<module->inputCount(); i++)
1245 {
1246 InputData* input = &(module->getInputAt(i));
1247 input->setLabel(createDataLabel(module->getLabel(),
1248 input->getPort(), ":I"));
1249 input->setOwner(module);
1250 if ((input = (InputData*)graph.addNode(input))) {
1251 graph.addLink(module, input, 0,
1252 !(input->isRequired()));
1253 } else {
1254 input = &(module->getInputAt(i));
1255 module->removeInput(*input);
1256 OSTRINGSTREAM msg;
1257 msg<<"Input ";
1258 msg<<createDataLabel(module->getLabel(),
1259 input->getPort(), ":I");
1260 msg<<" already exists.";
1261 logger->addWarning(msg);
1262 }
1263 }
1264
1265 /* Adding output nodes to the graph*/
1266 for(int i=0; i<module->outputCount(); i++)
1267 {
1268 OutputData* output = &(module->getOutputAt(i));
1269 output->setLabel(createDataLabel(module->getLabel(),
1270 output->getPort(), ":O"));
1271 output->setOwner(module);
1272 if ((output = (OutputData*)graph.addNode(output))) {
1273 graph.addLink(output, module, 0);
1274 } else {
1275 output = &(module->getOutputAt(i));
1276 module->removeOutput(*output);
1277 OSTRINGSTREAM msg;
1278 msg<<"Output ";
1279 msg<<createDataLabel(module->getLabel(),
1280 output->getPort(), ":O");
1281 msg<<" already exists.";
1282 logger->addWarning(msg);
1283 }
1284 }
1285
1286 /* Adding resources to the graph
1287 * all multiple resources will be add as single MultiResource entity
1288 */
1289 MultiResource mres;
1290 OSTRINGSTREAM strLabel;
1291 strLabel<<module->getLabel()<<":MultipleResource";
1292 mres.setLabel(strLabel.str().c_str());
1293 mres.setName("MultipleResource");
1294 mres.setOwner(module);
1295 for (int i = 0; i < module->resourceCount(); i++) {
1296 mres.addResource(module->getResourceAt(i));
1297 }
1298 Node* node = graph.addNode(&mres);
1299 graph.addLink(module, node, 0);
1300
1301 return module;
1302}
1303
1305{
1306 // updating iApplication
1307 application->removeAllIapplications();
1308 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
1309 {
1310 auto* embApp = dynamic_cast<Application*>(*itr);
1311 if(embApp && (embApp != application) && (embApp->owner() == application))
1312 {
1313 ApplicationInterface iapp(embApp->getName());
1314 iapp.setPrefix(embApp->getBasePrefix());
1315 if (embApp->getModel()) {
1316 iapp.setModelBase(*embApp->getModel());
1317 } else {
1318 iapp.setModelBase(embApp->getModelBase());
1319 }
1320 application->addIapplication(iapp);
1321 }
1322 }
1323
1324 //updating imodules
1325 application->removeAllImodules();
1326 for(GraphIterator itr=tmpGraph.begin(); itr!=tmpGraph.end(); itr++)
1327 {
1328 auto* module = dynamic_cast<Module*>(*itr);
1329 if(module && (module->owner() == application))
1330 {
1331 ModuleInterface imod(module);
1332 imod.setPrefix(module->getBasePrefix());
1333 application->addImodule(imod);
1334 }
1335 }
1336
1337 // updating connections modelBase with Model if exists
1338 for(int i=0; i<application->connectionCount(); i++)
1339 {
1340 Connection* pcon = &application->getConnectionAt(i);
1341 if (pcon->getModel()) {
1342 pcon->setModelBase(*pcon->getModel());
1343 }
1344 }
1345
1346 // updating arbitrators modelBase with Model if exists
1347 for(int i=0; i<application->arbitratorCount(); i++)
1348 {
1349 Arbitrator* parb = &application->getArbitratorAt(i);
1350 if (parb->getModel()) {
1351 parb->setModelBase(*parb->getModel());
1352 }
1353 }
1354
1355 return appSaver->save(application);
1356}
1357
1358bool KnowledgeBase::removeModuleFromGraph(Graph& graph, Module* mod)
1359{
1360
1361 // removing inputs and outputs and resource
1362 GraphIterator itr=graph.begin();
1363
1364 while(itr!=graph.end())
1365 {
1366 auto* input = dynamic_cast<InputData*>(*itr);
1367 if(input && (input->owner() == mod))
1368 {
1369 graph.removeNode(input);
1370 itr=graph.begin();
1371 }
1372 else
1373 {
1374 auto* output = dynamic_cast<OutputData*>(*itr);
1375 if(output && (output->owner() == mod))
1376 {
1377 graph.removeNode(output);
1378 itr=graph.begin();
1379 }
1380 else
1381 {
1382 auto* res = dynamic_cast<MultiResource*>(*itr);
1383 if(res && (res->owner() == mod))
1384 {
1385 graph.removeNode(res);
1386 itr=graph.begin();
1387 } else {
1388 itr++;
1389 }
1390 }
1391 }
1392 //itr++;
1393 }
1394
1395 // removing module
1396 return graph.removeNode(mod);
1397}
1398
1399
1400bool KnowledgeBase::moduleCompleteness(Module* module)
1401{
1403
1404 /* Checking module name */
1405 if(strlen(module->getName()) == 0)
1406 {
1407 logger->addWarning("Module has no name.");
1408 return false;
1409 }
1410
1411 /* Checking inputs name and port */
1412 for(int i=0; i<module->inputCount(); i++)
1413 {
1414 const char* szType = module->getInputAt(i).getName();
1415 const char* szPort = module->getInputAt(i).getPort();
1416 if (!strlen(szType)) {
1417 logger->addWarning(std::string(module->getName()) + std::string(" has an input with no type."));
1418 }
1419 if (!strlen(szPort)) {
1420 logger->addWarning(std::string(module->getName()) + std::string(" has an input with no port."));
1421 }
1422 }
1423
1424 /* Checking outputs name and port */
1425 for(int i=0; i<module->outputCount(); i++)
1426 {
1427 const char* szType = module->getOutputAt(i).getName();
1428 const char* szPort = module->getOutputAt(i).getPort();
1429 if (!strlen(szType)) {
1430 logger->addWarning(std::string(module->getName()) + std::string(" has an output with no type."));
1431 }
1432 if (!strlen(szPort)) {
1433 logger->addWarning(std::string(module->getName()) + std::string(" has an output with no port."));
1434 }
1435 }
1436 return true;
1437}
1438
1439
1440Module* KnowledgeBase::findOwner(Graph& graph, InputData* input)
1441{
1442 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
1443 {
1444 if((*itr)->getType() == MODULE)
1445 {
1446 auto* module = (Module*)(*itr);
1447 for(int i=0; i<module->sucCount(); i++)
1448 {
1449 Link l = module->getLinkAt(i);
1450 if ((InputData*)l.to() == input) {
1451 return module;
1452 }
1453 }
1454 }
1455 }
1456 return nullptr;
1457}
1458
1459
1460/*
1461void KnowledgeBase::updateExtraLink(Graph& graph, CnnContainer* connections)
1462{
1463 // update graph with external connection
1464 CnnIterator itrC;
1465 for(itrC=connections->begin(); itrC!=connections->end(); itrC++)
1466 {
1467 Connection cnn = (*itrC);
1468
1469 GenericResource* res = findResByName(graph, cnn.from());
1470 OutputData* output = findOutputByPort(graph, cnn.from());
1471 InputData* input = findInputByPort(graph, cnn.to());
1472 if(res && input)
1473 {
1474 res->setOwner(findOwner(graph, input));
1475 (*itrC).setOwner(findOwner(graph, input));
1476 input->addSuc(res, 0.0);
1477 }
1478 else if(output && input)
1479 {
1480 (*itrC).setOwner(findOwner(graph, input));
1481 input->addSuc(output, 0.0);
1482 }
1483 }
1484}
1485*/
1486
1487void KnowledgeBase::updateNodesLink(Graph& graph, int level)
1488{
1492 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
1493 {
1494 if((*itr)->getType() == INPUTD)
1495 {
1496 auto* input = (InputData*)(*itr);
1500 for(GraphIterator itr2=graph.begin(); itr2!=graph.end(); itr2++)
1501 {
1502 if((*itr2)->getType() == RESOURCE)
1503 {
1504 auto* res = (ResYarpPort*)(*itr2);
1505 if (compareString(res->getName(), input->getName())) {
1506 graph.addLink(input, res, 0.0, false);
1507 }
1508 }
1509 }
1510
1514 if (level == NODELINK_DEEP) {
1515 linkToOutputs(graph, input);
1516 }
1517 }
1518 }
1519}
1520
1521void KnowledgeBase::updateResourceWeight(Graph& graph,
1522 GenericResource* resource, float weight)
1523{
1524 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
1525 {
1526 for (int i = 0; i < (*itr)->sucCount(); i++) {
1527 if ((*itr)->getLinkAt(i).to() == resource) {
1528 (*itr)->getLinkAt(i).setWeight(weight);
1529 }
1530 }
1531 }
1532
1533}
1534
1535void KnowledgeBase::makeResourceLinks(Graph& graph)
1536{
1540 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
1541 {
1542 auto* resource = dynamic_cast<GenericResource*>(*itr);
1543 if(resource && resource->owner())
1544 {
1545 resource->removeAllSuc();
1546 auto* module = dynamic_cast<Module*>(resource->owner());
1547 if(module && module->getForced())
1548 {
1549 // we should create a provider resource with host name and
1550 // connect it to resource
1551 GenericResource* provider = findResByName(graph, module->getHost());
1552 if(!provider)
1553 {
1554 Computer comp;
1555 comp.setLabel(module->getHost());
1556 comp.setName(module->getHost());
1557 provider = (GenericResource*) graph.addNode(&comp);
1558 }
1559 float w = 0.0;
1560 if (dynamic_cast<Computer*>(provider)) {
1561 w = calculateLoad((Computer*)provider);
1562 }
1563 graph.addLink(resource, provider, w, false);
1564 }
1565 else if((module && !module->getForced()))
1566 {
1567 // linking resource providers to the relevant resources
1568 for(GraphIterator itr2=graph.begin(); itr2!=graph.end(); itr2++)
1569 {
1570 auto* provider = dynamic_cast<GenericResource*>(*itr2);
1571 if (provider && !provider->owner()) {
1572 if(provider->satisfy(resource))
1573 {
1574 float w = 0.0;
1575 if (dynamic_cast<Computer*>(provider)) {
1576 w = calculateLoad((Computer*)provider);
1577 }
1578 graph.addLink(resource, provider, w, false);
1579 }
1580 }
1581 }
1582 }
1583 }
1584 }
1585}
1586
1587
1588float KnowledgeBase::calculateLoad(Computer* comp)
1589{
1590 LoadAvg load = comp->getProcessor().getCPULoad();
1591 int siblings = comp->getProcessor().getSiblings();
1592 if (siblings == 0) {
1593 siblings = 1;
1594 }
1595 //cout<<comp->getName()<<": "<<load.loadAverage1<<", "<<load.loadAverage5<<", "<<load.loadAverage15;
1596 //cout<<" ("<<siblings<<")"<<endl;
1597 auto lavg = (float)((load.loadAverage1*15.0 +
1598 load.loadAverage5*10.0 +
1599 load.loadAverage15*1.0) / 26.0);
1600 return (lavg/(float)siblings);
1601}
1602
1603
1604void KnowledgeBase::linkToOutputs(Graph& graph, InputData* input)
1605{
1606 for(GraphIterator itr=graph.begin(); itr!=graph.end(); itr++)
1607 {
1608 if((*itr)->getType() == OUTPUTD)
1609 {
1610 auto* output = (OutputData*)(*itr);
1611 auto* producer = (Module*)output->getLinkAt(0).to();
1612 if (compareString(output->getName(), input->getName())
1613 && (producer != findOwner(graph, input))) {
1614 graph.addLink(input, output, (float)getProducerRank(graph, output), !input->isRequired());
1615 }
1616 }
1617 }
1618}
1619
1624int KnowledgeBase::getProducerRank(Graph& graph, OutputData* output)
1625{
1626 if(output->sucCount())
1627 {
1628 auto* module = (Module*)output->getLinkAt(0).to();
1629 return module->getRank();
1630 }
1631 return 0;
1632}
1633
1634
1636{
1637 //ErrorLogger* logger = ErrorLogger::Instance();
1638
1642 /*
1643 if(!application)
1644 {
1645 logger->addError("No application found.");
1646 return false;
1647 }
1648 */
1649
1654 /*
1655 if(application->isLeaf())
1656 {
1657 logger->addWarning("Empty application.");
1658 //return false;
1659 }
1660 */
1661 return true;
1662}
1663
1664Node* KnowledgeBase::getNode(std::string appName)
1665{
1666 return kbGraph.getNode(appName.c_str());
1667}
1668
1669bool KnowledgeBase::constrainSatisfied(Node* node,
1670 bool bAutoDependancy,
1671 bool bSilent)
1672{
1674
1675 // if it's a dependency resource with no provider
1676 auto* resource = dynamic_cast<GenericResource*>(node);
1677 if(resource && resource->isLeaf() &&
1678 dynamic_cast<Module*>(resource->owner()))
1679 {
1680 if(!bSilent)
1681 {
1682 OSTRINGSTREAM msg;
1683 msg<<"Some resource dependencies of ";
1684 msg<<dynamic_cast<Module*>(resource->owner())->getName();
1685 msg<<" are not satisfied.";
1686 logger->addWarning(msg);
1687 }
1688 return false;
1689 }
1690
1691 return true;
1692}
1693
1694/*
1695bool KnowledgeBase::constrainSatisfied(Node* node, bool bAutoDependancy)
1696{
1697 ErrorLogger* logger = ErrorLogger::Instance();
1698
1699 switch(node->getType()) {
1700 case INPUTD: {
1701 if( ((InputData*)node)->isRequired() && node->isLeaf() )
1702 {
1703 OSTRINGSTREAM msg;
1704 msg<<"Unsatisfied constrain. ";
1705 msg<<node->getLabel()<<" has no output candidate!";
1706 logger->addWarning(msg);
1707 if(bAutoDependancy)
1708 return false;
1709 }
1710 break;
1711 }
1712 default:
1713 break;
1714 };
1715 return true;
1716}
1717*/
1718
1719
1720bool KnowledgeBase::reason(Graph* graph, Node* initial,
1721 ApplicaitonPContainer &applications,
1722 ModulePContainer &modules,
1723 ResourcePContainer &resources,
1724 CnnContainer &connections,
1725 bool bAutoDependancy, bool bSilent)
1726{
1727 if(!constrainSatisfied(initial, bAutoDependancy, bSilent))
1728 {
1729 /* if it's a resource dependency */
1730 auto* resource = dynamic_cast<GenericResource*>(initial);
1731 if (resource && resource->owner()) {
1732 resources.push_back(resource);
1733 }
1734 return false;
1735 }
1736
1737 if(initial->isLeaf())
1738 {
1739 // adding resource
1740 if (dynamic_cast<GenericResource*>(initial)) {
1741 resources.push_back(dynamic_cast<GenericResource*>(initial));
1742 }
1743
1744 // adding connections
1745 auto* application = dynamic_cast<Application*>(initial);
1746 if(application)
1747 {
1748 applications.push_back(application);
1749 for (int i = 0; i < application->connectionCount(); i++) {
1750 connections.push_back(application->getConnectionAt(i));
1751 }
1752 }
1753 initial->setSatisfied(true);
1754 initial->setVisited(false);
1755 return true;
1756 }
1757
1758 /* now we are visiting this node */
1759 initial->setVisited(true);
1760 bool bPathFound = false;
1761
1762 Link* candidateLink = nullptr;
1763 float weight = -1.0;
1764
1765 for(int i=0; i<initial->sucCount(); i++)
1766 {
1767 Link l = initial->getLinkAt(i);
1768 Node* current = l.to();
1769
1770 /* we are not interested in virtual links
1771 * and we are not meeting a visited node to avoid looping
1772 */
1773 if(!l.isVirtual() && !current->isVisited())
1774 {
1775 ModulePContainer subModules;
1776 ApplicaitonPContainer subApplications;
1777 ResourcePContainer subResources;
1778 CnnContainer subConnections;
1779 bool ret = reason(graph, current,
1780 subApplications, subModules, subResources, subConnections,
1781 bAutoDependancy, bSilent);
1782 if (ret) {
1783 bPathFound = true;
1784 } else if (dynamic_cast<Application*>(initial) || dynamic_cast<Module*>(initial)) {
1785 bPathFound = false;
1786 }
1787
1788 /* we meet a conjunctive node and we need to copy all the
1789 * selected successors
1790 */
1791 if (dynamic_cast<Application*>(initial) ||
1792 dynamic_cast<Module*>(initial))
1793 {
1794 applications.insert(applications.end(), subApplications.begin(), subApplications.end());
1795 modules.insert(modules.end(), subModules.begin(), subModules.end());
1796 resources.insert(resources.end(), subResources.begin(), subResources.end());
1797 connections.insert(connections.end(), subConnections.begin(), subConnections.end());
1798 }
1799
1800 /* A disjunctive node; we should choose the best path */
1801 else if((weight<0.0) || (l.weight() < weight))
1802 {
1803 weight = l.weight();
1804 candidateLink = &initial->getLinkAt(i);
1805 modules = subModules;
1806 applications = subApplications;
1807 resources = subResources;
1808 connections = subConnections;
1809 }
1810
1811 }
1812 } // end for
1813
1814 /* if it's a resource dependency with a solution */
1815 auto* resource = dynamic_cast<GenericResource*>(initial);
1816 if(resource && resource->owner() && candidateLink)
1817 {
1818 auto* module = dynamic_cast<Module*>(resource->owner());
1819 auto* provider = dynamic_cast<GenericResource*>(candidateLink->to());
1820 if(module && provider)
1821 {
1822 // setting module's host property
1823 module->setHost(provider->getName());
1824
1825 // we need to update the weight of all links to the selected provider
1826 // with load balancer tunning value;
1827 // It will help for better load distribution among nodes
1828 auto* comp = dynamic_cast<Computer*>(provider);
1829 float default_tunning = 0.1F;
1830 if (comp && (comp->getProcessor().getSiblings() > 0)) {
1831 default_tunning = 1.0F / (float)comp->getProcessor().getSiblings();
1832 }
1833 float tunner = (module->getRank()<10)? default_tunning : (float)module->getRank()/100.0F;
1834 updateResourceWeight(*graph, provider, candidateLink->weight()+tunner);
1835 }
1836 resources.push_back(resource);
1837 }
1838
1839 /* adding current module to the modules list.*/
1840 if (dynamic_cast<Module*>(initial)) {
1841 modules.push_back(dynamic_cast<Module*>(initial));
1842 }
1843
1844 /* we should add all the connections */
1845 auto* application = dynamic_cast<Application*>(initial);
1846 if(application)
1847 {
1848 applications.push_back(dynamic_cast<Application*>(initial));
1849 for (int i = 0; i < application->connectionCount(); i++) {
1850 connections.push_back(application->getConnectionAt(i));
1851 }
1852 }
1853 initial->setSatisfied(bPathFound);
1854 initial->setVisited(false);
1855 return bPathFound;
1856}
1857
1858
1859const char* KnowledgeBase::createDataLabel(const char* modlabel,
1860 const char* port,
1861 const char* postfix)
1862{
1863 static std::string name;
1864 name.clear();
1865 name = std::string(modlabel) + std::string(port);
1866 if (postfix) {
1867 name += std::string(postfix);
1868 }
1869 return name.c_str();
1870}
bool ret
Abstract Class AppLoader.
virtual Application * getNextApplication()=0
virtual void reset()=0
virtual bool save(Application *application)=0
Class ApplicationInterface.
void setModelBase(GraphicModel &mdl)
void setPrefix(const char *szPrefix)
Class Application.
std::map< std::string, int > modList
void setName(const char *szName)
Arbitrator & addArbitrator(Arbitrator &arb)
bool addIapplication(ApplicationInterface &iapp)
Arbitrator & getArbitratorAt(int index)
void setBasePrefix(const char *szPrefix)
bool removeImodule(ModuleInterface &imod)
ModuleInterface & getImoduleAt(int index)
bool removeConnection(Connection &cnn)
void setModelBase(GraphicModel &mdl)
Connection & addConnection(Connection &cnn)
void setOwner(Node *owner)
bool removeArbitrator(Arbitrator &arb)
bool addResource(ResYarpPort &res)
ResYarpPort & getResourceAt(int index)
bool removeIapplication(ApplicationInterface &iapp)
bool addImodule(ModuleInterface &imod)
Connection & getConnectionAt(int index)
ApplicationInterface & getIapplicationAt(int index)
void setPrefix(const char *szPrefix)
Class port Arbitrator.
Definition arbitrator.h:24
void setOwner(Node *owner)
Definition arbitrator.h:54
GraphicModel * getModel()
Definition arbitrator.h:45
void setModelBase(GraphicModel &mdl)
Definition arbitrator.h:52
Processor & getProcessor()
Class Connection.
Definition application.h:56
void setTo(const char *szTo)
Definition application.h:81
void setOwner(Node *owner)
void setModelBase(GraphicModel &mdl)
void setFrom(const char *szFrom)
Definition application.h:80
GraphicModel * getModel()
Singleton class ErrorLogger.
Definition utility.h:58
void addError(const char *szError)
Definition utility.cpp:126
void addWarning(const char *szWarning)
Definition utility.cpp:104
static ErrorLogger * Instance()
Singleton class ErrorLogger.
Definition utility.cpp:98
void setName(const char *szName)
Definition resource.h:27
virtual bool satisfy(GenericResource *resource)=0
void setOwner(Node *owner)
Definition resource.h:33
Class GraphIterator.
Definition graph.h:66
Class Graph.
Definition graph.h:27
GraphIterator begin()
Definition graph.cpp:165
Node * addNode(Node *node)
Definition graph.cpp:17
bool removeNode(Node *node)
Definition graph.cpp:32
Node * getNode(const char *szLabel)
Definition graph.cpp:82
bool hasNode(Node *node)
Definition graph.cpp:135
bool removeLink(Node *first, Node *second)
Definition graph.cpp:114
bool addLink(Node *first, Node *second, float weight, bool _virtual=false)
Definition graph.cpp:91
GraphIterator end()
Definition graph.cpp:172
void setSatisfied(bool sat)
Definition graph.cpp:66
Class InputData.
Definition data.h:21
const char * getName()
Definition data.h:34
const char * getPort()
Definition data.h:36
void setOwner(Node *owner)
Definition data.h:47
Application * addIApplicationToApplication(Application *application, ApplicationInterface &app, bool isNew=false)
Definition kbase.cpp:661
const ArbContainer & getArbitrators(Application *parent=nullptr)
Definition kbase.cpp:305
const OutputContainer & getOutputCandidates(InputData *input)
Definition kbase.cpp:331
bool removeModule(Module *module)
Definition kbase.cpp:177
const ModulePContainer & getModules(Application *parent=nullptr)
Definition kbase.cpp:217
bool removeIModuleFromApplication(Application *application, const char *szTag)
Definition kbase.cpp:779
const InputContainer & getInputCandidates(OutputData *output)
Definition kbase.cpp:318
bool updateConnectionOfApplication(Application *application, Connection &prev, Connection &con)
Definition kbase.cpp:598
bool setModulePrefix(Module *module, const char *szPrefix, bool updateBasePrefix=true)
Definition kbase.cpp:467
bool removeResource(GenericResource *resource)
Definition kbase.cpp:182
bool removeConnectionFromApplication(Application *application, Connection &cnn)
Definition kbase.cpp:634
Arbitrator & addArbitratorToApplication(Application *application, Arbitrator &arb)
Definition kbase.cpp:580
bool reasolveDependency(const char *szName, bool bAutoDependancy=false, bool bSilent=false)
Definition kbase.cpp:894
bool addResource(GenericResource *resource)
Definition kbase.cpp:144
Connection & addConnectionToApplication(Application *application, Connection &cnn)
Definition kbase.cpp:562
Node * getNode(std::string appName)
Definition kbase.cpp:1664
Module * addIModuleToApplication(Application *application, ModuleInterface &mod, bool isNew=false)
Definition kbase.cpp:719
bool removeIApplicationFromApplication(Application *application, const char *szTag)
Definition kbase.cpp:800
bool addModule(Module *module)
Definition kbase.cpp:120
const ApplicaitonPContainer & getApplications(Application *parent=nullptr)
Definition kbase.cpp:188
bool removeApplication(Application *application)
Definition kbase.cpp:172
bool createFrom(ModuleLoader *_mloader, AppLoader *_apploader, ResourceLoader *_resloader)
Definition kbase.cpp:19
const CnnContainer & getConnections(Application *parent=nullptr)
Definition kbase.cpp:246
const std::string getUniqueAppID(Application *parent, const char *szAppName)
Definition kbase.cpp:650
const ResourcePContainer & getResources(Application *parent=nullptr)
Definition kbase.cpp:261
bool removeArbitratorFromApplication(Application *application, Arbitrator &arb)
Definition kbase.cpp:626
bool setApplicationPrefix(Application *app, const char *szPrefix, bool updateBasePref=true)
Definition kbase.cpp:507
bool addApplication(Application *application, char **szAppName_=nullptr, bool modifyName=false)
Definition kbase.cpp:76
bool saveApplication(AppSaver *appSaver, Application *application)
Definition kbase.cpp:1304
Class ModuleInterface.
void setTag(const char *szTag)
void setPrefix(const char *szPrefix)
ResourceContainer & getResources()
Abstract Class ModuleLoader.
virtual Module * getNextModule()=0
Class Module.
Definition module.h:99
Node * clone() override
Definition module.cpp:75
const char * getBasePrefix()
Definition module.h:142
const char * getPrefix()
Definition module.h:140
const char * getHost()
Definition module.h:131
const char * getName()
Definition module.h:128
GenericResource & getResourceAt(int index) const
Definition module.h:153
Class MultiResource.
Definition resource.h:67
bool addResource(GenericResource &res)
Definition resource.cpp:58
GenericResource & getResourceAt(int index) const
Definition resource.h:78
a Node of a Graph
Definition node.h:64
virtual Node * clone()=0
bool isVisited()
Definition node.h:86
void removeAllSuc()
Definition node.cpp:40
Link & getLinkAt(int index)
Definition node.h:95
void setSatisfied(bool sat)
Definition node.h:83
bool isLeaf()
Definition node.h:87
void setLabel(const char *szLabel)
Definition node.h:92
void setVisited(bool vis)
Definition node.h:85
const char * getLabel()
Definition node.h:93
void setOwner(Node *owner)
Definition data.h:91
const char * getPort()
Definition data.h:83
const char * getName()
Definition data.h:81
const LoadAvg & getCPULoad()
Abstract Class ResourceLoader.
virtual GenericResource * getNextResource()=0
#define NODELINK_DEEP
Definition kbase.h:23
bool compareString(const char *szFirst, const char *szSecond)
Definition utility.cpp:326
std::vector< InputData > InputContainer
Definition module.h:85
std::vector< Arbitrator > ArbContainer
Definition arbitrator.h:90
std::vector< ResYarpPort >::iterator ResourceIterator
std::vector< OutputData > OutputContainer
Definition module.h:86
std::vector< Connection >::iterator CnnIterator
std::vector< Module * > ModulePContainer
Definition module.h:230
std::stringstream OSTRINGSTREAM
Definition utility.h:50
std::vector< GenericResource * > ResourcePContainer
Definition resource.h:58
std::vector< Application * > ApplicaitonPContainer
std::vector< Connection > CnnContainer
#define __CHECK_NULLPTR(_ptr)
Definition ymm-types.h:77