summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new')
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new962
1 files changed, 0 insertions, 962 deletions
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new
deleted file mode 100644
index 8238577..0000000
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.new
+++ /dev/null
@@ -1,962 +0,0 @@
-/**
- * @file
- * @author 2012-2013 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de)
- * @copyright Simplified BSD
- *
- * @cond
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the FreeBSD license as published by the FreeBSD
- * project.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the FreeBSD license along with this
- * program. If not, see <http://www.opensource.org/licenses/bsd-license>.
- * @endcond
- */
-
-#include <boost/algorithm/string.hpp>
-
-#include "uscxml/Common.h"
-#include "uscxml/config.h"
-#include "SWIDataModel.h"
-#include "uscxml/DOMUtils.h"
-#include "uscxml/Message.h"
-#include <glog/logging.h>
-
-#ifdef BUILD_AS_PLUGINS
-#include <Pluma/Connector.hpp>
-#endif
-
-// these are defined but not exported by swi-prolog 7
-extern "C" {
- PL_EXPORT(int) PL_is_dict(term_t t);
- PL_EXPORT(int) PL_for_dict(term_t dict, int (*func)(term_t key, term_t value, int last, void *closure), void *closure, int flags);
-}
-#define RETHROW_PLEX_AS_EVENT \
-catch (PlException plex) { \
- ERROR_EXECUTION_THROW((char*)plex); \
-} \
-
-#define PL_MODULE \
-_interpreter.getSessionId().c_str() \
-
-#define SET_PL_ENGINE(dm) \
-assert(_swiEngines.find(dm) != _swiEngines.end()); \
-int rc = PL_set_engine(_swiEngines[dm], NULL); \
-assert(rc == PL_ENGINE_SET); \
-_dmPtr = dm;
-
-namespace uscxml {
-
-using namespace Arabica::XPath;
-using namespace Arabica::DOM;
-
-#ifdef BUILD_AS_PLUGINS
-PLUMA_CONNECTOR
-bool pluginConnect(pluma::Host& host) {
- host.add( new SWIDataModelProvider() );
- return true;
-}
-#endif
-
-// SWI prolog does not support passing user data
-static SWIDataModel* _dmPtr;
-static std::map<SWIDataModel*, PL_engine_t> _swiEngines;
-
-PL_blob_t SWIDataModel::blobType = {
- PL_BLOB_MAGIC,
- PL_BLOB_NOCOPY,
- (char*)"blob",
- releaseBlob,
- compareBlob,
- writeBlob,
- acquireBlob
-};
-
-SWIDataModel::SWIDataModel() {
-}
-
-SWIDataModel::~SWIDataModel() {
- try {
- if (_swiEngines.find(this) != _swiEngines.end()) {
- PL_destroy_engine(_swiEngines[this]);
- _swiEngines.erase(this);
- }
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-boost::shared_ptr<DataModelImpl> SWIDataModel::create(InterpreterImpl* interpreter) {
- try {
- boost::shared_ptr<SWIDataModel> dm = boost::shared_ptr<SWIDataModel>(new SWIDataModel());
- dm->_interpreter = interpreter;
-
- const char* swibin = getenv("SWI_BINARY");
- if (swibin == NULL)
- swibin = SWI_BINARY;
- const char* quiet = "--quiet";
-
- int argc = 2;
- static char * av[] = {
- (char*)swibin,
- (char*)quiet,
- NULL
- };
-
- if (!PL_is_initialised(NULL, NULL)) {
- if(!PL_initialise(argc,av)) {
- LOG(ERROR) << "Error intializing prolog engine";
- PL_halt(1);
- return boost::shared_ptr<DataModelImpl>();
- }
-
- PL_set_engine(PL_ENGINE_CURRENT, &_engine);
-
- // load SWI XML parser
- try {
- PlCall("use_module", PlCompound("library", PlTerm("sgml")));
- } catch (PlException plex) {
-
- LOG(ERROR) << "Cannot load prolog sgml module - make sure you have it installed in your prolog runtime: " << (char*)plex;
- throw plex;
- }
-
- // load json parser
- try {
- PlCall("use_module", PlCompound("library", PlTerm("http/json")));
- PlCall("use_module", PlCompound("library", PlTerm("http/json_convert")));
- } catch (PlException plex) {
- LOG(ERROR) << "Cannot load prolog json module or json_convert - make sure you have it installed in your prolog runtime: " << (char*)plex;
- throw plex;
- }
-
- } else {
- LOG(WARNING) << "Instantiating more than one SWI prolog datamodel will lead to weird effects as I cannot seperate the environments";
-// engine = PL_create_engine(NULL);
- }
-
-// assert(engine);
-// _swiEngines[dm.get()] = engine;
- _dmPtr = dm.get();
-
-// int rc = PL_set_engine(engine, NULL);
-// assert(rc == PL_ENGINE_SET);
-// (void)rc;
-
- _plModule = boost::replace_all_copy(interpreter->getSessionId(), "-", "");
- boost::replace_all(_plModule, "0", "g");
- boost::replace_all(_plModule, "1", "h");
- boost::replace_all(_plModule, "2", "i");
- boost::replace_all(_plModule, "3", "j");
- boost::replace_all(_plModule, "4", "k");
- boost::replace_all(_plModule, "5", "l");
- boost::replace_all(_plModule, "6", "m");
- boost::replace_all(_plModule, "7", "n");
- boost::replace_all(_plModule, "8", "o");
- boost::replace_all(_plModule, "9", "p");
-
- // use atoms for double quoted
- PlCall("set_prolog_flag(double_quotes,atom).");
-
- // set system variables
- PlCall("assert", PlCompound("sessionid", PlTerm(PlString(dm->_interpreter->getSessionId().c_str()))));
- PlCall("assert", PlCompound("name", PlTerm(PlString(dm->_interpreter->getName().c_str()))));
-
- std::map<std::string, IOProcessor>::const_iterator ioProcIter = dm->_interpreter->getIOProcessors().begin();
- while(ioProcIter != dm->_interpreter->getIOProcessors().end()) {
- Data ioProcData = ioProcIter->second.getDataModelVariables();
-
- if (ioProcIter->first.find_first_of(":/'") == std::string::npos) {
- std::stringstream ioProcShortCall;
- ioProcShortCall << "assert(ioprocessors(" << ioProcIter->first << "(location('" << ioProcData.compound["location"].atom << "'))))";
- PlCall(ioProcShortCall.str().c_str());
- }
- std::stringstream ioProcCall;
- ioProcCall << "assert(ioprocessors(name('" << ioProcIter->first << "'), location('" << ioProcData.compound["location"].atom << "')))";
- PlCall(ioProcCall.str().c_str());
-
- ioProcIter++;
- }
-
- // the in predicate
- PlRegister("user", "in", 1, SWIDataModel::inPredicate);
- PL_set_engine(NULL, NULL);
- return dm;
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-foreign_t SWIDataModel::inPredicate(term_t a0, int arity, void* context) {
- try {
- char *s;
- if ( PL_get_atom_chars(a0, &s) ) {
- if (_dmPtr->_interpreter->isInState(s)) {
- return true;
- }
- }
- return FALSE;
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-void SWIDataModel::registerIOProcessor(const std::string& name, const IOProcessor& ioprocessor) {
-// std::cout << "SWIDataModel::registerIOProcessor" << std::endl;
-}
-
-void SWIDataModel::setSessionId(const std::string& sessionId) {
-// std::cout << "SWIDataModel::setSessionId" << std::endl;
- _sessionId = sessionId;
-}
-
-void SWIDataModel::setName(const std::string& name) {
-// std::cout << "SWIDataModel::setName" << std::endl;
- _name = name;
-}
-
-void SWIDataModel::pushContext() {
-// std::cout << "SWIDataModel::pushContext" << std::endl;
-}
-
-void SWIDataModel::popContext() {
-// std::cout << "SWIDataModel::popContext" << std::endl;
-}
-
-void SWIDataModel::initialize() {
-// std::cout << "SWIDataModel::initialize" << std::endl;
-}
-
-void SWIDataModel::setEvent(const Event& event) {
- SWIEngineLock engineLock;
-
- // remove old event
- try {
- PlCall("retractall(event(_))");
-
- // simple values
- PlCall("assert", PlCompound("event", PlCompound("name", PlTerm(event.name.c_str()))));
- PlCall("assert", PlCompound("event", PlCompound("origin", PlString(event.origin.c_str()))));
- PlCall("assert", PlCompound("event", PlCompound("origintype", PlString(event.invokeid.c_str()))));
- PlCall("assert", PlCompound("event", PlCompound("invokeid", PlTerm(event.origintype.c_str()))));
- PlCall("assert", PlCompound("event", PlCompound("raw", PlString(event.raw.c_str()))));
-
- // event.type
- std::string type;
- switch (event.eventType) {
- case Event::PLATFORM:
- type = "platform";
- break;
- case Event::INTERNAL:
- type = "internal";
- break;
- case Event::EXTERNAL:
- type = "external";
- break;
- }
- PlCall("assert", PlCompound("event", PlCompound("type", PlTerm(type.c_str()))));
-
- // event.sendid
- if (!event.hideSendId)
- PlCall("assert", PlCompound("event", PlCompound("sendid", PlTerm(event.sendid.c_str()))));
-
- // event.data
- URL domUrl;
- if (event.dom) {
- std::stringstream dataInitStr;
- std::stringstream xmlDoc;
-// xmlDoc << event.getFirstDOMElement();
- xmlDoc << event.dom;
- domUrl = URL::toLocalFile(xmlDoc.str(), ".pl");
- dataInitStr << "load_xml_file('" << domUrl.asLocalFile(".pl") << "', XML), copy_term(XML,DATA), assert(event(data(DATA)))";
- PlCall(dataInitStr.str().c_str());
- } else if (event.content.size() > 0) {
- PlCall("assert", PlCompound("event", PlCompound("data", PlString(InterpreterImpl::spaceNormalize(event.content).c_str()))));
- } else if (!event.data.empty()) {
- assertFromData(event.data, "event(data(", 2);
- }
-
- Event::params_t::const_iterator paramIter = event.params.begin();
- while(paramIter != event.params.end()) {
- assertFromData(paramIter->second, "event(param(" + paramIter->first + "(", 3);
- paramIter++;
- }
-
- Event::namelist_t::const_iterator namelistIter = event.namelist.begin();
- while(namelistIter != event.namelist.end()) {
- assertFromData(paramIter->second, "event(param(" + namelistIter->first + "(", 3);
- namelistIter++;
- }
-
-#if 0
- // event.params
- size_t uniqueKeys = 0;
- Event::params_t::const_iterator paramIter = event.params.begin();
- while(paramIter != event.params.end()) {
- uniqueKeys++;
- paramIter = event.params.upper_bound(paramIter->first);
- }
- if (uniqueKeys > 0) {
- paramIter = event.params.begin();
- for(int i = 0; paramIter != event.params.end(); i++) {
- std::stringstream paramArray;
- Event::params_t::const_iterator lastValueIter = event.params.upper_bound(paramIter->first);
-
- paramArray << paramIter->first << "([";
- std::string termSep = "";
-
- for (int j = 0; paramIter != lastValueIter; j++) {
- paramArray << termSep << "'" << paramIter->second << "'";
- termSep = ", ";
- paramIter++;
- }
- paramArray << "])";
- std::stringstream paramExpr;
- paramExpr << "assert(event(param(" << paramArray.str() << ")))";
- //std::cout << paramExpr.str() << std::endl;
- PlCall(paramExpr.str().c_str());
-
- paramIter = lastValueIter;
- }
- }
-#endif
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-void SWIDataModel::assertFromData(const Data& data, const std::string& expr, size_t nesting) {
- if (data.atom.size() > 0) {
- // terminal branch, this is where we assert
-
- std::stringstream ss;
- ss << expr;
-// nesting++;
-
- if (data.type == Data::VERBATIM) {
- ss << "\"" << data.atom << "\"";
- } else {
- ss << data.atom;
- }
-
- for (size_t i = 0; i < nesting; i++) {
- ss << ")";
- }
-
-// std::cout << ss.str() << std::endl;
- PlCall("assert", PlCompound(ss.str().c_str()));
- return;
- }
-
- if (data.compound.size() > 0) {
- std::map<std::string, Data>::const_iterator compIter = data.compound.begin();
- while(compIter != data.compound.end()) {
-// std::cout << compIter->first << std::endl;
- std::stringstream prefix;
- size_t prefixNesting = 0;
- size_t oldPos = 0;
- size_t pos = 0;
- while((pos = compIter->first.find_first_of(",.(-", oldPos)) != std::string::npos) {
- prefix << compIter->first.substr(oldPos, pos - oldPos) << "(";
- prefixNesting++;
- oldPos = pos + 1;
- }
- if (oldPos != compIter->first.size()) {
- prefix << compIter->first.substr(oldPos, compIter->first.size() - oldPos) << "(";
- prefixNesting++;
- }
- assertFromData(compIter->second, expr + prefix.str(), nesting + prefixNesting);
- compIter++;
- }
- }
-
- if (data.array.size() > 0) {
- std::list<Data>::const_iterator arrIter = data.array.begin();
- while(arrIter != data.array.end()) {
- assertFromData(*arrIter, expr, nesting);
- arrIter++;
- }
- }
-
- if (data.node) {
- std::stringstream dataInitStr;
- std::stringstream xmlDoc;
-
- xmlDoc << data.node;
- URL domUrl = URL::toLocalFile(xmlDoc.str(), ".pl");
- dataInitStr << "load_xml_file('" << domUrl.asLocalFile(".pl") << "', XML), ";
- dataInitStr << "copy_term(XML,DATA), ";
- dataInitStr << "assert(";
- dataInitStr << expr << "(DATA)";
-
- for (size_t i = 0; i < nesting; i++) {
- dataInitStr << ")";
- }
-
- PlCall(dataInitStr.str().c_str());
- return;
- }
-}
-
-#if 0
-std::list<PlCompound> SWIDataModel::getSolutions(PlCompound compound) {
- std::list<PlCompound> solutions;
-
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- PlQuery query(compound.name(), termv);
- while(query.next_solution()) {
-// std::cout << (char*)compound << std::endl;
- solutions.push_back(compound);
- }
- return solutions;
-}
-#endif
-
-Data SWIDataModel::getStringAsData(const std::string& content) {
- SWIEngineLock engineLock;
- try {
- PlCompound compound(content.c_str());
- PlCompound orig(content.c_str());
- Data data;
-
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- PlQuery query(compound.name(), termv);
-
- while(query.next_solution()) {
- std::map<std::string, PlTerm> vars = resolveAtoms(compound, orig);
- std::map<std::string, PlTerm>::const_iterator varIter = vars.begin();
-
- while(varIter != vars.end()) {
- data.merge(termAsData(varIter->second));
- varIter++;
- }
-
- }
-// std::cout << Data::toJSON(data) << std::endl;
- return data;
- } catch (PlException plex) {
- try {
- // could not parse as compound, try term and type in termAsData
- PlTerm term(content.c_str());
- return(termAsData(term));
- }
- RETHROW_PLEX_AS_EVENT
- }
- return Data();
-}
-
-Data SWIDataModel::termAsData(PlTerm term) {
-
- Data data;
-// std::cout << term.name() << (char*)term << std::endl;
-
- switch (term.type()) {
- case PL_TERM:
- for (int i = 1; i <= term.arity(); i++) { // arguments start at 1
- data.compound[term.name()] = termAsData(term[i]);
- }
- break;
- case PL_VARIABLE:
- case PL_INTEGER:
- case PL_FLOAT:
- case PL_SHORT:
- case PL_INT:
- case PL_LONG:
- case PL_DOUBLE:
- data.atom = std::string(term);
- data.type = Data::INTERPRETED;
- break;
- case PL_STRING:
- case PL_ATOM:
- data.atom = std::string(term);
- data.type = Data::VERBATIM;
- break;
-#ifdef SWI_HAS_PL_NIL
- case PL_NIL:
- data.array.push_back(Data("", Data::VERBATIM));
- break;
-#endif
-#ifdef SWI_HAS_PL_LIST_PAIR
- case PL_LIST_PAIR: {
- PlTail tail(term);
- PlTerm item;
- while(tail.next(item)) {
- data.array.push_back(termAsData(item));
- }
- break;
- }
-#endif
-#ifdef SWI_HAS_DICT
- case PL_DICT: {
- std::string key(term);
- size_t curlyPos = key.find_first_of("{");
- if (curlyPos == std::string::npos || curlyPos == 0) {
- // no key given
- PL_for_dict(term, SWIDataModel::dictCallBack, &data, 0);
- } else {
- // with key given
- Data& tmp = data.compound[boost::trim_copy(key.substr(0, curlyPos))];
- PL_for_dict(term, SWIDataModel::dictCallBack, &tmp, 0);
- }
- break;
- }
-#endif
- default:
- LOG(ERROR) << "Prolog type " << term.type() << " at '" << (char*)term << "' not supported";
- break;
- }
- return data;
-}
-
-int SWIDataModel::dictCallBack(term_t key, term_t value, int last, void *closure) {
- Data* data = (Data*)closure;
- PlTerm keyTerm(key);
- data->compound[(char*)keyTerm] = termAsData(value);
- return 0;
-}
-
-PlTerm SWIDataModel::dataAsTerm(Data data) {
- if (data.atom.length() > 0) {
- return PlTerm(data.atom.c_str());
- }
- if (data.array.size() > 0) {
- PlTerm head;
- PlTail list(head);
-
- std::list<Data>::const_iterator arrIter = data.array.begin();
- while(arrIter != data.array.end()) {
- list.append(dataAsTerm(*arrIter));
- arrIter++;
- }
- list.close();
- return PlTail(head);
- }
- if (data.compound.size() > 0) {
- if (data.compound.size() == 1 && data.compound.begin()->second.array.size() > 0) {
- // this used to be a prolog compound
- const Data& arr = data.compound.begin()->second;
- PlTermv termv(arr.array.size());
- int index = 0;
-
- std::list<Data>::const_iterator arrIter = arr.array.begin();
- while(arrIter != arr.array.end()) {
- termv[index] = dataAsTerm(*arrIter);
- index++;
- arrIter++;
- }
- return PlCompound(data.compound.begin()->first.c_str(), termv);
- } else if (data.compound.size() == 1 && data.compound.begin()->second.compound.size() > 0) {
- // this used to be a named dict - until we have dict support in C/C++ use PL_chars_to_term
- std::stringstream dictSS;
- std::string seperator;
- dictSS << data.compound.begin()->first << "{";
-
- std::map<std::string, Data>::const_iterator keyIter = data.compound.begin()->second.compound.begin();
- while(keyIter != data.compound.begin()->second.compound.end()) {
- dictSS << seperator << keyIter->first << ":" << (char*)dataAsTerm(keyIter->second);
- seperator = ",";
- keyIter++;
- }
- dictSS << "}";
- return PlCompound(dictSS.str().c_str());
-
- } else {
- // an array of dicts
- PlTermv termv(data.compound.size());
- int index = 0;
-
- std::map<std::string, Data>::const_iterator compIter = data.compound.begin();
- while(compIter != data.compound.end()) {
- termv[index] = PlCompound(compIter->first.c_str(), dataAsTerm(compIter->second));
- index++;
- compIter++;
- }
- return PlCompound(data.compound.begin()->first.c_str(), termv);
-
- }
- }
- if (data.binary) {
- LOG(ERROR) << "Binary data with prolog datamodel still very experimental";
-// term_t binTerm = PL_new_term_ref();
-// PL_put_blob(binTerm, data.binary->data, data.binary->size, &blobType);
-// return binTerm;
- }
- if (data.node) {
- LOG(ERROR) << "DOM in event with prolog datamodel still very experimental";
- std::stringstream dataInitStr;
- std::stringstream xmlDoc;
- // xmlDoc << event.getFirstDOMElement();
- xmlDoc << data.node;
- URL domUrl = URL::toLocalFile(xmlDoc.str(), ".pl");
- dataInitStr << "load_xml_file('" << domUrl.asLocalFile(".pl") << "', XML), copy_term(XML,DATA), assert(event(data(DATA)))";
- PlCall(dataInitStr.str().c_str());
- }
-
- return PlTerm();
-}
-
-bool SWIDataModel::validate(const std::string& location, const std::string& schema) {
- SWIEngineLock engineLock;
-// std::cout << "SWIDataModel::validate" << std::endl;
- return true;
-}
-
-bool SWIDataModel::isLocation(const std::string& expr) {
- return true;
-}
-
-uint32_t SWIDataModel::getLength(const std::string& expr) {
- SWIEngineLock engineLock;
- try {
- PlCompound compound(expr.c_str());
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- PlQuery query(compound.name(), termv);
- uint32_t length = 0;
- while(query.next_solution() > 0)
- length++;
- return length;
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-void SWIDataModel::setForeach(const std::string& item,
- const std::string& array,
- const std::string& index,
- uint32_t iteration) {
- SWIEngineLock engineLock;
- try {
- PlCompound compound(array.c_str());
- PlCompound orig(array.c_str());
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- {
- int tmp = iteration + 1;
- PlQuery query(compound.name(), termv);
- while (tmp) {
- query.next_solution();
- tmp--;
- }
- }
- PlCall("retractall", PlCompound(index.c_str(), 1));
- PlCall("retractall", PlCompound(item.c_str(), 1));
- PlCall("assert", PlCompound(index.c_str(), PlTerm((long)iteration)));
-
- std::map<std::string, PlTerm> vars = resolveAtoms(compound, orig);
- std::map<std::string, PlTerm>::iterator varIter = vars.begin();
- while(varIter != vars.end()) {
- PlCall("assert", PlCompound(item.c_str(), varIter->second));
- varIter++;
- }
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-void SWIDataModel::eval(const Element<std::string>& scriptElem, const std::string& expr) {
- SWIEngineLock engineLock;
- try {
- if (scriptElem && HAS_ATTR(scriptElem, "type") && iequals(ATTR(scriptElem, "type"), "query")) {
- evalAsBool(expr);
- } else {
- URL localPLFile = URL::toLocalFile(expr, ".pl");
- PlCall("user", "load_files", PlTermv(localPLFile.asLocalFile(".pl").c_str())) || LOG(ERROR) << "Could not execute prolog from file";
- }
- }
- RETHROW_PLEX_AS_EVENT;
-}
-
-bool SWIDataModel::evalAsBool(const std::string& expr) {
- return evalAsBool(Arabica::DOM::Element<std::string>(), expr);
-}
-
-bool SWIDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) {
- SWIEngineLock engineLock;
- try {
- PlCompound compound(expr.c_str());
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- PlQuery query(compound.name(), termv);
- return query.next_solution() > 0;
- }
- RETHROW_PLEX_AS_EVENT
- catch(...) {
- return false;
- }
-}
-
-std::string SWIDataModel::evalAsString(const std::string& expr) {
- SWIEngineLock engineLock;
- try {
-
- PlCompound compound(expr.c_str());
-
- if (strlen(compound.name())) {
- PlCompound orig(expr.c_str());
-
- PlTermv termv(compound.arity());
- for (int i = 0; i < compound.arity(); i++) {
- termv[i] = compound[i + 1];
- }
- PlQuery query(compound.name(), termv);
-
- std::stringstream ss;
- std::string solSeparator = "";
- while (query.next_solution()) {
- ss << solSeparator;
- std::map<std::string, PlTerm> vars = resolveAtoms(compound, orig);
- std::map<std::string, PlTerm>::const_iterator varIter = vars.begin();
-
- std::string varSeparator = "";
- while(varIter != vars.end()) {
- ss << varSeparator << (char *)varIter->second;
- varSeparator = ", ";
- varIter++;
- }
- solSeparator = "\n";
- }
- return ss.str();
- }
- return std::string(compound);
-
- } catch(PlException plex) {
- // we got an exception while trying to evaluate as compound
- PlTerm term(expr.c_str());
- if (term.type() == PL_ATOM || term.type() == PL_CHARS || term.type() == PL_STRING) {
- return std::string(term);
- } else {
- ERROR_EXECUTION_THROW((char*)plex);
- }
- }
-}
-
-
-// this is similar to http://etalis.googlecode.com/svn/eEtalis/src/term.c
-std::map<std::string, PlTerm> SWIDataModel::resolveAtoms(PlTerm& term, PlTerm& orig) {
- try {
- std::map<std::string, PlTerm> atoms;
- switch (orig.type()) {
- case PL_VARIABLE: {
- atoms[(char *)orig] = term;
- break;
- }
- case PL_ATOM:
- break;
- case PL_STRING:
- break;
- case PL_INTEGER:
- break;
- case PL_TERM:
- for (int i = 1; i <= orig.arity(); i++) {
- PlTerm newTerm = term[i];
- PlTerm newOrig = orig[i];
- std::map<std::string, PlTerm> result = resolveAtoms(newTerm, newOrig);
- atoms.insert(result.begin(), result.end());
- }
- break;
- default:
- LOG(ERROR) << "Resolving variable of unknown type in query solution";
- }
- return atoms;
- }
- RETHROW_PLEX_AS_EVENT
-}
-
-void SWIDataModel::assign(const Element<std::string>& assignElem,
- const Node<std::string>& node,
- const std::string& content) {
- SWIEngineLock engineLock;
- try {
- std::string callAssert = "assert";
- std::string solution;
- std::string expr = content;
- std::string predicate;
- if (HAS_ATTR(assignElem, "solution"))
- solution = ATTR(assignElem, "solution");
- if (HAS_ATTR(assignElem, "expr"))
- expr = ATTR(assignElem, "expr");
- if (HAS_ATTR(assignElem, "id"))
- predicate = ATTR(assignElem, "id");
- if (HAS_ATTR(assignElem, "location"))
- predicate = ATTR(assignElem, "location");
-
- if (solution.size() > 0 && expr.size() > 0 && predicate.size() > 0) {
- // <assign location="var1" solution="Y" expr="var1(X), Y is X + 1, retractall(var1(_))"/>
- std::cout << expr + ", " + callAssert + "(" + predicate + "(" + solution + "))" << std::endl;
- PlCall((expr + ", " + callAssert + "(" + predicate + "(" + solution + "))").c_str());
- return;
- }
-
- if (expr.size() > 0 && predicate.size()) {
- Data json = Data::fromJSON(expr);
- if (!json.empty()) {
- std::cout << callAssert + "(" + predicate + ")" << std::endl;
- PlCall((callAssert + "(" + predicate + ")").c_str());
- // expression is a JSON structure!
- std::stringstream dataInitStr;
- // if (iequals(type, "retract"))
- // PlCall("retractall", PlCompound(predicate.c_str(), 1));
- dataInitStr << "json_to_prolog(" << expr << ", JSON), assert(" << predicate << "(JSON))";
- PlCall(dataInitStr.str().c_str());
- return;
- }
- }
-
- if (expr.size() > 0 && predicate.size()) {
- // treat content as . seperated facts
- std::stringstream factStream(expr);
- std::string item;
- while(std::getline(factStream, item, '.')) {
- std::string fact = boost::trim_copy(item);
- if (fact.length() == 0)
- continue;
- std::cout << callAssert + "(" + predicate + "(" + fact + "))" << std::endl;
- PlCall((callAssert + "(" + predicate + "(" + fact + "))").c_str());
- }
- return;
- }
-
- if (predicate.size() > 0) {
- std::cout << callAssert + "(" + predicate + ")" << std::endl;
- PlCall((callAssert + "(" + predicate + ")").c_str());
- return;
- }
-
- abort();
-
- if (expr.size() == 0) {
- // no expression, just assert id or idlocation
- std::cout << callAssert + "(" + predicate + ")" << std::endl;
- PlCall((callAssert + "(" + predicate + ")").c_str());
- return;
- }
-
-
- std::cout << expr + ", " + callAssert + "(" + predicate + ")" << std::endl;
- PlCall((expr + ", " + callAssert + "(" + predicate + ")").c_str());
-
-
- }
-#if 0
- try {
- std::string expr = content;
- std::string predicate;
- if (HAS_ATTR(assignElem, "expr")) {
- expr = ATTR(assignElem, "expr");
- }
- if (HAS_ATTR(assignElem, "id"))
- predicate = ATTR(assignElem, "id");
- if (HAS_ATTR(assignElem, "location"))
- predicate = ATTR(assignElem, "location");
-
- if (predicate.size() > 0) {
- std::string callAssert = "assert";
- std::string type;
- if (HAS_ATTR(assignElem, "type")) {
- type = ATTR(assignElem, "type");
- if(iequals(type, "append")) {
- callAssert = "assertz";
- } else if(iequals(type, "prepend")) {
- callAssert = "asserta";
- }
- }
-
- URL domUrl;
- Data json;
- if (!node)
- json = Data::fromJSON(expr);
- if (node) {
- std::stringstream dataInitStr;
- std::stringstream xmlDoc;
- Node<std::string> child = node;
- while(child) {
- xmlDoc << child;
- child = child.getNextSibling();
- }
- domUrl = URL::toLocalFile(xmlDoc.str(), ".pl");
- if (iequals(type, "retract"))
- PlCall("retractall", PlCompound(predicate.c_str(), 1));
- dataInitStr << "load_xml_file('" << domUrl.asLocalFile(".pl") << "', XML), copy_term(XML,DATA), " << callAssert << "(" << predicate << "(DATA))";
- PlCall(dataInitStr.str().c_str());
- } else if (!json.empty()) {
- std::stringstream dataInitStr;
- if (iequals(type, "retract"))
- PlCall("retractall", PlCompound(predicate.c_str(), 1));
- dataInitStr << "json_to_prolog(" << expr << ", JSON), assert(" << predicate << "(JSON))";
- PlCall(dataInitStr.str().c_str());
- } else {
- // treat content as . seperated facts
- std::stringstream factStream(content);
- std::string item;
- while(std::getline(factStream, item, '.')) {
- std::string fact = boost::trim_copy(item);
- if (fact.length() == 0)
- continue;
- PlCall((callAssert + "(" + predicate + "(" + fact + "))").c_str());
- }
- }
- } else if (expr.length() > 0) {
- if (boost::equals(TAGNAME(assignElem), "data")) {
- eval(assignElem, expr);
- } else {
- std::stringstream exprStream(expr);
- std::string item;
- while(std::getline(exprStream, item, '.')) {
- std::string plExpr = boost::trim_copy(item);
- if (plExpr.length() == 0)
- continue;
- PlCall(plExpr.c_str());
- }
- }
- }
- }
-#endif
- RETHROW_PLEX_AS_EVENT
-}
-
-void SWIDataModel::assign(const std::string& location, const Data& data) {
- eval(Element<std::string>(), data.atom);
-}
-
-void SWIDataModel::init(const Element<std::string>& dataElem,
- const Node<std::string>& node,
- const std::string& content) {
- assign(dataElem, node, content);
-}
-void SWIDataModel::init(const std::string& location, const Data& data) {
- assign(location, data);
-}
-
-bool SWIDataModel::isDeclared(const std::string& expr) {
- return true;
-}
-
-void SWIDataModel::acquireBlob(atom_t symbol) {
-}
-
-
-int SWIDataModel::releaseBlob(atom_t symbol) {
- return TRUE;
-}
-
-int SWIDataModel::compareBlob(atom_t a, atom_t b) {
- return 0;
-}
-
-int SWIDataModel::writeBlob(void *s, atom_t symbol, int flags) {
- return TRUE;
-}
-
-
-}