Skip to content

Commit

Permalink
Refactoring AgentKnowledge
Browse files Browse the repository at this point in the history
  • Loading branch information
lmorisse committed Aug 18, 2020
1 parent 5b38b96 commit a868f26
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 163 deletions.
2 changes: 1 addition & 1 deletion SourceCode/Symu/Classes/Agents/CognitiveAgent.Murphies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ protected virtual void CheckBlockerIncompleteKnowledge(SymuTask task, ushort kno
byte mandatoryIndex = 0;
byte requiredIndex = 0;
Environment.Organization.Murphies.IncompleteKnowledge.CheckKnowledge(knowledgeId, taskBits,
KnowledgeModel.Expertise, ref mandatoryOk, ref requiredOk,
KnowledgeModel, ref mandatoryOk, ref requiredOk,
ref mandatoryIndex, ref requiredIndex, Schedule.Step);
if (!mandatoryOk)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public void AddKnowledge(ushort knowledgeId, KnowledgeLevel level, float minimum
return null;
}

if (!Expertise.KnowsEnough(knowledgeId, knowledgeBit,
if (!KnowsEnough(knowledgeId, knowledgeBit,
_messageContent.MinimumKnowledgeToSendPerBit, step))
{
return null;
Expand Down Expand Up @@ -241,5 +241,87 @@ public AgentKnowledge GetKnowledge(ushort knowledgeId)
{
return Expertise.GetKnowledge(knowledgeId);
}

#region KnowsEnough

/// <summary>
/// Check if agentKnowLedgeBits include or not taskKnowledgeIndexes
/// </summary>
/// <param name="agentKnowledge"></param>
/// <param name="taskKnowledgeIndexes">indexes of the KnowledgeBits that must be checked</param>
/// <param name="index"></param>
/// <param name="knowledgeThreshHoldForDoing"></param>
/// <param name="step"></param>
/// <returns>0 if agentKnowLedgeBits include taskKnowledge</returns>
/// <returns>index if agentKnowLedgeBits include taskKnowledge</returns>
public bool Check(AgentKnowledge agentKnowledge, byte[] taskKnowledgeIndexes, out byte index, float knowledgeThreshHoldForDoing, ushort step)
{
if (taskKnowledgeIndexes is null)
{
throw new ArgumentNullException(nameof(taskKnowledgeIndexes));
}

for (byte i = 0; i < taskKnowledgeIndexes.Length; i++)
{
if (KnowsEnough(agentKnowledge, taskKnowledgeIndexes[i], knowledgeThreshHoldForDoing, step))
{
continue;
}

index = taskKnowledgeIndexes[i];
return false;
}

index = 0;
return true;
}

/// <summary>
/// Check that agent has the knowledgeId[knowledgeBit] == 1
/// </summary>
/// <param name="knowledgeId"></param>
/// <param name="knowledgeBit"></param>
/// <param name="knowledgeThreshHoldForAnswer"></param>
/// <param name="step"></param>
/// <returns>true if the agent has the knowledge</returns>
public bool KnowsEnough(ushort knowledgeId, byte knowledgeBit, float knowledgeThreshHoldForAnswer, ushort step)
{
if (!Expertise.Contains(knowledgeId))
{
return false;
}

var knowledge = GetKnowledge(knowledgeId);
return KnowsEnough(knowledge, knowledgeBit, knowledgeThreshHoldForAnswer, step);
}

/// <summary>
/// Check that agent has the knowledgeBit
/// </summary>
/// <param name="agentKnowledge"></param>
/// <param name="index">index of the knowledgeBit</param>
/// <param name="knowledgeThreshHoldForAnswer"></param>
/// <param name="step"></param>
/// <returns>true if agent has the knowledge</returns>
public static bool KnowsEnough(AgentKnowledge agentKnowledge, byte index, float knowledgeThreshHoldForAnswer, ushort step)
{
if (agentKnowledge == null)
{
throw new ArgumentNullException(nameof(agentKnowledge));
}

if (agentKnowledge.Length == 0)
{
return false;
}

if (index >= agentKnowledge.Length)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

return agentKnowledge.KnowledgeBits.GetBit(index, step) >= knowledgeThreshHoldForAnswer;
}
#endregion
}
}
29 changes: 18 additions & 11 deletions SourceCode/Symu/Classes/Murphies/MurphyIncompleteKnowledge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#region using directives

using System;
using Symu.Classes.Agents.Models.CognitiveModels;
using Symu.Classes.Task;
using Symu.Repository.Networks.Knowledges;

Expand All @@ -28,13 +29,13 @@ public class MurphyIncompleteKnowledge : MurphyIncomplete
/// </summary>
/// <param name="knowledgeId"></param>
/// <param name="taskBitIndexes">KnowledgeBits indexes of the task that must be checked against worker Knowledge</param>
/// <param name="expertise"></param>
/// <param name="knowledgeModel"></param>
/// <param name="mandatoryCheck"></param>
/// <param name="requiredCheck"></param>
/// <param name="mandatoryIndex"></param>
/// <param name="requiredIndex"></param>
/// <param name="step"></param>
public void CheckKnowledge(ushort knowledgeId, TaskKnowledgeBits taskBitIndexes, AgentExpertise expertise,
public void CheckKnowledge(ushort knowledgeId, TaskKnowledgeBits taskBitIndexes, KnowledgeModel knowledgeModel,
ref bool mandatoryCheck,
ref bool requiredCheck, ref byte mandatoryIndex, ref byte requiredIndex, ushort step)
{
Expand All @@ -43,6 +44,11 @@ public class MurphyIncompleteKnowledge : MurphyIncomplete
throw new ArgumentNullException(nameof(taskBitIndexes));
}

if (knowledgeModel == null)
{
throw new ArgumentNullException(nameof(knowledgeModel));
}

// model is off
if (!IsAgentOn())
{
Expand All @@ -52,15 +58,15 @@ public class MurphyIncompleteKnowledge : MurphyIncomplete
}

// agent may don't have the knowledge at all
var workerKnowledge = expertise?.GetKnowledge(knowledgeId);
var workerKnowledge = knowledgeModel.Expertise.GetKnowledge(knowledgeId);
if (workerKnowledge == null)
{
return;
}

mandatoryCheck = workerKnowledge.Check(taskBitIndexes.GetMandatory(), out mandatoryIndex,
mandatoryCheck = knowledgeModel.Check(workerKnowledge, taskBitIndexes.GetMandatory(), out mandatoryIndex,
ThresholdForReacting, step);
requiredCheck = workerKnowledge.Check(taskBitIndexes.GetRequired(), out requiredIndex,
requiredCheck = knowledgeModel.Check(workerKnowledge, taskBitIndexes.GetRequired(), out requiredIndex,
ThresholdForReacting, step);
}

Expand All @@ -69,21 +75,22 @@ public class MurphyIncompleteKnowledge : MurphyIncomplete
/// </summary>
/// <param name="knowledgeId"></param>
/// <param name="knowledgeBit">KnowledgeBit index of the task that must be checked against worker Knowledge</param>
/// <param name="expertise"></param>
/// <param name="knowledgeModel"></param>
/// <param name="step"></param>
/// <returns>True if the knowledgeBit is known enough</returns>
public bool CheckKnowledge(ushort knowledgeId, byte knowledgeBit, AgentExpertise expertise, ushort step)
public bool CheckKnowledge(ushort knowledgeId, byte knowledgeBit, KnowledgeModel knowledgeModel, ushort step)
{
if (!IsAgentOn())
{
return false;
}

// workerKnowledge may don't have the knowledge at all
var workerKnowledge = expertise?.GetKnowledge(knowledgeId);
return workerKnowledge != null &&
workerKnowledge.KnowsEnough(knowledgeBit, ThresholdForReacting,
step);
return knowledgeModel.KnowsEnough(knowledgeId, knowledgeBit, ThresholdForReacting, step);
//var workerKnowledge = expertise?.GetKnowledge(knowledngeId);
//return workerKnowledge != null &&
// workerKnowledge.KnowsEnough(knowledgeBit, ThresholdForReacting,
// step);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public DataBaseEntity(IAgentId agentId, CommunicationTemplate medium)

AgentId = agentId;
CognitiveArchitecture = new CognitiveArchitecture();
// Communication
CognitiveArchitecture.MessageContent.MaximumNumberOfBitsOfBeliefToSend =
medium.MaximumNumberOfBitsOfBeliefToSend;
CognitiveArchitecture.MessageContent.MaximumNumberOfBitsOfKnowledgeToSend =
Expand All @@ -58,6 +59,10 @@ public DataBaseEntity(IAgentId agentId, CommunicationTemplate medium)
CognitiveArchitecture.MessageContent.MinimumNumberOfBitsOfKnowledgeToSend =
medium.MinimumNumberOfBitsOfKnowledgeToSend;
CognitiveArchitecture.InternalCharacteristics.TimeToLive = medium.TimeToLive;
// Knowledge
CognitiveArchitecture.TasksAndPerformance.LearningRate = 1;
CognitiveArchitecture.InternalCharacteristics.CanLearn = true;
CognitiveArchitecture.KnowledgeAndBeliefs.HasKnowledge = true;
}

/// <summary>
Expand Down
20 changes: 0 additions & 20 deletions SourceCode/Symu/Repository/Networks/Knowledges/AgentExpertise.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,26 +148,6 @@ public IEnumerable<ushort> GetKnowledgeIds()
return List.Select(x => x.KnowledgeId);
}

/// <summary>
/// Check that agent has the knowledgeId[knowledgeBit] == 1
/// </summary>
/// <param name="knowledgeId"></param>
/// <param name="knowledgeBit"></param>
/// <param name="knowledgeThreshHoldForAnswer"></param>
/// <param name="step"></param>
/// <returns>true if the agent has the knowledge</returns>
public bool KnowsEnough(ushort knowledgeId, byte knowledgeBit, float knowledgeThreshHoldForAnswer, ushort step)
{
if (!Contains(knowledgeId))
{
return false;
}

var knowledge = GetKnowledge(knowledgeId);
return knowledge.KnowsEnough(knowledgeBit, knowledgeThreshHoldForAnswer, step);
}


///// <summary>
///// OnAfterLearning event is triggered if learning occurs,
///// you can subscribe to this event to treat the new learning
Expand Down
53 changes: 0 additions & 53 deletions SourceCode/Symu/Repository/Networks/Knowledges/AgentKnowledge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#region using directives

using System;
using static Symu.Common.Constants;

#endregion

Expand Down Expand Up @@ -201,57 +200,5 @@ public void SetKnowledgeBit(byte index, float value, ushort step)
KnowledgeBits.SetBit(index, value, step);
}

/// <summary>
/// Check if agentKnowLedgeBits include or not taskKnowledgeIndexes
/// </summary>
/// <param name="taskKnowledgeIndexes">indexes of the KnowledgeBits that must be checked</param>
/// <param name="index"></param>
/// <param name="knowledgeThreshHoldForDoing"></param>
/// <param name="step"></param>
/// <returns>0 if agentKnowLedgeBits include taskKnowledge</returns>
/// <returns>index if agentKnowLedgeBits include taskKnowledge</returns>
public bool Check(byte[] taskKnowledgeIndexes, out byte index, float knowledgeThreshHoldForDoing, ushort step)
{
if (taskKnowledgeIndexes is null)
{
throw new ArgumentNullException(nameof(taskKnowledgeIndexes));
}

for (byte i = 0; i < taskKnowledgeIndexes.Length; i++)
{
if (KnowsEnough(taskKnowledgeIndexes[i], knowledgeThreshHoldForDoing, step))
{
continue;
}

index = taskKnowledgeIndexes[i];
return false;
}

index = 0;
return true;
}

/// <summary>
/// Check that agent has the knowledgeBit
/// </summary>
/// <param name="index">index of the knowledgeBit</param>
/// <param name="knowledgeThreshHoldForAnswer"></param>
/// <param name="step"></param>
/// <returns>true if agent has the knowledge</returns>
public bool KnowsEnough(byte index, float knowledgeThreshHoldForAnswer, ushort step)
{
if (Length == 0)
{
return false;
}

if (index >= Length)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

return KnowledgeBits.GetBit(index, step) >= knowledgeThreshHoldForAnswer;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ namespace SymuTests.Classes.Agents.Models.CognitiveModels
[TestClass]
public class KnowledgeModelTests
{
private const float Threshold = 0.1F;
private readonly byte[] _taskKnowledge0 = { 0 };
private readonly byte[] _taskKnowledge1 = { 1 };
private readonly float[] _knowledgeFloatBits = { 0.1F, 0.1F };
private readonly float[] _knowledge01Bits = { 0, 1 };
private readonly float[] _knowledge0Bits = { 0, 0 };
//private readonly float[] _knowledge1Bits = { 1, 1 };
private AgentKnowledge _agentKnowledge0;
private AgentKnowledge _agentKnowledge01;
private AgentKnowledge _agentKnowledge1;
private AgentKnowledge _agentKnowledgeFloat;
private readonly AgentId _agentId = new AgentId(1, 1);
private readonly EmailTemplate _emailTemplate = new EmailTemplate();
private AgentExpertise _expertise;
Expand Down Expand Up @@ -57,6 +68,10 @@ public void Initialize()
_network.Knowledge.Add(_agentId, _expertise);
_taskBits.SetMandatory(new byte[] {0});
_taskBits.SetRequired(new byte[] {0});
_agentKnowledgeFloat = new AgentKnowledge(3, _knowledgeFloatBits, 0, -1, 0);
_agentKnowledge0 = new AgentKnowledge(0, _knowledge0Bits, 0, -1, 0);
_agentKnowledge1 = new AgentKnowledge(1, _knowledge1Bits, 0, -1, 0);
_agentKnowledge01 = new AgentKnowledge(2, _knowledge01Bits, 0, -1, 0);
}

/// <summary>
Expand Down Expand Up @@ -305,5 +320,54 @@ public void InitializeKnowledgeTest()
var agentKnowledge = _knowledgeModel.Expertise.GetKnowledge(_knowledge.Id);
Assert.AreEqual(1, agentKnowledge.KnowledgeBits.GetBit(0));
}

#region KnowsEnough

[TestMethod]
public void CheckTest()
{
Assert.IsFalse(_knowledgeModel.Check(_agentKnowledge0, _taskKnowledge0, out var index, Threshold, 0));
Assert.AreEqual(0, index);
Assert.IsFalse(_knowledgeModel.Check(_agentKnowledge0, _taskKnowledge1, out index, Threshold, 0));
Assert.AreEqual(1, index);
Assert.IsTrue(_knowledgeModel.Check(_agentKnowledge1, _taskKnowledge0, out _, Threshold, 0));
Assert.IsTrue(_knowledgeModel.Check(_agentKnowledge1, _taskKnowledge1, out _, Threshold, 0));
Assert.IsFalse(_knowledgeModel.Check(_agentKnowledge01, _taskKnowledge0, out index, Threshold, 0));
Assert.AreEqual(0, index);
Assert.IsTrue(_knowledgeModel.Check(_agentKnowledge01, _taskKnowledge1, out _, Threshold, 0));
Assert.IsTrue(_knowledgeModel.Check(_agentKnowledgeFloat, _taskKnowledge0, out _, Threshold, 0));
Assert.IsTrue(_knowledgeModel.Check(_agentKnowledgeFloat, _taskKnowledge1, out _, Threshold, 0));
}

[TestMethod]
public void KnowsEnoughTest()
{
var agentKnowledge = new AgentKnowledge(4, KnowledgeLevel.BasicKnowledge, 0, -1);
// Non passing test
Assert.IsFalse(KnowledgeModel.KnowsEnough(agentKnowledge, 0, Threshold, 0));
// Passing tests
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledge0, 0, 0, 0));
Assert.IsFalse(KnowledgeModel.KnowsEnough(_agentKnowledge0, 0, Threshold, 0));
Assert.IsFalse(KnowledgeModel.KnowsEnough(_agentKnowledge0, 1, Threshold, 0));
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledge1, 0, Threshold, 0));
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledge1, 1, Threshold, 0));
Assert.IsFalse(KnowledgeModel.KnowsEnough(_agentKnowledge01, 0, Threshold, 0));
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledge01, 1, Threshold, 0));
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledgeFloat, 0, Threshold, 0));
Assert.IsTrue(KnowledgeModel.KnowsEnough(_agentKnowledgeFloat, 1, Threshold, 0));
}


[TestMethod]
public void HasTest()
{
float[] bits = { 0, 1 };
var knowledgeBits = new KnowledgeBits(bits, 0, -1);
var agentKnowledge = new AgentKnowledge(1, knowledgeBits);
_expertise.Add(agentKnowledge);
Assert.IsFalse(_knowledgeModel.KnowsEnough(_knowledge.Id, 0, 0.1F, 0));
Assert.IsTrue(_knowledgeModel.KnowsEnough(_knowledge.Id, 1, 0.1F, 0));
}
#endregion
}
}

0 comments on commit a868f26

Please sign in to comment.