summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-16 00:31:12 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-01-16 00:31:12 (GMT)
commit57b7b1cb196ea9f51aebaba1a838b9a86a9f83fe (patch)
treed2ae2a83f1357b66c9712b741a2ad048444caa06
parent1088a76a715ef8a2728ad3fa8cde02bde4eec760 (diff)
downloaduscxml-57b7b1cb196ea9f51aebaba1a838b9a86a9f83fe.zip
uscxml-57b7b1cb196ea9f51aebaba1a838b9a86a9f83fe.tar.gz
uscxml-57b7b1cb196ea9f51aebaba1a838b9a86a9f83fe.tar.bz2
More work on Prolog datamodel
-rw-r--r--config.h.in1
-rw-r--r--contrib/cmake/FindSWI.cmake6
-rw-r--r--src/uscxml/Factory.h1
-rw-r--r--src/uscxml/Interpreter.cpp11
-rw-r--r--src/uscxml/Interpreter.h1
-rw-r--r--src/uscxml/URL.cpp68
-rw-r--r--src/uscxml/URL.h9
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp59
-rw-r--r--test/samples/uscxml/test-prolog.scxml26
-rw-r--r--test/src/test-prolog-swi.cpp49
-rw-r--r--test/src/test-url.cpp6
11 files changed, 181 insertions, 56 deletions
diff --git a/config.h.in b/config.h.in
index 333b8a0..1bef782 100644
--- a/config.h.in
+++ b/config.h.in
@@ -48,6 +48,7 @@
/** miscellaneous */
#cmakedefine PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@"
#cmakedefine DIST_PREPARE
+#cmakedefine SWI_BINARY "@SWI_BINARY@"
/** Optional libraries we found */
#cmakedefine UMUNDO_FOUND
diff --git a/contrib/cmake/FindSWI.cmake b/contrib/cmake/FindSWI.cmake
index 4c71ecd..fb30be4 100644
--- a/contrib/cmake/FindSWI.cmake
+++ b/contrib/cmake/FindSWI.cmake
@@ -63,10 +63,10 @@ if (SWI_PLATFORM_PATH OR SWI_INCLUDE_HINT)
PATHS ${SWI_PLATFORM_PATH}
HINTS ${SWI_LIBRARY_HINT}
)
-
+
if (SWI_LIBRARY_RELEASE)
list(APPEND SWI_LIBRARY optimized ${SWI_LIBRARY_RELEASE})
- add_definitions("-DSWI_LIBRARY_PATH=\"${SWI_PLATFORM_PATH}\"")
+ set(SWI_BINARY ${SWI_PLATFORM_PATH})
endif()
@@ -84,5 +84,5 @@ if (SWI_PLATFORM_PATH OR SWI_INCLUDE_HINT)
endif()
INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWI DEFAULT_MSG SWI_LIBRARY SWI_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWI DEFAULT_MSG SWI_LIBRARY SWI_INCLUDE_DIR SWI_BINARY)
MARK_AS_ADVANCED(SWI_LIBRARY SWI_INCLUDE_DIR)
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index 29f7f9a..3cc8018 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -159,6 +159,7 @@ public:
virtual void eval(const std::string& expr) { return _impl->eval(expr); }
virtual std::string evalAsString(const std::string& expr) { return _impl->evalAsString(expr); }
virtual bool evalAsBool(const std::string& expr) { return _impl->evalAsBool(expr); }
+
virtual void assign(const std::string& location, const std::string& expr) { return _impl->assign(location, expr); }
virtual void assign(const std::string& location, const Data& data) { return _impl->assign(location, data); }
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 5449272..9063cef 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -33,6 +33,7 @@ Interpreter::Interpreter() : Arabica::SAX2DOM::Parser<std::string>() {
_thread = NULL;
_sendQueue = NULL;
_running = false;
+ _done = false;
#ifdef _WIN32
WSADATA wsaData;
@@ -172,6 +173,7 @@ Interpreter::~Interpreter() {
}
void Interpreter::start() {
+ _done = false;
_thread = new tthread::thread(Interpreter::run, this);
}
@@ -180,10 +182,12 @@ void Interpreter::run(void* instance) {
}
bool Interpreter::runOnMainThread(int fps, bool blocking) {
+ if (_done)
+ return false;
+
if (fps > 0) {
uint64_t nextRun = _lastRunOnMainThread + (1000 / fps);
if (blocking) {
- tthread::lock_guard<tthread::mutex> lock(_mutex);
while(nextRun > tthread::timeStamp()) {
tthread::this_thread::sleep_for(tthread::chrono::milliseconds(nextRun - tthread::timeStamp()));
}
@@ -194,6 +198,7 @@ bool Interpreter::runOnMainThread(int fps, bool blocking) {
_lastRunOnMainThread = tthread::timeStamp();
+ tthread::lock_guard<tthread::mutex> lock(_mutex);
std::map<std::string, IOProcessor>::iterator ioProcessorIter = _ioProcessors.begin();
while(ioProcessorIter != _ioProcessors.end()) {
ioProcessorIter->second.runOnMainThread();
@@ -1411,8 +1416,10 @@ void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enable
}
for (int i = 0; i < _configuration.size(); i++) {
Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)_configuration[i];
- if (isFinal(stateElem) && parentIsScxmlState(stateElem))
+ if (isFinal(stateElem) && parentIsScxmlState(stateElem)) {
_running = false;
+ _done = true;
+ }
}
}
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index ab8cf6d..d5c719b 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -171,6 +171,7 @@ protected:
std::string _nsPrefix;
bool _running;
+ bool _done;
Binding _binding;
Arabica::XPath::NodeSet<std::string> _configuration;
Arabica::XPath::NodeSet<std::string> _statesToInvoke;
diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp
index ca3e8f7..db128ef 100644
--- a/src/uscxml/URL.cpp
+++ b/src/uscxml/URL.cpp
@@ -52,26 +52,13 @@ const bool URLImpl::toAbsoluteCwd() {
return toAbsolute(std::string("file://" + std::string(currPath) + "/"));
}
-const bool URLImpl::toAbsolute(const std::string& baseUrl) {
- if (_uri.is_absolute())
- return true;
- _uri = Arabica::io::URI(baseUrl, _uri.as_string());
- if (!_uri.is_absolute())
- return false;
- return true;
-}
-
-const std::string URLImpl::asLocalFile(const std::string& suffix, bool reload) {
- // this is already a local file
- if (_uri.scheme().compare("file") == 0)
- return _uri.path();
-
- if (_localFile.length() > 0 && !reload)
- return _localFile;
-
+std::string URLImpl::getLocalFilename(const std::string& suffix) {
if (_localFile.length() > 0)
- remove(_localFile.c_str());
+ return _localFile;
+ if (_uri.scheme().compare("file") == 0)
+ return _uri.path();
+
// try hard to find a temporary directory
const char* tmpDir = NULL;
if (tmpDir == NULL)
@@ -106,10 +93,49 @@ const std::string URLImpl::asLocalFile(const std::string& suffix, bool reload) {
_close(fd);
#else
close(fd);
-#endif
- _localFile = std::string(tmpl);
+#endif
+ return std::string(tmpl);
+}
- std::ofstream file(tmpl, std::ios_base::out);
+boost::shared_ptr<URLImpl> URLImpl::toLocalFile(const std::string& content, const std::string& suffix) {
+ boost::shared_ptr<URLImpl> urlImpl = boost::shared_ptr<URLImpl>(new URLImpl());
+ urlImpl->_localFile = urlImpl->getLocalFilename(suffix);
+ urlImpl->_uri = std::string("file://") + urlImpl->_localFile;
+
+ std::ofstream file(urlImpl->_localFile.c_str(), std::ios_base::out);
+ if(file.is_open()) {
+ file << content;
+ file.close();
+ } else {
+ return boost::shared_ptr<URLImpl>();
+ }
+
+ return urlImpl;
+}
+
+const bool URLImpl::toAbsolute(const std::string& baseUrl) {
+ if (_uri.is_absolute())
+ return true;
+ _uri = Arabica::io::URI(baseUrl, _uri.as_string());
+ if (!_uri.is_absolute())
+ return false;
+ return true;
+}
+
+const std::string URLImpl::asLocalFile(const std::string& suffix, bool reload) {
+ // this is already a local file
+ if (_uri.scheme().compare("file") == 0)
+ return _uri.path();
+
+ if (_localFile.length() > 0 && !reload)
+ return _localFile;
+
+ if (_localFile.length() > 0)
+ remove(_localFile.c_str());
+
+ _localFile = getLocalFilename(suffix);
+
+ std::ofstream file(_localFile.c_str(), std::ios_base::out);
if(file.is_open()) {
file << URL(this->shared_from_this());
file.close();
diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h
index 07921f3..5bcbd27 100644
--- a/src/uscxml/URL.h
+++ b/src/uscxml/URL.h
@@ -22,6 +22,8 @@ public:
const bool toAbsolute(const std::string& baseUrl);
const std::string asLocalFile(const std::string& suffix, bool reload = false);
+ static boost::shared_ptr<URLImpl> toLocalFile(const std::string& content, const std::string& suffix);
+
const bool isAbsolute() const { return _uri.is_absolute(); }
const std::string scheme() const { return _uri.scheme(); }
const std::string host() const { return _uri.host(); }
@@ -30,6 +32,8 @@ public:
const std::string asString() const { return _uri.as_string(); }
private:
+ std::string getLocalFilename(const std::string& suffix);
+
Arabica::io::URI _uri;
std::string _localFile;
};
@@ -41,6 +45,11 @@ public:
URL(boost::shared_ptr<URLImpl> const impl) : _impl(impl) { }
URL(const URL& other) : _impl(other._impl) { }
virtual ~URL() {};
+
+ static URL toLocalFile(const std::string& content, const std::string& suffix) {
+ boost::shared_ptr<URLImpl> impl = URLImpl::toLocalFile(content, suffix);
+ return URL(impl);
+ }
operator bool() const { return _impl;}
bool operator< (const URL& other) const { return _impl < other._impl; }
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
index e753a32..ffb48f9 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
@@ -1,4 +1,5 @@
#include "uscxml/Common.h"
+#include "uscxml/config.h"
#include "SWIDataModel.h"
#include "uscxml/Message.h"
#include <glog/logging.h>
@@ -23,8 +24,24 @@ SWIDataModel::SWIDataModel() {
boost::shared_ptr<DataModelImpl> SWIDataModel::create(Interpreter* interpreter) {
boost::shared_ptr<SWIDataModel> dm = boost::shared_ptr<SWIDataModel>(new SWIDataModel());
dm->_interpreter = interpreter;
- const char* swiPath = "/foo";
- dm->_plEngine = new PlEngine((char*)swiPath);
+
+ const char* swibin = getenv("SWI_BINARY");
+ if (swibin == NULL)
+ swibin = SWI_BINARY;
+ const char* quiet = "--quiet";
+
+ static char * av[] = {
+ (char*)swibin,
+ (char*)quiet,
+ // "-s",
+ // "/Users/sradomski/Documents/TK/Code/pl-devel/demo/likes.pl",
+ NULL};
+ if(!PL_initialise(2,av)) {
+ LOG(ERROR) << "Error intializing prolog engine";
+ PL_halt(1);
+ return boost::shared_ptr<DataModelImpl>();
+ }
+
return dm;
}
@@ -79,25 +96,49 @@ uint32_t SWIDataModel::getLength(const std::string& expr) {
}
void SWIDataModel::eval(const std::string& expr) {
- std::cout << "SWIDataModel::eval" << std::endl;
+ URL localPLFile = URL::toLocalFile(expr, ".pl");
+ PlCall("user", "load_files", PlTermv(localPLFile.asLocalFile(".pl").c_str())) || LOG(ERROR) << "Could not execute prolog from file";
}
bool SWIDataModel::evalAsBool(const std::string& expr) {
- std::cout << "SWIDataModel::evalAsBool" << std::endl;
- return true;
+ 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;
}
std::string SWIDataModel::evalAsString(const std::string& expr) {
- std::cout << "SWIDataModel::evalAsString" << std::endl;
- return std::string("");
+ PlCompound compound(expr.c_str());
+ if (strlen(compound.name())) {
+ 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;
+ while (query.next_solution()) {
+ for (int i = 0; i < compound.arity(); i++) {
+ const char* separator = "";
+ ss << separator << (char *)termv[i];
+ separator = ", ";
+ }
+ ss << std::endl;
+ }
+ return ss.str();
+ }
+ return std::string(compound);
}
void SWIDataModel::assign(const std::string& location, const Data& data) {
- std::cout << "SWIDataModel::assign" << std::endl;
+ eval(data.atom);
}
void SWIDataModel::assign(const std::string& location, const std::string& expr) {
- std::cout << "SWIDataModel::assign" << std::endl;
+ eval(expr);
}
} \ No newline at end of file
diff --git a/test/samples/uscxml/test-prolog.scxml b/test/samples/uscxml/test-prolog.scxml
index 85d45bc..266bd8d 100644
--- a/test/samples/uscxml/test-prolog.scxml
+++ b/test/samples/uscxml/test-prolog.scxml
@@ -1,20 +1,22 @@
<scxml datamodel="prolog" initial="start" binding="late">
<datamodel>
- <!-- data id="facts">
- cat(tom).
- animal(X):- cat(X).
- </data -->
- <data id="likes" src="prolog/likes.pl" />
+ <data id="facts">
+% see http://www.swi-prolog.org/FAQ/Multifile.html
+:- multifile animal/1.
+cat(tom).
+animal(X):- cat(X).
+ </data>
</datamodel>
- <!-- script>
- cat(tom).
- cat(X).
- animal(X).
- </script -->
<script>
- likes(sam,curry).
- likes(sam,chips).
+mouse(jerry).
+animal(X):- mouse(X).
</script>
<state id="start">
+ <transition target="end" cond="not(cat(jerry)), cat(tom), mouse(jerry)." />
+ </state>
+ <state id="end" final="true">
+ <onentry>
+ <log expr="animal(X)." />
+ </onentry>
</state>
</scxml> \ No newline at end of file
diff --git a/test/src/test-prolog-swi.cpp b/test/src/test-prolog-swi.cpp
index 5fa1cb4..afe0754 100644
--- a/test/src/test-prolog-swi.cpp
+++ b/test/src/test-prolog-swi.cpp
@@ -1,13 +1,17 @@
#include <iostream>
#include <SWI-Prolog.h>
#include <SWI-cpp.h>
+#include "uscxml/config.h"
using namespace std;
int main(void){
+ const char* swibin = getenv("SWI_BINARY");
+ if (swibin == NULL)
+ swibin = SWI_BINARY;
static char * av[] = {
- "/Users/sradomski/Documents/TK/Code/uscxml/contrib/prebuilt/darwin-i386/clang/lib/swipl-6.3.5/bin/x86_64-darwin12.2.0/swipl",
+ (char*)swibin,
// "--quiet",
// "-s",
// "/Users/sradomski/Documents/TK/Code/pl-devel/demo/likes.pl",
@@ -23,17 +27,44 @@ int main(void){
int rval;
PlFrame frame;
- rval = PlCall("system", "load_files", PlTermv("/Users/sradomski/Documents/TK/Code/pl-devel/demo/likes.pl"));
- PlQuery query("user", "likes", PlTermv("sam", "chips"));
- if (query.next_solution() > 0) {
- std::cout << "Yes!" << std::endl;
- } else {
- std::cout << "No!" << std::endl;
+ rval = PlCall("user", "load_files", PlTermv("/Users/sradomski/Documents/TK/Code/pl-devel/demo/likes.pl"));
+
+// PlCompound compound("likes(sam, X)");
+ PlCompound compound("listing");
+ PlTermv termv(compound.arity());
+// termv[0] = PlTerm();
+ for (int i = 0; i < compound.arity(); i++) {
+ termv[i] = compound[i + 1];
+ }
+
+ PlQuery q(compound.name(), termv);
+ bool solutionExists = false;
+ while( q.next_solution() ) {
+ solutionExists = true;
+ for (int i = 0; i < compound.arity(); i++) {
+ switch (compound[i + 1].type()) {
+ case PL_VARIABLE:
+ std::cout << (char *)termv[i] << ", ";
+ break;
+ case PL_FLOAT:
+ std::cout << (double)termv[i] << ", ";
+ break;
+ case PL_ATOM:
+ std::cout << (PlAtom)termv[i] << ", ";
+ break;
+ case PL_STRING:
+ std::cout << (char *)termv[i] << ", ";
+ break;
+ case PL_TERM:
+ std::cout << (char *)termv[i] << ", ";
+ break;
+ default: ;
+ }
+ }
+ std::cout << std::endl;
}
- PlQuery q("call", PlTermv(PlCompound("likes(sam,curry)."))
-// PlCompound compound("likes(sam,curry).");
// PlQuery query2(compound.name(), PlTermv(compound));
// if (query2.next_solution() > 0) {
// std::cout << "Yes!" << std::endl;
diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp
index 239ff3c..a9a6594 100644
--- a/test/src/test-url.cpp
+++ b/test/src/test-url.cpp
@@ -40,4 +40,10 @@ int main(int argc, char** argv) {
assert(iequals(url.scheme(), "file"));
std::cout << url.asString() << std::endl;
}
+ {
+ URL url = URL::toLocalFile("this is quite some content!", "txt");
+ std::cout << url.asLocalFile("txt");
+ assert(url.isAbsolute());
+ assert(iequals(url.scheme(), "file"));
+ }
} \ No newline at end of file