Soufflé Documentation
repository·master·Indexed 22 days ago
https://github.com/souffle-lang/souffleA high-performance Datalog-like language designed for program analysis and domain-specific logic problems. Soufflé translates Datalog programs into efficient, parallel C++ code and provides tools such as souffle-compile for building generated files, souffle-config for dependency identification, and souffle-profile for performance analysis. It supports extended Datalog semantics, including unbounded recursions and recursively defined record types (ADTs).
What's inside Soufflé
- Soufflé is a language project similar to Datalog that is frequently used as a domain-specific language for analysis problems. It features extended semantics of Datalog, such as permitting unbounded recursions with numbers and terms, and uses recursively defined record types (ADTs/constructors) for tuples. It provides efficient translation to parallel C++ and efficient interpretation using de-specialization techniques.
Use legacy mode for older Soufflé code
masterIf you are running code written for an older version of Soufflé, you can enable legacy compatibility using either a command line flag or a source code pragma.
.pragma "legacy"Install Soufflé
masterYou can obtain Soufflé in two ways:
- Packaged Versions: For Ubuntu, Fedora, or Oracle Linux, download a pre-built version from the Releases section.
- Source Code: Clone the repository using git.
For detailed build instructions, refer to the official build guide.
$ git clone https://github.com/souffle-lang/souffle.gitRepresent a Datalog clause using the Clause class
masterIn the Soufflé AST, a
Clauserepresents a horn clause. It can take two forms:- A Fact: A clause with only a head (e.g.,
X(a, b)). - A Rule: A clause with a head and a body (e.g.,
Y(a, b) :- X(a, b)).
You can construct a clause using various constructors depending on whether you are defining a fact, a rule, or a named clause. You can manipulate the body of the clause by adding literals or setting the entire collection of body literals.
// Example conceptual usage for a rule: Head :- Body1, Body2 // Note: This requires existing Atom and Literal objects souffle::ast::Clause rule( std::move(headAtom), std::move(bodyLiterals), std::move(executionPlan) );- A Fact: A clause with only a head (e.g.,
Define user-defined functors in Soufflé
masterIn Soufflé, you can declare custom functors to extend the language's capabilities. A functor declaration specifies a name, a list of parameter attributes, a return type attribute, and whether the functor is stateful.
Example syntax in Soufflé code:
.functor foo(x:number, y:number):numberImplement LLVM-style RTTI for AST nodes
masterThe
souffle::ast::Nodeclass uses an LLVM-style Run-Time Type Information (RTTI) system. To integrate a new class into the AST hierarchy, you must:- Add the class to the
NodeKindenum withinNode. - Implement
static bool classof(const Node*)for your class. - If the class is
final, provide a single enum entry. If it is non-final, provide a range of enums (e.g.,NK_T,NK_Child1, ...,NK_LastT) to represent its subtypes.
This allows for safe downcasting and type checking within the Soufflé compiler infrastructure.
- Add the class to the
Use the souffle CLI to compile and execute Datalog programs
masterThe
soufflecommand translates declarative Datalog programs into high-performance C++ code. To compile and execute a program in one step, use the-cor--compileflag. You can also specify input fact directories and output destinations.Common workflow patterns:
- Compile and run: Use
-cto execute the program. - Direct output: Use
-D-to write output relations tostdout. - Parallel execution: Use
-j <N>to run the compiler/interpreter usingNthreads (useN=autofor system default).
souffle -c program.dl -Ffacts -D- -j20- Compile and run: Use
Use souffle-profile to analyze Datalog program performance
masterThe
souffle-profiletool interactively displays performance profile information for Soufflé programs. It provides three types of views: relation-based, rule-based, and a graphical visualization.Prerequisite: To use this tool, your Soufflé programs must be compiled with the
-poption to generate the necessary profile information files.Generate C++ source code or executable programs from Datalog
masterIf you want to inspect or use the generated code rather than just running the program, use the following flags:
- Generate C++ source: Use
-g <FILE>or--generate=<FILE>to write the C++ source code produced from a Datalog file. - Generate executable: Use
-o <FILE>or--dl-program=<FILE>to write the executable program to a file without executing it.
souffle -g output.cpp program.dl- Generate C++ source: Use
Generate a GUI version of the profiler
masterTo convert your profiling log into an interactive HTML/JS GUI, use the
-jflag. You can optionally specify a custom output filename.Examples
Generate with default filename:
souffle-profile my_log.log -jGenerate with a specific filename:
souffle-profile my_log.log -j my_custom_report.htmlsouffle-profile my_log.log -j my_custom_report.htmlRun souffle-profile examples
masterCommon ways to invoke the profiler include checking the version, viewing help, or passing a log file for analysis.
souffle-profile -v souffle-profile -h souffle-profile <log-file> souffle-profile -c "help" <log-file>Filter clause body literals with getBodyLiterals()
masterThe
getBodyLiteralstemplate allows you to extract literals of a specific type from a clause's body. It iterates through the body and usesas<T>to perform dynamic casting, returning a vector of pointers to the matching literals.template <typename T, typename C> std::vector<T*> getBodyLiterals(const C& clause);