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.
- NOTE:
scafi-coreandscafi-simulatorcross-target both the JVM and the JavaScript Platform (via Scala.js)
Add the dependency to scafi in your project, e.g., via sbt
// build.sbtvalscafi_version="1.1.5"valscafi_core="it.unibo.scafi"%%"scafi-core"% scafi_version
valscafi_simulator="it.unibo.scafi"%%"scafi-simulator"% scafi_version
valscafi_simulator_gui="it.unibo.scafi"%%"scafi-simulator-gui"% scafi_version
valscafi_platform="it.unibo.scafi"%%"scafi-distributed"% scafi_version
libraryDependencies ++=Seq(scafi_core, scafi_simulator, scafi_platform)or Gradle
// build.gradle.kts
dependencies {
implementation("it.unibo.scafi:scafi-core_2.13:1.1.5")
}- Consider the following repository: https://github.com/scafi/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
packageexperiments// Method #1: Use an incarnation which is already defined// (Note: BasicSimulationIncarnation is defined in module 'scafi-simulator')importit.unibo.scafi.incarnations.BasicSimulationIncarnation.AggregateProgram// Method #2: Define a custom incarnation and import stuff from itobjectMyIncarnationextends it.unibo.scafi.incarnations.BasicAbstractIncarnationimportMyIncarnation._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.objectMyAggregateProgramextendsAggregateProgramwithStandardSensorNames{
// 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 coordinationoverridedefmain() = 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 neighbourdefgradient(source: Boolean):Double=
rep(Double.PositiveInfinity){ distance =>
mux(source) { 0.0 } {
foldhoodPlus(Double.PositiveInfinity)(Math.min)(nbr{distance}+nbrRange)
}
}
// A custom local sensordefisSource= sense[Boolean]("source")
// A custom "neighbouring sensor"defnbrRange= 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.
importit.unibo.scafi.simulation.gui.{Launcher, Settings}
objectSimulationRunnerextendsLauncher {
Settings.Sim_ProgramClass="experiments.MyAggregateProgram"Settings.ShowConfigPanel=true
launch()
}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.
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 libraryscafi-simulator: provides a basic support for simulating aggregate systemsscafi-simulator-gui: provides a GUI for visualising simulations of aggregate systemsspala: provides an actor-based aggregate computing middlewarescafi-distributed: ScaFi integration-layer forspala
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-corein for a fine-grained integration. For more straightforward distributed system setup, take a look atscafi-distributed. - Play, exercise, and experiment with aggregate programming.
Bring
scafi-corein for writing aggregate programs as well asscafi-simulator-guito quickly render an executing system. - Set up sophisticated simulations
Bring
scafi-corein for writing aggregate programs and either (A) leverage the basic machinery provided byscafi-simulator, or (B) leverage the ScaFi support provided by Alchemist.
- Roberto Casadei
- Gianluca Aguzzi
- Mirko Viroli
- Ferruccio Damiani
- Giorgio Audrito
- Danilo Pianini
Please refer to the ScaFi Developer Manual.
scafi is Open Source and available under the Apache 2 License.