ScaFi (Scala Fields)

workflow-master badge License codecov master Maven Central

ScaFi is a Scala-based library and framework for Aggregate Programming. It implements a variant of the Higher-Order Field Calculus (HOFC) operational semantics, which is made available as a usable domain-specific language (DSL), and provides a platform and API for simulating and executing Aggregate Computing systems and applications.

Please refer to the ScaFi main website and ScaFi Documentation the for further information.


Notes for application developers

  • NOTE: scafi-core and scafi-simulator cross-target both the JVM and the JavaScript Platform (via Scala.js)

Import via Maven/sbt/Gradle

Add the dependency to scafi in your project, e.g., via sbt

// build.sbt
val scafi_version = "1.1.5"

val scafi_core  = "it.unibo.scafi" %% "scafi-core"  % scafi_version
val scafi_simulator  = "it.unibo.scafi" %% "scafi-simulator"  % scafi_version
val scafi_simulator_gui  = "it.unibo.scafi" %% "scafi-simulator-gui"  % scafi_version
val scafi_platform = "it.unibo.scafi" %% "scafi-distributed"  % scafi_version

libraryDependencies ++= Seq(scafi_core, scafi_simulator, scafi_platform)

or Gradle

// build.gradle.kts
dependencies {

Hello, ScaFi

As another example, consider the following steps.

Step 1: Import or define an incarnation (a family of types), from which you can import types like AggregateProgram

package experiments

// Method #1: Use an incarnation which is already defined
// (Note: BasicSimulationIncarnation is defined in module 'scafi-simulator')
import it.unibo.scafi.incarnations.BasicSimulationIncarnation.AggregateProgram

// Method #2: Define a custom incarnation and import stuff from it
object MyIncarnation extends it.unibo.scafi.incarnations.BasicAbstractIncarnation
import MyIncarnation._

Step 2: Define an AggregateProgram which expresses the global behaviour of an ensemble.

// An "aggregate program" can be seen as a function from a Context to an Export
// The Context is the input for a local computation: includes state 
//  from previous computations, sensor data, and exports from neighbours.
// The export is a tree-like data structure that contains all the information needed
//  for coordinating with neighbours. It also contains the output of the computation.
object MyAggregateProgram extends AggregateProgram with StandardSensorNames{
  // Main program expression driving the ensemble
  // This is run in a loop for each agent
  // According to this expression, coordination messages are automatically generated
  // The platform/middleware/simulator is responsible for coordination
  override def main() = gradient(isSource)

  // The gradient is the (self-adaptive) field of the minimum distances from source nodes
  // `rep` is the construct for state transformation (remember the round-by-round loop behaviour)
  // `mux` is a purely functional multiplexer (selects the first or second branch according to condition)
  // `foldhoodPlus` folds over the neighbourhood (think like Scala's fold)
  // (`Plus` means "without self"--with plain `foldhood`, the device itself is folded)
  // `nbr(e)` denotes the values to be locally computed and shared with neighbours
  // `nbrRange` is a sensor that, when folding, returns the distance wrt each neighbour
  def gradient(source: Boolean): Double =
    rep(Double.PositiveInfinity){ distance =>
      mux(source) { 0.0 } {

  // A custom local sensor
  def isSource = sense[Boolean]("source")
  // A custom "neighbouring sensor"
  def nbrRange = nbrvar[Double](NBR_RANGE)

Step 3: Use ScaFi's internal simulator and GUI (modules scafi-simulator and scafi-simulator-gui, respectively) to run the program on a predefined network of devices.

import it.unibo.scafi.simulation.gui.{Launcher, Settings}

object SimulationRunner extends Launcher {
  Settings.Sim_ProgramClass = "experiments.MyAggregateProgram"
  Settings.ShowConfigPanel = true

Alternatively, you can (a) implement your integration/middleware layer, or (b) leverages integration with the Alchemist simulator, for more sophisticated simulations. This and much more is described in the ScaFi Documentation Page.

ScaFi Architecture

From a deployment perspective, ScaFi consists of the following modules:

  • scafi-commons: provides basic entities (e.g., spatial and temporal abstractions)
  • scafi-core: represents the core of the project and provides an implementation of the ScaFi aggregate programming DSL, together with its standard library
  • scafi-simulator: provides a basic support for simulating aggregate systems
  • scafi-simulator-gui: provides a GUI for visualising simulations of aggregate systems
  • spala: provides an actor-based aggregate computing middleware
  • scafi-distributed: ScaFi integration-layer for spala

The modules to be imported (e.g., via sbt or Gradle) depend on the use case:

  • Development of a real-world aggregate application. Bring scafi-core in for a fine-grained integration. For more straightforward distributed system setup, take a look at scafi-distributed.
  • Play, exercise, and experiment with aggregate programming. Bring scafi-core in for writing aggregate programs as well as scafi-simulator-gui to quickly render an executing system.
  • Set up sophisticated simulations Bring scafi-core in for writing aggregate programs and either (A) leverage the basic machinery provided by scafi-simulator, or (B) leverage the ScaFi support provided by Alchemist.


Main Researchers and Authors

  • Roberto Casadei
  • Gianluca Aguzzi
  • Mirko Viroli

Research Collaborators

  • Ferruccio Damiani
  • Giorgio Audrito
  • Danilo Pianini


Please refer to the ScaFi Developer Manual.


scafi is Open Source and available under the Apache 2 License.