diff --git a/src/main/scala/org/scadcop/solver/decentralized/mgm2/AgentBehaviour.scala b/src/main/scala/org/scadcop/solver/decentralized/mgm2/AgentBehaviour.scala
index d5f98e30f49c0cb86b7b32d7e9d3589562437254..5dea133593a2d77f0cb541b4b18d034f1646b59a 100644
--- a/src/main/scala/org/scadcop/solver/decentralized/mgm2/AgentBehaviour.scala
+++ b/src/main/scala/org/scadcop/solver/decentralized/mgm2/AgentBehaviour.scala
@@ -26,12 +26,22 @@ class AgentBehaviour(variable: Variable,
debug = true
-
/**
* Initially the agent has no task in the bundle
*/
startWith(Init, new MGM2Mind())
+ /**
+ * Reject some offers
+ */
+ def rejectOffers(offers: List[Offer]): Unit =
+ offers.foreach{ offer: Offer =>
+ val neighbour: Variable = offer.offererVariable
+ if (trace) println(s"$variable -> $neighbour : Reject($offer)")
+ directory.addressOf(neighbour) ! Reject(offer)
+ }
+
+
/**
* Either the agent is in the initial state
*/
@@ -57,14 +67,14 @@ class AgentBehaviour(variable: Variable,
*/
when(Continue) {
- //when the supervisor tells it to stop
- case Event(StopAlgo, mind) => {
+ //When the supervisor tells it to stop
+ case Event(StopAlgo, mind) =>
if (debug) println(s"$variable in $stateName has StopAlgo")
goto(Final) using mind
- }
- //when the supervisor tells it to continue
- case Event(ContinueAlgo, mind) => {
+
+ //When the supervisor tells it to continue
+ case Event(ContinueAlgo, mind) =>
if (debug) println(s"$variable in $stateName has received ContinueAlgo")
val updatedMind = mind.reset(variable) // performing a reset
if (trace) println(s"$variable -> All : InformValue(${updatedMind.context.getValue(variable).get})")
@@ -74,33 +84,29 @@ class AgentBehaviour(variable: Variable,
directory.addressOf(variable) ! ChooseSubset(b)
unstashAll
goto(WaitingForRole) using updatedMind
- }
- //when the partner from previous round tells it to Go
- case Event(GiveGo(_), mind) => {
+ // When the partner from previous round tells it to Go
+ case Event(GiveGo(_), mind) =>
if (debug) println(s"$variable in $stateName has received GiveGo")
stay using mind
- }
- //when the partner from previous round tells it to not Go
- case Event(GiveNoGo, mind) => {
+ // When the partner from previous round tells it to not Go
+ case Event(GiveNoGo, mind) =>
if (debug) println(s"$variable in $stateName has received GiveNoGo")
stay using mind
- }
- //when the partner gets an informValue
- case Event(InformValue(_), mind) => {
+ // When the partner gets an informValue
+ case Event(InformValue(_), mind) =>
if (debug) println(s"$variable in $stateName has received InformValue")
stash
stay using mind
- }
-
}
/**
* Either the agent is in the WaitingForRole state
*/
when(WaitingForRole){
+
// When it receives an InformValue
case Event(InformValue(_),mind) =>
if (debug) println(s"$variable in $stateName has received InformValue")
@@ -142,7 +148,7 @@ class AgentBehaviour(variable: Variable,
if (debug) println(s"$variable: the value of $peerVariable is $peerValue " +
s"(${updatedMind.context.size-1}/${neighbours.size})")
val potentialPartner: Variable = updatedMind.choosePartner(neighbours)
- updatedMind = updatedMind.setPartner(variable, peerVariable)
+ updatedMind = updatedMind.setPartner(peerVariable)
if (debug) println(s"$variable> context before computing the joint offer=${updatedMind.currentContext}")
val moves: List[BilateralMove] = updatedMind.computeJointOffer(potentialPartner, neighbours, constraints)
val offer: Offer = new Offer(variable, moves)
@@ -185,27 +191,31 @@ class AgentBehaviour(variable: Variable,
if (debug) println(s"$variable in $stateName has received Accept")
val newPartner: Variable = directory.variableOf(sender)
val move : Move = offer.moves.head
- val updatedMind: MGM2Mind = mind.fullyCommit(variable, newPartner, offer)
+ val updatedMind: MGM2Mind = mind.commitFully(newPartner, offer)
if (trace) println(s"$variable -> All : InformDelta(${updatedMind.deltas(variable)})")
broadcast(InformDelta(updatedMind.deltas(variable)))
unstashAll
goto(Committed) using updatedMind
- //when it receives a refusal from its potential partner
- case Event(Reject(_), mind) => //TODO check sender partner
+ // When it receives a refusal from its potential partner
+ case Event(Reject(_), mind) if directory.variableOf(sender) == mind.partner.get => //TODO check sender partner
if (debug) println(s"$variable in $stateName has received Reject")
- var updatedMind = mind.uncommit(variable)
+ var updatedMind = mind.uncommit()
val (bestMove, bestDelta) = updatedMind.bestUnilateralMove(variable, constraints)
val bestOffer = bestMove match {
case Some(m) => Some(new Offer(variable, List(m)))
case None => None
}
updatedMind = updatedMind.updateDeltas(variable: Variable, bestDelta)
- updatedMind = updatedMind.setCurrBestOffer(variable, bestOffer)
+ updatedMind = updatedMind.setCurrBestOffer(bestOffer)
if (trace) println(s"$variable -> All : InformDelta(${updatedMind.deltas(variable)})")
broadcast(InformDelta(updatedMind.deltas(variable)))
unstashAll
goto(Uncommitted) using updatedMind
+
+ // TODO When it receives a refusal from a peer which is not a potential partner
+ case Event(Reject(_), mind) if directory.variableOf(sender) != mind.partner.get =>
+ stay using mind
}
/**
@@ -225,7 +235,7 @@ class AgentBehaviour(variable: Variable,
if (debug) println(s"$variable in $stateName has received InformValue and the context is full.")
val peerVariable = directory.variableOf(sender)
var updatedMind: MGM2Mind = mind.updateContext(variable, peerVariable, peerValue)
- updatedMind = updatedMind.setPartner(variable, updatedMind.choosePartner(neighbours) )
+ updatedMind = updatedMind.setPartner(updatedMind.choosePartner(neighbours))
if (debug) println(s"$variable: the value of $peerVariable is $peerValue (${updatedMind.context.size-1}/${neighbours.size})")
unstashAll
goto(ReceiverWaitingOffers) using updatedMind
@@ -245,20 +255,20 @@ class AgentBehaviour(variable: Variable,
// When offers are still missing
case Event(MakeOffer(eventualOffer), mind) if mind.nbReceivedOffers < neighbours.size-1 =>
if (debug) println(s"$variable in $stateName has received MakeOffer and the context is partial.")
- val updatedMind: MGM2Mind = mind.addOffer(variable, eventualOffer)
+ val updatedMind: MGM2Mind = mind.addOffer(eventualOffer)
stay using updatedMind
// When the last offer is received
case Event(MakeOffer(eventualOffer), mind) if mind.nbReceivedOffers == neighbours.size-1 =>
if (debug) println(s"$variable in $stateName has received MakeOffer and the context is full.")
- var updatedMind: MGM2Mind = mind.addOffer(variable, eventualOffer)
+ var updatedMind: MGM2Mind = mind.addOffer(eventualOffer)
val (bestOffer, bestDelta) = updatedMind.chooseBestSingleOffer(variable, neighbours, constraints)
updatedMind = updatedMind.updateDeltas(variable, bestDelta)
val partner : Option[Variable]= bestOffer match {
case Some(o) => Some(o.offererVariable)
case None => None
}
- updatedMind = updatedMind.setCurrBestOffer(variable, bestOffer)
+ updatedMind = updatedMind.setCurrBestOffer(bestOffer)
if (trace) println(s"$variable -> $variable : BestOffer($bestOffer)")
self ! BestOffer(bestOffer)
unstashAll
@@ -287,9 +297,8 @@ class AgentBehaviour(variable: Variable,
if (debug) println(s"$variable in $stateName has received BestOffer")
if (trace) println(s"$variable -> ${bestOffer.offererVariable} : Accept($bestOffer)")
directory.addressOf(bestOffer.offererVariable) ! Accept(bestOffer)
- val updatedMind: MGM2Mind = mind.fullyCommit(variable, bestOffer.offererVariable, bestOffer)
- if (trace) println(s"$variable -> All except ${updatedMind.partner} : Reject(someOffer)")
- updatedMind.rejectAllUselessOffers(directory, Some(bestOffer)) //decline all other offers
+ val updatedMind: MGM2Mind = mind.commitFully(bestOffer.offererVariable, bestOffer)
+ rejectOffers(updatedMind.receivedOffers.filterNot(_ == bestOffer))//decline all other offers
if (trace) println(s"$variable -> All : InformDelta(${updatedMind.deltas(variable)})")
broadcast(InformDelta(updatedMind.deltas(variable))) //inform all neighbours
unstashAll
@@ -298,9 +307,9 @@ class AgentBehaviour(variable: Variable,
// When there is no coordinated move a unilateral move is performed
case Event(BestOffer(None), mind) =>
if (debug) println(s"$variable in $stateName has received BestOffer(empty)")
- val updatedMind: MGM2Mind = mind.uncommit(variable)
+ val updatedMind: MGM2Mind = mind.uncommit()
if (trace) println(s"$variable -> All : Reject(someOffer)")
- updatedMind.rejectAllUselessOffers(directory, None) //decline all offers
+ rejectOffers(updatedMind.receivedOffers) //decline all offers
if (trace) println(s"$variable -> All : InformDelta(${updatedMind.deltas(variable)})")
broadcast(InformDelta(updatedMind.deltas(variable))) //inform all neighbours
unstashAll
@@ -329,7 +338,7 @@ class AgentBehaviour(variable: Variable,
val neighbour: Variable = directory.variableOf(sender)
val updatedMind: MGM2Mind = mind.updateDeltas(neighbour: Variable, delta: Double)
val shouldIact: Boolean = updatedMind.amIBest(variable)
- var bestOffer: Option[Offer] = updatedMind.currBestOffer match {
+ val bestOffer: Option[Offer] = updatedMind.currBestOffer match {
case Some(o) => Some(o)
case None => throw new RuntimeException(s"Error $variable should have a best offer in $stateName")
}
@@ -354,14 +363,14 @@ class AgentBehaviour(variable: Variable,
if (debug) println(s"$variable in $stateName has received MakeOffer")
stay using mind
- //when it receives a neighbour's delta and the neighbourDeltas is partial
+ // When it receives a neighbour's delta and the neighbourDeltas is partial
case Event(InformDelta(delta), mind) if mind.deltas.size < neighbours.size =>
if (debug) println(s"$variable in $stateName has received InformDelta (${mind.deltas.size}/${neighbours.size}) and the context is partial.")
val neighbour: Variable = directory.variableOf(sender)
val updatedMind: MGM2Mind = mind.updateDeltas(neighbour: Variable, delta: Double)
stay using updatedMind
- //when it receves a neighbour's delta and the context is full
+ // When it receives a neighbour's delta and the context is full
case Event(InformDelta(delta), mind) if mind.deltas.size == neighbours.size =>
if (debug) println(s"$variable in $stateName has received InformDelta (${mind.deltas.size}/${neighbours.size})and the context is full.")
val neighbour: Variable = directory.variableOf(sender)
@@ -387,7 +396,8 @@ class AgentBehaviour(variable: Variable,
* Either the agent is in the ActSolo state
*/
when(ActSolo){
- //when it should act because it has the highest delta in the neighbourhood
+
+ // When it should act because it has the highest delta in the neighbourhood
case Event(Act(true, move), mind) =>
if (debug) println(s"$variable in $stateName has received Act(true)")
val newVal: Value = mind.updateVal(variable, move)
@@ -396,7 +406,7 @@ class AgentBehaviour(variable: Variable,
//supervisor ! InformValue(updatedMind.context.getValue(variable).get)
goto(Continue) using updatedMind
- //when it should not act because it does not have the highest delta in the neighbourhood
+ // When it should not act because it does not have the highest delta in the neighbourhood
case Event(Act(false, _), mind) =>
if (debug) println(s"$variable in $stateName has received Act(false)")
if (trace) println(s"$variable -> $supervisor : I didn't change = InformValue(${mind.context.getValue(variable).get})")
@@ -408,16 +418,16 @@ class AgentBehaviour(variable: Variable,
* Either the agent is in the GivingPartnerGoNogo state
*/
when(GivingPartnerGoNogo){
- //when it receives its own acting decision and should not act
- case Event(Act(false, _), mind) => {
+
+ // When it receives its own acting decision and should not act
+ case Event(Act(false, _), mind) =>
if (debug) println(s"$variable in $stateName has received Act(false)")
if (trace) println(s"$variable -> $supervisor : I didn't change = InformValue(${mind.context.getValue(variable).get})")
supervisor ! InformValue(mind.context.getValue(variable).get)
goto(Continue) using mind
- }
- //when it receives its own acting decision and should act
- case Event(Act(true, move), mind) => {
+ // When it receives its own acting decision and should act
+ case Event(Act(true, move), mind) =>
if (debug) println(s"$variable in $stateName has received Act(true)")
unstashAll
val partner: Variable = mind.partner match {
@@ -427,29 +437,27 @@ class AgentBehaviour(variable: Variable,
if (trace) println(s"$variable -> ${directory.addressOf(partner)} : GiveGo($move)")
directory.addressOf(partner) ! GiveGo(move)
goto(HandlingPartnersGoNogo) using mind
- }
- //when its partner tells it to go
- case Event(GiveGo(_), mind) => {
+ // When its partner tells it to go
+ case Event(GiveGo(_), mind) =>
if (debug) println(s"$variable in $stateName has received GiveGo")
stash
stay using mind
- }
- //when its partner tells it not to go
- case Event(GiveNoGo, mind) => {
+ // When its partner tells it not to go
+ case Event(GiveNoGo, mind) =>
if (debug) println(s"$variable in $stateName has received GiveNoGo")
stash
stay using mind
- }
}
/**
* Either the agent is in the GivingPartnerGoNogo state
*/
when(HandlingPartnersGoNogo){
- //when it receives a Go from its partner
- case Event(GiveGo(move), mind) => {
+
+ // When it receives a Go from its partner
+ case Event(GiveGo(move), mind) =>
if (debug) println(s"$variable in $stateName has received Trigger")
val newVal: Value = mind.updateVal(variable, move)
val updatedMind: MGM2Mind = new MGM2Mind(context = mind.context.fix(variable, newVal),
@@ -460,8 +468,8 @@ class AgentBehaviour(variable: Variable,
if (trace) println(s"$variable -> $supervisor : I'm changing = InformValue(${updatedMind.context.getValue(variable).get})")
supervisor ! InformValue(updatedMind.context.getValue(variable).get)
goto(Continue) using updatedMind
- }
- //when it receives a NoGo from its partner
+
+ // When it receives a NoGo from its partner
case Event(GiveNoGo, mind) => {
if (debug) println(s"$variable in $stateName has received GiveNoGo")
if (trace) println(s"$variable -> $supervisor : I'm not changing = InformValue(${mind.context.getValue(variable).get})")
@@ -475,22 +483,26 @@ class AgentBehaviour(variable: Variable,
* Whatever the state is
**/
whenUnhandled {
+
// If the agent is killed
case Event(Query, mind) =>
sender ! Inform(mind.metric)
context.stop(self)
stay using mind
+
// If the agent is enlightened with the acquaintances it is no more blind
case Event(Light(directory), mind) =>
supervisor = sender
this.directory = directory
sender ! Ready
stay using mind
+
// If the agent must trace the protocol
case Event(Trace, mind) =>
if (debug) println("Agent receives Trace")
this.trace = true
stay using mind
+
// Other
case Event(msg @ _, _) =>
throw new RuntimeException(s"Error $variable was not expected message $msg in state $stateName")
diff --git a/src/main/scala/org/scadcop/solver/decentralized/mgm2/MGM2Mind.scala b/src/main/scala/org/scadcop/solver/decentralized/mgm2/MGM2Mind.scala
index 6eecb11e7cbf5f86244a44016ebb4de9b99cf7fa..3a1b53d67b7f1ebdf4483943ba6aa3560d7674cc 100644
--- a/src/main/scala/org/scadcop/solver/decentralized/mgm2/MGM2Mind.scala
+++ b/src/main/scala/org/scadcop/solver/decentralized/mgm2/MGM2Mind.scala
@@ -223,7 +223,7 @@ class MGM2Mind(val context : Context = new Context(),
/*
* Add an offer
*/
- def addOffer(variable: Variable, newOffer: Offer): MGM2Mind = {
+ def addOffer(newOffer: Offer): MGM2Mind = {
new MGM2Mind(context,
isCommitted,
partner,
@@ -238,7 +238,7 @@ class MGM2Mind(val context : Context = new Context(),
/**
* Set partner
*/
- def setPartner(variable: Variable, newPartner: Variable) : MGM2Mind = {
+ def setPartner(newPartner: Variable): MGM2Mind = {
new MGM2Mind(context,
isCommitted,
Some(newPartner),
@@ -252,7 +252,7 @@ class MGM2Mind(val context : Context = new Context(),
/**
* Set current best offer
*/
- def setCurrBestOffer(variable: Variable, newOffer: Option[Offer]) : MGM2Mind = {
+ def setCurrBestOffer(newOffer: Option[Offer]): MGM2Mind = {
new MGM2Mind(context,
isCommitted,
partner,
@@ -266,7 +266,7 @@ class MGM2Mind(val context : Context = new Context(),
/**
* Set commitment
*/
- def uncommit(variable: Variable) : MGM2Mind = {
+ def uncommit(): MGM2Mind = {
new MGM2Mind(context,
isCommitted = false,
partner = None,
@@ -280,7 +280,7 @@ class MGM2Mind(val context : Context = new Context(),
/**
* Set commitment
*/
- def fullyCommit(variable: Variable, newPartner: Variable, newOffer: Offer): MGM2Mind = {
+ def commitFully(newPartner: Variable, newOffer: Offer): MGM2Mind = {
new MGM2Mind(context,
isCommitted = true,
partner = Some(newPartner),
@@ -291,18 +291,4 @@ class MGM2Mind(val context : Context = new Context(),
currBestOffer = Some(newOffer))
}
- /**
- * Reject all the offers from a set of received offers except maybe one (or none)
- */
- //??? type
- def rejectAllUselessOffers(directory: Directory, acceptedOffer: Option[Offer]): Unit = {
- val rejectedOffers = acceptedOffer match {
- case Some(o) => receivedOffers.filter(_ != o)
- case None => receivedOffers
- }
- rejectedOffers.foreach{ offer: Offer =>
- val neighbour: Variable = offer.offererVariable
- directory.addressOf(neighbour) ! Reject(offer)
- }
- }
}