### Install Souffle System-Wide Source: https://context7.com/souffle-lang/souffle/llms.txt Install Souffle system-wide after building by running the CMake install command with sudo privileges. ```bash sudo cmake --install build ``` -------------------------------- ### Install Build Dependencies and Ruby Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs essential build tools like `redhat-lsb` and `rpm-build`, and Ruby for the `package_cloud` CLI. This is a common setup for RPM-based systems. ```docker RUN yum -y install redhat-lsb rpm-build # Install ruby as it is a dependency for the package_cloud CLI tool RUN yum -y install ruby ruby-devel # Install package cloud CLI tool RUN sudo gem install package_cloud # Copy everything into souffle directory of container COPY . . ENV DOMAIN_SIZE "64bit" ENV PKG_EXTENSION ".rpm" ENV PKG_CLOUD_OS_NAME "oraclelinux/8" ENTRYPOINT [".github/actions/create-package/entrypoint.sh"] ``` -------------------------------- ### Install PackageCloud Repository Script (Debian/Ubuntu) Source: https://github.com/souffle-lang/souffle/wiki/Packaging This command downloads and executes a script to set up the Soufflé PackageCloud repository on Debian-based systems. It's used for both general installation and specific OS examples. ```bash curl -s https://packagecloud.io/install/repositories/souffle-lang/souffle-test/script.deb.sh | sudo bash ``` ```bash curl -s https://packagecloud.io/install/repositories/souffle-lang/souffle/script.deb.sh | sudo bash ``` -------------------------------- ### Instantiate Test Libraries Source: https://github.com/souffle-lang/souffle/blob/master/tests/semantic/pragma2/CMakeLists.txt Calls the setup function to create two distinct test libraries, 'lib_foo' and 'lib_bar', with specific shared object names. ```cmake souffle_test_semantic_pragma2_setup(lib_foo "never gonna") souffle_test_semantic_pragma2_setup(lib_bar "let you") ``` -------------------------------- ### Run Docker Container for Oracle Linux Source: https://github.com/souffle-lang/souffle/wiki/Packaging Command to start an interactive Docker container running Oracle Linux 8, used for environment setup and verification. ```bash docker container run -it oraclelinux:8 /bin/bash ``` -------------------------------- ### Install Ruby for Debian-based Systems Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs the `ruby-full` package on Debian-based systems, which is sufficient for the `package_cloud` CLI to install successfully without needing separate development headers. ```docker RUN apt-get -y install ruby-full ``` -------------------------------- ### Install Ruby Development Environment for PackageCloud Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs `ruby` and `ruby-devel` on Fedora-like systems to resolve header file issues when installing the `package_cloud` CLI. This ensures the `gem install package_cloud` command succeeds. ```docker RUN yum -y install ruby ruby-devel RUN sudo gem install package_cloud ``` -------------------------------- ### Install Build Dependencies Source: https://github.com/souffle-lang/souffle/wiki/Code-Coverage Installs the necessary dependencies required to build the Souffle project on an Ubuntu environment. ```yaml - name: install-deps run: sudo sh/setup/install_ubuntu_deps.sh ``` -------------------------------- ### Launch Interactive Provenance Shell Source: https://context7.com/souffle-lang/souffle/llms.txt Start an interactive shell for querying proof trees of derived facts. Use the `explain` command within the shell to investigate specific tuples. ```bash souffle -t explain analysis.dl ``` ```bash # Inside the shell: # > explain path("A", "D") # Returns a proof tree showing which rules and base facts led to path("A","D") ``` -------------------------------- ### Push Package to PackageCloud Source: https://github.com/souffle-lang/souffle/wiki/Packaging Example of how to push a Soufflé package to a specific repository and OS version on PackageCloud. Replace `` with your actual token. ```bash PACKAGECLOUD_TOKEN= package_cloud push souffle-lang/souffle-test random-package.deb ``` -------------------------------- ### Install Souffle Build Dependencies Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs essential build tools and libraries for Souffle on Ubuntu. This command should be updated if new dependencies are introduced. ```docker # Install souffle build dependencies RUN apt-get update && \ apt-get -y install \ bash-completion \ sudo \ autoconf \ automake \ bison \ build-essential \ clang \ doxygen \ flex \ g++ \ git \ libffi-dev \ libncurses5-dev \ libtool \ libsqlite3-dev \ make \ mcpp \ python \ sqlite \ zlib1g-dev \ cmake ``` ```docker # For CMakeLists.txt to figure out the specific version of Ubuntu RUN apt-get -y install lsb-release ``` -------------------------------- ### Get testsuite Help Source: https://github.com/souffle-lang/souffle/wiki/Testing,-Continuous-Integration,-and-Deployment Display the help message for the testsuite script to understand available options and usage. ```bash souffle/tests/testsuite -h ``` -------------------------------- ### Basic C++ Embedding Example Source: https://context7.com/souffle-lang/souffle/llms.txt Demonstrates how to instantiate a compiled Souffle program, populate input relations, execute the program, and iterate over output relations. ```APIDOC ## C++ Embedding API (`SouffleInterface.h`) Souffle programs compiled with `-g` emit a self-contained C++ class. Applications link against it via `SouffleInterface.h`, using `ProgramFactory::newInstance`, `Relation::insert`, `SouffleProgram::run`, `Relation::contains`, and iteration over output relations. ```cpp // ---- analysis.dl (compiled with: souffle -g analysis.cpp analysis.dl) ---- // .type Node <: symbol // .decl edge(src: Node, dst: Node) // .input edge() // .decl path(src: Node, dst: Node) // .output path() // path(X, Y) :- edge(X, Y). // path(X, Z) :- path(X, Y), edge(Y, Z). // ---- host_app.cpp ---- // Compile: g++ -D__EMBEDDED_SOUFFLE__ -o host_app host_app.cpp analysis.cpp \ // -I$(souffle --show-include-dir) -fopenmp #include "souffle/SouffleInterface.h" #include #include #include int main() { // Instantiate the compiled Souffle program by name (matches .dl filename) souffle::SouffleProgram* prog = souffle::ProgramFactory::newInstance("analysis"); if (!prog) { std::cerr << "Error: could not create program instance\n"; return 1; } // Populate input relation "edge" programmatically souffle::Relation* edge = prog->getRelation("edge"); if (!edge) { std::cerr << "Error: relation 'edge' not found\n"; return 1; } std::vector> edges = { {"A", "B"}, {"B", "C"}, {"C", "D"}, {"D", "E"} }; for (auto& e : edges) { souffle::tuple t(edge); t << e[0] << e[1]; edge->insert(t); } // Check existence before inserting souffle::tuple check(edge); check << "A" << "B"; if (edge->contains(check)) { std::cout << "Edge A->B already present\n"; } // Execute the Datalog program (computes fixpoint) prog->run(); // Iterate over output relation "path" souffle::Relation* path = prog->getRelation("path"); if (!path) { std::cerr << "Error: relation 'path' not found\n"; return 1; } std::cout << "Reachable paths (" << path->size() << " total):\n"; for (auto& tuple : *path) { std::string src, dst; tuple >> src >> dst; std::cout << " " << src << " -> " << dst << "\n"; } // Expected output: // Reachable paths (6 total): // A -> B // A -> C // A -> D // B -> C // B -> D (etc.) // Write all output relations to CSV files in the current directory prog->printAll("./output/"); // Introspect relation metadata std::cout << "Relation signature: " << path->getSignature() << "\n"; // Expected: std::cout << "Arity: " << path->getArity() << "\n"; delete prog; return 0; } ``` ``` -------------------------------- ### Install Package Cloud CLI Dependencies Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs Ruby and the package_cloud CLI tool. Ensure Ruby is available if you need to use package_cloud. ```docker RUN apt-get -y install ruby-full RUN sudo gem install package_cloud ``` -------------------------------- ### Install Latest Soufflé Version (Ubuntu) Source: https://github.com/souffle-lang/souffle/wiki/Packaging Use this command with apt-get to install the latest available version of the Soufflé package from the configured PackageCloud repository. ```bash sudo apt-get install souffle ``` -------------------------------- ### Install Ruby and PackageCloud CLI in Dockerfile Source: https://github.com/souffle-lang/souffle/wiki/Packaging Installs Ruby and the PackageCloud CLI tool. Ensure Ruby version 2.x is used to avoid compatibility issues with the PackageCloud CLI. ```docker RUN yum -y install ruby ruby-devel RUN sudo gem install package_cloud ``` -------------------------------- ### Install Specific Soufflé Version (Ubuntu) Source: https://github.com/souffle-lang/souffle/wiki/Packaging Use this command with apt-get to install a specific version of the Soufflé package from the configured PackageCloud repository. ```bash sudo apt-get install souffle=2.0.2 ``` -------------------------------- ### Clone Soufflé Repository Source: https://github.com/souffle-lang/souffle/blob/master/README.md Use git to obtain the source code of Soufflé. This is the initial step to get the project files. ```bash git clone https://github.com/souffle-lang/souffle.git ``` -------------------------------- ### Install redhat-lsb Package Source: https://github.com/souffle-lang/souffle/wiki/Packaging Command to install the redhat-lsb package within an Oracle Linux Docker container, which provides the lsb_release command. ```bash yum -y install redhat-lsb ``` -------------------------------- ### Install lcov for Coverage Reporting Source: https://github.com/souffle-lang/souffle/wiki/Code-Coverage Installs the 'lcov' utility on the Ubuntu runner. 'lcov' is used to generate and manipulate code coverage data. ```yaml - name: install-lcov run: sudo apt-get update && sudo apt-get install lcov ``` -------------------------------- ### Set Architecture for Package Building Source: https://github.com/souffle-lang/souffle/wiki/Packaging Configures the build architecture using the DOMAIN_SIZE environment variable. This example shows setting it to '64bit'. ```docker ENV DOMAIN_SIZE "64bit" ``` -------------------------------- ### Dockerfile for Souffle Packaging Source: https://github.com/souffle-lang/souffle/wiki/Packaging This Dockerfile sets up an Ubuntu 21.04 environment to build and package Souffle. It installs build dependencies, CMake, and the packagecloud CLI. ```dockerfile FROM ubuntu:21.04 ARG DEBIAN_FRONTEND=noninteractive # Create a souffle directory WORKDIR /souffle # Install souffle build dependencies RUN apt-get update && \ apt-get -y install \ bash-completion \ sudo \ autoconf \ automake \ bison \ build-essential \ clang \ doxygen \ flex \ g++ \ git \ libffi-dev \ libncurses5-dev \ libtool \ libsqlite3-dev \ make \ mcpp \ python \ sqlite \ zlib1g-dev \ cmake # For CMakeLists.txt to figure out the specific version of Ubuntu RUN apt-get -y install lsb-release # Install dependencies for packagecloud CLI RUN apt-get -y install ruby-full RUN sudo gem install package_cloud ``` -------------------------------- ### Upload Package to PackageCloud Repository Source: https://github.com/souffle-lang/souffle/wiki/Packaging Uploads a built package to a specified PackageCloud repository. The example shows uploading to the 'souffle-test' repository. ```bash # Upload the package to packagecloud.io PACKAGECLOUD_TOKEN="$PACKAGE_CLOUD_API_KEY" package_cloud push souffle-lang/souffle-test/$PKG_CLOUD_OS_NAME "$(ls *$PKG_EXTENSION | head -n1)" ``` -------------------------------- ### Dockerfile for Oracle Linux 8 64bit Environment Source: https://github.com/souffle-lang/souffle/wiki/Packaging Sets up the Docker environment for building Souffle packages on Oracle Linux 8 64-bit, including installing build dependencies. ```docker FROM oraclelinux:8 WORKDIR /souffle # Specify all the build-time dependencies for Oracle Linux to build Souffle RUN yum -y install \ bash-completion \ ... ``` -------------------------------- ### Configure Bash Completion Installation Source: https://github.com/souffle-lang/souffle/wiki/Packaging Configures CMake to find and install bash completion scripts. It checks for the bash-completion package and sets a fallback directory if not found. ```makefile find_package (bash-completion) if (BASH_COMPLETION_FOUND) message(STATUS "Using bash completion dir ${BASH_COMPLETION_COMPLETIONSDIR}") else() set (BASH_COMPLETION_COMPLETIONSDIR "/etc/bash_completion.d") message (STATUS "Using fallback bash completion dir ${BASH_COMPLETION_COMPLETIONSDIR}") endif() install( FILES "${CMAKE_SOURCE_DIR}/debian/souffle.bash-completion" DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR} RENAME "souffle" ) ``` -------------------------------- ### Souffle Strongly-Typed Type System Examples Source: https://context7.com/souffle-lang/souffle/llms.txt Demonstrates Souffle's type system including sub-types, record types, and algebraic data types (ADTs). ADTs can be used in rules and pattern matching. ```prolog // Sub-type aliases .type Name <: symbol .type Age <: number .type Salary <: float // Record type (product / tuple) .type Person = [name: Name, age: Age] // Algebraic Data Type (sum type / discriminated union) .type Shape = Circle { radius: float } | Rectangle { width: float, height: float } | Point {} // Enum-style ADT (all constructors take no arguments) .type Day = Mon {} | Tue {} | Wed {} | Thu {} | Fri {} | Sat {} | Sun {} // Using ADTs in rules .decl HasArea(s: Shape, area: float) HasArea($Circle(r), 3.14159 * r * r) :- r > 0. HasArea($Rectangle(w, h), w * h) :- w > 0, h > 0. // Pattern matching via ADT binary constraints .type Expr = Num { val: number } | Add { left: Expr, right: Expr } .decl IsLeaf(e: Expr) IsLeaf(e) :- e = $Num(_). // ADT binary constraints .decl R(x: Shape) R($Circle(1.0)) :- $Circle(1.0) != $Rectangle(1.0, 2.0). // true .output R, HasArea, IsLeaf ``` -------------------------------- ### Java Embedding with SWIG Source: https://context7.com/souffle-lang/souffle/llms.txt Example of how to embed a Souffle program in a Java application using SWIG-generated wrappers. Requires generating wrappers, compiling, and loading the native library. ```java // ---- Java embedding ---- // 1. Generate wrappers: souffle -s java analysis.dl // 2. Compile: javac -classpath . SwigInterface.java AnalysisDriver.java // 3. Run: java -Djava.library.path=. AnalysisDriver public class AnalysisDriver { public static void main(String[] args) { // Load the native library (Linux) System.loadLibrary("SwigInterface"); // macOS alternative: // System.load(System.getProperty("java.library.path") + "/libSwigInterface.so"); // Instantiate program by .dl filename (without extension) SWIGSouffleProgram prog = SwigInterface.newInstance("analysis"); if (prog == null) { System.err.println("Failed to load analysis program"); System.exit(1); } prog.loadAll("./facts"); // reads edge.facts etc. prog.run(); // compute fixpoint prog.printAll("./output"); // write output CSVs prog.finalize(); // release native resources System.out.println("Analysis complete. See ./output/ for results."); } } ``` -------------------------------- ### Python Embedding with SWIG Source: https://context7.com/souffle-lang/souffle/llms.txt Example of how to embed a Souffle program in a Python application using SWIG-generated wrappers. Requires generating wrappers and running the Python driver script. ```python # ---- Python embedding ---- # 1. Generate wrappers: souffle -s python analysis.dl # 2. Run: python3 analysis_driver.py import SwigInterface import sys # Instantiate the compiled Souffle program prog = SwigInterface.newInstance("analysis") if prog is None: print("Error: could not load program 'analysis'", file=sys.stderr) sys.exit(1) prog.loadAll("./facts") # load input relations from ./facts/ prog.run() # execute the Datalog analysis prog.printAll("./output") # write output relations to ./output/ print("Done. Results written to ./output/") ``` -------------------------------- ### Bash Script for Ubuntu Dependencies Source: https://github.com/souffle-lang/souffle/wiki/Packaging An alternative bash script for installing Souffle build dependencies. This script is provided for reference and was not used in the main Dockerfile to leverage Docker's build cache. ```bash #!/bin/sh apt-get update -q apt-get install -y -q autoconf automake bash-completion bison build-essential clang debhelper default-jdk-headless devscripts doxygen fakeroot flex g++ gdb git graphviz libffi-dev libncurses5-dev libsqlite3-dev libtool make mcpp pkg-config python3-dev sqlite swig zlib1g-dev cmake ``` -------------------------------- ### Enable Legacy Mode in Soufflé Source: https://github.com/souffle-lang/souffle/blob/master/README.md To ensure compatibility with older Soufflé versions, you can either use the command line flag `--legacy` or add this pragma to the start of your source code. ```souffle .pragma "legacy" ``` -------------------------------- ### Setup Souffle Semantic Test Library Source: https://github.com/souffle-lang/souffle/blob/master/tests/semantic/pragma2/CMakeLists.txt Defines a CMake function to set up a shared library for Souffle semantic tests. It configures compilation features, target properties like output name and C++ extensions, and platform-specific compile options. ```cmake function(SOUFFLE_TEST_SEMANTIC_PRAGMA2_SETUP FILE SO_NAME) add_library(${FILE} SHARED "${FILE}.cpp") target_include_directories(${FILE} PRIVATE "${CMAKE_SOURCE_DIR}/src/include") target_compile_features(${FILE} PUBLIC cxx_std_17) set_target_properties( ${FILE} PROPERTIES OUTPUT_NAME "'${SO_NAME}'" CXX_EXTENSIONS OFF WINDOWS_EXPORT_ALL_SYMBOLS ON ) if (NOT MSVC) target_compile_options(${FILE} PUBLIC "-Wall;-Wextra;-fwrapv") else () target_compile_options(${FILE} PUBLIC /W3 /WX) endif() if (WIN32) # Prefix all shared libraries with 'lib'. set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # Prefix all static libraries with 'lib'. set(CMAKE_STATIC_LIBRARY_PREFIX "lib") endif () if (SOUFFLE_DOMAIN_64BIT) target_compile_definitions(${FILE} PUBLIC RAM_DOMAIN_SIZE=64) endif() endfunction() ``` -------------------------------- ### Creating a Soufflé Program Instance Source: https://github.com/souffle-lang/souffle/wiki/Cxx-Interface Demonstrates how to create an instance of a Soufflé program using the ProgramFactory. ```APIDOC ## Creating a Soufflé Program Instance ### Description This code snippet shows how to create an instance of a Soufflé program using the `ProgramFactory::newInstance` method. It includes basic error handling for instance creation. ### Method `souffle::ProgramFactory::newInstance("")` ### Parameters * **""** (string) - Required - The name of the Soufflé program. ### Request Example ```cpp #include "souffle/SouffleInterface.h" if(souffle::SouffleProgram *prog = souffle::ProgramFactory::newInstance("")) { // ... program logic ... delete prog; } else { std::cerr << "Failed to create instance for program \n"; exit(1); } ``` ### Response * Returns a pointer to a `souffle::SouffleProgram` instance on success. * Returns `nullptr` on failure. ``` -------------------------------- ### Instantiate and Run Souffle Program in Java Source: https://github.com/souffle-lang/souffle/wiki/SWIG Create an instance of the Souffle program, load input, run it, print output, and finalize. Ensure the Java library path is set during execution. ```java SWIGSouffleProgram p = SwigInterface.newInstance("") ``` ```java p.loadAll("."); ``` ```java p.run(); ``` ```java p.printAll("."); ``` ```java p.finalize(); ``` ```bash java -Djava.library.path= <.java> ``` -------------------------------- ### Dockerfile Base Configuration Source: https://github.com/souffle-lang/souffle/wiki/Packaging Sets up the base Ubuntu image and non-interactive apt-get for Docker builds. Use this for creating a reproducible build environment. ```docker FROM ubuntu:21.04 ``` ```docker ARG DEBIAN_FRONTEND=noninteractive ``` ```docker WORKDIR /souffle ``` -------------------------------- ### Instantiate and Run Souffle Program in Python Source: https://github.com/souffle-lang/souffle/wiki/SWIG Create an instance of the Souffle program, load input, run it, and print output. The program will output CSV files upon execution. ```python p = SwigInterface.newInstance("") ``` ```python p.loadAll('.') ``` ```python p.run() ``` ```python p.printAll('.') ``` -------------------------------- ### Configure Package Build for 32-bit and 64-bit Architectures Source: https://github.com/souffle-lang/souffle/wiki/Packaging Uses a case statement in an entrypoint script to conditionally set CMake build options based on the DOMAIN_SIZE environment variable for 32-bit and 64-bit architectures. ```bash # Run the build command case "$DOMAIN_SIZE" in "64bit") cmake -S . -B ./build -DSOUFFLE_DOMAIN_64BIT=ON ;; "32bit") cmake -S . -B ./build ;; esac ``` -------------------------------- ### Navigate to Build Directory and Upload Package Source: https://github.com/souffle-lang/souffle/wiki/Packaging Changes the current directory to './build' and then uploads the Souffle package to packagecloud.io. Ensure the necessary environment variables are set. ```bash cd build PACKAGECLOUD_TOKEN="$PACKAGE_CLOUD_API_KEY" package_cloud push souffle-lang/souffle-test/$PKG_CLOUD_OS_NAME "$(ls *$PKG_EXTENSION | head -n1)" ``` -------------------------------- ### Entrypoint Script for Package Building Source: https://github.com/souffle-lang/souffle/wiki/Packaging The main entrypoint script that configures CMake based on DOMAIN_SIZE and then builds the package. It requires the PackageCloud API key as the first argument. ```bash #!/bin/sh PACKAGE_CLOUD_API_KEY="$1" # Run the build command case "$DOMAIN_SIZE" in "64bit") cmake -S . -B ./build -DSOUFFLE_DOMAIN_64BIT=ON ;; "32bit") cmake -S . -B ./build ;; esac # Create the package cmake --build ./build --parallel "$(nproc)" --target package cd build ``` -------------------------------- ### Show all available options Source: https://context7.com/souffle-lang/souffle/llms.txt Displays all available command-line options for the Souffle compiler using the `-h` flag. ```bash souffle -h ``` -------------------------------- ### Launch Text-Mode Profiler UI Source: https://context7.com/souffle-lang/souffle/llms.txt Analyze performance profiles generated by Souffle using the `souffleprof` command in text mode. ```bash souffleprof profile.log ``` -------------------------------- ### Build Doxygen Documentation Source: https://github.com/souffle-lang/souffle/wiki/Internals Use this command to generate Doxygen documentation in HTML format. The output will be in the `doc/html` directory. ```bash make doxygen-doc ``` -------------------------------- ### Configure SQLite3 I/O Source: https://context7.com/souffle-lang/souffle/llms.txt Integrate with SQLite databases for input and output by specifying the `sqlite` IO type along with the database name and table. ```prolog .decl Employee(id: number, name: symbol, dept: symbol) .input Employee(IO=sqlite, dbname="company.db", table="employees") .output Employee(IO=sqlite, dbname="results.db", table="emp_results") ``` -------------------------------- ### Configure Compressed File Output Source: https://context7.com/souffle-lang/souffle/llms.txt Enable compression for file output by setting the `compress` option to `true` in the `.output` directive. ```prolog .decl LargeData(a: number, b: symbol) .output LargeData(IO=file, filename="large.csv.gz", compress=true) ``` -------------------------------- ### Generate Souffle Compile Python Script Source: https://github.com/souffle-lang/souffle/blob/master/src/CMakeLists.txt Generates the souffle-compile.py script using a CMake template. This script is essential for the compilation process and is installed to the bin directory. ```cmake set(SOUFFLE_COMPILE_PY "#!/usr/bin/env python3 JSON_DATA_TEXT = \"""{ \"compiler\": \"${SOUFFLE_COMPILED_CXX_COMPILER}\", \"compiler_id\": \"${SOUFFLE_COMPILED_CXX_COMPILER_ID}\", \"compiler_version\": \"${SOUFFLE_COMPILED_CXX_COMPILER_VERSION}\", \"msvc_version\": \"${MSVC_VERSION}\", \"includes\": \"${SOUFFLE_COMPILED_INCLUDES}\", \"std_flag\": \"${SOUFFLE_COMPILED_CXX_STANDARD}\", \"cxx_flags\": \"${SOUFFLE_COMPILED_CXX_FLAGS}\", \"cxx_link_flags\": \"${SOUFFLE_COMPILED_CXX_LINK_FLAGS}\", \"release_cxx_flags\": \"${SOUFFLE_COMPILED_RELEASE_CXX_FLAGS}\", \"debug_cxx_flags\": \"${SOUFFLE_COMPILED_DEBUG_CXX_FLAGS}\", \"definitions\": \"${SOUFFLE_COMPILED_DEFINITIONS}\", \"compile_options\": \"${SOUFFLE_COMPILED_CXX_OPTIONS}\", \"link_options\": \"${SOUFFLE_COMPILED_LINK_OPTIONS}\", \"rpaths\": \"${SOUFFLE_COMPILED_RPATH_LIST}\", \"outname_fmt\": \"${OUTNAME_FMT}\", \"libdir_fmt\": \"${LIBDIR_FMT}\", \"libname_fmt\": \"${LIBNAME_FMT}\", \"rpath_fmt\": \"${RPATH_FMT}\", \"path_delimiter\": \"${OS_PATH_DELIMITER}\", \"exe_extension\": \"${EXE_EXTENSION}\", \"source_include_dir\": \"${CMAKE_CURRENT_SOURCE_DIR}/include\", \"jni_includes\": \"${JAVA_INCLUDE_PATH}${OS_PATH_DELIMITER}${JAVA_INCLUDE_PATH2}\" }\""" ${TEMPLATE} ") file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/souffle-compile.py" CONTENT "${SOUFFLE_COMPILE_PY}") install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/souffle-compile.py DESTINATION bin) ``` -------------------------------- ### Get LSB Release ID Short Source: https://github.com/souffle-lang/souffle/wiki/Packaging Shell command to determine the LSB release ID short for the current Linux distribution, useful for CMake configuration. ```bash lsb_release --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE ``` -------------------------------- ### Embed Souffle Program in C++ Application Source: https://context7.com/souffle-lang/souffle/llms.txt Demonstrates how to instantiate a compiled Souffle program, populate its input relations, execute it, and iterate over its output relations from a C++ host application. Ensure the Souffle program is compiled with the -g flag and the host application is linked correctly. ```cpp #include "souffle/SouffleInterface.h" #include #include #include int main() { // Instantiate the compiled Souffle program by name (matches .dl filename) souffle::SouffleProgram* prog = souffle::ProgramFactory::newInstance("analysis"); if (!prog) { std::cerr << "Error: could not create program instance\n"; return 1; } // Populate input relation "edge" programmatically souffle::Relation* edge = prog->getRelation("edge"); if (!edge) { std::cerr << "Error: relation 'edge' not found\n"; return 1; } std::vector> edges = { {"A", "B"}, {"B", "C"}, {"C", "D"}, {"D", "E"} }; for (auto& e : edges) { souffle::tuple t(edge); t << e[0] << e[1]; edge->insert(t); } // Check existence before inserting souffle::tuple check(edge); check << "A" << "B"; if (edge->contains(check)) { std::cout << "Edge A->B already present\n"; } // Execute the Datalog program (computes fixpoint) prog->run(); // Iterate over output relation "path" souffle::Relation* path = prog->getRelation("path"); if (!path) { std::cerr << "Error: relation 'path' not found\n"; return 1; } std::cout << "Reachable paths (" << path->size() << " total):\n"; for (auto& tuple : *path) { std::string src, dst; tuple >> src >> dst; std::cout << " " << src << " -> " << dst << "\n"; } // Expected output: // Reachable paths (6 total): // A -> B // A -> C // A -> D // B -> C // B -> D (etc.) // Write all output relations to CSV files in the current directory prog->printAll("./output/"); // Introspect relation metadata std::cout << "Relation signature: " << path->getSignature() << "\n"; // Expected: std::cout << "Arity: " << path->getArity() << "\n"; delete prog; return 0; } ``` -------------------------------- ### Call SOUFFLE_LINK_TEST for UNIX Systems Source: https://github.com/souffle-lang/souffle/blob/master/tests/link/CMakeLists.txt Example of how to invoke the `SOUFFLE_LINK_TEST` function for regular and negative tests on UNIX systems. This sets up tests named 'link2' and 'link2_negative'. ```cmake if (UNIX) souffle_link_test(TEST_NAME link2 DATALOG_FILES insert_for1.dl insert_for2.dl) souffle_link_test(NEGATIVE TEST_NAME link2 DATALOG_FILES insert_for1.dl insert_for2.dl) endif(UNIX) ``` -------------------------------- ### Materialize Aggregate with Complex Body Source: https://github.com/souffle-lang/souffle/wiki/High-Level-AST-Transformations This example shows an aggregate with a complex body being transformed. The aggregate's intermediate results are materialized into an auxiliary relation `agg_rel_0`. ```souffle B(x) :- A(n), x = sum z : { C(z), z < 10 }. ``` ```souffle B(x) :- A(n), x = sum z : agg_rel_0(z). agg_rel_0(z) :- C(z), z < 10. ``` -------------------------------- ### Load SwigInterface Library in Java Source: https://github.com/souffle-lang/souffle/wiki/SWIG Load the SwigInterface library to use Souffle in Java. MAC users may need to specify the full path. ```java System.loadLibrary("SwigInterface") ``` ```java System.load(System.getProperty("java.library.path") + "/" + "libSwigInterface.so") ``` -------------------------------- ### Build Souffle with CMake Source: https://context7.com/souffle-lang/souffle/llms.txt Build the Souffle project using CMake's build command, utilizing all available CPU cores for faster compilation. ```bash cmake --build build --parallel $(nproc) ``` -------------------------------- ### Get Linux LSB Release Information Source: https://github.com/souffle-lang/souffle/wiki/Packaging A utility function to detect the Linux distribution and version using the `lsb_release` command. It sets variables like `LSB_RELEASE_ID_SHORT` which are crucial for conditional packaging. ```makefile function(get_linux_lsb_release_information) find_program(LSB_RELEASE_EXEC lsb_release) if(NOT LSB_RELEASE_EXEC) message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information") endif() execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE) set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE) set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Create PackageCloud Repository Source: https://github.com/souffle-lang/souffle/wiki/Packaging Command to create a new repository on PackageCloud. Refer to the packagecloud.io documentation for more details. ```bash package_cloud repository create ``` -------------------------------- ### Define SOUFFLE_LINK_TEST CMake Function Source: https://github.com/souffle-lang/souffle/blob/master/tests/link/CMakeLists.txt Defines a CMake function to encapsulate the logic for creating a Souffle link test. It handles argument parsing, directory setup, and test command generation. ```cmake function(SOUFFLE_LINK_TEST) cmake_parse_arguments( PARAM "NEGATIVE" "TEST_NAME" "DATALOG_FILES" ${ARGV} ) set(INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${PARAM_TEST_NAME}") set(FACTS_DIR "${INPUT_DIR}/facts") if (PARAM_NEGATIVE) set(TEST_SUFFIX "_negative") set (NAMESPACE_FLAG "") else () set(NAMESPACE_FLAG "--namespace") endif() set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PARAM_TEST_NAME}${TEST_SUFFIX}") ADD_TEST(NAME "${PARAM_TEST_NAME}${TEST_SUFFIX}" COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cmake/redirect.py --out ${PARAM_TEST_NAME}.out --err ${PARAM_TEST_NAME}.err ${Python3_EXECUTABLE} ${INPUT_DIR}/test.py --input_dir ${INPUT_DIR} --output_dir ${OUTPUT_DIR} --cxx ${CMAKE_CXX_COMPILER} --souffle $ --driver driver.cpp --include "${CMAKE_SOURCE_DIR}/src/include" ${NAMESPACE_FLAG} ${PARAM_DATALOG_FILES} COMMAND_EXPAND_LISTS WORKING_DIRECTORY ${INPUT_DIR} ) if (PARAM_NEGATIVE) set_tests_properties("${PARAM_TEST_NAME}${TEST_SUFFIX}" PROPERTIES WILL_FAIL TRUE) endif() endfunction() ``` -------------------------------- ### Run SWIG Command Line Option in Souffle Source: https://github.com/souffle-lang/souffle/wiki/SWIG Use this command to generate wrapper files for a specified language. The language must be in lowercase. ```bash ./souffle -s <.dl file> ``` -------------------------------- ### GitHub Workflow Job for Oracle Linux Package Source: https://github.com/souffle-lang/souffle/wiki/Packaging Example GitHub Actions job to create and upload packages for Oracle Linux 8 64-bit. This job utilizes a private GitHub Action. ```yaml Package-Oracle-Linux-8-64bit: strategy: fail-fast: false runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 with: fetch-depth: 0 - name: Package souffle uses: ./.github/actions/create-package/oracle-linux/8/64bit/ with: package_cloud_api_key: ${{ secrets.PACKAGECLOUD_TOKEN }} ``` -------------------------------- ### Get Linux LSB Release Information Source: https://github.com/souffle-lang/souffle/wiki/Packaging A CMake utility function to find and execute the 'lsb_release' command to gather information about the Linux distribution ID, version, and codename. It sets these as PARENT SCOPE variables. ```makefile # -------------------------------------------------- # Utility function to help us distinguish between Linux distros when packaging # -------------------------------------------------- function(get_linux_lsb_release_information) find_program(LSB_RELEASE_EXEC lsb_release) if(NOT LSB_RELEASE_EXEC) message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information") endif() execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE) set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE) set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Compile Souffle with Provenance Support Source: https://context7.com/souffle-lang/souffle/llms.txt Compile a Souffle program with provenance tracking enabled using the `-t explain` flag. This allows for detailed analysis of how facts are derived. ```bash souffle -c -t explain analysis.dl ``` -------------------------------- ### Define Souffle Scheduler Test Function Source: https://github.com/souffle-lang/souffle/blob/master/tests/scheduler/CMakeLists.txt Defines a CMake function to set up and run Souffle scheduler integration tests. It configures input/output directories, test labels, and calls helper functions for test setup and comparison. ```cmake function(SOUFFLE_ADD_SCHEDULER_TEST TEST_NAME) set(INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}") set(FACTS_DIR "${INPUT_DIR}/facts") set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}") set(TEST_LABELS "scheduler;positive;integration") # Setup test dir set(QUALIFIED_TEST_NAME scheduler/${TEST_NAME}) set(FIXTURE_NAME ${QUALIFIED_TEST_NAME}_fixture) souffle_setup_integration_test_dir(TEST_NAME ${TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} DATA_CHECK_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} FIXTURE_NAME ${FIXTURE_NAME} TEST_LABELS ${TEST_LABELS}) set(QUALIFIED_TEST_NAME scheduler/${TEST_NAME}_stats_collection) # Run stats collection set(SOUFFLE_PARAMS "-p" "${OUTPUT_DIR}/${TEST_NAME}.prof" "--emit-statistics" "-F" "${FACTS_DIR}") add_test(NAME ${QUALIFIED_TEST_NAME} COMMAND ${Python3_executable} --out ${TEST_NAME}.out --err ${TEST_NAME}.err ${STDIN_ARGS} $ ${SOUFFLE_PARAMS} "${INPUT_DIR}/${TEST_NAME}.dl" COMMAND_EXPAND_LISTS) set_tests_properties(${QUALIFIED_TEST_NAME} PROPERTIES WORKING_DIRECTORY "${OUTPUT_DIR}" LABELS "${TEST_LABELS}" FIXTURES_SETUP ${FIXTURE_NAME}_stats_collection FIXTURES_REQUIRED ${FIXTURE_NAME}_setup) souffle_compare_csv(QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} INPUT_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} RUN_AFTER_FIXTURE ${FIXTURE_NAME}_stats_collection NEGATIVE ${PARAM_NEGATIVE} TEST_LABELS ${TEST_LABELS}) # Run scheduler set(QUALIFIED_TEST_NAME scheduler/${TEST_NAME}_auto_scheduler) set(SOUFFLE_PARAMS "--auto-schedule" "${OUTPUT_DIR}/${TEST_NAME}.prof" "-c" "-F" "${FACTS_DIR}") add_test(NAME ${QUALIFIED_TEST_NAME} COMMAND ${Python3_executable} --out ${TEST_NAME}.out --err ${TEST_NAME}.err ${STDIN_ARGS} $ ${SOUFFLE_PARAMS} "${INPUT_DIR}/${TEST_NAME}.dl" COMMAND_EXPAND_LISTS) set_tests_properties(${QUALIFIED_TEST_NAME} PROPERTIES WORKING_DIRECTORY "${OUTPUT_DIR}" LABELS "${TEST_LABELS}" FIXTURES_SETUP ${FIXTURE_NAME}_auto_scheduler FIXTURES_REQUIRED ${FIXTURE_NAME}_stats_collection) # Check output souffle_compare_std_outputs(TEST_NAME ${TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} OUTPUT_DIR ${OUTPUT_DIR} RUN_AFTER_FIXTURE ${FIXTURE_NAME}_auto_scheduler TEST_LABELS ${TEST_LABELS}) souffle_compare_csv(QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} INPUT_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} RUN_AFTER_FIXTURE ${FIXTURE_NAME}_auto_scheduler NEGATIVE ${PARAM_NEGATIVE} TEST_LABELS ${TEST_LABELS}) endfunction() ``` -------------------------------- ### Load Input Relations from Directory Source: https://github.com/souffle-lang/souffle/wiki/Cxx-Interface Loads all input relations from a specified directory. The directory path should contain the CSV files for the relations. ```cpp prog->loadAll(""); ``` -------------------------------- ### Upload Package to PackageCloud Source: https://github.com/souffle-lang/souffle/wiki/Packaging Use this command to push a package to your PackageCloud repository. Ensure the PACKAGECLOUD_TOKEN and PKG_CLOUD_OS_NAME environment variables are set. ```bash PACKAGECLOUD_TOKEN="$PACKAGE_CLOUD_API_KEY" package_cloud push souffle-lang/souffle/$PKG_CLOUD_OS_NAME "$(ls *$PKG_EXTENSION | head -n1)" ``` -------------------------------- ### Define Souffle C++ Test Helper Function Source: https://github.com/souffle-lang/souffle/blob/master/tests/interface/CMakeLists.txt A helper CMake function to set up and run Souffle integration tests, including directory setup, compilation, execution, and output comparison. It configures test paths, labels, and compiler flags. ```cmake function(SOUFFLE_RUN_CPP_TEST_HELPER) # PARAM_TEST_NAME - the name of the test, the short directory name under tests// cmake_parse_arguments( PARAM "COMPARE_STDOUT" "TEST_NAME" #Single valued options "" ${ARGV} ) set(INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${PARAM_TEST_NAME}") set(FACTS_DIR "${INPUT_DIR}/facts") set(OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${PARAM_TEST_NAME}") # Give the test a name which has good info about it when running # People can then search for the test by the name, or the labels we create set(QUALIFIED_TEST_NAME interface/${PARAM_TEST_NAME}) set(FIXTURE_NAME ${QUALIFIED_TEST_NAME}_fixture) set(TEST_LABELS "positive;integration") set(PP_FLAGS) if (MSVC) list(APPEND PP_FLAGS "--preprocessor" "cl -nologo -TC -E") endif () souffle_setup_integration_test_dir(TEST_NAME ${PARAM_TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} DATA_CHECK_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} EXTRA_DATA ${EXTRA} FIXTURE_NAME ${FIXTURE_NAME} TEST_LABELS ${TEST_LABELS}) souffle_run_integration_test(TEST_NAME ${PARAM_TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} INPUT_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} FIXTURE_NAME ${FIXTURE_NAME} TEST_LABELS "${TEST_LABELS}" SOUFFLE_PARAMS "-g" "${OUTPUT_DIR}/${TEST_NAME}.cpp" ${PP_FLAGS}) souffle_run_cpp_test(TEST_NAME ${PARAM_TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} INPUT_DIR ${INPUT_DIR} OUTPUT_DIR ${OUTPUT_DIR} FIXTURE_NAME ${FIXTURE_NAME} FACTS_DIR "${FACTS_DIR}" TEST_LABELS ${TEST_LABELS}) souffle_compare_std_outputs(TEST_NAME ${PARAM_TEST_NAME} QUALIFIED_TEST_NAME ${QUALIFIED_TEST_NAME} OUTPUT_DIR ${OUTPUT_DIR} EXTRA_DATA ${EXTRA} RUN_AFTER_FIXTURE ${FIXTURE_NAME}_run_cpp TEST_LABELS ${TEST_LABELS}) endfunction() ``` -------------------------------- ### Checkout Source Code Source: https://github.com/souffle-lang/souffle/wiki/Code-Coverage This step uses the 'actions/checkout@v2' action to fetch the repository's source code. 'fetch-depth: 0' ensures that the entire Git history is fetched, which might be necessary for some code coverage tools. ```yaml - name: checkout uses: actions/checkout@v2 with: fetch-depth: 0 ``` -------------------------------- ### Configure Multiple Output Targets Source: https://context7.com/souffle-lang/souffle/llms.txt A single relation can be output to multiple destinations, such as a file and standard output, by specifying separate `.output` directives. ```prolog .decl Result(x: number, y: number) .output Result(IO=file, filename="result.csv") .output Result(IO=stdout) ``` -------------------------------- ### Configure CMake Build for Domain Size Source: https://github.com/souffle-lang/souffle/wiki/Packaging Configures the CMake build based on the system's domain size (32-bit or 64-bit). Use -DSOUFFLE_DOMAIN_64BIT=ON for 64-bit builds. ```bash case "$DOMAIN_SIZE" in "64bit") cmake -S . -B ./build -DSOUFFLE_DOMAIN_64BIT=ON ;; "32bit") cmake -S . -B ./build ;; esac ``` -------------------------------- ### Directory Structure for Oracle Linux Action Source: https://github.com/souffle-lang/souffle/wiki/Packaging Illustrates the required directory structure for a private GitHub Action targeting Oracle Linux 8 64-bit. ```text .github/actions/create-package/oracle-linux/ └── 8 └── 64bit ├── action.yml └── Dockerfile ``` -------------------------------- ### Set Basic Package Metadata Source: https://github.com/souffle-lang/souffle/wiki/Packaging Configures essential metadata for the package, including contact information, a full description, and a short summary. ```makefile SET(CPACK_PACKAGE_CONTACT "Patrick H.") SET(CPACK_PACKAGE_DESCRIPTION "Souffle - A Datalog Compiler") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A Datalog Compiler") ``` -------------------------------- ### Configure File I/O with Custom Delimiters Source: https://context7.com/souffle-lang/souffle/llms.txt Use the `.input` and `.output` directives with the `file` IO type to specify custom filenames and delimiters for reading and writing relation data. ```prolog .decl Person(id: number, name: symbol, age: number) .input Person(IO=file, filename="people.tsv", delimiter="\t") .output Person(IO=file, filename="people_out.csv", delimiter=",") ``` -------------------------------- ### Configure Windows Library Prefixes Source: https://github.com/souffle-lang/souffle/blob/master/tests/semantic/issue2373/CMakeLists.txt Sets the prefixes for shared and static libraries on Windows systems. ```cmake set(CMAKE_SHARED_LIBRARY_PREFIX "lib") ``` ```cmake set(CMAKE_STATIC_LIBRARY_PREFIX "lib") ``` -------------------------------- ### Loop Nest Simulation for Productivity Source: https://github.com/souffle-lang/souffle/wiki/discussions Illustrates a conceptual loop nest for a rule with constraints, including counters for successful and failed iterations of each predicate. This is used to refine productivity measurement. ```souffle for t1 in B1: success1 += c1(t1); fail1 += !c1(t1); if c1(t1): for t2 in B2: success2 += c2(t2); fail2 += !c2(t2); if c2(t2): ... for tk in Bk: successk += ck(tk); failk += !ck(tk); if ck(tk): project (t1,…., tk) into A ```