diff --git a/Aplib.Core.Tests/BdiAgentTests.cs b/Aplib.Core.Tests/BdiAgentTests.cs index 3745714a..dd4cc9eb 100644 --- a/Aplib.Core.Tests/BdiAgentTests.cs +++ b/Aplib.Core.Tests/BdiAgentTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Agents; using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; diff --git a/Aplib.Core.Tests/Belief/BeliefSetTests.cs b/Aplib.Core.Tests/Belief/BeliefSetTests.cs index 6a0b2a4f..0200b6ca 100644 --- a/Aplib.Core.Tests/Belief/BeliefSetTests.cs +++ b/Aplib.Core.Tests/Belief/BeliefSetTests.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.Beliefs; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.Beliefs; using Aplib.Core.Belief.BeliefSets; namespace Aplib.Core.Tests.Belief; @@ -9,79 +13,45 @@ namespace Aplib.Core.Tests.Belief; public class BeliefSetTests { /// - /// Given a BeliefSet instance with multiple public field beliefs, - /// When UpdateBeliefs is called, - /// Then all beliefs are updated. + /// A simple belief that can be used to test whether has been called. /// - [Fact] - public void UpdateBeliefs_PublicBeliefFields_UpdatesAllBeliefs() + private class SimpleBelief : IBelief { - // Arrange - TestBeliefSetPublic beliefSet = new(); - - // Act - // UpdateBeliefs should set Updated to true for all beliefs. - beliefSet.UpdateBeliefs(); + /// + /// Stores whether has been called. + /// + public bool Updated { get; private set; } = false; - // Assert - Assert.True(beliefSet.Belief1.Updated); - Assert.True(beliefSet.Belief2.Updated); + /// + /// Sets to true. + /// + public void UpdateBelief() + { + Updated = true; + } } - /// - /// Given a BeliefSet instance with multiple public property beliefs, - /// When UpdateBeliefs is called, - /// Then no beliefs are updated. - /// - [Fact] - public void UpdateBeliefs_PublicBeliefProperties_DoesNotUpdateAnyBeliefs() - { - // Arrange - TestBeliefSetProperties beliefSet = new(); - - // Act - // UpdateBeliefs should *not* set Updated to true for any belief. - beliefSet.UpdateBeliefs(); - - // Assert - Assert.False(beliefSet.Belief1.Updated); - Assert.False(beliefSet.Belief2.Updated); - } /// - /// Given a BeliefSet instance with multiple private field beliefs, - /// When UpdateBeliefs is called, - /// Then no beliefs are updated. + /// A test belief set that contains two private simple beliefs. /// - [Fact] - public void UpdateBeliefs_PrivateBeliefFields_DoesNotUpdateAnyBeliefs() + private class TestBeliefSetPrivate : BeliefSet { - // Arrange - TestBeliefSetPrivate beliefSet = new(); - - // Act - // UpdateBeliefs should *not* set Updated to true for any belief. - beliefSet.UpdateBeliefs(); + /// + public SimpleBelief Belief1 => _belief1; - // Assert - Assert.False(beliefSet.Belief1.Updated); - Assert.False(beliefSet.Belief2.Updated); - } + /// + public SimpleBelief Belief2 => _belief2; - /// - /// A test belief set that contains two public simple beliefs. - /// - private class TestBeliefSetPublic : BeliefSet - { /// /// Belief that sets Updated to true when UpdateBelief is called. /// - public SimpleBelief Belief1 = new(); + private SimpleBelief _belief1 = new(); /// /// Belief that sets Updated to true when UpdateBelief is called. /// - public SimpleBelief Belief2 = new(); + private SimpleBelief _belief2 = new(); } @@ -101,45 +71,79 @@ private class TestBeliefSetProperties : BeliefSet public SimpleBelief Belief2 { get; } = new(); } - /// - /// A test belief set that contains two private simple beliefs. + /// A test belief set that contains two public simple beliefs. /// - private class TestBeliefSetPrivate : BeliefSet + private class TestBeliefSetPublic : BeliefSet { /// /// Belief that sets Updated to true when UpdateBelief is called. /// - private SimpleBelief _belief1 = new(); + public SimpleBelief Belief1 = new(); /// /// Belief that sets Updated to true when UpdateBelief is called. /// - private SimpleBelief _belief2 = new(); + public SimpleBelief Belief2 = new(); + } - /// - public SimpleBelief Belief1 => _belief1; + /// + /// Given a BeliefSet instance with multiple private field beliefs, + /// When UpdateBeliefs is called, + /// Then no beliefs are updated. + /// + [Fact] + public void UpdateBeliefs_PrivateBeliefFields_DoesNotUpdateAnyBeliefs() + { + // Arrange + TestBeliefSetPrivate beliefSet = new(); - /// - public SimpleBelief Belief2 => _belief2; + // Act + // UpdateBeliefs should *not* set Updated to true for any belief. + beliefSet.UpdateBeliefs(); + + // Assert + Assert.False(beliefSet.Belief1.Updated); + Assert.False(beliefSet.Belief2.Updated); } /// - /// A simple belief that can be used to test whether has been called. + /// Given a BeliefSet instance with multiple public field beliefs, + /// When UpdateBeliefs is called, + /// Then all beliefs are updated. /// - private class SimpleBelief : IBelief + [Fact] + public void UpdateBeliefs_PublicBeliefFields_UpdatesAllBeliefs() { - /// - /// Stores whether has been called. - /// - public bool Updated { get; private set; } = false; + // Arrange + TestBeliefSetPublic beliefSet = new(); - /// - /// Sets to true. - /// - public void UpdateBelief() - { - Updated = true; - } + // Act + // UpdateBeliefs should set Updated to true for all beliefs. + beliefSet.UpdateBeliefs(); + + // Assert + Assert.True(beliefSet.Belief1.Updated); + Assert.True(beliefSet.Belief2.Updated); + } + + /// + /// Given a BeliefSet instance with multiple public property beliefs, + /// When UpdateBeliefs is called, + /// Then no beliefs are updated. + /// + [Fact] + public void UpdateBeliefs_PublicBeliefProperties_DoesNotUpdateAnyBeliefs() + { + // Arrange + TestBeliefSetProperties beliefSet = new(); + + // Act + // UpdateBeliefs should *not* set Updated to true for any belief. + beliefSet.UpdateBeliefs(); + + // Assert + Assert.False(beliefSet.Belief1.Updated); + Assert.False(beliefSet.Belief2.Updated); } } diff --git a/Aplib.Core.Tests/Belief/BeliefTests.cs b/Aplib.Core.Tests/Belief/BeliefTests.cs index 342c2b0d..b286c3c9 100644 --- a/Aplib.Core.Tests/Belief/BeliefTests.cs +++ b/Aplib.Core.Tests/Belief/BeliefTests.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.Beliefs; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.Beliefs; using FluentAssertions; using Moq; using System.Collections; @@ -34,9 +38,8 @@ public IEnumerator GetEnumerator() public class TestBelief : Belief { - public object Reference => _reference; - public System.Func GetObservationFromReference => _getObservationFromReference; + public object Reference => _reference; public System.Predicate ShouldUpdate => _shouldUpdate; @@ -68,6 +71,67 @@ public TestBelief(object reference, System.Func getObservationFr } } + /// + /// Given a Belief instance, + /// When it is assigned to a variable of its observation type, + /// Then it is implicitly converted to its observation type. + /// + [Fact] + public void Belief_AssignedToObservationType_IsCorrectlyImplicitlyConvertedToObservationType() + { + // Arrange + // ReSharper disable once ConvertToConstant.Local + string def = "def"; + + // Observation: Get the first letter. + Belief belief = new(def, reference => reference[0]); + + // Act, Assert + Assert.Equal(belief.Observation, belief); + } + + /// + /// Given a reference that is actually a value type, hidden behind an interface, + /// When a new Belief is constructed from this reference, + /// The constructor throws an ArgumentException. + /// + [Fact] + public void Belief_ConstructedWithAValueTypeViaAnInterface_IsRejected() + { + // Arrange + MyEnumerable value = new(1); + const string paramName = "reference"; + + // ReSharper disable once ConvertToLocalFunction + System.Action construction = () => + { + // The bug is the fact that we can get around the constraint that `TReference` should be a reference type. + _ = new Belief, List>(value, values => values.ToList()); + }; + + // Act, Assert + Assert.Throws(paramName, construction); + } + + /// + /// Given a reference, + /// When a new Belief is constructed, + /// Then the observation is also initialized. + /// + [Fact] + public void Belief_DuringConstruction_UpdatesTheObservation() + { + // Arrange + // ReSharper disable once ConvertToConstant.Local + string def = "def"; + + // Act + Belief belief = new(def, str => str); + + // Assert + Assert.Equal(def, belief.Observation); + } + [Fact] public void Belief_WhenConstructed_HasExpectedData() { @@ -107,24 +171,6 @@ public void Belief_WithoutMetadata_HasExpectedData() belief.ShouldUpdate.Should().Be(shouldUpdate); } - [Fact] - public void Belief_WithoutShouldUpdate_HasExpectedData() - { - // Arrange - Metadata metadata = It.IsAny(); - object reference = new Mock().Object; - System.Func getObservationFromReference = new Mock>().Object; - - // Act - TestBelief belief = new(metadata, reference, getObservationFromReference); - - // Assert - belief.Metadata.Should().Be(metadata); - belief.Reference.Should().Be(reference); - belief.GetObservationFromReference.Should().Be(getObservationFromReference); - belief.ShouldUpdate(reference).Should().BeTrue(); - } - [Fact] public void Belief_WithoutMetadataWithoutShouldUpdate_HasExpectedData() { @@ -144,65 +190,22 @@ public void Belief_WithoutMetadataWithoutShouldUpdate_HasExpectedData() belief.ShouldUpdate(reference).Should().BeTrue(); } - /// - /// Given a Belief instance, - /// When it is assigned to a variable of its observation type, - /// Then it is implicitly converted to its observation type. - /// - [Fact] - public void Belief_AssignedToObservationType_IsCorrectlyImplicitlyConvertedToObservationType() - { - // Arrange - // ReSharper disable once ConvertToConstant.Local - string def = "def"; - - // Observation: Get the first letter. - Belief belief = new(def, reference => reference[0]); - - // Act, Assert - Assert.Equal(belief.Observation, belief); - } - - /// - /// Given a reference that is actually a value type, hidden behind an interface, - /// When a new Belief is constructed from this reference, - /// The constructor throws an ArgumentException. - /// - [Fact] - public void Belief_ConstructedWithAValueTypeViaAnInterface_IsRejected() - { - // Arrange - MyEnumerable value = new(1); - const string paramName = "reference"; - - // ReSharper disable once ConvertToLocalFunction - System.Action construction = () => - { - // The bug is the fact that we can get around the constraint that `TReference` should be a reference type. - _ = new Belief, List>(value, values => values.ToList()); - }; - - // Act, Assert - Assert.Throws(paramName, construction); - } - - /// - /// Given a reference, - /// When a new Belief is constructed, - /// Then the observation is also initialized. - /// [Fact] - public void Belief_DuringConstruction_UpdatesTheObservation() + public void Belief_WithoutShouldUpdate_HasExpectedData() { // Arrange - // ReSharper disable once ConvertToConstant.Local - string def = "def"; + Metadata metadata = It.IsAny(); + object reference = new Mock().Object; + System.Func getObservationFromReference = new Mock>().Object; // Act - Belief belief = new(def, str => str); + TestBelief belief = new(metadata, reference, getObservationFromReference); // Assert - Assert.Equal(def, belief.Observation); + belief.Metadata.Should().Be(metadata); + belief.Reference.Should().Be(reference); + belief.GetObservationFromReference.Should().Be(getObservationFromReference); + belief.ShouldUpdate(reference).Should().BeTrue(); } /// diff --git a/Aplib.Core.Tests/Belief/ListBeliefTests.cs b/Aplib.Core.Tests/Belief/ListBeliefTests.cs index 5d9e042f..49c16de4 100644 --- a/Aplib.Core.Tests/Belief/ListBeliefTests.cs +++ b/Aplib.Core.Tests/Belief/ListBeliefTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.Beliefs; using System.Collections.Generic; @@ -9,26 +13,22 @@ namespace Aplib.Core.Tests.Belief; public class ListBeliefTests { /// - /// Given a ListBelief without an explicit shouldUpdate parameter, - /// When UpdateBelief is called, - /// Then the observation is updated. + /// Given an empty collection, + /// When a ListBelief is created from that collection, + /// Then the observation is also empty /// [Fact] - public void ListBelief_WithoutShouldUpdate_UpdatesObservation() + public void ListBelief_FromEmptyEnumerable_HasEmptyObservationList() { // Arrange - int[] numbers = [1, 1, 2, 3, 5, 8]; - - // Observation: Is the number even? - ListBelief belief = new(numbers, i => i % 2 == 0); + // ReSharper disable once CollectionNeverUpdated.Local + Stack stack = new(); // Act - numbers[0] = 0; - belief.UpdateBelief(); + ListBelief belief = new(stack, b => b); // Assert - List expected = [true, false, true, false, false, true]; - Assert.Equal(expected, belief); + Assert.Empty(belief.Observation); } /// @@ -55,21 +55,25 @@ public void ListBelief_ShouldUpdateConditionIsNotSatisfied_DoesNotUpdateObservat } /// - /// Given an empty collection, - /// When a ListBelief is created from that collection, - /// Then the observation is also empty + /// Given a ListBelief without an explicit shouldUpdate parameter, + /// When UpdateBelief is called, + /// Then the observation is updated. /// [Fact] - public void ListBelief_FromEmptyEnumerable_HasEmptyObservationList() + public void ListBelief_WithoutShouldUpdate_UpdatesObservation() { // Arrange - // ReSharper disable once CollectionNeverUpdated.Local - Stack stack = new(); + int[] numbers = [1, 1, 2, 3, 5, 8]; + + // Observation: Is the number even? + ListBelief belief = new(numbers, i => i % 2 == 0); // Act - ListBelief belief = new(stack, b => b); + numbers[0] = 0; + belief.UpdateBelief(); // Assert - Assert.Empty(belief.Observation); + List expected = [true, false, true, false, false, true]; + Assert.Equal(expected, belief); } } diff --git a/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs b/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs index 71d3b303..f43f7a7b 100644 --- a/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs +++ b/Aplib.Core.Tests/Belief/MemoryBeliefTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.Beliefs; using Aplib.Core.Collections; using FluentAssertions; @@ -13,13 +17,12 @@ public class MemoryBeliefTests { public class TestMemoryBelief : MemoryBelief { - public object Reference => _reference; - public System.Func GetObservationFromReference => _getObservationFromReference; - public System.Predicate ShouldUpdate => _shouldUpdate; - public ExposedQueue MemorizedObservations => _memorizedObservations; + public object Reference => _reference; + + public System.Predicate ShouldUpdate => _shouldUpdate; public TestMemoryBelief ( @@ -62,88 +65,68 @@ public TestMemoryBelief } } + /// + /// Given a MemoryBelief instance with an observation, + /// When the observation is updated and GetAllMemories is called, + /// Then all the currently saved observations are returned. + /// [Fact] - public void MemoryBelief_WhenConstructed_HasExpectedData() - { - // Arrange - Metadata metadata = It.IsAny(); - object reference = new Mock().Object; - System.Func getObservationFromReference = new Mock>().Object; - const int framesToRemember = 0; - System.Predicate shouldUpdate = It.IsAny>(); - - // Act - TestMemoryBelief belief = new(metadata, reference, getObservationFromReference, framesToRemember, shouldUpdate); - - // Assert - belief.Metadata.Should().Be(metadata); - belief.Reference.Should().Be(reference); - belief.GetObservationFromReference.Should().Be(getObservationFromReference); - belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); - belief.ShouldUpdate.Should().Be(shouldUpdate); - } - - [Fact] - public void MemoryBelief_WithoutMetadata_HasExpectedData() + public void GetAllMemories_ReturnsAllMemories() { // Arrange - object reference = new Mock().Object; - System.Func getObservationFromReference = new Mock>().Object; - const int framesToRemember = 1; - System.Predicate shouldUpdate = It.IsAny>(); + List list = [1, 2, 3]; + MemoryBelief, int> belief = new(list, reference => reference.Count, 3); // Act - TestMemoryBelief belief = new(reference, getObservationFromReference, framesToRemember, shouldUpdate); + list.Add(4); + belief.UpdateBelief(); // Assert - belief.Metadata.Id.Should().NotBeEmpty(); - belief.Metadata.Name.Should().BeNull(); - belief.Metadata.Description.Should().BeNull(); - belief.Reference.Should().Be(reference); - belief.GetObservationFromReference.Should().Be(getObservationFromReference); - belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); - belief.ShouldUpdate.Should().Be(shouldUpdate); + Assert.Equal([3], belief.GetAllMemories()); } + /// + /// Given a MemoryBelief instance with an observation, + /// When asking for an index that is out of bounds, + /// Then an exception should be thrown. + /// [Fact] - public void MemoryBelief_WithoutShouldUpdate_HasExpectedData() + public void GetMemoryAt_IndexOutOfBounds_ShouldThrowException() { // Arrange - Metadata metadata = It.IsAny(); - object reference = new Mock().Object; - System.Func getObservationFromReference = new Mock>().Object; - const int framesToRemember = 2; + List list = [1, 2, 3]; + MemoryBelief, int> belief = new(list, reference => reference.Count, 3); // Act - TestMemoryBelief belief = new(metadata, reference, getObservationFromReference, framesToRemember); + void GetMemoryAtNegativeIndex() => belief.GetMemoryAt(-1); + void GetMemoryAtIndexGreaterThanCount() => belief.GetMemoryAt(3); // Assert - belief.Metadata.Should().Be(metadata); - belief.Reference.Should().Be(reference); - belief.GetObservationFromReference.Should().Be(getObservationFromReference); - belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); - belief.ShouldUpdate(reference).Should().BeTrue(); + Assert.Throws(GetMemoryAtNegativeIndex); + Assert.Throws(GetMemoryAtIndexGreaterThanCount); } + /// + /// Given a MemoryBelief instance with an observation, + /// When the observation is updated and GetMemoryAt is called with an index, + /// Then the observation at the specified index is returned. + /// [Fact] - public void MemoryBelief_WithoutMetadataWithoutShouldUpdate_HasExpectedData() + public void GetMemoryAt_WhenObservationIsUpdated_ShouldReturnObservationAtSpecifiedIndex() { // Arrange - object reference = new Mock().Object; - System.Func getObservationFromReference = new Mock>().Object; - const int framesToRemember = 3; + List list = [1, 2, 3]; + MemoryBelief, int> belief = new(list, reference => reference.Count, 3); // Act - TestMemoryBelief belief = new(reference, getObservationFromReference, framesToRemember); + list.Add(4); + belief.UpdateBelief(); + list.Add(5); + belief.UpdateBelief(); // Assert - belief.Metadata.Id.Should().NotBeEmpty(); - belief.Metadata.Name.Should().BeNull(); - belief.Metadata.Description.Should().BeNull(); - belief.Reference.Should().Be(reference); - belief.GetObservationFromReference.Should().Be(getObservationFromReference); - belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); - belief.ShouldUpdate(reference).Should().BeTrue(); + Assert.Equal(4, belief.GetMemoryAt(0)); + Assert.Equal(3, belief.GetMemoryAt(1)); } /// @@ -166,67 +149,87 @@ public void GetMostRecentMemory_WhenObservationIsUpdated_ShouldReturnLastObserva Assert.Equal(1, belief.GetMostRecentMemory()); } - /// - /// Given a MemoryBelief instance with an observation, - /// When the observation is updated and GetMemoryAt is called with an index, - /// Then the observation at the specified index is returned. - /// [Fact] - public void GetMemoryAt_WhenObservationIsUpdated_ShouldReturnObservationAtSpecifiedIndex() + public void MemoryBelief_WhenConstructed_HasExpectedData() { // Arrange - List list = [1, 2, 3]; - MemoryBelief, int> belief = new(list, reference => reference.Count, 3); + Metadata metadata = It.IsAny(); + object reference = new Mock().Object; + System.Func getObservationFromReference = new Mock>().Object; + const int framesToRemember = 0; + System.Predicate shouldUpdate = It.IsAny>(); // Act - list.Add(4); - belief.UpdateBelief(); - list.Add(5); - belief.UpdateBelief(); + TestMemoryBelief belief = new(metadata, reference, getObservationFromReference, framesToRemember, shouldUpdate); // Assert - Assert.Equal(4, belief.GetMemoryAt(0)); - Assert.Equal(3, belief.GetMemoryAt(1)); + belief.Metadata.Should().Be(metadata); + belief.Reference.Should().Be(reference); + belief.GetObservationFromReference.Should().Be(getObservationFromReference); + belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); + belief.ShouldUpdate.Should().Be(shouldUpdate); } - /// - /// Given a MemoryBelief instance with an observation, - /// When asking for an index that is out of bounds, - /// Then an exception should be thrown. - /// [Fact] - public void GetMemoryAt_IndexOutOfBounds_ShouldThrowException() + public void MemoryBelief_WithoutMetadata_HasExpectedData() { // Arrange - List list = [1, 2, 3]; - MemoryBelief, int> belief = new(list, reference => reference.Count, 3); + object reference = new Mock().Object; + System.Func getObservationFromReference = new Mock>().Object; + const int framesToRemember = 1; + System.Predicate shouldUpdate = It.IsAny>(); // Act - void GetMemoryAtNegativeIndex() => belief.GetMemoryAt(-1); - void GetMemoryAtIndexGreaterThanCount() => belief.GetMemoryAt(3); + TestMemoryBelief belief = new(reference, getObservationFromReference, framesToRemember, shouldUpdate); // Assert - Assert.Throws(GetMemoryAtNegativeIndex); - Assert.Throws(GetMemoryAtIndexGreaterThanCount); + belief.Metadata.Id.Should().NotBeEmpty(); + belief.Metadata.Name.Should().BeNull(); + belief.Metadata.Description.Should().BeNull(); + belief.Reference.Should().Be(reference); + belief.GetObservationFromReference.Should().Be(getObservationFromReference); + belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); + belief.ShouldUpdate.Should().Be(shouldUpdate); } - /// - /// Given a MemoryBelief instance with an observation, - /// When the observation is updated and GetAllMemories is called, - /// Then all the currently saved observations are returned. - /// [Fact] - public void GetAllMemories_ReturnsAllMemories() + public void MemoryBelief_WithoutMetadataWithoutShouldUpdate_HasExpectedData() { // Arrange - List list = [1, 2, 3]; - MemoryBelief, int> belief = new(list, reference => reference.Count, 3); + object reference = new Mock().Object; + System.Func getObservationFromReference = new Mock>().Object; + const int framesToRemember = 3; // Act - list.Add(4); - belief.UpdateBelief(); + TestMemoryBelief belief = new(reference, getObservationFromReference, framesToRemember); // Assert - Assert.Equal([3], belief.GetAllMemories()); + belief.Metadata.Id.Should().NotBeEmpty(); + belief.Metadata.Name.Should().BeNull(); + belief.Metadata.Description.Should().BeNull(); + belief.Reference.Should().Be(reference); + belief.GetObservationFromReference.Should().Be(getObservationFromReference); + belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); + belief.ShouldUpdate(reference).Should().BeTrue(); + } + + [Fact] + public void MemoryBelief_WithoutShouldUpdate_HasExpectedData() + { + // Arrange + Metadata metadata = It.IsAny(); + object reference = new Mock().Object; + System.Func getObservationFromReference = new Mock>().Object; + const int framesToRemember = 2; + + // Act + TestMemoryBelief belief = new(metadata, reference, getObservationFromReference, framesToRemember); + + // Assert + belief.Metadata.Should().Be(metadata); + belief.Reference.Should().Be(reference); + belief.GetObservationFromReference.Should().Be(getObservationFromReference); + belief.MemorizedObservations.MaxCount.Should().Be(framesToRemember); + belief.ShouldUpdate(reference).Should().BeTrue(); } } diff --git a/Aplib.Core.Tests/Belief/SampledMemoryBeliefTests.cs b/Aplib.Core.Tests/Belief/SampledMemoryBeliefTests.cs index 6f0cf03c..679c843f 100644 --- a/Aplib.Core.Tests/Belief/SampledMemoryBeliefTests.cs +++ b/Aplib.Core.Tests/Belief/SampledMemoryBeliefTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.Beliefs; using System.Collections.Generic; using static Aplib.Core.Belief.Beliefs.UpdateMode; @@ -86,28 +90,28 @@ SampledMemoryBelief, int> belief } /// - /// Given a SampledMemoryBelief instance with update mode 'AlwaysUpdate', - /// When the belief is not in a sampleInterval-th cycle, - /// Then Observation should be up-to-date. + /// Given a SampledMemoryBelief instance with a shouldUpdate method, + /// When shouldUpdate returns false, + /// Then Observation should not be updated regardless of the update mode. /// [Fact] - public void Observation_WhenUpdateModeIsAlwaysUpdate_ShouldBeUpToDate() + public void Observation_WhenShouldUpdateReturnsFalse_ShouldNotBeUpdated() { // Arrange List list = []; int sampleInterval = 2, framesToRemember = 3; SampledMemoryBelief, int> belief - = new(list, reference => reference.Count, sampleInterval, AlwaysUpdate, framesToRemember); + = new(list, reference => reference.Count, sampleInterval, AlwaysUpdate, framesToRemember, _ => false); // Act // Expected values: // ----------------------------------------- // | list.Count | Observation // ----------------------------------------- - // Initial | 0 | 0 (observation is updated) - // Iteration 0 | 1 | 1 (observation is updated) - // Iteration 1 | 2 | 2 (observation is updated) + // Initial | 0 | 0 (set initial observation) + // Iteration 0 | 1 | 0 + // Iteration 1 | 2 | 0 // ----------------------------------------- for (int i = 0; i < 2; i++) { @@ -116,43 +120,41 @@ SampledMemoryBelief, int> belief } // Assert - Assert.Equal(list.Count, belief.Observation); + Assert.Equal(0, belief.Observation); } /// - /// Given a SampledMemoryBelief instance with update mode 'UpdateWhenSampled', + /// Given a SampledMemoryBelief instance with update mode 'AlwaysUpdate', /// When the belief is not in a sampleInterval-th cycle, - /// Then Observation should be outdated. + /// Then Observation should be up-to-date. /// [Fact] - public void Observation_WhenUpdateModeIsUpdateWhenSampled_ShouldBeOutdated() + public void Observation_WhenUpdateModeIsAlwaysUpdate_ShouldBeUpToDate() { // Arrange List list = []; int sampleInterval = 2, framesToRemember = 3; SampledMemoryBelief, int> belief - = new(list, reference => reference.Count, sampleInterval, UpdateWhenSampled, framesToRemember); + = new(list, reference => reference.Count, sampleInterval, AlwaysUpdate, framesToRemember); // Act // Expected values: // ----------------------------------------- // | list.Count | Observation // ----------------------------------------- - // Initial | 0 | 0 + // Initial | 0 | 0 (observation is updated) // Iteration 0 | 1 | 1 (observation is updated) - // Iteration 1 | 2 | 1 - // Iteration 2 | 3 | 3 (observation is updated) - // Iteration 3 | 4 | 3 + // Iteration 1 | 2 | 2 (observation is updated) // ----------------------------------------- - for (int i = 0; i < 4; i++) + for (int i = 0; i < 2; i++) { list.Add(0); belief.UpdateBelief(); } // Assert - Assert.NotEqual(list.Count, belief.Observation); + Assert.Equal(list.Count, belief.Observation); } /// @@ -200,36 +202,38 @@ SampledMemoryBelief, int> belief } /// - /// Given a SampledMemoryBelief instance with a shouldUpdate method, - /// When shouldUpdate returns false, - /// Then Observation should not be updated regardless of the update mode. + /// Given a SampledMemoryBelief instance with update mode 'UpdateWhenSampled', + /// When the belief is not in a sampleInterval-th cycle, + /// Then Observation should be outdated. /// [Fact] - public void Observation_WhenShouldUpdateReturnsFalse_ShouldNotBeUpdated() + public void Observation_WhenUpdateModeIsUpdateWhenSampled_ShouldBeOutdated() { // Arrange List list = []; int sampleInterval = 2, framesToRemember = 3; SampledMemoryBelief, int> belief - = new(list, reference => reference.Count, sampleInterval, AlwaysUpdate, framesToRemember, _ => false); + = new(list, reference => reference.Count, sampleInterval, UpdateWhenSampled, framesToRemember); // Act // Expected values: // ----------------------------------------- // | list.Count | Observation // ----------------------------------------- - // Initial | 0 | 0 (set initial observation) - // Iteration 0 | 1 | 0 - // Iteration 1 | 2 | 0 + // Initial | 0 | 0 + // Iteration 0 | 1 | 1 (observation is updated) + // Iteration 1 | 2 | 1 + // Iteration 2 | 3 | 3 (observation is updated) + // Iteration 3 | 4 | 3 // ----------------------------------------- - for (int i = 0; i < 2; i++) + for (int i = 0; i < 4; i++) { list.Add(0); belief.UpdateBelief(); } // Assert - Assert.Equal(0, belief.Observation); + Assert.NotEqual(list.Count, belief.Observation); } } diff --git a/Aplib.Core.Tests/Collections/CircularArrayTests.cs b/Aplib.Core.Tests/Collections/CircularArrayTests.cs index 34cda7ed..30b5bf03 100644 --- a/Aplib.Core.Tests/Collections/CircularArrayTests.cs +++ b/Aplib.Core.Tests/Collections/CircularArrayTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Collections; namespace Aplib.Core.Tests.Collections; @@ -6,93 +10,93 @@ public class CircularArrayTests { /// /// Given a CircularArray instance, - /// When an element is put into the array, - /// The array should wrap around when it reaches its end. - /// (i.e., the first element should become the previous second element, - /// and the last element should be the new element) + /// When the head is updated, + /// GetLast should return the last element. /// [Fact] - public void Put_ArrayIsFull_WrapsAround() + public void GetFirst_HeadIsUpdated_ReturnsFirstElement() { // Arrange - CircularArray circularArray = new([1, 2, 3, 4, 5]); + CircularArray circularArray = new([1, 2, 3]); + int prevFirst = circularArray.GetFirst(); // Act - circularArray.Put(0); + circularArray.Put(4); + int firstElement = circularArray.GetFirst(); // Assert - Assert.Equal(0, circularArray[0]); - Assert.Equal(1, circularArray[1]); - Assert.Equal(2, circularArray[2]); + Assert.NotEqual(prevFirst, firstElement); + Assert.Equal(4, firstElement); } /// /// Given a CircularArray instance, /// When the head is updated, - /// Putting an element should set the correct index - /// even if the head is not at the start of the array. + /// GetHead should return the correct head. /// [Fact] - public void Put_HeadIsUpdated_SetsCorrectIndex() + public void GetHead_HeadIsUpdated_ReturnsLastElement() { // Arrange - CircularArray circularArray = new(3); + CircularArray circularArray = new([1, 2, 3]); + int prevHead = circularArray.GetHead(); // Act - // circularArray.ToArray() == [0, 0, 0] - circularArray[1] = 6; - // circularArray.ToArray() == [0, 6, 0] - circularArray.Put(4); - // circularArray.ToArray() == [4, 0, 6] - circularArray[1] = 5; - // circularArray.ToArray() == [4, 5, 6] + circularArray.Put(0); + int head = circularArray.GetHead(); // Assert - Assert.Equal(4, circularArray[0]); - Assert.Equal(5, circularArray[1]); - Assert.Equal(6, circularArray[2]); + Assert.NotEqual(prevHead, head); + Assert.Equal(2, head); } /// /// Given a CircularArray instance, - /// When the head is updated, - /// GetHead should return the correct head. + /// When an element is put into the array, + /// The array should wrap around when it reaches its end. + /// (i.e., the first element should become the previous second element, + /// and the last element should be the new element) /// [Fact] - public void GetHead_HeadIsUpdated_ReturnsLastElement() + public void Put_ArrayIsFull_WrapsAround() { // Arrange - CircularArray circularArray = new([1, 2, 3]); - int prevHead = circularArray.GetHead(); + CircularArray circularArray = new([1, 2, 3, 4, 5]); // Act circularArray.Put(0); - int head = circularArray.GetHead(); // Assert - Assert.NotEqual(prevHead, head); - Assert.Equal(2, head); + Assert.Equal(0, circularArray[0]); + Assert.Equal(1, circularArray[1]); + Assert.Equal(2, circularArray[2]); } /// /// Given a CircularArray instance, /// When the head is updated, - /// GetLast should return the last element. + /// Putting an element should set the correct index + /// even if the head is not at the start of the array. /// [Fact] - public void GetFirst_HeadIsUpdated_ReturnsFirstElement() + public void Put_HeadIsUpdated_SetsCorrectIndex() { // Arrange - CircularArray circularArray = new([1, 2, 3]); - int prevFirst = circularArray.GetFirst(); + CircularArray circularArray = new(3); // Act + // circularArray.ToArray() == [0, 0, 0] + circularArray[1] = 6; + // circularArray.ToArray() == [0, 6, 0] circularArray.Put(4); - int firstElement = circularArray.GetFirst(); + // circularArray.ToArray() == [4, 0, 6] + circularArray[1] = 5; + // circularArray.ToArray() == [4, 5, 6] // Assert - Assert.NotEqual(prevFirst, firstElement); - Assert.Equal(4, firstElement); + Assert.Equal(4, circularArray[0]); + Assert.Equal(5, circularArray[1]); + Assert.Equal(6, circularArray[2]); } /// diff --git a/Aplib.Core.Tests/Collections/ExposedQueueTests.cs b/Aplib.Core.Tests/Collections/ExposedQueueTests.cs index 81319fff..bb4f2444 100644 --- a/Aplib.Core.Tests/Collections/ExposedQueueTests.cs +++ b/Aplib.Core.Tests/Collections/ExposedQueueTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Collections; using System.Collections.Generic; diff --git a/Aplib.Core.Tests/Collections/OptimizedActivationStackTests.cs b/Aplib.Core.Tests/Collections/OptimizedActivationStackTests.cs index 76f0b144..6f48500f 100644 --- a/Aplib.Core.Tests/Collections/OptimizedActivationStackTests.cs +++ b/Aplib.Core.Tests/Collections/OptimizedActivationStackTests.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Collections; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Collections; using FluentAssertions; using System.Collections.Generic; using System.Linq; @@ -28,6 +32,30 @@ public void ActivatableStackItems_WhenActivatablesAreGiven_ShouldContainEncapsul items.Should().BeEquivalentTo(activatables); } + /// + /// Given an optimized activation stack, + /// When an item from a different optimized activation stack is activated on this stack, + /// Then an argument exception should be thrown. + /// + [Fact] + public void Activate_WhenActivatedItemIsFromDifferentStack_ShouldThrowArgumentException() + { + // Arrange + int[] activatables = [1, 2, 3]; + OptimizedActivationStack activationStack = new(activatables); + + int[] otherActivatables = [4, 5, 6]; + OptimizedActivationStack otherActivationStack = new(otherActivatables); + OptimizedActivationStack.StackItem stackItemToActivate + = otherActivationStack.ActivatableStackItems.First(); + + // Act + System.Action activateItem = () => activationStack.Activate(stackItemToActivate); + + // Assert + activateItem.Should().Throw(); + } + /// /// Given an optimized activation stack with items on the stack, /// When an item is activated that was not activated yet, @@ -87,27 +115,28 @@ OptimizedActivationStack.StackItem stackItemToActivate } /// - /// Given an optimized activation stack, - /// When an item from a different optimized activation stack is activated on this stack, - /// Then an argument exception should be thrown. + /// Given an optimized activation stack with activated items on the stack, + /// When an item is peeked, + /// Then the count of the optimized activation stack should stay the same. /// [Fact] - public void Activate_WhenActivatedItemIsFromDifferentStack_ShouldThrowArgumentException() + public void Peek_WhenCalled_CountShouldStayTheSame() { // Arrange int[] activatables = [1, 2, 3]; OptimizedActivationStack activationStack = new(activatables); - int[] otherActivatables = [4, 5, 6]; - OptimizedActivationStack otherActivationStack = new(otherActivatables); - OptimizedActivationStack.StackItem stackItemToActivate - = otherActivationStack.ActivatableStackItems.First(); + // Activate all stack items. + foreach (OptimizedActivationStack.StackItem stackItem in activationStack.ActivatableStackItems) + activationStack.Activate(stackItem); // Act - System.Action activateItem = () => activationStack.Activate(stackItemToActivate); + int countBeforePeek = activationStack.Count; + _ = activationStack.Peek(); + int countAfterPeek = activationStack.Count; // Assert - activateItem.Should().Throw(); + countBeforePeek.Should().Be(countAfterPeek); } /// @@ -155,11 +184,11 @@ public void Peek_WhenStackIsEmpty_ShouldThrowInvalidOperationException() /// /// Given an optimized activation stack with activated items on the stack, - /// When an item is peeked, - /// Then the count of the optimized activation stack should stay the same. + /// When an item is popped, + /// Then the count of the optimized activation stack should be decreased by one. /// [Fact] - public void Peek_WhenCalled_CountShouldStayTheSame() + public void Pop_WhenCalled_CountShouldDecrement() { // Arrange int[] activatables = [1, 2, 3]; @@ -170,12 +199,12 @@ public void Peek_WhenCalled_CountShouldStayTheSame() activationStack.Activate(stackItem); // Act - int countBeforePeek = activationStack.Count; - _ = activationStack.Peek(); - int countAfterPeek = activationStack.Count; + int countBeforePop = activationStack.Count; + _ = activationStack.Pop(); + int countAfterPop = activationStack.Count; // Assert - countBeforePeek.Should().Be(countAfterPeek); + countAfterPop.Should().Be(countBeforePop - 1); } /// @@ -220,29 +249,4 @@ public void Pop_WhenStackIsEmpty_ShouldThrowInvalidOperationException() // Assert popItem.Should().Throw(); } - - /// - /// Given an optimized activation stack with activated items on the stack, - /// When an item is popped, - /// Then the count of the optimized activation stack should be decreased by one. - /// - [Fact] - public void Pop_WhenCalled_CountShouldDecrement() - { - // Arrange - int[] activatables = [1, 2, 3]; - OptimizedActivationStack activationStack = new(activatables); - - // Activate all stack items. - foreach (OptimizedActivationStack.StackItem stackItem in activationStack.ActivatableStackItems) - activationStack.Activate(stackItem); - - // Act - int countBeforePop = activationStack.Count; - _ = activationStack.Pop(); - int countAfterPop = activationStack.Count; - - // Assert - countAfterPop.Should().Be(countBeforePop - 1); - } } diff --git a/Aplib.Core.Tests/CombinatorTests.cs b/Aplib.Core.Tests/CombinatorTests.cs index 675e635c..0686a746 100644 --- a/Aplib.Core.Tests/CombinatorTests.cs +++ b/Aplib.Core.Tests/CombinatorTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Desire.GoalStructures; @@ -19,161 +23,91 @@ [new Metadata(System.Guid.Empty, description: "my description"), null, "my descr [new Metadata(System.Guid.Empty, "a name", "a description"), "a name", "a description"] ]; - private static void CheckMetadata(string? expectedName, string? expectedDescription, IMetadata actual) - { - actual.Id.Should().BeEmpty(); - actual.Name.Should().Be(expectedName); - actual.Description.Should().Be(expectedDescription); - } - - private static void CheckDefaultMetadata(IMetadata actual) - { - actual.Id.Should().NotBeEmpty(); - actual.Name.Should().BeNull(); - actual.Description.Should().BeNull(); - } - - #region GoalStructure combinator tests - [Theory] [MemberData(nameof(Metadatas))] - public void FirstOfGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure + public void AnyOfTacticCombinator_WhenCalled_GivesExpectedTactic (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Mock> goalStructure1 = new(); - goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); - - Mock> goalStructure2 = new(); - goalStructure2.SetupGet(g => g.Status).Returns(CompletionStatus.Success); - - IBeliefSet beliefSet = Mock.Of(); - - // Act - FirstOfGoalStructure firstOfGoalStructure = - FirstOf(metadata, goalStructure1.Object, goalStructure2.Object); - - firstOfGoalStructure.UpdateStatus(beliefSet); - firstOfGoalStructure.UpdateStatus(beliefSet); - - // Assert - CheckMetadata(expectedName, expectedDescription, firstOfGoalStructure.Metadata); - firstOfGoalStructure.Status.Should().Be(CompletionStatus.Success); - goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); - goalStructure2.Verify(x => x.UpdateStatus(It.IsAny()), Times.Never); - } - - [Fact] - public void FirstOfGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() - { - // Arrange - Mock> goalStructure1 = new(); - goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); - - Mock> goalStructure2 = new(); - goalStructure2.SetupGet(g => g.Status).Returns(CompletionStatus.Success); - - IBeliefSet beliefSet = Mock.Of(); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); + // ReSharper disable once ConvertToLocalFunction + System.Predicate guard = _ => false; // Act - FirstOfGoalStructure firstOfGoalStructure = - FirstOf(goalStructure1.Object, goalStructure2.Object); + RandomTactic anyOfTactic = + Random(metadata, guard, Primitive(action1, _ => true), Primitive(action2, _ => false)); - firstOfGoalStructure.UpdateStatus(beliefSet); - firstOfGoalStructure.UpdateStatus(beliefSet); + IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(firstOfGoalStructure.Metadata); - firstOfGoalStructure.Status.Should().Be(CompletionStatus.Success); - goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); - goalStructure2.Verify(x => x.UpdateStatus(It.IsAny()), Times.Never); + CheckMetadata(expectedName, expectedDescription, anyOfTactic.Metadata); + selectedAction.Should().BeNull(); } [Theory] [MemberData(nameof(Metadatas))] - public void PrimitiveGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure + public void AnyOfTacticCombinator_WithoutGuard_GivesExpectedTactic (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Mock> goal = new(); - goal.Setup(g => g.Status).Returns(CompletionStatus.Success); - IBeliefSet beliefSet = Mock.Of(); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); // Act - PrimitiveGoalStructure primitiveGoalStructure = Primitive(metadata, goal.Object); + RandomTactic anyOfTactic = + Random(metadata, Primitive(action1, _ => true), Primitive(action2, _ => false)); - primitiveGoalStructure.UpdateStatus(beliefSet); + IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, primitiveGoalStructure.Metadata); - primitiveGoalStructure.Status.Should().Be(CompletionStatus.Success); + CheckMetadata(expectedName, expectedDescription, anyOfTactic.Metadata); + selectedAction.Should().Be(action1); } [Fact] - public void PrimitiveGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() - { - // Arrange - Mock> goal = new(); - goal.Setup(g => g.Status).Returns(CompletionStatus.Success); - IBeliefSet beliefSet = Mock.Of(); - - // Act - PrimitiveGoalStructure primitiveGoalStructure = Primitive(goal.Object); - - primitiveGoalStructure.UpdateStatus(beliefSet); - - // Assert - CheckDefaultMetadata(primitiveGoalStructure.Metadata); - primitiveGoalStructure.Status.Should().Be(CompletionStatus.Success); - } - - [Theory] - [MemberData(nameof(Metadatas))] - public void RepeatGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure - (Metadata metadata, string? expectedName, string? expectedDescription) + public void AnyOfTacticCombinator_WithoutMetadata_GivesExpectedTactic() { // Arrange - Mock> goal = new(); - goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); - IBeliefSet beliefSet = Mock.Of(); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); + // ReSharper disable once ConvertToLocalFunction + System.Predicate guard = _ => false; // Act - RepeatGoalStructure repeatGoalStructure = Repeat(metadata, Primitive(goal.Object)); + RandomTactic anyOfTactic = + Random(guard, Primitive(action1, _ => true), Primitive(action2, _ => false)); - repeatGoalStructure.UpdateStatus(beliefSet); - IGoal currentGoal = repeatGoalStructure.GetCurrentGoal(beliefSet); + IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, repeatGoalStructure.Metadata); - repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); - currentGoal.Should().Be(goal.Object); + CheckDefaultMetadata(anyOfTactic.Metadata); + selectedAction.Should().BeNull(); } [Fact] - public void RepeatGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() + public void AnyOfTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedTactic() { // Arrange - Mock> goal = new(); - goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); - IBeliefSet beliefSet = Mock.Of(); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); // Act - RepeatGoalStructure repeatGoalStructure = Repeat(Primitive(goal.Object)); + RandomTactic anyOfTactic = Random(Primitive(action1, _ => true), Primitive(action2, _ => false)); - repeatGoalStructure.UpdateStatus(beliefSet); - IGoal currentGoal = repeatGoalStructure.GetCurrentGoal(beliefSet); + IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(repeatGoalStructure.Metadata); - repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); - currentGoal.Should().Be(goal.Object); + CheckDefaultMetadata(anyOfTactic.Metadata); + selectedAction.Should().Be(action1); } [Theory] [MemberData(nameof(Metadatas))] - public void SequentialGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure + public void FirstOfGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure (Metadata metadata, string? expectedName, string? expectedDescription) { + // Arrange Mock> goalStructure1 = new(); goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); @@ -183,21 +117,23 @@ public void SequentialGoalStructureCombinator_WhenCalled_GivesExpectedGoalStruct IBeliefSet beliefSet = Mock.Of(); // Act - SequentialGoalStructure sequentialGoalStructure = - Seq(metadata, goalStructure1.Object, goalStructure2.Object); + FirstOfGoalStructure firstOfGoalStructure = + FirstOf(metadata, goalStructure1.Object, goalStructure2.Object); - sequentialGoalStructure.UpdateStatus(beliefSet); - sequentialGoalStructure.UpdateStatus(beliefSet); + firstOfGoalStructure.UpdateStatus(beliefSet); + firstOfGoalStructure.UpdateStatus(beliefSet); // Assert - CheckMetadata(expectedName, expectedDescription, sequentialGoalStructure.Metadata); - sequentialGoalStructure.Status.Should().Be(CompletionStatus.Success); + CheckMetadata(expectedName, expectedDescription, firstOfGoalStructure.Metadata); + firstOfGoalStructure.Status.Should().Be(CompletionStatus.Success); goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); + goalStructure2.Verify(x => x.UpdateStatus(It.IsAny()), Times.Never); } [Fact] - public void SequentialGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() + public void FirstOfGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() { + // Arrange Mock> goalStructure1 = new(); goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); @@ -207,24 +143,22 @@ public void SequentialGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalS IBeliefSet beliefSet = Mock.Of(); // Act - SequentialGoalStructure sequentialGoalStructure = Seq(goalStructure1.Object, goalStructure2.Object); + FirstOfGoalStructure firstOfGoalStructure = + FirstOf(goalStructure1.Object, goalStructure2.Object); - sequentialGoalStructure.UpdateStatus(beliefSet); - sequentialGoalStructure.UpdateStatus(beliefSet); + firstOfGoalStructure.UpdateStatus(beliefSet); + firstOfGoalStructure.UpdateStatus(beliefSet); // Assert - CheckDefaultMetadata(sequentialGoalStructure.Metadata); - sequentialGoalStructure.Status.Should().Be(CompletionStatus.Success); + CheckDefaultMetadata(firstOfGoalStructure.Metadata); + firstOfGoalStructure.Status.Should().Be(CompletionStatus.Success); goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); + goalStructure2.Verify(x => x.UpdateStatus(It.IsAny()), Times.Never); } - #endregion - - #region Tactic combinator tests - [Theory] [MemberData(nameof(Metadatas))] - public void AnyOfTacticCombinator_WhenCalled_GivesExpectedTactic + public void FirstOfTacticCombinator_WhenCalled_GivesExpectedTactic (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange @@ -234,177 +168,204 @@ public void AnyOfTacticCombinator_WhenCalled_GivesExpectedTactic System.Predicate guard = _ => false; // Act - RandomTactic anyOfTactic = - Random(metadata, guard, Primitive(action1, _ => true), Primitive(action2, _ => false)); + FirstOfTactic firstOfTactic = + FirstOf(metadata, guard, Primitive(action1, _ => false), Primitive(action2, _ => true)); - IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); + IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, anyOfTactic.Metadata); + CheckMetadata(expectedName, expectedDescription, firstOfTactic.Metadata); selectedAction.Should().BeNull(); } - [Fact] - public void AnyOfTacticCombinator_WithoutMetadata_GivesExpectedTactic() + [Theory] + [MemberData(nameof(Metadatas))] + public void FirstOfTacticCombinator_WithoutGuard_GivesExpectedTactic + (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange Action action1 = new(_ => { }); Action action2 = new(_ => { }); - // ReSharper disable once ConvertToLocalFunction - System.Predicate guard = _ => false; // Act - RandomTactic anyOfTactic = - Random(guard, Primitive(action1, _ => true), Primitive(action2, _ => false)); + FirstOfTactic firstOfTactic = + FirstOf(metadata, Primitive(action1, _ => false), Primitive(action2, _ => true)); - IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); + IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(anyOfTactic.Metadata); - selectedAction.Should().BeNull(); + CheckMetadata(expectedName, expectedDescription, firstOfTactic.Metadata); + selectedAction.Should().Be(action2); } - [Theory] - [MemberData(nameof(Metadatas))] - public void AnyOfTacticCombinator_WithoutGuard_GivesExpectedTactic - (Metadata metadata, string? expectedName, string? expectedDescription) + [Fact] + public void FirstOfTacticCombinator_WithoutMetadata_GivesExpectedTactic() { // Arrange Action action1 = new(_ => { }); Action action2 = new(_ => { }); + // ReSharper disable once ConvertToLocalFunction + System.Predicate guard = _ => false; // Act - RandomTactic anyOfTactic = - Random(metadata, Primitive(action1, _ => true), Primitive(action2, _ => false)); + FirstOfTactic firstOfTactic = + FirstOf(guard, Primitive(action1, _ => false), Primitive(action2, _ => true)); - IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); + IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, anyOfTactic.Metadata); - selectedAction.Should().Be(action1); + CheckDefaultMetadata(firstOfTactic.Metadata); + selectedAction.Should().BeNull(); } [Fact] - public void AnyOfTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedTactic() + public void FirstOfTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedTactic() { // Arrange Action action1 = new(_ => { }); Action action2 = new(_ => { }); // Act - RandomTactic anyOfTactic = Random(Primitive(action1, _ => true), Primitive(action2, _ => false)); + FirstOfTactic firstOfTactic = + FirstOf(Primitive(action1, _ => false), Primitive(action2, _ => true)); - IAction? selectedAction = anyOfTactic.GetAction(It.IsAny()); + IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(anyOfTactic.Metadata); - selectedAction.Should().Be(action1); + CheckDefaultMetadata(firstOfTactic.Metadata); + selectedAction.Should().Be(action2); } [Theory] [MemberData(nameof(Metadatas))] - public void FirstOfTacticCombinator_WhenCalled_GivesExpectedTactic + public void PrimitiveGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); - // ReSharper disable once ConvertToLocalFunction - System.Predicate guard = _ => false; + Mock> goal = new(); + goal.Setup(g => g.Status).Returns(CompletionStatus.Success); + IBeliefSet beliefSet = Mock.Of(); // Act - FirstOfTactic firstOfTactic = - FirstOf(metadata, guard, Primitive(action1, _ => false), Primitive(action2, _ => true)); + PrimitiveGoalStructure primitiveGoalStructure = Primitive(metadata, goal.Object); - IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); + primitiveGoalStructure.UpdateStatus(beliefSet); // Assert - CheckMetadata(expectedName, expectedDescription, firstOfTactic.Metadata); - selectedAction.Should().BeNull(); + CheckMetadata(expectedName, expectedDescription, primitiveGoalStructure.Metadata); + primitiveGoalStructure.Status.Should().Be(CompletionStatus.Success); } [Fact] - public void FirstOfTacticCombinator_WithoutMetadata_GivesExpectedTactic() + public void PrimitiveGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() { // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); - // ReSharper disable once ConvertToLocalFunction - System.Predicate guard = _ => false; + Mock> goal = new(); + goal.Setup(g => g.Status).Returns(CompletionStatus.Success); + IBeliefSet beliefSet = Mock.Of(); // Act - FirstOfTactic firstOfTactic = - FirstOf(guard, Primitive(action1, _ => false), Primitive(action2, _ => true)); + PrimitiveGoalStructure primitiveGoalStructure = Primitive(goal.Object); - IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); + primitiveGoalStructure.UpdateStatus(beliefSet); // Assert - CheckDefaultMetadata(firstOfTactic.Metadata); - selectedAction.Should().BeNull(); + CheckDefaultMetadata(primitiveGoalStructure.Metadata); + primitiveGoalStructure.Status.Should().Be(CompletionStatus.Success); } [Theory] [MemberData(nameof(Metadatas))] - public void FirstOfTacticCombinator_WithoutGuard_GivesExpectedTactic + public void PrimitiveTacticCombinator_FromQueryable_GivesExpectedTactic (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); + Mock> query = new(); + query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); + QueryAction queryAction = new((_, _) => { }, query.Object); + Mock> guard = new(); + guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); // Act - FirstOfTactic firstOfTactic = - FirstOf(metadata, Primitive(action1, _ => false), Primitive(action2, _ => true)); + PrimitiveTactic primitiveTactic = Primitive(metadata, queryAction, guard.Object); - IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); + IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); + IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, firstOfTactic.Metadata); - selectedAction.Should().Be(action2); + CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); + actionFromFirstCall.Should().BeNull(); + actionFromSecondCall.Should().Be(queryAction); } - [Fact] - public void FirstOfTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedTactic() + [Theory] + [MemberData(nameof(Metadatas))] + public void PrimitiveTacticCombinator_FromQueryableWithoutGuard_GivesExpectedTactic + (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); + Mock> query = new(); + query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); + QueryAction queryAction = new((_, _) => { }, query.Object); // Act - FirstOfTactic firstOfTactic = - FirstOf(Primitive(action1, _ => false), Primitive(action2, _ => true)); + PrimitiveTactic primitiveTactic = Primitive(metadata, queryAction); - IAction? selectedAction = firstOfTactic.GetAction(It.IsAny()); + bool isActionable = primitiveTactic.IsActionable(It.IsAny()); + IAction? selectedAction = primitiveTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(firstOfTactic.Metadata); - selectedAction.Should().Be(action2); + CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); + isActionable.Should().BeTrue(); + selectedAction.Should().Be(queryAction); } - [Theory] - [MemberData(nameof(Metadatas))] - public void PrimitiveTacticCombinator_WhenCalled_GivesExpectedTactic - (Metadata metadata, string? expectedName, string? expectedDescription) + [Fact] + public void PrimitiveTacticCombinator_FromQueryableWithoutMetadata_GivesExpectedTactic() { // Arrange - Action action = new(_ => { }); + Mock> query = new(); + query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); + QueryAction queryAction = new((_, _) => { }, query.Object); Mock> guard = new(); guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); // Act - PrimitiveTactic primitiveTactic = Primitive(metadata, action, guard.Object); + PrimitiveTactic primitiveTactic = Primitive(queryAction, guard.Object); IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); // Assert - CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); + CheckDefaultMetadata(primitiveTactic.Metadata); actionFromFirstCall.Should().BeNull(); - actionFromSecondCall.Should().Be(action); + actionFromSecondCall.Should().Be(queryAction); } [Fact] - public void PrimitiveTacticCombinator_WithoutMetadata_GivesExpectedTactic() + public void PrimitiveTacticCombinator_FromQueryableWithoutMetadataWithoutGuard_GivesExpectedTactic() + { + // Arrange + Mock> query = new(); + query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); + QueryAction queryAction = new((_, _) => { }, query.Object); + + // Act + PrimitiveTactic primitiveTactic = Primitive(queryAction); + + bool isActionable = primitiveTactic.IsActionable(It.IsAny()); + IAction? selectedAction = primitiveTactic.GetAction(It.IsAny()); + + // Assert + CheckDefaultMetadata(primitiveTactic.Metadata); + isActionable.Should().BeTrue(); + selectedAction.Should().Be(queryAction); + } + + [Theory] + [MemberData(nameof(Metadatas))] + public void PrimitiveTacticCombinator_WhenCalled_GivesExpectedTactic + (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange Action action = new(_ => { }); @@ -412,13 +373,13 @@ public void PrimitiveTacticCombinator_WithoutMetadata_GivesExpectedTactic() guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); // Act - PrimitiveTactic primitiveTactic = Primitive(action, guard.Object); + PrimitiveTactic primitiveTactic = Primitive(metadata, action, guard.Object); IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); // Assert - CheckDefaultMetadata(primitiveTactic.Metadata); + CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); actionFromFirstCall.Should().BeNull(); actionFromSecondCall.Should().Be(action); } @@ -443,6 +404,26 @@ public void PrimitiveTacticCombinator_WithoutGuard_GivesExpectedTactic selectedAction.Should().Be(action); } + [Fact] + public void PrimitiveTacticCombinator_WithoutMetadata_GivesExpectedTactic() + { + // Arrange + Action action = new(_ => { }); + Mock> guard = new(); + guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); + + // Act + PrimitiveTactic primitiveTactic = Primitive(action, guard.Object); + + IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); + IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); + + // Assert + CheckDefaultMetadata(primitiveTactic.Metadata); + actionFromFirstCall.Should().BeNull(); + actionFromSecondCall.Should().Be(action); + } + [Fact] public void PrimitiveTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedTactic() { @@ -463,91 +444,106 @@ public void PrimitiveTacticCombinator_WithoutMetadataWithoutGuard_GivesExpectedT [Theory] [MemberData(nameof(Metadatas))] - public void PrimitiveTacticCombinator_FromQueryable_GivesExpectedTactic + public void RepeatGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure (Metadata metadata, string? expectedName, string? expectedDescription) { // Arrange - Mock> query = new(); - query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); - QueryAction queryAction = new((_, _) => { }, query.Object); - Mock> guard = new(); - guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); + Mock> goal = new(); + goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); + IBeliefSet beliefSet = Mock.Of(); // Act - PrimitiveTactic primitiveTactic = Primitive(metadata, queryAction, guard.Object); + RepeatGoalStructure repeatGoalStructure = Repeat(metadata, Primitive(goal.Object)); - IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); - IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); + repeatGoalStructure.UpdateStatus(beliefSet); + IGoal currentGoal = repeatGoalStructure.GetCurrentGoal(beliefSet); // Assert - CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); - actionFromFirstCall.Should().BeNull(); - actionFromSecondCall.Should().Be(queryAction); + CheckMetadata(expectedName, expectedDescription, repeatGoalStructure.Metadata); + repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); + currentGoal.Should().Be(goal.Object); } [Fact] - public void PrimitiveTacticCombinator_FromQueryableWithoutMetadata_GivesExpectedTactic() + public void RepeatGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() { // Arrange - Mock> query = new(); - query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); - QueryAction queryAction = new((_, _) => { }, query.Object); - Mock> guard = new(); - guard.SetupSequence(f => f(It.IsAny())).Returns(false).Returns(true); + Mock> goal = new(); + goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); + IBeliefSet beliefSet = Mock.Of(); // Act - PrimitiveTactic primitiveTactic = Primitive(queryAction, guard.Object); + RepeatGoalStructure repeatGoalStructure = Repeat(Primitive(goal.Object)); - IAction? actionFromFirstCall = primitiveTactic.GetAction(It.IsAny()); - IAction? actionFromSecondCall = primitiveTactic.GetAction(It.IsAny()); + repeatGoalStructure.UpdateStatus(beliefSet); + IGoal currentGoal = repeatGoalStructure.GetCurrentGoal(beliefSet); // Assert - CheckDefaultMetadata(primitiveTactic.Metadata); - actionFromFirstCall.Should().BeNull(); - actionFromSecondCall.Should().Be(queryAction); + CheckDefaultMetadata(repeatGoalStructure.Metadata); + repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); + currentGoal.Should().Be(goal.Object); } [Theory] [MemberData(nameof(Metadatas))] - public void PrimitiveTacticCombinator_FromQueryableWithoutGuard_GivesExpectedTactic + public void SequentialGoalStructureCombinator_WhenCalled_GivesExpectedGoalStructure (Metadata metadata, string? expectedName, string? expectedDescription) { - // Arrange - Mock> query = new(); - query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); - QueryAction queryAction = new((_, _) => { }, query.Object); + Mock> goalStructure1 = new(); + goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); + + Mock> goalStructure2 = new(); + goalStructure2.SetupGet(g => g.Status).Returns(CompletionStatus.Success); + + IBeliefSet beliefSet = Mock.Of(); // Act - PrimitiveTactic primitiveTactic = Primitive(metadata, queryAction); + SequentialGoalStructure sequentialGoalStructure = + Seq(metadata, goalStructure1.Object, goalStructure2.Object); - bool isActionable = primitiveTactic.IsActionable(It.IsAny()); - IAction? selectedAction = primitiveTactic.GetAction(It.IsAny()); + sequentialGoalStructure.UpdateStatus(beliefSet); + sequentialGoalStructure.UpdateStatus(beliefSet); // Assert - CheckMetadata(expectedName, expectedDescription, primitiveTactic.Metadata); - isActionable.Should().BeTrue(); - selectedAction.Should().Be(queryAction); + CheckMetadata(expectedName, expectedDescription, sequentialGoalStructure.Metadata); + sequentialGoalStructure.Status.Should().Be(CompletionStatus.Success); + goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); } [Fact] - public void PrimitiveTacticCombinator_FromQueryableWithoutMetadataWithoutGuard_GivesExpectedTactic() + public void SequentialGoalStructureCombinator_WithoutMetadata_GivesExpectedGoalStructure() { - // Arrange - Mock> query = new(); - query.SetupSequence(f => f(It.IsAny())).Returns(1).Returns(2); - QueryAction queryAction = new((_, _) => { }, query.Object); + Mock> goalStructure1 = new(); + goalStructure1.SetupGet(g => g.Status).Returns(CompletionStatus.Success); + + Mock> goalStructure2 = new(); + goalStructure2.SetupGet(g => g.Status).Returns(CompletionStatus.Success); + + IBeliefSet beliefSet = Mock.Of(); // Act - PrimitiveTactic primitiveTactic = Primitive(queryAction); + SequentialGoalStructure sequentialGoalStructure = Seq(goalStructure1.Object, goalStructure2.Object); - bool isActionable = primitiveTactic.IsActionable(It.IsAny()); - IAction? selectedAction = primitiveTactic.GetAction(It.IsAny()); + sequentialGoalStructure.UpdateStatus(beliefSet); + sequentialGoalStructure.UpdateStatus(beliefSet); // Assert - CheckDefaultMetadata(primitiveTactic.Metadata); - isActionable.Should().BeTrue(); - selectedAction.Should().Be(queryAction); + CheckDefaultMetadata(sequentialGoalStructure.Metadata); + sequentialGoalStructure.Status.Should().Be(CompletionStatus.Success); + goalStructure1.Verify(x => x.UpdateStatus(It.IsAny()), Times.Once); } - #endregion + private static void CheckDefaultMetadata(IMetadata actual) + { + actual.Id.Should().NotBeEmpty(); + actual.Name.Should().BeNull(); + actual.Description.Should().BeNull(); + } + + private static void CheckMetadata(string? expectedName, string? expectedDescription, IMetadata actual) + { + actual.Id.Should().BeEmpty(); + actual.Name.Should().Be(expectedName); + actual.Description.Should().Be(expectedDescription); + } } diff --git a/Aplib.Core.Tests/Desire/DesireSetTests.cs b/Aplib.Core.Tests/Desire/DesireSetTests.cs index 5c71742c..98aeb444 100644 --- a/Aplib.Core.Tests/Desire/DesireSetTests.cs +++ b/Aplib.Core.Tests/Desire/DesireSetTests.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Desire.GoalStructures; diff --git a/Aplib.Core.Tests/Desire/GoalStructureTests.cs b/Aplib.Core.Tests/Desire/GoalStructureTests.cs index 2da5c7cd..33f1c80e 100644 --- a/Aplib.Core.Tests/Desire/GoalStructureTests.cs +++ b/Aplib.Core.Tests/Desire/GoalStructureTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Desire.GoalStructures; @@ -276,6 +280,44 @@ public void PrimitiveGoalStructure_WhenReset_ShouldBeUnfinished() primitiveGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); } + [Fact] + public void RepeatGoalStructure_BeforeMaxRetriesIsExceeded_DoesNotFail() + { + // Arrange + Mock> goal = new(); + goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); + PrimitiveGoalStructure primitiveGoalStructure = new(goal.Object); + RepeatGoalStructure repeatGoalStructure = new(primitiveGoalStructure, 3); + IBeliefSet beliefSet = Mock.Of(); + + // Act + CompletionStatus status0 = repeatGoalStructure.Status; + repeatGoalStructure.UpdateStatus(beliefSet); + CompletionStatus status1 = repeatGoalStructure.Status; + repeatGoalStructure.UpdateStatus(beliefSet); + CompletionStatus status2 = repeatGoalStructure.Status; + repeatGoalStructure.UpdateStatus(beliefSet); + CompletionStatus status3 = repeatGoalStructure.Status; + + // Assert + status0.Should().Be(CompletionStatus.Unfinished); + status1.Should().Be(CompletionStatus.Unfinished); + status2.Should().Be(CompletionStatus.Unfinished); + status3.Should().Be(CompletionStatus.Unfinished); + } + + + [Fact] + public void RepeatGoalStructure_WhenConstructedWithNegativeMaxRetries_ThrowsException() + { + // Arrange + IGoalStructure goalStructure = It.IsAny>(); + System.Action act = () => _ = new RepeatGoalStructure(goalStructure, -3); + + // Act, Assert + act.Should().Throw().WithParameterName("maxRetries"); + } + [Fact] public void RepeatGoalStructure_WhenGoalIsNotFinished_ShouldReturnGoal() { @@ -370,42 +412,6 @@ public void RepeatGoalStructure_WhenInnerGoalStructureHasFailed_ShouldBeUnfinish repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); } - [Fact] - public void RepeatGoalStructure_WhenReset_ShouldResetInnerGoalStructure() - { - // Arrange - Mock> innerGoalStructure = new(); - RepeatGoalStructure repeatGoalStructure = new(innerGoalStructure.Object); - - // Act - repeatGoalStructure.Reset(); - - // Assert - innerGoalStructure.Verify(x => x.Reset(), Times.Once); - } - - [Fact] - public void RepeatGoalStructure_WhenReset_ShouldBeUnfinished() - { - // Arrange - Mock> goalStructure = new(); - goalStructure.SetupGet(g => g.Status).Returns(CompletionStatus.Success); - - IBeliefSet beliefSet = Mock.Of(); - RepeatGoalStructure repeatGoalStructure = new(goalStructure.Object); - - repeatGoalStructure.UpdateStatus(beliefSet); - - // Pre-conditions - repeatGoalStructure.Status.Should().Be(CompletionStatus.Success); - - // Act - repeatGoalStructure.Reset(); - - // Assert - repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); - } - [Fact] public void RepeatGoalStructure_WhenMaxRetriesIsExceeded_CanFail() { @@ -444,41 +450,39 @@ public void RepeatGoalStructure_WhenMaxRetriesIsZero_CanFailImmediately() } [Fact] - public void RepeatGoalStructure_BeforeMaxRetriesIsExceeded_DoesNotFail() + public void RepeatGoalStructure_WhenReset_ShouldBeUnfinished() { // Arrange - Mock> goal = new(); - goal.Setup(g => g.Status).Returns(CompletionStatus.Failure); - PrimitiveGoalStructure primitiveGoalStructure = new(goal.Object); - RepeatGoalStructure repeatGoalStructure = new(primitiveGoalStructure, 3); + Mock> goalStructure = new(); + goalStructure.SetupGet(g => g.Status).Returns(CompletionStatus.Success); + IBeliefSet beliefSet = Mock.Of(); + RepeatGoalStructure repeatGoalStructure = new(goalStructure.Object); - // Act - CompletionStatus status0 = repeatGoalStructure.Status; repeatGoalStructure.UpdateStatus(beliefSet); - CompletionStatus status1 = repeatGoalStructure.Status; - repeatGoalStructure.UpdateStatus(beliefSet); - CompletionStatus status2 = repeatGoalStructure.Status; - repeatGoalStructure.UpdateStatus(beliefSet); - CompletionStatus status3 = repeatGoalStructure.Status; + + // Pre-conditions + repeatGoalStructure.Status.Should().Be(CompletionStatus.Success); + + // Act + repeatGoalStructure.Reset(); // Assert - status0.Should().Be(CompletionStatus.Unfinished); - status1.Should().Be(CompletionStatus.Unfinished); - status2.Should().Be(CompletionStatus.Unfinished); - status3.Should().Be(CompletionStatus.Unfinished); + repeatGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); } - [Fact] - public void RepeatGoalStructure_WhenConstructedWithNegativeMaxRetries_ThrowsException() + public void RepeatGoalStructure_WhenReset_ShouldResetInnerGoalStructure() { // Arrange - IGoalStructure goalStructure = It.IsAny>(); - System.Action act = () => _ = new RepeatGoalStructure(goalStructure, -3); + Mock> innerGoalStructure = new(); + RepeatGoalStructure repeatGoalStructure = new(innerGoalStructure.Object); - // Act, Assert - act.Should().Throw().WithParameterName("maxRetries"); + // Act + repeatGoalStructure.Reset(); + + // Assert + innerGoalStructure.Verify(x => x.Reset(), Times.Once); } [Fact] @@ -642,24 +646,6 @@ public void SequentialGoalStructure_WhenProvidingNoGoalStructure_ShouldThrowExce act.Should().Throw(); } - [Fact] - public void SequentialGoalStructure_WhenReset_ShouldResetChildren() - { - // Arrange - Mock> goalStructure1 = new(); - Mock> goalStructure2 = new(); - - Mock> sequentialGoalStructure - = new(goalStructure1.Object, goalStructure2.Object) { CallBase = true }; - - // Act - sequentialGoalStructure.Object.Reset(); - - // Assert - goalStructure1.Verify(x => x.Reset(), Times.Once); - goalStructure2.Verify(x => x.Reset(), Times.Once); - } - [Fact] public void SequentialGoalStructure_WhenReset_ShouldBeUnfinished() @@ -684,4 +670,22 @@ public void SequentialGoalStructure_WhenReset_ShouldBeUnfinished() // Assert sequentialGoalStructure.Status.Should().Be(CompletionStatus.Unfinished); } + + [Fact] + public void SequentialGoalStructure_WhenReset_ShouldResetChildren() + { + // Arrange + Mock> goalStructure1 = new(); + Mock> goalStructure2 = new(); + + Mock> sequentialGoalStructure + = new(goalStructure1.Object, goalStructure2.Object) { CallBase = true }; + + // Act + sequentialGoalStructure.Object.Reset(); + + // Assert + goalStructure1.Verify(x => x.Reset(), Times.Once); + goalStructure2.Verify(x => x.Reset(), Times.Once); + } } diff --git a/Aplib.Core.Tests/Desire/GoalTests.cs b/Aplib.Core.Tests/Desire/GoalTests.cs index 4be5fe06..0e5383e9 100644 --- a/Aplib.Core.Tests/Desire/GoalTests.cs +++ b/Aplib.Core.Tests/Desire/GoalTests.cs @@ -1,10 +1,13 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Intent.Actions; using Aplib.Core.Intent.Tactics; using FluentAssertions; using Moq; -using System.Diagnostics.CodeAnalysis; namespace Aplib.Core.Tests.Desire; @@ -143,19 +146,21 @@ public void Goal_WhereHeuristicsChange_UsesUpdatedHeuristics() stateAfter.Should().Be(CompletionStatus.Success); } - [Fact] - public void UpdateStatus_WhenFailGuardIsTrue_FailsTheGoal() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Goal_WithoutFailGuard_DoesNotFail(bool shouldSucceed) { // Arrange IBeliefSet beliefSet = Mock.Of(); ITactic tactic = Mock.Of>(); - Goal goal = new(tactic, predicate: _ => false, failGuard: _ => true); + Goal goal = new(tactic, predicate: _ => shouldSucceed); // Act goal.UpdateStatus(beliefSet); // Assert - goal.Status.Should().Be(CompletionStatus.Failure); + goal.Status.Should().NotBe(CompletionStatus.Failure); } [Fact] @@ -173,20 +178,18 @@ public void UpdateStatus_WhenBothFailGuardIsTrueAndPredicateIsTrue_CompletesTheG goal.Status.Should().Be(CompletionStatus.Success); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void Goal_WithoutFailGuard_DoesNotFail(bool shouldSucceed) + [Fact] + public void UpdateStatus_WhenFailGuardIsTrue_FailsTheGoal() { // Arrange IBeliefSet beliefSet = Mock.Of(); ITactic tactic = Mock.Of>(); - Goal goal = new(tactic, predicate: _ => shouldSucceed); + Goal goal = new(tactic, predicate: _ => false, failGuard: _ => true); // Act goal.UpdateStatus(beliefSet); // Assert - goal.Status.Should().NotBe(CompletionStatus.Failure); + goal.Status.Should().Be(CompletionStatus.Failure); } } diff --git a/Aplib.Core.Tests/GlobalUsings.cs b/Aplib.Core.Tests/GlobalUsings.cs index c802f448..a8a8e6ed 100644 --- a/Aplib.Core.Tests/GlobalUsings.cs +++ b/Aplib.Core.Tests/GlobalUsings.cs @@ -1 +1,5 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + global using Xunit; diff --git a/Aplib.Core.Tests/Intent/Actions/ActionTests.cs b/Aplib.Core.Tests/Intent/Actions/ActionTests.cs index 3ef8cde7..8aad0e45 100644 --- a/Aplib.Core.Tests/Intent/Actions/ActionTests.cs +++ b/Aplib.Core.Tests/Intent/Actions/ActionTests.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using FluentAssertions; using Moq; diff --git a/Aplib.Core.Tests/Intent/Tactics/TacticTests.cs b/Aplib.Core.Tests/Intent/Tactics/TacticTests.cs index 5d233267..04cdb762 100644 --- a/Aplib.Core.Tests/Intent/Tactics/TacticTests.cs +++ b/Aplib.Core.Tests/Intent/Tactics/TacticTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using Aplib.Core.Intent.Tactics; @@ -10,25 +14,6 @@ namespace Aplib.Core.Tests.Intent.Tactics; public class TacticTests { - // A subclass of Tactic for testing - public class TestTactic : Tactic - { - public System.Predicate Guard => _guard; - - public TestTactic(Metadata metadata, System.Predicate guard) : base(metadata, guard) { } - - public TestTactic(System.Predicate guard) : base(guard) { } - - public TestTactic(Metadata metadata) : base(metadata) { } - - public TestTactic() { } - - public override IAction GetAction(IBeliefSet beliefSet) - => throw new System.NotImplementedException(); - public override IEnumerable GetLogChildren() - => throw new System.NotImplementedException(); - } - // A subclass of FirstOfTactic for testing public class TestFirstOfTactic : FirstOfTactic { @@ -55,115 +40,109 @@ public TestFirstOfTactic(System.Predicate guard, params ITactic[] subtactics) : base(subtactics) { } } - - [Fact] - public void Tactic_WhenConstructed_HasExpectedData() + // A subclass of Tactic for testing + public class TestTactic : Tactic { - // Arrange - Metadata metadata = It.IsAny(); - System.Predicate guard = It.IsAny>(); + public System.Predicate Guard => _guard; - // Act - TestTactic tactic = new(metadata, guard); + public TestTactic(Metadata metadata, System.Predicate guard) : base(metadata, guard) { } - // Assert - tactic.Metadata.Should().Be(metadata); - tactic.Guard.Should().Be(guard); - } + public TestTactic(System.Predicate guard) : base(guard) { } - [Fact] - public void Tactic_WithoutMetadata_HasExpectedData() - { - // Arrange - System.Predicate guard = It.IsAny>(); + public TestTactic(Metadata metadata) : base(metadata) { } - // Act - TestTactic tactic = new(guard); + public TestTactic() { } - // Assert - tactic.Metadata.Id.Should().NotBeEmpty(); - tactic.Metadata.Name.Should().BeNull(); - tactic.Metadata.Description.Should().BeNull(); - tactic.Guard.Should().Be(guard); + public override IAction GetAction(IBeliefSet beliefSet) + => throw new System.NotImplementedException(); + + public override IEnumerable GetLogChildren() + => throw new System.NotImplementedException(); } [Fact] - public void Tactic_WithoutGuard_HasExpectedData() + public void AnyOfTactic_WithFalseGuard_ReturnsNoAction() { // Arrange - Metadata metadata = It.IsAny(); + Action action = new(_ => { }); + PrimitiveTactic tactic = new(action, _ => true); + RandomTactic parentTactic = new(_ => false, tactic); // Act - TestTactic tactic = new(metadata); + IAction? selectedAction = parentTactic.GetAction(It.IsAny()); // Assert - tactic.Metadata.Should().Be(metadata); - tactic.Guard(It.IsAny()).Should().BeTrue(); + selectedAction.Should().BeNull(); } + /// + /// Given no metadata, + /// When an AnyOfTactic is constructed, + /// Then it has no name, and a random id. + /// [Fact] - public void Tactic_Default_HasExpectedData() + public void AnyOfTactic_WithoutMetadata_ContainsDefaultMetadata() { // Act - TestTactic tactic = new(); + RandomTactic tactic = new(_ => true); // Assert tactic.Metadata.Id.Should().NotBeEmpty(); tactic.Metadata.Name.Should().BeNull(); tactic.Metadata.Description.Should().BeNull(); - tactic.Guard(It.IsAny()).Should().BeTrue(); } /// - /// Given a tactic and an action, - /// When the guard of the tactic returns true, - /// Then an action should be selected. + /// Given a parent of type with two subtactics, + /// When getting the next tactic, + /// Then the result should be the action of an enabled tactic. /// [Fact] - public void PrimitveTacticExecute_WhenGuardReturnsTrue_ActionIsSelected() + public void AnyOfTacticGetAction_WhenASubtacticIsEnabled_ReturnsActionOfEnabledSubtactic() { // Arrange - Mock> action = new(); - PrimitiveTactic tactic = new(action.Object, guard: _ => true); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); + PrimitiveTactic tactic1 = new(action1, _ => true); + PrimitiveTactic tactic2 = new(action2, _ => false); + RandomTactic parentTactic = new(tactic1, tactic2); // Act - IAction selectedAction = tactic.GetAction(It.IsAny())!; + IAction? selectedAction = parentTactic.GetAction(It.IsAny()); // Assert - selectedAction.Should().NotBeNull(); + selectedAction.Should().Be(action1); } - /// - /// Given no metadata, - /// When an AnyOfTactic is constructed, - /// Then it has no name, and a random id. - /// [Fact] - public void AnyOfTactic_WithoutMetadata_ContainsDefaultMetadata() + public void FirstOfTactic_WithFalseGuard_ReturnsNoAction() { + // Arrange + Action action = new(_ => { }); + PrimitiveTactic tactic = new(action, _ => true); + FirstOfTactic parentTactic = new(_ => false, tactic); + // Act - RandomTactic tactic = new(_ => true); + IAction? selectedAction = parentTactic.GetAction(It.IsAny()); // Assert - tactic.Metadata.Id.Should().NotBeEmpty(); - tactic.Metadata.Name.Should().BeNull(); - tactic.Metadata.Description.Should().BeNull(); + selectedAction.Should().BeNull(); } /// - /// Given a parent of type with two subtactics, - /// When getting the next tactic, - /// Then the result should be the action of an enabled tactic. + /// Given a parent of type with two subtactics, + /// When both subtactic guards are true, + /// Then the result should be the first subtactic. /// [Fact] - public void AnyOfTacticGetAction_WhenASubtacticIsEnabled_ReturnsActionOfEnabledSubtactic() + public void FirstOfTacticGetAction_WhenBothSubtacticsEnabled_ReturnsFirstSubtactic() { // Arrange Action action1 = new(_ => { }); Action action2 = new(_ => { }); PrimitiveTactic tactic1 = new(action1, _ => true); - PrimitiveTactic tactic2 = new(action2, _ => false); - RandomTactic parentTactic = new(tactic1, tactic2); + PrimitiveTactic tactic2 = new(action2, _ => true); + FirstOfTactic parentTactic = new(tactic1, tactic2); // Act IAction? selectedAction = parentTactic.GetAction(It.IsAny()); @@ -172,19 +151,26 @@ public void AnyOfTacticGetAction_WhenASubtacticIsEnabled_ReturnsActionOfEnabledS selectedAction.Should().Be(action1); } + /// + /// Given a parent of type with two subtactics, + /// When the first subtactic guard is false and the second is true, + /// Then the result should be the second subtactic. + /// [Fact] - public void AnyOfTactic_WithFalseGuard_ReturnsNoAction() + public void FirstOfTacticGetAction_WhenFirstSubtacticIsDisabled_ReturnsSecondSubtactic() { // Arrange - Action action = new(_ => { }); - PrimitiveTactic tactic = new(action, _ => true); - RandomTactic parentTactic = new(_ => false, tactic); + Action action1 = new(_ => { }); + Action action2 = new(_ => { }); + PrimitiveTactic tactic1 = new(action1, _ => false); + PrimitiveTactic tactic2 = new(action2, _ => true); + FirstOfTactic parentTactic = new(tactic1, tactic2); // Act IAction? selectedAction = parentTactic.GetAction(It.IsAny()); // Assert - selectedAction.Should().BeNull(); + selectedAction.Should().Be(action2); } [Fact] @@ -256,62 +242,22 @@ public void FirstOfTacticTactic_WithoutMetadataWithoutGuard_HasExpectedData() } /// - /// Given a parent of type with two subtactics, - /// When both subtactic guards are true, - /// Then the result should be the first subtactic. - /// - [Fact] - public void FirstOfTacticGetAction_WhenBothSubtacticsEnabled_ReturnsFirstSubtactic() - { - // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); - PrimitiveTactic tactic1 = new(action1, _ => true); - PrimitiveTactic tactic2 = new(action2, _ => true); - FirstOfTactic parentTactic = new(tactic1, tactic2); - - // Act - IAction? selectedAction = parentTactic.GetAction(It.IsAny()); - - // Assert - selectedAction.Should().Be(action1); - } - - /// - /// Given a parent of type with two subtactics, - /// When the first subtactic guard is false and the second is true, - /// Then the result should be the second subtactic. + /// Given a primitive tactic with a non-actionable action, + /// When calling GetAction, + /// Then the result should be null. /// [Fact] - public void FirstOfTacticGetAction_WhenFirstSubtacticIsDisabled_ReturnsSecondSubtactic() - { - // Arrange - Action action1 = new(_ => { }); - Action action2 = new(_ => { }); - PrimitiveTactic tactic1 = new(action1, _ => false); - PrimitiveTactic tactic2 = new(action2, _ => true); - FirstOfTactic parentTactic = new(tactic1, tactic2); - - // Act - IAction? selectedAction = parentTactic.GetAction(It.IsAny()); - - // Assert - selectedAction.Should().Be(action2); - } - - [Fact] - public void FirstOfTactic_WithFalseGuard_ReturnsNoAction() + public void PrimitiveTactic_WhenTacticTypeIsPrimitiveAndActionIsNotActionable_ReturnsNoAction() { // Arrange Action action = new(_ => { }); - PrimitiveTactic tactic = new(action, _ => true); - FirstOfTactic parentTactic = new(_ => false, tactic); + PrimitiveTactic tactic = new(action, _ => false); // Act - IAction? selectedAction = parentTactic.GetAction(It.IsAny()); + IAction? enabledAction = tactic.GetAction(It.IsAny()); // Assert - selectedAction.Should().BeNull(); + enabledAction.Should().Be(null); } /// @@ -333,25 +279,6 @@ public void PrimitiveTacticGetAction_WhenTacticTypeIsPrimitiveAndActionIsActiona enabledAction.Should().Be(action); } - /// - /// Given a primitive tactic with a non-actionable action, - /// When calling GetAction, - /// Then the result should be null. - /// - [Fact] - public void PrimitiveTactic_WhenTacticTypeIsPrimitiveAndActionIsNotActionable_ReturnsNoAction() - { - // Arrange - Action action = new(_ => { }); - PrimitiveTactic tactic = new(action, _ => false); - - // Act - IAction? enabledAction = tactic.GetAction(It.IsAny()); - - // Assert - enabledAction.Should().Be(null); - } - /// /// Given a tactic with a guard that returns false, /// When checking if the tactic is actionable, @@ -389,6 +316,29 @@ public void PrimitiveTacticIsActionable_WhenGuardReturnsTrueAndActionIsActionabl isActionable.Should().BeTrue(); } + [Fact] + public void PrimitiveTacticIsActionable_WhenGuardReturnsTrueAndHasNullQuery_IsNotActionable() + { + // Arrange + int result = 0; + QueryAction action = new((_, b) => result = b!.Value, + _ => + { + int? x = null; + return x; + } + ); + PrimitiveTactic tactic = new(action, _ => true); + IBeliefSet beliefSet = Mock.Of(); + + // Act + bool isActionable = tactic.IsActionable(beliefSet); + + // Assert + isActionable.Should().BeFalse(); + result.Should().Be(0); + } + [Fact] public void PrimitiveTacticIsActionable_WhenGuardReturnsTrueAndHasQuery_ReturnsCorrectQuery() { @@ -407,26 +357,81 @@ public void PrimitiveTacticIsActionable_WhenGuardReturnsTrueAndHasQuery_ReturnsC result.Should().Be(42); } + /// + /// Given a tactic and an action, + /// When the guard of the tactic returns true, + /// Then an action should be selected. + /// [Fact] - public void PrimitiveTacticIsActionable_WhenGuardReturnsTrueAndHasNullQuery_IsNotActionable() + public void PrimitveTacticExecute_WhenGuardReturnsTrue_ActionIsSelected() { // Arrange - int result = 0; - QueryAction action = new((_, b) => result = b!.Value, - _ => - { - int? x = null; - return x; - } - ); - PrimitiveTactic tactic = new(action, _ => true); - IBeliefSet beliefSet = Mock.Of(); + Mock> action = new(); + PrimitiveTactic tactic = new(action.Object, guard: _ => true); // Act - bool isActionable = tactic.IsActionable(beliefSet); + IAction selectedAction = tactic.GetAction(It.IsAny())!; // Assert - isActionable.Should().BeFalse(); - result.Should().Be(0); + selectedAction.Should().NotBeNull(); + } + + [Fact] + public void Tactic_Default_HasExpectedData() + { + // Act + TestTactic tactic = new(); + + // Assert + tactic.Metadata.Id.Should().NotBeEmpty(); + tactic.Metadata.Name.Should().BeNull(); + tactic.Metadata.Description.Should().BeNull(); + tactic.Guard(It.IsAny()).Should().BeTrue(); + } + + + [Fact] + public void Tactic_WhenConstructed_HasExpectedData() + { + // Arrange + Metadata metadata = It.IsAny(); + System.Predicate guard = It.IsAny>(); + + // Act + TestTactic tactic = new(metadata, guard); + + // Assert + tactic.Metadata.Should().Be(metadata); + tactic.Guard.Should().Be(guard); + } + + [Fact] + public void Tactic_WithoutGuard_HasExpectedData() + { + // Arrange + Metadata metadata = It.IsAny(); + + // Act + TestTactic tactic = new(metadata); + + // Assert + tactic.Metadata.Should().Be(metadata); + tactic.Guard(It.IsAny()).Should().BeTrue(); + } + + [Fact] + public void Tactic_WithoutMetadata_HasExpectedData() + { + // Arrange + System.Predicate guard = It.IsAny>(); + + // Act + TestTactic tactic = new(guard); + + // Assert + tactic.Metadata.Id.Should().NotBeEmpty(); + tactic.Metadata.Name.Should().BeNull(); + tactic.Metadata.Description.Should().BeNull(); + tactic.Guard.Should().Be(guard); } } diff --git a/Aplib.Core.Tests/LiftingTests.cs b/Aplib.Core.Tests/LiftingTests.cs index f3ffa58e..890957ff 100644 --- a/Aplib.Core.Tests/LiftingTests.cs +++ b/Aplib.Core.Tests/LiftingTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; using Aplib.Core.Desire.Goals; @@ -24,94 +28,93 @@ [new Metadata(description: "aap noot mies") ] }; /// - /// Given a query action lifted to a tactic, + /// Given an action lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Fact] - public void ImplicitLifting_QueryActionLiftedToTactic_DoesNotDifferFromManualTactic() + [Theory] + [MemberData(nameof(MetadataMemberData))] + public void ExplicitLifting_ActionLiftedToTactic_DoesNotDifferFromManualTactic(Metadata metadata) { // Arrange - QueryAction action = new((_, _) => { }, _ => 69); + Action action = It.IsAny>(); // Act - Tactic liftedTactic = action; - Tactic manualTactic = new PrimitiveTactic(queryAction: action, _ => true); + Tactic liftedTactic = action.Lift(metadata); + Tactic manualTactic = new PrimitiveTactic(metadata, action, _ => true); // Assert - liftedTactic.GetAction(It.IsAny()) - .Should().Be(manualTactic.GetAction(It.IsAny())); - // TODO assert guard + liftedTactic.Should().BeEquivalentTo(manualTactic); } /// - /// Given a query action lifted to a tactic, + /// Given a goal lifted to a desire set, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Theory] [MemberData(nameof(MetadataMemberData))] - public void ExplicitLifting_QueryActionLiftedToTactic_DoesNotDifferFromManualTactic(Metadata metadata) + public void ExplicitLifting_GoalLiftedToDesireSet_DoesNotDifferFromManualTactic(Metadata metadata) { // Arrange - Action action = It.IsAny>(); + Goal goal = It.IsAny>(); // Act - Tactic liftedTactic = action.Lift(metadata); - Tactic manualTactic = new PrimitiveTactic(metadata, action, _ => true); + DesireSet liftedDesireSet = goal.Lift().Lift(metadata); + DesireSet manualDesireSet = new(metadata, new PrimitiveGoalStructure(goal)); // Assert - liftedTactic.Should().BeEquivalentTo(manualTactic); + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config); } /// - /// Given a query action lifted to a tactic, + /// Given a goal lifted to a goal structure, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Fact] - public void Lifting_IQueryableLiftedToTactic_DoesNotDifferFromManualTactic() + [Theory] + [MemberData(nameof(MetadataMemberData))] + public void ExplicitLifting_GoalLiftedToGoalStructure_DoesNotDifferFromManualTactic(Metadata metadata) { // Arrange - Action action = It.IsAny>(); + Goal goal = It.IsAny>(); // Act - Tactic liftedTactic = action.Lift(); - Tactic manualTactic = new PrimitiveTactic(action, _ => true); + GoalStructure liftedGoalStructure = goal.Lift(metadata); + GoalStructure manualGoalStructure = new PrimitiveGoalStructure(metadata, goal); // Assert - liftedTactic.Should().BeEquivalentTo(manualTactic, config => config.Excluding(o => o.Metadata.Id)); + liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure); } /// - /// Given an action lifted to a tactic, + /// Given a goal structure lifted to a desire set, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Fact] - public void ImplicitLifting_ActionLiftedToTactic_DoesNotDifferFromManualTactic() + [Theory] + [MemberData(nameof(MetadataMemberData))] + public void ExplicitLifting_GoalStructureLiftedToDesireSet_DoesNotDifferFromManualTactic(Metadata metadata) { // Arrange - Action action = It.IsAny>(); + GoalStructure goalStructure = It.IsAny>(); // Act - Tactic liftedTactic = action; - Tactic manualTactic = new PrimitiveTactic(action, _ => true); + DesireSet liftedDesireSet = goalStructure.Lift(metadata); + DesireSet manualDesireSet = new(metadata, goalStructure); // Assert - liftedTactic.GetAction(It.IsAny()) - .Should().Be(manualTactic.GetAction(It.IsAny())); - // TODO assert guard + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet); } /// - /// Given an action lifted to a tactic, + /// Given a query action lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Theory] [MemberData(nameof(MetadataMemberData))] - public void ExplicitLifting_ActionLiftedToTactic_DoesNotDifferFromManualTactic(Metadata metadata) + public void ExplicitLifting_QueryActionLiftedToTactic_DoesNotDifferFromManualTactic(Metadata metadata) { // Arrange Action action = It.IsAny>(); @@ -125,62 +128,63 @@ public void ExplicitLifting_ActionLiftedToTactic_DoesNotDifferFromManualTactic(M } /// - /// Given a goal lifted to a goal structure, + /// Given an action lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void ImplicitLifting_GoalLiftedToGoalStructure_DoesNotDifferFromManualTactic() + public void ImplicitLifting_ActionLiftedToTactic_DoesNotDifferFromManualTactic() { // Arrange - Goal goal = new(It.IsAny>(), _ => true); + Action action = It.IsAny>(); // Act - GoalStructure liftedGoalStructure = goal; - GoalStructure manualGoalStructure = new PrimitiveGoalStructure(goal); + Tactic liftedTactic = action; + Tactic manualTactic = new PrimitiveTactic(action, _ => true); // Assert - liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure, config => config - .Excluding(o => o.Metadata.Id)); + liftedTactic.GetAction(It.IsAny()) + .Should().Be(manualTactic.GetAction(It.IsAny())); + // TODO assert guard } /// - /// Given a goal lifted to a goal structure, + /// Given a goal lifted to a desire set, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Theory] - [MemberData(nameof(MetadataMemberData))] - public void ExplicitLifting_GoalLiftedToGoalStructure_DoesNotDifferFromManualTactic(Metadata metadata) + [Fact] + public void ImplicitLifting_GoalLiftedToDesireSet_DoesNotDifferFromManualTactic() { // Arrange - Goal goal = It.IsAny>(); + Goal goal = new(It.IsAny>(), _ => true); // Act - GoalStructure liftedGoalStructure = goal.Lift(metadata); - GoalStructure manualGoalStructure = new PrimitiveGoalStructure(metadata, goal); + DesireSet liftedDesireSet = goal; + DesireSet manualDesireSet = new(goal.Metadata, new PrimitiveGoalStructure(goal)); // Assert - liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure); + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config + .Excluding(o => o.Metadata.Id)); } /// - /// Given a goal structure lifted to a desire set, + /// Given a goal lifted to a goal structure, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void ImplicitLifting_GoalStructureLiftedToDesireSet_DoesNotDifferFromManualTactic() + public void ImplicitLifting_GoalLiftedToGoalStructure_DoesNotDifferFromManualTactic() { // Arrange - GoalStructure goalStructure = new PrimitiveGoalStructure(It.IsAny>()); + Goal goal = new(It.IsAny>(), _ => true); // Act - DesireSet liftedDesireSet = goalStructure; - DesireSet manualDesireSet = new(goalStructure.Metadata, goalStructure); + GoalStructure liftedGoalStructure = goal; + GoalStructure manualGoalStructure = new PrimitiveGoalStructure(goal); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config + liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure, config => config .Excluding(o => o.Metadata.Id)); } @@ -189,59 +193,59 @@ public void ImplicitLifting_GoalStructureLiftedToDesireSet_DoesNotDifferFromManu /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Theory] - [MemberData(nameof(MetadataMemberData))] - public void ExplicitLifting_GoalStructureLiftedToDesireSet_DoesNotDifferFromManualTactic(Metadata metadata) + [Fact] + public void ImplicitLifting_GoalStructureLiftedToDesireSet_DoesNotDifferFromManualTactic() { // Arrange - GoalStructure goalStructure = It.IsAny>(); + GoalStructure goalStructure = new PrimitiveGoalStructure(It.IsAny>()); // Act - DesireSet liftedDesireSet = goalStructure.Lift(metadata); - DesireSet manualDesireSet = new(metadata, goalStructure); + DesireSet liftedDesireSet = goalStructure; + DesireSet manualDesireSet = new(goalStructure.Metadata, goalStructure); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet); + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config + .Excluding(o => o.Metadata.Id)); } /// - /// Given a goal lifted to a desire set, + /// Given a query action lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void ImplicitLifting_GoalLiftedToDesireSet_DoesNotDifferFromManualTactic() + public void ImplicitLifting_QueryActionLiftedToTactic_DoesNotDifferFromManualTactic() { // Arrange - Goal goal = new(It.IsAny>(), _ => true); + QueryAction action = new((_, _) => { }, _ => 69); // Act - DesireSet liftedDesireSet = goal; - DesireSet manualDesireSet = new(goal.Metadata, new PrimitiveGoalStructure(goal)); + Tactic liftedTactic = action; + Tactic manualTactic = new PrimitiveTactic(queryAction: action, _ => true); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config - .Excluding(o => o.Metadata.Id)); + liftedTactic.GetAction(It.IsAny()) + .Should().Be(manualTactic.GetAction(It.IsAny())); + // TODO assert guard } /// - /// Given a goal lifted to a desire set, + /// Given a query action lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// - [Theory] - [MemberData(nameof(MetadataMemberData))] - public void ExplicitLifting_GoalLiftedToDesireSet_DoesNotDifferFromManualTactic(Metadata metadata) + [Fact] + public void Lifting_IQueryableLiftedToTactic_DoesNotDifferFromManualTactic() { // Arrange - Goal goal = It.IsAny>(); + Action action = It.IsAny>(); // Act - DesireSet liftedDesireSet = goal.Lift().Lift(metadata); - DesireSet manualDesireSet = new(metadata, new PrimitiveGoalStructure(goal)); + Tactic liftedTactic = action.Lift(); + Tactic manualTactic = new PrimitiveTactic(action, _ => true); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config); + liftedTactic.Should().BeEquivalentTo(manualTactic, config => config.Excluding(o => o.Metadata.Id)); } /// @@ -264,81 +268,81 @@ public void Lifting_UndocumentedActionToTactic_DoesNotDifferFromManualTactic() } /// - /// Given an undocumented action which is lifted to a tactic, + /// Given an undocumented goal lifted to a desire set, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void Lifting_UndocumentedQueryActionToTactic_DoesNotDifferFromManualTactic() + public void Lifting_UndocumentedGoalLiftedToDesireSet_DoesNotDifferFromManualTactic() { - Mock> undocumentedQueryAction = new(); + // Arrange + Mock> undocumentedGoal = new(); // Act - Tactic liftedTactic = undocumentedQueryAction.Object.Lift(); - Tactic manualTactic = new PrimitiveTactic(undocumentedQueryAction.Object, _ => true); + DesireSet liftedDesireSet = undocumentedGoal.Object.Lift(); + DesireSet manualDesireSet = new(new PrimitiveGoalStructure(undocumentedGoal.Object)); // Assert - liftedTactic.Should().BeEquivalentTo(manualTactic, config => config + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config .Excluding(o => o.Metadata.Id)); } /// - /// Given an undocumented goal which is lifted to a goal structure, + /// Given an undocumented goal structure which is lifted to a desire set, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void Lifting_UndocumentedGoalToGoalStructure_DoesNotDifferFromManualTactic() + public void Lifting_UndocumentedGoalStructureToDesireSet_DoesNotDifferFromManualTactic() { // Arrange - Mock> undocumentedGoal = new(); + Mock> undocumentedGoalStructure = new(); // Act - GoalStructure liftedGoalStructure = undocumentedGoal.Object.Lift(); - GoalStructure manualGoalStructure = new PrimitiveGoalStructure(undocumentedGoal.Object); + DesireSet liftedDesireSet = undocumentedGoalStructure.Object.Lift(); + DesireSet manualDesireSet = new(undocumentedGoalStructure.Object); // Assert - liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure, config => config + liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config .Excluding(o => o.Metadata.Id)); } /// - /// Given an undocumented goal lifted to a desire set, + /// Given an undocumented goal which is lifted to a goal structure, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void Lifting_UndocumentedGoalLiftedToDesireSet_DoesNotDifferFromManualTactic() + public void Lifting_UndocumentedGoalToGoalStructure_DoesNotDifferFromManualTactic() { // Arrange Mock> undocumentedGoal = new(); // Act - DesireSet liftedDesireSet = undocumentedGoal.Object.Lift(); - DesireSet manualDesireSet = new(new PrimitiveGoalStructure(undocumentedGoal.Object)); + GoalStructure liftedGoalStructure = undocumentedGoal.Object.Lift(); + GoalStructure manualGoalStructure = new PrimitiveGoalStructure(undocumentedGoal.Object); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config + liftedGoalStructure.Should().BeEquivalentTo(manualGoalStructure, config => config .Excluding(o => o.Metadata.Id)); } /// - /// Given an undocumented goal structure which is lifted to a desire set, + /// Given an undocumented action which is lifted to a tactic, /// When compared to the latter, manually created to be trivially correct, /// Then the two should be equal, but the metadata name should differ. /// [Fact] - public void Lifting_UndocumentedGoalStructureToDesireSet_DoesNotDifferFromManualTactic() + public void Lifting_UndocumentedQueryActionToTactic_DoesNotDifferFromManualTactic() { - // Arrange - Mock> undocumentedGoalStructure = new(); + Mock> undocumentedQueryAction = new(); // Act - DesireSet liftedDesireSet = undocumentedGoalStructure.Object.Lift(); - DesireSet manualDesireSet = new(undocumentedGoalStructure.Object); + Tactic liftedTactic = undocumentedQueryAction.Object.Lift(); + Tactic manualTactic = new PrimitiveTactic(undocumentedQueryAction.Object, _ => true); // Assert - liftedDesireSet.Should().BeEquivalentTo(manualDesireSet, config => config + liftedTactic.Should().BeEquivalentTo(manualTactic, config => config .Excluding(o => o.Metadata.Id)); } } diff --git a/Aplib.Core.Tests/LoggableTests.cs b/Aplib.Core.Tests/LoggableTests.cs index 7fc08d28..d8707371 100644 --- a/Aplib.Core.Tests/LoggableTests.cs +++ b/Aplib.Core.Tests/LoggableTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; using Aplib.Core.Desire.Goals; @@ -13,10 +17,10 @@ public class LoggableTests { private readonly Action _action1; private readonly Action _action2; - private readonly PrimitiveTactic _tactic1; - private readonly PrimitiveTactic _tactic2; private readonly Goal _goal1; private readonly Goal _goal2; + private readonly PrimitiveTactic _tactic1; + private readonly PrimitiveTactic _tactic2; /// /// Set up (part of a) DesireSet to use in the tests. @@ -32,12 +36,14 @@ public LoggableTests() } [Fact] - public void PrimitiveTactic_WhenGettingTree_ReturnsCorrectTree() + public void AnyOfTactic_WhenGettingTree_ReturnsCorrectTree() { // Arrange - PrimitiveTactic tactic = new(_action1, _ => true); + RandomTactic tactic = new(_tactic1, _tactic2); - LogNode expectedRoot = new(tactic, 0, [new LogNode(_action1, 1)]); + LogNode tactic1Node = new(_tactic1, 1, [new LogNode(_action1, 2)]); + LogNode tactic2Node = new(_tactic2, 1, [new LogNode(_action2, 2)]); + LogNode expectedRoot = new(tactic, 0, [tactic1Node, tactic2Node]); // Act LogNode root = ((ILoggable)tactic).GetLogTree(); @@ -47,17 +53,19 @@ public void PrimitiveTactic_WhenGettingTree_ReturnsCorrectTree() } [Fact] - public void AnyOfTactic_WhenGettingTree_ReturnsCorrectTree() + public void DesireSet_WhenGettingTree_ReturnsCorrectTree() { // Arrange - RandomTactic tactic = new(_tactic1, _tactic2); + Goal goal = new(_tactic1, _ => true); + PrimitiveGoalStructure goalStructure = new(goal); + DesireSet desireSet = new(goalStructure); - LogNode tactic1Node = new(_tactic1, 1, [new LogNode(_action1, 2)]); - LogNode tactic2Node = new(_tactic2, 1, [new LogNode(_action2, 2)]); - LogNode expectedRoot = new(tactic, 0, [tactic1Node, tactic2Node]); + LogNode goalNode = new(goal, 2, [new LogNode(_tactic1, 3, [new LogNode(_action1, 4)])]); + LogNode goalStructureNode = new(goalStructure, 1, [goalNode]); + LogNode expectedRoot = new(desireSet, 0, [goalStructureNode]); // Act - LogNode root = ((ILoggable)tactic).GetLogTree(); + LogNode root = ((ILoggable)desireSet).GetLogTree(); // Assert root.Should().BeEquivalentTo(expectedRoot); @@ -116,40 +124,36 @@ public void PrimitiveGoalStructure_WhenGettingTree_ReturnsCorrectTree() } [Fact] - public void SequentialGoalStructure_WhenGettingTree_ReturnsCorrectTree() + public void PrimitiveTactic_WhenGettingTree_ReturnsCorrectTree() { // Arrange - PrimitiveGoalStructure primitiveStructure1 = new(_goal1); - PrimitiveGoalStructure primitiveStructure2 = new(_goal2); - SequentialGoalStructure seqStructure = new(primitiveStructure1, primitiveStructure2); + PrimitiveTactic tactic = new(_action1, _ => true); - LogNode goalNode1 = new(_goal1, 2, [new LogNode(_tactic1, 3, [new LogNode(_action1, 4)])]); - LogNode goalStructureNode1 = new(primitiveStructure1, 1, [goalNode1]); - LogNode goalNode2 = new(_goal2, 2, [new LogNode(_tactic2, 3, [new LogNode(_action2, 4)])]); - LogNode goalStructureNode2 = new(primitiveStructure2, 1, [goalNode2]); - LogNode expectedRoot = new(seqStructure, 0, [goalStructureNode1, goalStructureNode2]); + LogNode expectedRoot = new(tactic, 0, [new LogNode(_action1, 1)]); // Act - LogNode root = ((ILoggable)seqStructure).GetLogTree(); + LogNode root = ((ILoggable)tactic).GetLogTree(); // Assert root.Should().BeEquivalentTo(expectedRoot); } [Fact] - public void DesireSet_WhenGettingTree_ReturnsCorrectTree() + public void SequentialGoalStructure_WhenGettingTree_ReturnsCorrectTree() { // Arrange - Goal goal = new(_tactic1, _ => true); - PrimitiveGoalStructure goalStructure = new(goal); - DesireSet desireSet = new(goalStructure); + PrimitiveGoalStructure primitiveStructure1 = new(_goal1); + PrimitiveGoalStructure primitiveStructure2 = new(_goal2); + SequentialGoalStructure seqStructure = new(primitiveStructure1, primitiveStructure2); - LogNode goalNode = new(goal, 2, [new LogNode(_tactic1, 3, [new LogNode(_action1, 4)])]); - LogNode goalStructureNode = new(goalStructure, 1, [goalNode]); - LogNode expectedRoot = new(desireSet, 0, [goalStructureNode]); + LogNode goalNode1 = new(_goal1, 2, [new LogNode(_tactic1, 3, [new LogNode(_action1, 4)])]); + LogNode goalStructureNode1 = new(primitiveStructure1, 1, [goalNode1]); + LogNode goalNode2 = new(_goal2, 2, [new LogNode(_tactic2, 3, [new LogNode(_action2, 4)])]); + LogNode goalStructureNode2 = new(primitiveStructure2, 1, [goalNode2]); + LogNode expectedRoot = new(seqStructure, 0, [goalStructureNode1, goalStructureNode2]); // Act - LogNode root = ((ILoggable)desireSet).GetLogTree(); + LogNode root = ((ILoggable)seqStructure).GetLogTree(); // Assert root.Should().BeEquivalentTo(expectedRoot); diff --git a/Aplib.Core.Tests/MetadataTests.cs b/Aplib.Core.Tests/MetadataTests.cs index a5d28de4..1829e653 100644 --- a/Aplib.Core.Tests/MetadataTests.cs +++ b/Aplib.Core.Tests/MetadataTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using FluentAssertions; namespace Aplib.Core.Tests; diff --git a/Aplib.Core/Agents/BdiAgent.cs b/Aplib.Core/Agents/BdiAgent.cs index dd0841fd..1ae563d6 100644 --- a/Aplib.Core/Agents/BdiAgent.cs +++ b/Aplib.Core/Agents/BdiAgent.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; using Aplib.Core.Desire.Goals; @@ -12,6 +16,9 @@ namespace Aplib.Core.Agents public class BdiAgent : IAgent where TBeliefSet : IBeliefSet { + /// + public CompletionStatus Status => _desireSet.Status; + /// /// Gets the belief set of the agent. /// @@ -25,9 +32,6 @@ public class BdiAgent : IAgent /// private readonly IDesireSet _desireSet; - /// - public CompletionStatus Status => _desireSet.Status; - /// /// Initializes a new instance of the class, /// from a given set of beliefs and desires. diff --git a/Aplib.Core/Agents/IAgent.cs b/Aplib.Core/Agents/IAgent.cs index 9cee722b..569342c0 100644 --- a/Aplib.Core/Agents/IAgent.cs +++ b/Aplib.Core/Agents/IAgent.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + namespace Aplib.Core.Agents { /// diff --git a/Aplib.Core/Belief/BeliefSets/BeliefSet.cs b/Aplib.Core/Belief/BeliefSets/BeliefSet.cs index 67c9c348..33cc28bd 100644 --- a/Aplib.Core/Belief/BeliefSets/BeliefSet.cs +++ b/Aplib.Core/Belief/BeliefSets/BeliefSet.cs @@ -1,14 +1,18 @@ -using Aplib.Core.Belief.Beliefs; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.Beliefs; using System.Linq; namespace Aplib.Core.Belief.BeliefSets { /// /// This class can be inherited to define a set of beliefs for an agent. - /// All public fields defined in the inheriting class that implement + /// All public fields defined in the inheriting class that implement /// are automatically updated when calling . /// - public abstract class BeliefSet : IBeliefSet + public class BeliefSet : IBeliefSet { /// /// An array storing all public fields of type that are defined in the inheriting diff --git a/Aplib.Core/Belief/BeliefSets/IBeliefSet.cs b/Aplib.Core/Belief/BeliefSets/IBeliefSet.cs index 8845d55c..de431c2f 100644 --- a/Aplib.Core/Belief/BeliefSets/IBeliefSet.cs +++ b/Aplib.Core/Belief/BeliefSets/IBeliefSet.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core.Belief.BeliefSets +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core.Belief.BeliefSets { /// /// A belief set defines the beliefs of an agent. diff --git a/Aplib.Core/Belief/Beliefs/Belief.cs b/Aplib.Core/Belief/Beliefs/Belief.cs index 2e85ae32..0277c9c8 100644 --- a/Aplib.Core/Belief/Beliefs/Belief.cs +++ b/Aplib.Core/Belief/Beliefs/Belief.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core.Belief.Beliefs +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core.Belief.Beliefs { /// /// Represents the agent's belief of a single object. @@ -17,34 +21,34 @@ public class Belief : IBelief where TReference : class { /// - /// The object reference used to generate/update the observation. + /// Gets the metadata of the Belief. /// - protected internal readonly TReference _reference; + /// + /// This metadata may be useful for debugging or logging. + /// + public Metadata Metadata { get; } /// - /// A function that takes an object reference and generates/updates an observation. + /// The observation represented by the belief + /// (i.e., some information about the game state as perceived by an agent). /// - protected internal readonly System.Func _getObservationFromReference; + public TObservation Observation { get; protected set; } /// - /// A condition on when the observation should be updated. Takes the object reference - /// of the belief as a parameter for the predicate. + /// A function that takes an object reference and generates/updates an observation. /// - protected internal readonly System.Predicate _shouldUpdate; + protected internal readonly System.Func _getObservationFromReference; /// - /// Gets the metadata of the Belief. + /// The object reference used to generate/update the observation. /// - /// - /// This metadata may be useful for debugging or logging. - /// - public Metadata Metadata { get; } + protected internal readonly TReference _reference; /// - /// The observation represented by the belief - /// (i.e., some information about the game state as perceived by an agent). + /// A condition on when the observation should be updated. Takes the object reference + /// of the belief as a parameter for the predicate. /// - public TObservation Observation { get; protected set; } + protected internal readonly System.Predicate _shouldUpdate; /// /// Initializes a new instance of the class with an object diff --git a/Aplib.Core/Belief/Beliefs/IBelief.cs b/Aplib.Core/Belief/Beliefs/IBelief.cs index 2774c5c7..53a589a1 100644 --- a/Aplib.Core/Belief/Beliefs/IBelief.cs +++ b/Aplib.Core/Belief/Beliefs/IBelief.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core.Belief.Beliefs +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core.Belief.Beliefs { /// /// A belief represents/encapsulates an observation, diff --git a/Aplib.Core/Belief/Beliefs/ListBelief.cs b/Aplib.Core/Belief/Beliefs/ListBelief.cs index c765a155..96936d2d 100644 --- a/Aplib.Core/Belief/Beliefs/ListBelief.cs +++ b/Aplib.Core/Belief/Beliefs/ListBelief.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using System.Collections.Generic; using System.Linq; diff --git a/Aplib.Core/Belief/Beliefs/MemoryBelief.cs b/Aplib.Core/Belief/Beliefs/MemoryBelief.cs index 4d2258f0..5ded500d 100644 --- a/Aplib.Core/Belief/Beliefs/MemoryBelief.cs +++ b/Aplib.Core/Belief/Beliefs/MemoryBelief.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Collections; namespace Aplib.Core.Belief.Beliefs @@ -103,10 +107,11 @@ public override void UpdateBelief() } /// - /// Gets the most recently memorized observation. + /// Gets all the memorized observations. + /// The first element is the newest memory. /// - /// The most recent memory of the observation. - public TObservation GetMostRecentMemory() => _memorizedObservations.GetFirst(); + /// An array of all the memorized observations. + public TObservation[] GetAllMemories() => _memorizedObservations.ToArray(); /// /// Gets the memorized observation at a specific index. @@ -127,10 +132,9 @@ public TObservation GetMemoryAt(int index, bool clamp = false) } /// - /// Gets all the memorized observations. - /// The first element is the newest memory. + /// Gets the most recently memorized observation. /// - /// An array of all the memorized observations. - public TObservation[] GetAllMemories() => _memorizedObservations.ToArray(); + /// The most recent memory of the observation. + public TObservation GetMostRecentMemory() => _memorizedObservations.GetFirst(); } } diff --git a/Aplib.Core/Belief/Beliefs/SampledMemoryBelief.cs b/Aplib.Core/Belief/Beliefs/SampledMemoryBelief.cs index 6e8d770f..77f6adcb 100644 --- a/Aplib.Core/Belief/Beliefs/SampledMemoryBelief.cs +++ b/Aplib.Core/Belief/Beliefs/SampledMemoryBelief.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using static Aplib.Core.Belief.Beliefs.UpdateMode; namespace Aplib.Core.Belief.Beliefs @@ -22,6 +26,8 @@ namespace Aplib.Core.Belief.Beliefs public class SampledMemoryBelief : MemoryBelief where TReference : class { + private int _moduloCounter = 0; + /// /// The sample interval of the memory (inverse of the sample rate). /// One observation memory (i.e., snapshot) is stored every -th cycle. @@ -33,8 +39,6 @@ public class SampledMemoryBelief : MemoryBelief private readonly UpdateMode _updateMode; - private int _moduloCounter = 0; - /// /// The number of cycles that have passed since the last memory sample was stored. /// @@ -160,13 +164,6 @@ int framesToRemember { } - /// - /// Determines whether the memory should be sampled. - /// One observation memory (i.e., snapshot) is stored every sampleInterval-th cycle. - /// - /// Whether a memory sample should be stored in the current cycle. - private bool ShouldSampleMemory() => ModuloCounter++ == 0; - /// /// Generates/updates the observation if applicable. /// Also stores the previous observation in memory every sampleInterval-th cycle. @@ -177,5 +174,12 @@ public override void UpdateBelief() base.UpdateBelief(); else if (_updateMode is AlwaysUpdate && _shouldUpdate(_reference)) UpdateObservation(); } + + /// + /// Determines whether the memory should be sampled. + /// One observation memory (i.e., snapshot) is stored every sampleInterval-th cycle. + /// + /// Whether a memory sample should be stored in the current cycle. + private bool ShouldSampleMemory() => ModuloCounter++ == 0; } } diff --git a/Aplib.Core/Belief/Beliefs/UpdateMode.cs b/Aplib.Core/Belief/Beliefs/UpdateMode.cs index 27d921f6..7374c79c 100644 --- a/Aplib.Core/Belief/Beliefs/UpdateMode.cs +++ b/Aplib.Core/Belief/Beliefs/UpdateMode.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core.Belief.Beliefs +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core.Belief.Beliefs { /// /// Specifies the update mode of a sampled memory belief. diff --git a/Aplib.Core/Collections/CircularArray.cs b/Aplib.Core/Collections/CircularArray.cs index 91c31e72..99228a44 100644 --- a/Aplib.Core/Collections/CircularArray.cs +++ b/Aplib.Core/Collections/CircularArray.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + namespace Aplib.Core.Collections { /// @@ -6,13 +10,24 @@ namespace Aplib.Core.Collections /// public class CircularArray { + /// + /// The length of the array. + /// + public int Length { get; private set; } + private readonly T[] _array; private int _head; /// - /// The length of the array. + /// Gets the element at the specified index. /// - public int Length { get; private set; } + /// The index of the element to get. + /// The element at the specified index. + public T this[int index] + { + get => _array[(index + _head + 1) % Length]; + set => _array[(index + _head + 1) % Length] = value; + } /// /// Initializes a new instance of the class. @@ -37,22 +52,21 @@ public CircularArray(T[] array) } /// - /// Gets the element at the specified index. + /// Gets the first element of the array. /// - /// The index of the element to get. - /// The element at the specified index. - public T this[int index] + /// The last element of the array + public T GetFirst() { - get => _array[(index + _head + 1) % Length]; - set => _array[(index + _head + 1) % Length] = value; + return this[0]; } /// - /// Decrements the head of the array. + /// Gets the element at the head of the array. /// - private void DecrementHead() + /// The element at the head of the array + public T GetHead() { - _head = (_head - 1 + Length) % Length; + return _array[_head]; } /// @@ -65,24 +79,6 @@ public void Put(T value) DecrementHead(); } - /// - /// Gets the element at the head of the array. - /// - /// The element at the head of the array - public T GetHead() - { - return _array[_head]; - } - - /// - /// Gets the first element of the array. - /// - /// The last element of the array - public T GetFirst() - { - return this[0]; - } - /// /// Converts the circular array to an array. /// The head should be the last element of the array. @@ -99,5 +95,13 @@ public T[] ToArray(int start = 0, int end = -1) return result; } + + /// + /// Decrements the head of the array. + /// + private void DecrementHead() + { + _head = (_head - 1 + Length) % Length; + } } } diff --git a/Aplib.Core/Collections/ExposedQueue.cs b/Aplib.Core/Collections/ExposedQueue.cs index 3b77f3a0..6f5818f8 100644 --- a/Aplib.Core/Collections/ExposedQueue.cs +++ b/Aplib.Core/Collections/ExposedQueue.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using System.Collections; using System.Collections.Generic; @@ -15,11 +19,6 @@ namespace Aplib.Core.Collections /// public class ExposedQueue : ICollection { - /// - /// The length of the array. - /// - public int MaxCount { get; private set; } - /// /// Actual number of elements in the array. /// @@ -28,9 +27,36 @@ public class ExposedQueue : ICollection /// public bool IsReadOnly => false; + /// + /// The length of the array. + /// + public int MaxCount { get; private set; } + private readonly T[] _array; private int _head; + /// + /// Gets the element at the specified index. Throws an exception if the index is out of bounds. + /// + /// The index of the element to get. + /// The element at the specified index. + /// + /// Thrown when the index is out of range. + /// + public T this[int index] + { + get + { + if (index < 0 || index >= Count) throw new System.ArgumentOutOfRangeException(nameof(index)); + return _array[(index + _head + 1) % MaxCount]; + } + private set + { + if (index < 0 || index >= Count) throw new System.ArgumentOutOfRangeException(nameof(index)); + _array[(index + _head + 1) % MaxCount] = value; + } + } + /// /// Initializes a new empty instance of the class. /// @@ -74,53 +100,25 @@ public ExposedQueue(T[] array) { } - /// - /// Gets the element at the specified index. Throws an exception if the index is out of bounds. - /// - /// The index of the element to get. - /// The element at the specified index. - /// - /// Thrown when the index is out of range. - /// - public T this[int index] - { - get - { - if (index < 0 || index >= Count) throw new System.ArgumentOutOfRangeException(nameof(index)); - return _array[(index + _head + 1) % MaxCount]; - } - private set - { - if (index < 0 || index >= Count) throw new System.ArgumentOutOfRangeException(nameof(index)); - _array[(index + _head + 1) % MaxCount] = value; - } - } + /// + public void Add(T item) => Put(item); - /// - /// Puts an element at the start of the queue. - /// - /// The element to add to the queue. - public void Put(T value) + /// + public void Clear() { - _array[_head] = value; - DecrementHead(); - if (Count < MaxCount) Count++; + for (int i = 0; i < MaxCount; i++) _array[i] = default!; + _head = MaxCount - 1; + Count = 0; } /// - public void Add(T item) => Put(item); - - /// - /// Gets the element at the end of the queue. - /// - /// The element at the end of the queue. - public T GetLast() => _array[_head]; - - /// - /// Gets the first element of the queue. - /// - /// The first element of the queue. - public T GetFirst() => this[0]; + public bool Contains(T item) + { + for (int i = 0; i < Count; i++) + if (this[i]!.Equals(item)) + return true; + return false; + } /// /// Copies the ExposedQueue to an array. @@ -144,47 +142,33 @@ public void CopyTo(T[] array, int arrayIndex, int endIndex) /// public void CopyTo(T[] array, int arrayIndex) => CopyTo(array, arrayIndex, arrayIndex + Count - 1); - /// - /// Converts the ExposedQueue to an array. - /// - /// The start index of the range to convert. - /// The end index of the range to convert. - /// An array containing the elements within the specified range. - public T[] ToArray(int start, int end) + /// + public IEnumerator GetEnumerator() { - if (start < 0 || start >= Count) - throw new System.ArgumentOutOfRangeException(nameof(start), - "Start index must be within the bounds of the array." - ); - if (end < 0 || end >= Count) - throw new System.ArgumentOutOfRangeException - (nameof(end), "End index must be within the bounds of the array."); - T[] result = new T[end - start + 1]; - CopyTo(result, start, end); - return result; + for (int i = 0; i < Count; i++) yield return this[i]; } /// - /// Converts the ExposedQueue to an array. Only returns the used slots. + /// Gets the first element of the queue. /// - /// An array containing the elements within the specified range. - public T[] ToArray() => ToArray(0, Count - 1); + /// The first element of the queue. + public T GetFirst() => this[0]; - /// - public void Clear() - { - for (int i = 0; i < MaxCount; i++) _array[i] = default!; - _head = MaxCount - 1; - Count = 0; - } + /// + /// Gets the element at the end of the queue. + /// + /// The element at the end of the queue. + public T GetLast() => _array[_head]; - /// - public bool Contains(T item) + /// + /// Puts an element at the start of the queue. + /// + /// The element to add to the queue. + public void Put(T value) { - for (int i = 0; i < Count; i++) - if (this[i]!.Equals(item)) - return true; - return false; + _array[_head] = value; + DecrementHead(); + if (Count < MaxCount) Count++; } /// @@ -210,19 +194,39 @@ public bool Remove(T item) return false; } - /// - public IEnumerator GetEnumerator() + /// + /// Converts the ExposedQueue to an array. + /// + /// The start index of the range to convert. + /// The end index of the range to convert. + /// An array containing the elements within the specified range. + public T[] ToArray(int start, int end) { - for (int i = 0; i < Count; i++) yield return this[i]; + if (start < 0 || start >= Count) + throw new System.ArgumentOutOfRangeException(nameof(start), + "Start index must be within the bounds of the array." + ); + if (end < 0 || end >= Count) + throw new System.ArgumentOutOfRangeException + (nameof(end), "End index must be within the bounds of the array."); + T[] result = new T[end - start + 1]; + CopyTo(result, start, end); + return result; } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + /// + /// Converts the ExposedQueue to an array. Only returns the used slots. + /// + /// An array containing the elements within the specified range. + public T[] ToArray() => ToArray(0, Count - 1); /// /// Decrements the head of the array. /// private void DecrementHead() => _head = (_head - 1 + MaxCount) % MaxCount; + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + /// /// Removes the element at the specified index. /// Shifts all other elements to the left. diff --git a/Aplib.Core/Collections/OptimizedActivationStack.cs b/Aplib.Core/Collections/OptimizedActivationStack.cs index f2e6072c..12d740ca 100644 --- a/Aplib.Core/Collections/OptimizedActivationStack.cs +++ b/Aplib.Core/Collections/OptimizedActivationStack.cs @@ -1,4 +1,8 @@ -using System.Collections.Generic; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using System.Collections.Generic; using System.Linq; namespace Aplib.Core.Collections @@ -17,9 +21,111 @@ namespace Aplib.Core.Collections public class OptimizedActivationStack { /// - /// The top item on the stack. + /// Represents (i.e., encapsulates) an item on the activation stack. /// - private StackItem? _top; + /// + /// This class is public, because the whole stack item should be accessible from the outside to + /// provide O(1) activation of a stack item with . + /// + public sealed class StackItem + { + /// + /// Gets the activation stack instance that this stack item belongs to. + /// + public OptimizedActivationStack ActivationStack { get; } + + /// + /// Gets the data that this stack item represents. + /// + public T Data { get; } + + /// + /// Gets or sets a value indicating whether the item is currently on the stack. + /// + public bool IsActive { get; set; } = false; + + /// + /// Gets or sets the next (above) item on the stack. + /// + public StackItem? Next { get; set; } + + /// + /// Gets or sets the previous (below) item on the stack. + /// + public StackItem? Previous { get; set; } + + /// + /// Creates a stack item for the class. + /// + /// The data to put on the stack. + /// The activation stack instance that this stack item belongs to. + public StackItem(T data, OptimizedActivationStack activationStack) + { + Data = data; + ActivationStack = activationStack; + } + + /// + /// Pushes an item that is not on the stack yet after another item that is already on the stack. + /// + /// An item that is already on the stack. + /// + /// Thrown when an item is pushed after an item that is not on the same stack, + /// when an item is already on the stack, + /// or when an item is pushed after an item that is not on the stack. + /// + public void PushOnStackAfter(StackItem item) + { + if (ActivationStack != item.ActivationStack) + throw new System.ArgumentException( + "Cannot push an item after an item that is not an activatable of the same stack." + ); + if (IsActive) throw new System.ArgumentException("Cannot push an item that is already on the stack."); + if (!item.IsActive) + throw new System.ArgumentException("Cannot push an item after an item that is not on the stack."); + + SetNext(item.Next); + SetPrevious(item); + + IsActive = true; + } + + /// + /// Safely remove the item from the stack. + /// + public void RemoveFromStack() + { + Previous?.SetNext(Next); + Next?.SetPrevious(Previous); + + Previous = null; + Next = null; + + IsActive = false; + } + + /// + /// Links this item before another item. + /// + /// The item that should be on top. + private void SetNext(StackItem? item) + { + Next = item; + + if (item is not null) item.Previous = this; + } + + /// + /// Links this item after another item. + /// + /// The item that should be below. + private void SetPrevious(StackItem? item) + { + Previous = item; + + if (item is not null) item.Next = this; + } + } /// /// Gets the activatable stack items. @@ -30,8 +136,6 @@ public class OptimizedActivationStack /// public IEnumerable ActivatableStackItems { get; } - private int _count = 0; - /// /// Gets the number of items that are currently activated (i.e., on the stack). /// @@ -49,6 +153,13 @@ private set } } + private int _count = 0; + + /// + /// The top item on the stack. + /// + private StackItem? _top; + /// /// Initializes an optimized activation stack with a set of activatable data. /// @@ -128,112 +239,5 @@ public T Pop() return _oldTop.Data; } - - /// - /// Represents (i.e., encapsulates) an item on the activation stack. - /// - /// - /// This class is public, because the whole stack item should be accessible from the outside to - /// provide O(1) activation of a stack item with . - /// - public sealed class StackItem - { - /// - /// Gets the data that this stack item represents. - /// - public T Data { get; } - - /// - /// Gets the activation stack instance that this stack item belongs to. - /// - public OptimizedActivationStack ActivationStack { get; } - - /// - /// Gets or sets the previous (below) item on the stack. - /// - public StackItem? Previous { get; set; } - - /// - /// Gets or sets the next (above) item on the stack. - /// - public StackItem? Next { get; set; } - - /// - /// Gets or sets a value indicating whether the item is currently on the stack. - /// - public bool IsActive { get; set; } = false; - - /// - /// Creates a stack item for the class. - /// - /// The data to put on the stack. - /// The activation stack instance that this stack item belongs to. - public StackItem(T data, OptimizedActivationStack activationStack) - { - Data = data; - ActivationStack = activationStack; - } - - /// - /// Links this item before another item. - /// - /// The item that should be on top. - private void SetNext(StackItem? item) - { - Next = item; - - if (item is not null) item.Previous = this; - } - - /// - /// Links this item after another item. - /// - /// The item that should be below. - private void SetPrevious(StackItem? item) - { - Previous = item; - - if (item is not null) item.Next = this; - } - - /// - /// Pushes an item that is not on the stack yet after another item that is already on the stack. - /// - /// An item that is already on the stack. - /// - /// Thrown when an item is pushed after an item that is not on the same stack, - /// when an item is already on the stack, - /// or when an item is pushed after an item that is not on the stack. - /// - public void PushOnStackAfter(StackItem item) - { - if (ActivationStack != item.ActivationStack) - throw new System.ArgumentException( - "Cannot push an item after an item that is not an activatable of the same stack." - ); - if (IsActive) throw new System.ArgumentException("Cannot push an item that is already on the stack."); - if (!item.IsActive) - throw new System.ArgumentException("Cannot push an item after an item that is not on the stack."); - - SetNext(item.Next); - SetPrevious(item); - - IsActive = true; - } - - /// - /// Safely remove the item from the stack. - /// - public void RemoveFromStack() - { - Previous?.SetNext(Next); - Next?.SetPrevious(Previous); - - Previous = null; - Next = null; - - IsActive = false; - } - } } } diff --git a/Aplib.Core/Combinators.cs b/Aplib.Core/Combinators.cs index 303f7ada..b8362371 100644 --- a/Aplib.Core/Combinators.cs +++ b/Aplib.Core/Combinators.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Desire.GoalStructures; @@ -11,8 +15,6 @@ namespace Aplib.Core /// public static class Combinators { - #region GoalStructure combinators - /// public static FirstOfGoalStructure FirstOf (IMetadata metadata, params IGoalStructure[] children) @@ -24,66 +26,6 @@ public static FirstOfGoalStructure FirstOf(params IGoalS where TBeliefSet : IBeliefSet => new(children); - /// - public static PrimitiveGoalStructure Primitive - (IMetadata metadata, IGoal goal) - where TBeliefSet : IBeliefSet => - new(metadata, goal); - - /// - public static PrimitiveGoalStructure Primitive(IGoal goal) - where TBeliefSet : IBeliefSet => - new(goal); - - /// - public static RepeatGoalStructure Repeat - (IMetadata metadata, IGoalStructure goalStructure) - where TBeliefSet : IBeliefSet => - new(metadata, goalStructure); - - /// - public static RepeatGoalStructure Repeat(IGoalStructure goalStructure) - where TBeliefSet : IBeliefSet => - new(goalStructure); - - /// - public static SequentialGoalStructure Seq - (IMetadata metadata, params IGoalStructure[] children) - where TBeliefSet : IBeliefSet => - new(metadata, children); - - /// - public static SequentialGoalStructure Seq(params IGoalStructure[] children) - where TBeliefSet : IBeliefSet => - new(children); - - #endregion - - #region Tactic combinators - - /// - public static RandomTactic Random - (IMetadata metadata, System.Predicate guard, params ITactic[] subtactics) - where TBeliefSet : IBeliefSet => - new(metadata, guard, subtactics); - - /// - public static RandomTactic Random - (System.Predicate guard, params ITactic[] subtactics) - where TBeliefSet : IBeliefSet => - new(guard, subtactics); - - /// - public static RandomTactic Random - (IMetadata metadata, params ITactic[] subtactics) - where TBeliefSet : IBeliefSet => - new(metadata, subtactics); - - /// - public static RandomTactic Random(params ITactic[] subtactics) - where TBeliefSet : IBeliefSet => - new(subtactics); - /// public static FirstOfTactic FirstOf @@ -108,6 +50,17 @@ public static FirstOfTactic FirstOf(params ITactic new(subtactics); + /// + public static PrimitiveGoalStructure Primitive + (IMetadata metadata, IGoal goal) + where TBeliefSet : IBeliefSet => + new(metadata, goal); + + /// + public static PrimitiveGoalStructure Primitive(IGoal goal) + where TBeliefSet : IBeliefSet => + new(goal); + /// public static PrimitiveTactic Primitive (IMetadata metadata, IAction action, System.Predicate guard) @@ -154,6 +107,49 @@ public static PrimitiveTactic Primitive(IQueryable new(queryAction); - #endregion + /// + public static RandomTactic Random + (IMetadata metadata, System.Predicate guard, params ITactic[] subtactics) + where TBeliefSet : IBeliefSet => + new(metadata, guard, subtactics); + + /// + public static RandomTactic Random + (System.Predicate guard, params ITactic[] subtactics) + where TBeliefSet : IBeliefSet => + new(guard, subtactics); + + /// + public static RandomTactic Random + (IMetadata metadata, params ITactic[] subtactics) + where TBeliefSet : IBeliefSet => + new(metadata, subtactics); + + /// + public static RandomTactic Random(params ITactic[] subtactics) + where TBeliefSet : IBeliefSet => + new(subtactics); + + /// + public static RepeatGoalStructure Repeat + (IMetadata metadata, IGoalStructure goalStructure) + where TBeliefSet : IBeliefSet => + new(metadata, goalStructure); + + /// + public static RepeatGoalStructure Repeat(IGoalStructure goalStructure) + where TBeliefSet : IBeliefSet => + new(goalStructure); + + /// + public static SequentialGoalStructure Seq + (IMetadata metadata, params IGoalStructure[] children) + where TBeliefSet : IBeliefSet => + new(metadata, children); + + /// + public static SequentialGoalStructure Seq(params IGoalStructure[] children) + where TBeliefSet : IBeliefSet => + new(children); } } diff --git a/Aplib.Core/CompletionStatus.cs b/Aplib.Core/CompletionStatus.cs index 4cdcd1d1..163a1d78 100644 --- a/Aplib.Core/CompletionStatus.cs +++ b/Aplib.Core/CompletionStatus.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core { /// /// Represents the state of a completable object. diff --git a/Aplib.Core/Desire/DesireSets/DesireSet.cs b/Aplib.Core/Desire/DesireSets/DesireSet.cs index 107cc73a..7b137755 100644 --- a/Aplib.Core/Desire/DesireSets/DesireSet.cs +++ b/Aplib.Core/Desire/DesireSets/DesireSet.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Collections; using Aplib.Core.Desire.Goals; using Aplib.Core.Desire.GoalStructures; @@ -16,9 +20,10 @@ public class DesireSet : IDesireSet, ILoggable public IMetadata Metadata { get; } /// - /// Stores the main goal structure of the agent. + /// If there are no goal structures left to be completed, the status of this desire set is set to the main goal status. /// - private readonly IGoalStructure _mainGoal; + public CompletionStatus Status + => _goalStructureStack.Count == 0 ? _mainGoal.Status : CompletionStatus.Unfinished; /// /// Stores the side goal structures of the agent. @@ -30,10 +35,9 @@ private readonly OptimizedActivationStack <(IGoalStructure goalStructure, System.Predicate guard)> _goalStructureStack; /// - /// If there are no goal structures left to be completed, the status of this desire set is set to the main goal status. + /// Stores the main goal structure of the agent. /// - public CompletionStatus Status - => _goalStructureStack.Count == 0 ? _mainGoal.Status : CompletionStatus.Unfinished; + private readonly IGoalStructure _mainGoal; /// /// Initializes a new instance of the class. @@ -65,18 +69,19 @@ public DesireSet( { } /// - /// Pushes side goal structures on the stack if their guard is fulfilled. + /// Implicitly lifts a goal into a desire set. /// - /// The belief set to check the guards of the goal structures with. - private void ActivateRelevantGoalStructures(TBeliefSet beliefSet) - { - // Filter all the goal structures by their guards. - var itemsToActivate = _goalStructureStack.ActivatableStackItems - .Where(item => item.Data.guard(beliefSet)); + /// + /// The most logically matching desire set, wrapping around . + public static implicit operator DesireSet(Goal goal) => goal.Lift().Lift(); - // (Re)activate the filtered goal structures. - foreach (var item in itemsToActivate) _goalStructureStack.Activate(item); - } + /// + /// Implicitly lifts a goal structure a desire set. + /// + /// + /// The most logically matching desire set, wrapping around . + public static implicit operator DesireSet(GoalStructure goalStructure) => + goalStructure.Lift(); /// public IGoal GetCurrentGoal(TBeliefSet beliefSet) @@ -86,6 +91,10 @@ public IGoal GetCurrentGoal(TBeliefSet beliefSet) return currentGoalStructure.GetCurrentGoal(beliefSet); } + /// + public IEnumerable GetLogChildren() => + _mainGoal is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); + /// /// Activates side goal structures when their guard is satisfied, and updates the activation stack /// by popping goal structures from the top of the stack when they are finished. @@ -111,23 +120,18 @@ public void Update(TBeliefSet beliefSet) } } - /// - public IEnumerable GetLogChildren() => - _mainGoal is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); - /// - /// Implicitly lifts a goal into a desire set. + /// Pushes side goal structures on the stack if their guard is fulfilled. /// - /// - /// The most logically matching desire set, wrapping around . - public static implicit operator DesireSet(Goal goal) => goal.Lift().Lift(); + /// The belief set to check the guards of the goal structures with. + private void ActivateRelevantGoalStructures(TBeliefSet beliefSet) + { + // Filter all the goal structures by their guards. + var itemsToActivate = _goalStructureStack.ActivatableStackItems + .Where(item => item.Data.guard(beliefSet)); - /// - /// Implicitly lifts a goal structure a desire set. - /// - /// - /// The most logically matching desire set, wrapping around . - public static implicit operator DesireSet(GoalStructure goalStructure) => - goalStructure.Lift(); + // (Re)activate the filtered goal structures. + foreach (var item in itemsToActivate) _goalStructureStack.Activate(item); + } } } diff --git a/Aplib.Core/Desire/DesireSets/IDesireSet.cs b/Aplib.Core/Desire/DesireSets/IDesireSet.cs index ef54277e..db816a39 100644 --- a/Aplib.Core/Desire/DesireSets/IDesireSet.cs +++ b/Aplib.Core/Desire/DesireSets/IDesireSet.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; namespace Aplib.Core.Desire.DesireSets diff --git a/Aplib.Core/Desire/GoalStructures/FirstOfGoalStructure.cs b/Aplib.Core/Desire/GoalStructures/FirstOfGoalStructure.cs index da17120a..e3ab50fa 100644 --- a/Aplib.Core/Desire/GoalStructures/FirstOfGoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/FirstOfGoalStructure.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Logging; @@ -40,6 +44,18 @@ public FirstOfGoalStructure(params IGoalStructure[] children) : this public override IGoal GetCurrentGoal(TBeliefSet beliefSet) => _currentGoalStructure!.GetCurrentGoal(beliefSet); + /// + public override IEnumerable GetLogChildren() => _children.OfType(); + + /// + public override void Reset() + { + base.Reset(); + + _childrenEnumerator.Reset(); + _childrenEnumerator.MoveNext(); + } + /// /// Updates the status of the . /// The goal structure status is set to: @@ -75,15 +91,6 @@ public override void UpdateStatus(TBeliefSet beliefSet) Status = _currentGoalStructure.Status; } - /// - public override void Reset() - { - base.Reset(); - - _childrenEnumerator.Reset(); - _childrenEnumerator.MoveNext(); - } - /// public void Dispose() { @@ -96,8 +103,5 @@ public void Dispose() /// /// Whether we are actually disposing. protected virtual void Dispose(bool disposing) => _childrenEnumerator.Dispose(); - - /// - public override IEnumerable GetLogChildren() => _children.OfType(); } } diff --git a/Aplib.Core/Desire/GoalStructures/GoalStructure.cs b/Aplib.Core/Desire/GoalStructures/GoalStructure.cs index aafec8fe..b05ac2ce 100644 --- a/Aplib.Core/Desire/GoalStructures/GoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/GoalStructure.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Logging; @@ -14,14 +18,14 @@ public abstract class GoalStructure : IGoalStructure, IL /// public IMetadata Metadata { get; } + /// + public CompletionStatus Status { get; protected set; } = CompletionStatus.Unfinished; + /// /// The children of the goal structure. /// protected readonly IEnumerable> _children; - /// - public CompletionStatus Status { get; protected set; } = CompletionStatus.Unfinished; - /// /// The goal structure that is currently being fulfilled. /// @@ -44,17 +48,11 @@ protected GoalStructure(IMetadata metadata, IEnumerable> children) : this(new Metadata(), children) { } /// - /// Gets the current goal using the given . - /// - /// The belief set of the agent. - /// The current goal to be fulfilled. - public abstract IGoal GetCurrentGoal(TBeliefSet beliefSet); - - /// - /// Updates the state of the goal structure. + /// Implicitly lifts a goal into a goal structure. /// - /// The belief set of the agent. - public abstract void UpdateStatus(TBeliefSet beliefSet); + /// + /// The most logically matching goal structure, wrapping around . + public static implicit operator GoalStructure(Goal goal) => goal.Lift(); /// public virtual void Reset() @@ -64,14 +62,20 @@ public virtual void Reset() Status = CompletionStatus.Unfinished; } + /// + /// Gets the current goal using the given . + /// + /// The belief set of the agent. + /// The current goal to be fulfilled. + public abstract IGoal GetCurrentGoal(TBeliefSet beliefSet); + /// public abstract IEnumerable GetLogChildren(); /// - /// Implicitly lifts a goal into a goal structure. + /// Updates the state of the goal structure. /// - /// - /// The most logically matching goal structure, wrapping around . - public static implicit operator GoalStructure(Goal goal) => goal.Lift(); + /// The belief set of the agent. + public abstract void UpdateStatus(TBeliefSet beliefSet); } } diff --git a/Aplib.Core/Desire/GoalStructures/IGoalStructure.cs b/Aplib.Core/Desire/GoalStructures/IGoalStructure.cs index 34bf61fb..4c5b7038 100644 --- a/Aplib.Core/Desire/GoalStructures/IGoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/IGoalStructure.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; namespace Aplib.Core.Desire.GoalStructures @@ -21,14 +25,14 @@ public interface IGoalStructure : ICompletable IGoal GetCurrentGoal(TBeliefSet beliefSet); /// - /// Updates the state of the goal structure. + /// Resets the goal structure to its initial state. /// - /// The belief set of the agent. - void UpdateStatus(TBeliefSet beliefSet); + void Reset(); /// - /// Resets the goal structure to its initial state. + /// Updates the state of the goal structure. /// - void Reset(); + /// The belief set of the agent. + void UpdateStatus(TBeliefSet beliefSet); } } diff --git a/Aplib.Core/Desire/GoalStructures/PrimitiveGoalStructure.cs b/Aplib.Core/Desire/GoalStructures/PrimitiveGoalStructure.cs index 2facd4a8..940b1506 100644 --- a/Aplib.Core/Desire/GoalStructures/PrimitiveGoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/PrimitiveGoalStructure.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Logging; @@ -36,6 +40,10 @@ public PrimitiveGoalStructure(IGoal goal) : this(new Metadata(), goa /// public override IGoal GetCurrentGoal(TBeliefSet beliefSet) => _goal; + /// + public override IEnumerable GetLogChildren() => + _goal is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); + /// /// Updates the status of the . /// The goal structure status is set to the status of the underlying . @@ -46,9 +54,5 @@ public override void UpdateStatus(TBeliefSet beliefSet) _goal.UpdateStatus(beliefSet); Status = _goal.Status; } - - /// - public override IEnumerable GetLogChildren() => - _goal is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); } } diff --git a/Aplib.Core/Desire/GoalStructures/RepeatGoalStructure.cs b/Aplib.Core/Desire/GoalStructures/RepeatGoalStructure.cs index cc20cf92..34ab6821 100644 --- a/Aplib.Core/Desire/GoalStructures/RepeatGoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/RepeatGoalStructure.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Logging; @@ -81,6 +85,10 @@ protected RepeatGoalStructure(IMetadata metadata, IGoalStructure goa public override IGoal GetCurrentGoal(TBeliefSet beliefSet) => _currentGoalStructure!.GetCurrentGoal(beliefSet); + /// + public override IEnumerable GetLogChildren() => + _currentGoalStructure is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); + /// /// Updates the status of the . /// The goal structure status is set to: @@ -120,9 +128,5 @@ public override void UpdateStatus(TBeliefSet beliefSet) Status = _currentGoalStructure.Status; } - - /// - public override IEnumerable GetLogChildren() => - _currentGoalStructure is ILoggable loggable ? new[] { loggable } : Enumerable.Empty(); } } diff --git a/Aplib.Core/Desire/GoalStructures/SequentialGoalStructure.cs b/Aplib.Core/Desire/GoalStructures/SequentialGoalStructure.cs index 07681914..18caa922 100644 --- a/Aplib.Core/Desire/GoalStructures/SequentialGoalStructure.cs +++ b/Aplib.Core/Desire/GoalStructures/SequentialGoalStructure.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.Goals; using Aplib.Core.Logging; @@ -49,6 +53,18 @@ public SequentialGoalStructure(params IGoalStructure[] children) : t public override IGoal GetCurrentGoal(TBeliefSet beliefSet) => _currentGoalStructure!.GetCurrentGoal(beliefSet); + /// + public override IEnumerable GetLogChildren() => _children.OfType(); + + /// + public override void Reset() + { + base.Reset(); + + _childrenEnumerator.Reset(); + _childrenEnumerator.MoveNext(); + } + /// /// Updates the status of the . /// The goal structure status is set to: @@ -84,15 +100,6 @@ public override void UpdateStatus(TBeliefSet beliefSet) Status = _currentGoalStructure.Status; } - /// - public override void Reset() - { - base.Reset(); - - _childrenEnumerator.Reset(); - _childrenEnumerator.MoveNext(); - } - /// public void Dispose() { @@ -105,8 +112,5 @@ public void Dispose() /// /// Whether the object is being disposed. protected virtual void Dispose(bool disposing) => _childrenEnumerator.Dispose(); - - /// - public override IEnumerable GetLogChildren() => _children.OfType(); } } diff --git a/Aplib.Core/Desire/Goals/Goal.cs b/Aplib.Core/Desire/Goals/Goal.cs index b145d1a9..e013d670 100644 --- a/Aplib.Core/Desire/Goals/Goal.cs +++ b/Aplib.Core/Desire/Goals/Goal.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.GoalStructures; using Aplib.Core.Intent.Tactics; @@ -18,20 +22,15 @@ namespace Aplib.Core.Desire.Goals public class Goal : IGoal, ILoggable where TBeliefSet : IBeliefSet { - /// - /// A predicate that determines whether the goal has succeeded. - /// Intuitively, the predicate is the goal itself. - /// - protected internal readonly System.Predicate _predicate; + /// + public IMetadata Metadata { get; } /// - /// An (optional) fail-guard for the goal's completion status. - /// The fail-guard predicate is a condition that, when true, indicates that the goal has failed. + /// Gets the completion status of the goal. + /// This value may need to be updated first using the method. /// - protected internal readonly System.Predicate _failGuard; - - /// - public IMetadata Metadata { get; } + /// + public CompletionStatus Status { get; protected set; } /// /// The used to achieve this . @@ -40,11 +39,16 @@ public class Goal : IGoal, ILoggable public ITactic Tactic { get; } /// - /// Gets the completion status of the goal. - /// This value may need to be updated first using the method. + /// An (optional) fail-guard for the goal's completion status. + /// The fail-guard predicate is a condition that, when true, indicates that the goal has failed. /// - /// - public CompletionStatus Status { get; protected set; } + protected internal readonly System.Predicate _failGuard; + + /// + /// A predicate that determines whether the goal has succeeded. + /// Intuitively, the predicate is the goal itself. + /// + protected internal readonly System.Predicate _predicate; /// /// Initializes a new goal from a given tactic and a success predicate, and an optional fail-guard. diff --git a/Aplib.Core/Desire/Goals/IGoal.cs b/Aplib.Core/Desire/Goals/IGoal.cs index e0ffcc79..1948d27f 100644 --- a/Aplib.Core/Desire/Goals/IGoal.cs +++ b/Aplib.Core/Desire/Goals/IGoal.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Tactics; namespace Aplib.Core.Desire.Goals diff --git a/Aplib.Core/ICompletable.cs b/Aplib.Core/ICompletable.cs index a9cac4d7..ad0ad239 100644 --- a/Aplib.Core/ICompletable.cs +++ b/Aplib.Core/ICompletable.cs @@ -1,4 +1,8 @@ -namespace Aplib.Core +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core { /// /// Defines an object that can be completed. diff --git a/Aplib.Core/IDocumented.cs b/Aplib.Core/IDocumented.cs index 788c8f7f..f749f9cd 100644 --- a/Aplib.Core/IDocumented.cs +++ b/Aplib.Core/IDocumented.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + namespace Aplib.Core { /// diff --git a/Aplib.Core/IMetadata.cs b/Aplib.Core/IMetadata.cs index ebf4bbbf..978e161a 100644 --- a/Aplib.Core/IMetadata.cs +++ b/Aplib.Core/IMetadata.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + namespace Aplib.Core { /// @@ -7,6 +11,11 @@ namespace Aplib.Core /// public interface IMetadata { + /// + /// Gets the description used to describe the instance. + /// + public string? Description { get; } + /// /// Gets the unique identifier of the instance. /// @@ -16,10 +25,5 @@ public interface IMetadata /// Gets the name used to display the instance. /// public string? Name { get; } - - /// - /// Gets the description used to describe the instance. - /// - public string? Description { get; } } } diff --git a/Aplib.Core/Intent/Actions/Action.cs b/Aplib.Core/Intent/Actions/Action.cs index f4d00503..0a8dbb3a 100644 --- a/Aplib.Core/Intent/Actions/Action.cs +++ b/Aplib.Core/Intent/Actions/Action.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Logging; using System.Collections.Generic; @@ -12,14 +16,14 @@ namespace Aplib.Core.Intent.Actions public class Action : IAction, ILoggable where TBeliefSet : IBeliefSet { + /// + public IMetadata Metadata { get; } + /// /// Gets or sets the effect of the action. /// protected readonly System.Action _effect; - /// - public IMetadata Metadata { get; } - /// /// Initializes a new instance of the class. /// = diff --git a/Aplib.Core/Intent/Actions/IAction.cs b/Aplib.Core/Intent/Actions/IAction.cs index ee0aa1d0..320ef408 100644 --- a/Aplib.Core/Intent/Actions/IAction.cs +++ b/Aplib.Core/Intent/Actions/IAction.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; namespace Aplib.Core.Intent.Actions { diff --git a/Aplib.Core/Intent/Actions/IQueryable.cs b/Aplib.Core/Intent/Actions/IQueryable.cs index 775f4df9..db855914 100644 --- a/Aplib.Core/Intent/Actions/IQueryable.cs +++ b/Aplib.Core/Intent/Actions/IQueryable.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; namespace Aplib.Core.Intent.Actions diff --git a/Aplib.Core/Intent/Actions/QueryAction.cs b/Aplib.Core/Intent/Actions/QueryAction.cs index 0dfc0b04..99d0da19 100644 --- a/Aplib.Core/Intent/Actions/QueryAction.cs +++ b/Aplib.Core/Intent/Actions/QueryAction.cs @@ -1,5 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; -using Aplib.Core.Intent.Tactics; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; namespace Aplib.Core.Intent.Actions { diff --git a/Aplib.Core/Intent/Tactics/FirstOfTactic.cs b/Aplib.Core/Intent/Tactics/FirstOfTactic.cs index c6dc30d1..ea974646 100644 --- a/Aplib.Core/Intent/Tactics/FirstOfTactic.cs +++ b/Aplib.Core/Intent/Tactics/FirstOfTactic.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using Aplib.Core.Logging; using System.Collections.Generic; diff --git a/Aplib.Core/Intent/Tactics/ITactic.cs b/Aplib.Core/Intent/Tactics/ITactic.cs index bcae164b..eadf9ece 100644 --- a/Aplib.Core/Intent/Tactics/ITactic.cs +++ b/Aplib.Core/Intent/Tactics/ITactic.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; namespace Aplib.Core.Intent.Tactics diff --git a/Aplib.Core/Intent/Tactics/PrimitiveTactic.cs b/Aplib.Core/Intent/Tactics/PrimitiveTactic.cs index bbfe61fb..ba140202 100644 --- a/Aplib.Core/Intent/Tactics/PrimitiveTactic.cs +++ b/Aplib.Core/Intent/Tactics/PrimitiveTactic.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using Aplib.Core.Logging; using System.Collections.Generic; diff --git a/Aplib.Core/Intent/Tactics/RandomTactic.cs b/Aplib.Core/Intent/Tactics/RandomTactic.cs index 3402c4dd..f56c5c28 100644 --- a/Aplib.Core/Intent/Tactics/RandomTactic.cs +++ b/Aplib.Core/Intent/Tactics/RandomTactic.cs @@ -1,4 +1,8 @@ -using Aplib.Core.Belief.BeliefSets; +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using Aplib.Core.Logging; using System.Collections.Generic; diff --git a/Aplib.Core/Intent/Tactics/Tactic.cs b/Aplib.Core/Intent/Tactics/Tactic.cs index b5064ef1..96f968b2 100644 --- a/Aplib.Core/Intent/Tactics/Tactic.cs +++ b/Aplib.Core/Intent/Tactics/Tactic.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; using Aplib.Core.Logging; @@ -16,14 +20,14 @@ namespace Aplib.Core.Intent.Tactics public abstract class Tactic : ITactic, ILoggable where TBeliefSet : IBeliefSet { + /// + public IMetadata Metadata { get; } + /// /// Gets or sets the guard of the tactic. /// protected readonly System.Predicate _guard; - /// - public IMetadata Metadata { get; } - /// /// Initializes a new instance of the class with a specified guard. /// @@ -46,20 +50,20 @@ protected Tactic(IMetadata metadata) : this(metadata, _ => true) { } /// protected Tactic() : this(new Metadata(), _ => true) { } - /// - public abstract IAction? GetAction(TBeliefSet beliefSet); - - /// - public virtual bool IsActionable(TBeliefSet beliefSet) => _guard(beliefSet); - - /// - public abstract IEnumerable GetLogChildren(); - /// /// Implicitly lifts an action into a tactic. /// /// /// The most logically matching tactic, wrapping around . public static implicit operator Tactic(Action action) => action.Lift(); + + /// + public virtual bool IsActionable(TBeliefSet beliefSet) => _guard(beliefSet); + + /// + public abstract IAction? GetAction(TBeliefSet beliefSet); + + /// + public abstract IEnumerable GetLogChildren(); } } diff --git a/Aplib.Core/LiftingExtensionMethods.cs b/Aplib.Core/LiftingExtensionMethods.cs index 51660635..7b593de2 100644 --- a/Aplib.Core/LiftingExtensionMethods.cs +++ b/Aplib.Core/LiftingExtensionMethods.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Desire.DesireSets; using Aplib.Core.Desire.Goals; diff --git a/Aplib.Core/Logging/ILoggable.cs b/Aplib.Core/Logging/ILoggable.cs index 5828762f..fb1a8c63 100644 --- a/Aplib.Core/Logging/ILoggable.cs +++ b/Aplib.Core/Logging/ILoggable.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using System.Collections.Generic; namespace Aplib.Core.Logging @@ -9,12 +13,6 @@ namespace Aplib.Core.Logging /// public interface ILoggable : IDocumented { - /// - /// Gets the children of the loggable object. - /// - /// The children of the loggable object. - public IEnumerable GetLogChildren(); - /// /// Generates a log tree of the loggable object. /// @@ -29,5 +27,11 @@ public LogNode GetLogTree(int depth = 0) return root; } + + /// + /// Gets the children of the loggable object. + /// + /// The children of the loggable object. + public IEnumerable GetLogChildren(); } } diff --git a/Aplib.Core/Logging/LogNode.cs b/Aplib.Core/Logging/LogNode.cs index 339775fa..1ef805eb 100644 --- a/Aplib.Core/Logging/LogNode.cs +++ b/Aplib.Core/Logging/LogNode.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using System.Collections.Generic; namespace Aplib.Core.Logging @@ -8,9 +12,9 @@ namespace Aplib.Core.Logging public class LogNode { /// - /// The loggable object of the node. + /// The children of the node. /// - public ILoggable Loggable { get; } + public List Children { get; } /// /// The depth at which this node resides. @@ -18,9 +22,9 @@ public class LogNode public int Depth { get; } /// - /// The children of the node. + /// The loggable object of the node. /// - public List Children { get; } + public ILoggable Loggable { get; } /// /// Initialize a new from a given loggable object, diff --git a/Aplib.Core/Metadata.cs b/Aplib.Core/Metadata.cs index 7ccc17de..f8744a2c 100644 --- a/Aplib.Core/Metadata.cs +++ b/Aplib.Core/Metadata.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + namespace Aplib.Core { /// @@ -6,13 +10,13 @@ namespace Aplib.Core public class Metadata : IMetadata { /// - public System.Guid Id { get; } + public string? Description { get; } /// - public string? Name { get; } + public System.Guid Id { get; } /// - public string? Description { get; } + public string? Name { get; } /// /// Store information about a BDI cycle component which may be useful for debugging or logging or general diff --git a/Aplib.Core/ThreadSafeRandom.cs b/Aplib.Core/ThreadSafeRandom.cs index 26518b41..e3aad45c 100644 --- a/Aplib.Core/ThreadSafeRandom.cs +++ b/Aplib.Core/ThreadSafeRandom.cs @@ -1,10 +1,15 @@ -namespace Aplib.Core +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Core { internal static class ThreadSafeRandom { + private static readonly System.Random _global = new(); + [System.ThreadStatic] private static System.Random? _local; - private static readonly System.Random _global = new(); private static System.Random Instance { diff --git a/Aplib.Extensions.Tests/GlobalUsings.cs b/Aplib.Extensions.Tests/GlobalUsings.cs index c802f448..a8a8e6ed 100644 --- a/Aplib.Extensions.Tests/GlobalUsings.cs +++ b/Aplib.Extensions.Tests/GlobalUsings.cs @@ -1 +1,5 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + global using Xunit; diff --git a/Aplib.Extensions.Tests/PathfindingActionTests.cs b/Aplib.Extensions.Tests/PathfindingActionTests.cs index 8bd5382f..3d9d1811 100644 --- a/Aplib.Extensions.Tests/PathfindingActionTests.cs +++ b/Aplib.Extensions.Tests/PathfindingActionTests.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core.Belief.BeliefSets; using Aplib.Extensions.Actions; using Moq; diff --git a/Aplib.Extensions/Actions/PathfinderAction.cs b/Aplib.Extensions/Actions/PathfinderAction.cs index 36f3113e..49ea1425 100644 --- a/Aplib.Extensions/Actions/PathfinderAction.cs +++ b/Aplib.Extensions/Actions/PathfinderAction.cs @@ -1,3 +1,7 @@ +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + using Aplib.Core; using Aplib.Core.Belief.BeliefSets; using Aplib.Core.Intent.Actions; diff --git a/Aplib.Extensions/IPathfinder.cs b/Aplib.Extensions/IPathfinder.cs index b5b7e85f..d78adf23 100644 --- a/Aplib.Extensions/IPathfinder.cs +++ b/Aplib.Extensions/IPathfinder.cs @@ -1,4 +1,8 @@ -namespace Aplib.Extensions +// This program has been developed by students from the bachelor Computer Science at Utrecht +// University within the Software Project course. +// Copyright Utrecht University (Department of Information and Computing Sciences) + +namespace Aplib.Extensions { /// /// Defines a pathfinding algorithm used to find a path from a starting point to an end point.