-
Notifications
You must be signed in to change notification settings - Fork 208
Cxx Interface
Applications may want to integrate Soufflé programs as a library rather than as a stand-alone tool. For this purpose, we have developed a C++ interface to call Soufflé programs.
With the option -g <name>.cpp
a C++ class is generated for a Soufflé program that can be directly embedded in another C++ application.
The generated class may have several instances.
An instance provides interfaces to populate input relations,
to run the program,
and to retrieve data from the output relations.
Note that the generated class is required to be compiled with the flag __EMBEDDED_SOUFFLE__
to disable the default main()
function of a Soufflé program.
After a Souffle program has been written and stored in a datalog file, a c++ file can be generated for this Souffle program with the option -g <name>.cpp
in the command line. After this, an instance of the c++ class of this Soufflé program can be generated by executing the following code:
#include "souffle/SouffleInterface.h"
if(souffle::SouffleProgram *prog=souffle::ProgramFactory::newInstance("<name>")) {
/* populate input relations */
/* run a program */
/* retrieve data from output relations */
/* other functionalities*/
delete prog;
} else {
std::cerr << "Failed to create instance for program <name>\n";
exit(1);
}
"" is the name of a Souffle programs. If an instance is created sucessfully, a pointer to the instance of the SouffleProgram class is returned and stored in the variable prog.
The functions provided in the interface can be found in SouffleInterface.h file. In this file, there are four classes, tuple, relation, SouffleProgram, and ProgramFactory each with functions that can be called. As mentioned before, variable prog is a pointer to an instance of SouffleProgram. The functions prog can call are the public functions defined in the SouffleProgram class in SouffleInterface.h file. The functions are called by "prog->".
There are two ways to populate input relations.
The first way is through loading data from CSV files and then inserting them to the relations by using loadAll() function. This functionality is executed by invoking the code
prog->loadAll("<dir>");
The directory <dir>
represents the input directory where the input files of the relations are located.
The second way is through creating the tuples objects, adding data to them, and then using insert() function to insert the tuples objects into the relation.
if(souffle::Relation *rel = prog->getRelation("<rel-name>")) {
: get relation reference
souffle::tuple newTuple(rel);
: create tuple for the relation
Place integers/symbols into the relation using << operator.
The arity and the data type of the variables have to follow the relation "my-rel" correspondingly.
newTuple << "TestData" << 10;
rel->insert(newTuple);
: insert tuple into relation
}
A Soufflé program is executed invoking the run()
function, e.g..,
#include "souffle/SouffleInterface.h"
if(souffle::SouffleProgram *prog=souffle::ProgramFactory::newInstance("<name>")) {
prog->loadAll(".");
: load from current directory
prog->run();
: run catalog program
/* retrieve data from output relations */
delete prog;
} else {
std::cerr << "Failed to create instance for program <name>\n";
exit(1);
}
Output relations can be accessed via the container provided by the relation. The current tuple provides stream operators to write data into variables.
if(souffle::Relation *rel = prog->souffle::getRelation("<my-rel>")) {
for(auto &output : *rel ) {
output >> var1 >> var2;
}
}
Alternatively, the function prog->printAll()
writes the contents of the output relations to their defined destinations.
Check whether a tuple exists in relation by using the contains()
function.
if(souffle::Relation *rel = prog->souffle::getRelation("<my-rel>")) {
tuple test(rel);
: Create a tuple for further checking
test << "A" << 123;
if (rel->contains(test)) {
: Check if "my-rel" contain a tuple {"A", 123}
...
}
}
Alternatively, the function size()
indicates the number of tuples in a relation, the function getSignature()
returns
the attribute type of the relation.