Skip to content

Commit

Permalink
refactor: wip on plan implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
anitvam committed Oct 21, 2024
1 parent ac2e5e6 commit 613cb77
Show file tree
Hide file tree
Showing 31 changed files with 280 additions and 488 deletions.
2 changes: 1 addition & 1 deletion jakta-api/src/main/kotlin/it/unibo/jakta/beliefs/Belief.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package it.unibo.jakta.beliefs

interface Belief<B> {
interface Belief<out B> {
val content: B
}
32 changes: 21 additions & 11 deletions jakta-api/src/main/kotlin/it/unibo/jakta/beliefs/BeliefBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,46 @@ package it.unibo.jakta.beliefs
import it.unibo.jakta.resolution.Solution

/** A BDI Agent's collection of [Belief]s */
interface BeliefBase<B : Belief<*>, C : BeliefBase<B, C>> : Iterable<B> {
interface BeliefBase<B : Belief<*>, BB : BeliefBase<B, BB>> : Collection<B> {

/**
* List of [BeliefUpdate] that populated the current [BeliefBase].
**/
val delta: List<BeliefUpdate<B>>

/**
* Resets the [BeliefBase] operations.
* @return a [BeliefBase] where the delta list is empty.
*/
fun resetDelta(): BB

/**
* Adds a [Belief] to this [BeliefBase]
* @param belief: the [Belief] to be added
* @return a [RetrieveResult] with the new [BeliefBase] and the added [Belief]
* @return the new [BeliefBase] and the added [Belief]
**/
fun add(belief: B): RetrieveResult<B>
operator fun plus(belief: B): BB

/**
* Adds all the given beliefs into this [BeliefBase]
* @param beliefs: beliefs to be added
* @return a [RetrieveResult] with the new [BeliefBase] and the added [Belief]s
* @return the new [BeliefBase] and the added [Belief]s
**/
fun addAll(beliefs: C): RetrieveResult<B>
operator fun plus(beliefs: BB): BB

/**
* Removes a [Belief] from the [BeliefBase]
* @param belief: the [Belief] to be removed
* @return a [RetrieveResult] with the new [BeliefBase] and the removed [Belief]
* @return the new [BeliefBase] and the removed [Belief]
*/
fun remove(belief: B): RetrieveResult<B>
operator fun minus(belief: B): BB

/**
* Removes all the specified beliefs from this [BeliefBase]
* @param beliefs: beliefs to be removed
* @return a [RetrieveResult] with the new [BeliefBase] and the removed [Belief]s
* @return the new [BeliefBase] and the removed [Belief]s
*/
fun removeAll(beliefs: C): RetrieveResult<*>

fun update(belief: B): RetrieveResult<B>
operator fun minus(beliefs: BB): BB

/**
* Performs unification between [B] and values in this [BeliefBase]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ import it.unibo.jakta.context.Addition
import it.unibo.jakta.context.ContextUpdate
import it.unibo.jakta.context.Removal

/** Result of an update method over a PrologBeliefBase */
data class RetrieveResult<B : Belief<*>, C : BeliefBase<B, C>>(
/** Beliefs that are added or removed from the updatedBeliefBase */
val modifiedBeliefs: List<BeliefUpdate<B>>,

/** The updated PrologBeliefBase */
val updatedBeliefBase: BeliefBase<B, C>,
)

data class BeliefUpdate<B : Belief<*>>(
val belief: B,
val updateType: ContextUpdate,
Expand Down
21 changes: 0 additions & 21 deletions jakta-api/src/main/kotlin/it/unibo/jakta/context/AgentContext.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package it.unibo.jakta.context

import it.unibo.jakta.actions.InternalAction
import it.unibo.jakta.actions.InternalActions
import it.unibo.jakta.beliefs.Belief
import it.unibo.jakta.beliefs.BeliefBase
import it.unibo.jakta.beliefs.PrologBeliefBase
import it.unibo.jakta.context.impl.AgentContextImpl
import it.unibo.jakta.events.Event
import it.unibo.jakta.events.EventQueue
import it.unibo.jakta.events.Trigger
import it.unibo.jakta.intentions.IntentionPool
import it.unibo.jakta.plans.Plan
Expand Down Expand Up @@ -35,21 +31,4 @@ interface AgentContext<B : Belief<*>, C : BeliefBase<B, C>, T : Trigger<*>> {
val intentions: IntentionPool

val internalActions: Map<String, InternalAction>

fun copy(
beliefBase: C = this.beliefBase,
events: EventQueue = this.events,
planLibrary: PlanLibrary = this.planLibrary,
intentions: IntentionPool = this.intentions,
internalActions: Map<String, InternalAction> = this.internalActions,
): AgentContext = AgentContextImpl(beliefBase, events, planLibrary, internalActions, intentions)

companion object {
fun of(
beliefBase: C = PrologBeliefBase.empty(),
events: EventQueue = emptyList(),
planLibrary: PlanLibrary = PlanLibrary.empty(),
internalActions: Map<String, InternalAction> = InternalActions.default(),
): AgentContext = AgentContextImpl(beliefBase, events, planLibrary, internalActions)
}
}
25 changes: 17 additions & 8 deletions jakta-api/src/main/kotlin/it/unibo/jakta/events/Trigger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,49 @@ import it.unibo.jakta.beliefs.Belief
import it.unibo.jakta.beliefs.BeliefBase

/** [Trigger] denotes the change that took place for the [Event] generation. */
sealed interface Trigger<X> {
sealed interface Trigger<out X> {
val value: X
}

/** [Trigger] generated after a [Belief] addition (or removal) from the [BeliefBase]. */
interface BeliefBaseRevision<out X : Belief<*>> : Trigger<X>

/** [Trigger] generated after a [Belief] addition to agent's [BeliefBase]. */
class BeliefBaseAddition<X>(override val value: Belief<X>) : Trigger<Belief<X>> {
class BeliefBaseAddition<X : Belief<*>>(override val value: X) : BeliefBaseRevision<X> {
override fun toString(): String = "BeliefBaseAddition(value=$value)"
}

/** [Trigger] generated after a [Belief] removal from agent's [BeliefBase]. */
data class BeliefBaseRemoval<X>(override val value: Belief<X>) : Trigger<Belief<X>> {
data class BeliefBaseRemoval<X : Belief<*>>(override val value: X) : BeliefBaseRevision<X> {
override fun toString(): String = "BeliefBaseRemoval(value=$value)"
}

data class BeliefBaseUpdate<X>(override val value: Belief<X>) : Trigger<Belief<X>> {
data class BeliefBaseUpdate<X : Belief<*>>(override val value: X) : BeliefBaseRevision<X> {
override fun toString(): String = "BeliefBaseUpdate(value=$value)"
}

/** [Trigger] of an event made by a [Test] Goal. */
interface TestGoalTrigger<out X> : Trigger<X>

/** [Trigger] generated after an invocation of a [Test] Goal. */
data class TestGoalInvocation<X>(override val value: X) : Trigger<X> {
data class TestGoalInvocation<X>(override val value: X) : TestGoalTrigger<X> {
override fun toString(): String = "TestGoalInvocation(value=$value)"
}

/** [Trigger] generated after a failure of a [Test] Goal. */
data class TestGoalFailure<X>(override val value: X) : Trigger<X> {
data class TestGoalFailure<X>(override val value: X) : TestGoalTrigger<X> {
override fun toString(): String = "TestGoalFailure(value=$value)"
}

/** [Trigger] of an event made by a [Achieve] Goal. */
interface AchievementGoalTrigger<out X> : Trigger<X>

/** [Trigger] generated after the invocation of a [Achieve] Goal. */
data class AchievementGoalInvocation<X>(override val value: X) : Trigger<X> {
data class AchievementGoalInvocation<X>(override val value: X) : AchievementGoalTrigger<X> {
override fun toString(): String = "AchievementGoalInvocation(value=$value)"
}

/** [Trigger] generated after the failure of a [Achieve] Goal. */
data class AchievementGoalFailure<X>(override val value: X) : Trigger<X> {
data class AchievementGoalFailure<X>(override val value: X) : AchievementGoalTrigger<X> {
override fun toString(): String = "AchievementGoalFailure(value=$value)"
}
102 changes: 12 additions & 90 deletions jakta-api/src/main/kotlin/it/unibo/jakta/goals/Goal.kt
Original file line number Diff line number Diff line change
@@ -1,105 +1,27 @@
package it.unibo.jakta.goals

import it.unibo.jakta.beliefs.Belief
import it.unibo.jakta.goals.impl.AchieveImpl
import it.unibo.jakta.goals.impl.ActExternallyImpl
import it.unibo.jakta.goals.impl.ActImpl
import it.unibo.jakta.goals.impl.ActInternallyImpl
import it.unibo.jakta.goals.impl.AddBeliefImpl
import it.unibo.jakta.goals.impl.RemoveBeliefImpl
import it.unibo.jakta.goals.impl.SpawnImpl
import it.unibo.jakta.goals.impl.TestImpl
import it.unibo.jakta.goals.impl.UpdateBeliefImpl
import it.unibo.tuprolog.core.Struct
import it.unibo.tuprolog.core.Substitution
import it.unibo.tuprolog.core.Truth

sealed interface Goal {
val value: Struct

fun applySubstitution(substitution: Substitution): Goal

fun copy(value: Struct = this.value): Goal
sealed interface Goal<X> {
val value: X
}

class EmptyGoal(override val value: Struct = Truth.TRUE) : Goal {
override fun applySubstitution(substitution: Substitution): Goal = this
data class EmptyGoal<X>(override val value: X) : Goal<X>

override fun copy(value: Struct): Goal = EmptyGoal(value)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
data class AddBelief<B : Belief<*>> (override val value: B) : Goal<B>

other as EmptyGoal
data class RemoveBelief<B : Belief<*>> (override val value: B) : Goal<B>

if (value != other.value) return false
data class UpdateBelief<B : Belief<*>> (override val value: B) : Goal<B>

return true
}
data class Achieve<X> (override val value: X) : Goal<X>

override fun hashCode() = value.hashCode()
}
data class Test<X> (override val value: X) : Goal<X>

sealed interface BeliefGoal : Goal {
val belief: Struct
get() = value
}
data class Spawn<X> (override val value: X) : Goal<X>

interface AddBelief : BeliefGoal {
companion object {
fun of(belief: Belief): AddBelief = AddBeliefImpl(belief)
}
}
data class Act<X> (override val value: X) : Goal<X>

interface RemoveBelief : BeliefGoal {
companion object {
fun of(belief: Belief): RemoveBelief = RemoveBeliefImpl(belief)
}
}
data class ActInternally<X> (override val value: X) : Goal<X>

interface UpdateBelief : BeliefGoal {
companion object {
fun of(belief: Belief): UpdateBelief = UpdateBeliefImpl(belief)
}
}

interface Achieve : Goal {
companion object {
fun of(value: Struct): Achieve = AchieveImpl(value)
}
}

interface Test : Goal {
companion object {
fun of(belief: Belief): Test = TestImpl(belief)
}
}

interface Spawn : Goal {
companion object {
fun of(value: Struct): Spawn = SpawnImpl(value)
}
}

sealed interface ActionGoal : Goal {
val action: Struct
get() = value
}

interface Act : ActionGoal {
companion object {
fun of(value: Struct): Act = ActImpl(value)
}
}

interface ActInternally : ActionGoal {
companion object {
fun of(value: Struct): ActInternally = ActInternallyImpl(value)
}
}

interface ActExternally : ActionGoal {
companion object {
fun of(value: Struct): ActExternally = ActExternallyImpl(value)
}
}
data class ActExternally<X> (override val value: X) : Goal<X>
8 changes: 4 additions & 4 deletions jakta-api/src/main/kotlin/it/unibo/jakta/plans/Plan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import it.unibo.jakta.events.Event
import it.unibo.jakta.events.Trigger
import it.unibo.jakta.goals.Goal

interface Plan<T : Trigger<*>, G : Guard<*>> {
interface Plan<T : Trigger<*>, Gu : Guard<*>, Go : Goal<*>> {
val trigger: T
val guard: G
val goals: List<Goal>
val guard: Gu
val goals: List<Go>

/** Determines if a plan is applicable */
fun <B : Belief<*>, C : BeliefBase<B, C>> isApplicable(event: Event<T>, beliefBase: C): Boolean

/** Returns the computed applicable plan */
fun <B : Belief<*>, C : BeliefBase<B, C>> applicablePlan(event: Event<T>, beliefBase: C): Plan<T, G>
fun <B : Belief<*>, C : BeliefBase<B, C>> applicablePlan(event: Event<T>, beliefBase: C): Plan<T, Gu, Go>

fun isRelevant(event: Event<T>): Boolean

Expand Down
32 changes: 15 additions & 17 deletions jakta-api/src/main/kotlin/it/unibo/jakta/plans/PlanLibrary.kt
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
package it.unibo.jakta.plans

import it.unibo.jakta.beliefs.PrologBeliefBase
import it.unibo.jakta.beliefs.Belief
import it.unibo.jakta.beliefs.BeliefBase
import it.unibo.jakta.events.Event
import it.unibo.jakta.events.Trigger
import it.unibo.jakta.plans.impl.PlanLibraryImpl
import it.unibo.jakta.goals.Goal

interface PlanLibrary<T, G, P> where
interface PlanLibrary<T, Gu, Go, P> where
T : Trigger<*>,
G : Guard<*>,
P : Plan<T, G> {
Gu : Guard<*>,
Go : Goal<*>,
P : Plan<T, Gu, Go> {
/**
* Like a standard practice in prolog, plans are ordered to let programmers know when the end of an eventual recursion happens.
*/
val plans: List<P>

/** @return all the relevant [Plan]s from a given [Event] */
fun relevantPlans(event: Event<T>): PlanLibrary<T, G, P>
fun relevantPlans(event: Event<T>): PlanLibrary<T, Gu, Go, P>

/** @return all the applicable [Plan]s in the agent with the specified [PrologBeliefBase] */
fun applicablePlans(event: Event<T>, beliefBase: PrologBeliefBase): PlanLibrary
/** @return all the applicable [Plan]s in the agent with the specified [BeliefBase] */
fun <B : Belief<*>, BB : BeliefBase<B, BB>> applicablePlans(
event: Event<T>,
beliefBase: BB,
): PlanLibrary<T, Gu, Go, P>

fun addPlan(plan: Plan): PlanLibrary
fun addPlan(plan: P): PlanLibrary<T, Gu, Go, P>

fun removePlan(plan: Plan): PlanLibrary

companion object {
fun of(plans: List<Plan>): PlanLibrary = PlanLibraryImpl(plans)
fun of(vararg plans: Plan): PlanLibrary = of(plans.asList())

fun empty(): PlanLibrary = PlanLibraryImpl(emptyList())
}
fun removePlan(plan: P): PlanLibrary<T, Gu, Go, P>
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ interface PrologBeliefBase : BeliefBase<PrologBelief, PrologBeliefBase> {

fun solve(struct: Struct): Solution<TuprologSolution>

/**
* Updates the content of the [BeliefBase] without saving the change in delta variable.
* @param belief the [Belief] to update
* @return a [BeliefBase]
*/
fun update(belief: PrologBelief): PrologBeliefBase

companion object {
/** @return an empty [PrologBeliefBase] */
fun empty(): PrologBeliefBase = PrologBeliefBaseImpl()
Expand All @@ -21,7 +28,7 @@ interface PrologBeliefBase : BeliefBase<PrologBelief, PrologBeliefBase> {
*/
fun of(beliefs: Iterable<PrologBelief>): PrologBeliefBase {
var bb = empty()
beliefs.forEach { bb = bb.add(it).updatedBeliefBase }
beliefs.forEach { bb += it }
return bb
}

Expand Down
Loading

0 comments on commit 613cb77

Please sign in to comment.