Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b74604f
feat!: add a reactive engine (#5066)
S-furi Jan 19, 2026
4bfdc8e
docs: improve Javadoc
S-furi Jan 19, 2026
ad61806
chore(api): provide a way to register to an observable without trigge…
S-furi Jan 21, 2026
ffd2ba4
chore(biochemestry): port `BiomolPresentInNeighbor` to kotlin
S-furi Jan 21, 2026
feda98d
feat!: fully transition to observable neighborhoods
S-furi Jan 21, 2026
bcbfb8c
feat!: make node counting observable
S-furi Jan 21, 2026
231ef33
fix(biochemistry): use current node count in assertions
S-furi Jan 22, 2026
d54850d
chore(api): add `updateOrNull` with observable map values
S-furi Jan 22, 2026
c0a2941
feat!: fully transition to observable positions
S-furi Jan 22, 2026
669dde8
chore(api): add way to register to observables without sending initia…
S-furi Jan 22, 2026
c03202d
fix(scafi): avoid depending on observables
S-furi Jan 22, 2026
bc26cb6
feat!: replace Engine with reactive counterpart and get rid of depend…
S-furi Jan 22, 2026
761d3ae
fix: properly implement and call `dispose` on nodes and reactions
S-furi Jan 29, 2026
82bdb4e
chore: try avoid memory leaks for region observers
S-furi Jan 29, 2026
b06e31a
feat(api): improve lapsed listener problem avoidance with `Lifecycle`
S-furi Jan 29, 2026
dd0f916
chore(api): cleanup conditions if conditions are set mulitple times
S-furi Jan 30, 2026
dac79a7
refactor(api): extract lifecycle components into multiple files
S-furi Feb 10, 2026
c4d5535
fix: fix line length
S-furi Feb 10, 2026
2dfa880
chore(docs): remove useless whitespace
S-furi Feb 13, 2026
8b2fba7
fix(cognitive-agents): use `getCurrentPosition` to retireve node's ac…
S-furi Feb 15, 2026
0c3ec1c
test(engine): simplify engine test suite (fixed detekt error)
S-furi Feb 15, 2026
a2cc72d
chore(implementation-base): suppress `AbstractClassCanBeConcreteClass…
S-furi Feb 15, 2026
804c28a
fix(test): retrieve current position from observable when asserting
S-furi Feb 16, 2026
50a354b
fix(sapere): trigger LSAReaction update only on target molecule chang…
S-furi Feb 19, 2026
d0aafb9
fix(implementation-base): merge conditions into single observable source
S-furi Feb 19, 2026
477ae8a
fix(sapere): use generalised molecules for dsl expressions test failure
S-furi Feb 19, 2026
40d8e63
fix(sapere): keep observing for neighbrhoods LSA spaces changes
S-furi Feb 19, 2026
a0ee1b4
fix: fix checkstyle error
S-furi Feb 19, 2026
2e50026
perf: improve speed, SAPERE fine-grained dependencies and memory usage
S-furi Feb 20, 2026
79c0f7e
style(api): simplify sum assertion in ObservableTest
DanySK Apr 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions alchemist-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ dependencies {
api(libs.jool)
api(libs.listset)
implementation(libs.kotlin.reflect)
api(libs.arrow.core)
api(libs.kotlinx.collections.immutable)
testImplementation(libs.kotlin.test)
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
package it.unibo.alchemist.model;

import it.unibo.alchemist.core.Simulation;
import it.unibo.alchemist.model.observation.Disposable;
import it.unibo.alchemist.model.observation.Observable;
import it.unibo.alchemist.model.observation.ObservableSet;
import org.danilopianini.util.ListSet;

import java.io.Serializable;
Expand All @@ -20,7 +23,7 @@
* @param <T>
* The type which describes the concentration of a molecule
*/
public interface Condition<T> extends Serializable {
public interface Condition<T> extends Serializable, Disposable {

/**
* This method allows cloning this action on a new node. It may result
Expand All @@ -46,6 +49,12 @@ public interface Condition<T> extends Serializable {
*/
ListSet<? extends Dependency> getInboundDependencies();

/**
* @return The set of dependencies which may influence the truth value of this
* condition, as an {@link ObservableSet} of {@link Observable}
*/
ObservableSet<? extends Observable<?>> observeInboundDependencies();

/**
* @return the node this Condition belongs to
*/
Expand All @@ -61,11 +70,24 @@ public interface Condition<T> extends Serializable {
*/
double getPropensityContribution();

/**
* An observable and reactive view of the corresponding {@link #getPropensityContribution()}.
*
* @return an observable view of how this condition may influence the propensity.
*/
Observable<Double> observePropensityContribution();

/**
* @return true if the condition is satisfied in the current environment.
*/
boolean isValid();

/**
* @return an observable that emits true if the condition is satisfied in the
* current environment.
*/
Observable<Boolean> observeValidity();

/**
* This method is called by the {@link Simulation} once the {@link Reaction}
* whose this {@link Condition} belongs to is the next one to be executed, and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

package it.unibo.alchemist.model

import it.unibo.alchemist.model.observation.Disposable
import it.unibo.alchemist.model.observation.Observable
import it.unibo.alchemist.model.observation.lifecycle.LifecycleOwner
import java.io.Serializable
import org.danilopianini.util.ListSet

Expand All @@ -17,13 +20,23 @@ import org.danilopianini.util.ListSet
*/
sealed interface Actionable<T> :
Comparable<Actionable<T>>,
Serializable {
Serializable,
Disposable,
LifecycleOwner {
/**
* @return true if the reaction can be executed (namely, all the conditions
* are satisfied).
*/
fun canExecute(): Boolean

/**
* Observes whether the reaction can be executed. This observable emits updates
* to indicate if the conditions required for execution are satisfied.
*
* @return An [Observable] emitting true if the reaction van be executed, false otherwise.
*/
fun observeCanExecute(): Observable<Boolean>

/**
* Executes the reactions.
*/
Expand Down Expand Up @@ -88,6 +101,12 @@ sealed interface Actionable<T> :
*/
val timeDistribution: TimeDistribution<T>

/**
* Emits when this reaction requests the [Scheduler][it.unibo.alchemist.core.Scheduler]
* to reschedule this reaction.
*/
val rescheduleRequest: Observable<Unit>

/**
* Updates the scheduling of this reaction.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
package it.unibo.alchemist.model

import it.unibo.alchemist.core.Simulation
import it.unibo.alchemist.model.observation.Observable
import it.unibo.alchemist.model.observation.ObservableSet
import java.io.Serializable
import org.danilopianini.util.ListSet

Expand All @@ -18,6 +20,7 @@ import org.danilopianini.util.ListSet
* Every environment must implement this specification.
* [T] is the [Concentration] type, [P] is the [Position] type.
*/
@Suppress("TooManyFunctions")
interface Environment<T, P : Position<out P>> :
Serializable,
Iterable<Node<T>> {
Expand Down Expand Up @@ -91,9 +94,10 @@ interface Environment<T, P : Position<out P>> :
var linkingRule: LinkingRule<T, P>

/**
* Given a [node], this method returns its neighborhood.
* Given a [node], this method returns an observable view of
* its neighborhood.
*/
fun getNeighborhood(node: Node<T>): Neighborhood<T>
fun getNeighborhood(node: Node<T>): Observable<Neighborhood<T>>

/**
* Allows accessing a [Node] in this [Environment] known its [id].
Expand All @@ -108,9 +112,14 @@ interface Environment<T, P : Position<out P>> :
val nodes: ListSet<Node<T>>

/**
* Returns the number of [Node]s currently in the [Environment].
* An [Observable] view of all the [Node]s that exist in current [Environment].
*/
val nodeCount: Int
val observableNodes: ObservableSet<Node<T>>

/**
* Returns an [Observable] view of the number of [Node]s currently in the [Environment].
*/
val nodeCount: Observable<Int>

/**
* Given a [node] this method returns a list of all the surrounding
Expand All @@ -122,6 +131,11 @@ interface Environment<T, P : Position<out P>> :
*/
fun getNodesWithinRange(node: Node<T>, range: Double): ListSet<Node<T>>

/**
* An [Observable] alternative to [getNodesWithinRange].
*/
fun observeNodesWithinRange(node: Node<T>, range: Double): ObservableSet<Node<T>>

/**
* Given a [position] this method returns a list of all the
* surrounding nodes within the given [range].
Expand All @@ -130,6 +144,11 @@ interface Environment<T, P : Position<out P>> :
*/
fun getNodesWithinRange(position: P, range: Double): ListSet<Node<T>>

/**
* An [Observable] alternative to [getNodesWithinRange].
*/
fun observeNodesWithinRange(position: P, range: Double): ObservableSet<Node<T>>

/**
* This method allows to know which are the smallest coordinates represented.
* Return an array of length [dimensions] containing the smallest
Expand All @@ -138,9 +157,14 @@ interface Environment<T, P : Position<out P>> :
val offset: DoubleArray

/**
* Calculates the position of a [node].
* Observe the position of a [node].
*/
fun getPosition(node: Node<T>): Observable<P>

/**
* Retrieves [node]'s current position.
*/
fun getPosition(node: Node<T>): P
fun getCurrentPosition(node: Node<T>): P = getPosition(node).current

/**
* Return the current [Simulation], if present, or throws an [IllegalStateException] otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ interface EuclideanEnvironment<T, P> : Environment<T, P> where P : Position<P>,
* method may suffice.
*/
fun moveNode(node: Node<T>, direction: P) {
val oldcoord = getPosition(node)
val oldcoord = getCurrentPosition(node)
moveNodeToPosition(node, oldcoord.plus(direction))
}

Expand Down
37 changes: 36 additions & 1 deletion alchemist-api/src/main/kotlin/it/unibo/alchemist/model/Node.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
*/
package it.unibo.alchemist.model

import arrow.core.Option
import it.unibo.alchemist.model.observation.Disposable
import it.unibo.alchemist.model.observation.Observable
import it.unibo.alchemist.model.observation.ObservableMap
import it.unibo.alchemist.model.observation.lifecycle.LifecycleOwner
import java.io.Serializable
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
Expand All @@ -22,7 +27,9 @@ import kotlin.reflect.jvm.jvmErasure
interface Node<T> :
Serializable,
Iterable<Reaction<T>>,
Comparable<Node<T>> {
Comparable<Node<T>>,
Disposable,
LifecycleOwner {
/**
* Adds a reaction to this node.
* The reaction is added only in the node,
Expand Down Expand Up @@ -60,6 +67,14 @@ interface Node<T> :
*/
operator fun contains(molecule: Molecule): Boolean

/**
* Observes whether a node contains a [Molecule].
*
* @param molecule * the molecule to check
* @return emit true if the molecule is present, false otherwise
*/
fun observeContains(molecule: Molecule): Observable<Boolean>

/**
* Calculates the concentration of a molecule.
*
Expand All @@ -69,11 +84,26 @@ interface Node<T> :
*/
fun getConcentration(molecule: Molecule): T

/**
* Observe the concentration calculated with the given molecule.
* The result of this computation is wrapped into an [Option] and
* [some][arrow.core.Some] if the value is present, otherwise
* [none][arrow.core.None].
*
* @param molecule the molecule whose concentration will be returned
*/
fun observeConcentration(molecule: Molecule): Observable<Option<T>>

/**
* @return the molecule corresponding to the i-th position
*/
val contents: Map<Molecule, T>

/**
* @return an observable view of the molecule corresponding to the i-th position
*/
val observableContents: ObservableMap<Molecule, T>

/**
* @return an univocal id for this node in the environment
*/
Expand All @@ -84,6 +114,11 @@ interface Node<T> :
*/
val moleculeCount: Int

/**
* Observes the count of different molecules in this node.
*/
val observeMoleculeCount: Observable<Int>

/**
* @return a list of the node's properties/capabilities
*/
Expand Down
Loading
Loading