Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add GoalStructure #25

Merged
merged 19 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 35 additions & 37 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true

# XMLDOC settings
xmldoc_indent_size = 0

# C# files
[*.cs]

# XMLDoc settings
resharper_xmldoc_indent_size = 0

#### Core EditorConfig Options ####

# Indentation and spacing
Expand Down Expand Up @@ -107,7 +107,7 @@ csharp_style_conditional_delegate_call = true

# Modifier preferences
csharp_prefer_static_local_function = true
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
csharp_preferred_modifier_order = public, private, protected, internal, file, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, required, volatile, async
csharp_style_prefer_readonly_struct = true
csharp_style_prefer_readonly_struct_member = true

Expand Down Expand Up @@ -195,6 +195,10 @@ csharp_preserve_single_line_statements = true

# Naming rules

dotnet_naming_rule.private_members_with_underscore.severity = warning
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore

dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
Expand All @@ -203,64 +207,58 @@ dotnet_naming_rule.types_should_be_pascal_case.severity = warning
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.classes_should_be_pascal_case.severity = warning
dotnet_naming_rule.classes_should_be_pascal_case.symbols = classes
dotnet_naming_rule.classes_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.private_members_with_underscore.severity = warning
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
dotnet_naming_rule.public_fields_should_be_pascal_case.severity = warning
dotnet_naming_rule.public_fields_should_be_pascal_case.symbols = public_fields
dotnet_naming_rule.public_fields_should_be_pascal_case.style = pascal_case

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum, field
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.classes.applicable_kinds = class, struct, enum
dotnet_naming_symbols.classes.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.classes.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_symbols.non_field_members.required_modifiers =

dotnet_naming_symbols.private_fields.applicable_kinds = field, property
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
dotnet_naming_symbols.public_fields.applicable_kinds = field, property
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal, protected_internal

dotnet_naming_symbols.private_fields.applicable_kinds = field, property
dotnet_naming_symbols.private_fields.applicable_accessibilities = protected, private_protected, private

# Naming styles

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

dotnet_naming_style.prefix_underscore.capitalization = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _

[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf

# Use underscores for private fields
dotnet_naming_symbols.private_fields.applicable_kinds = field
dotnet_naming_symbols.private_fields.applicable_accessibilities = internal, protected_internal, private

dotnet_naming_style.prefix_underscore.capitalization = camel_case
dotnet_naming_style.prefix_underscore.required_prefix = _

dotnet_naming_rule.private_fields_with_underscore.symbols = private_fields
dotnet_naming_rule.private_fields_with_underscore.style = prefix_underscore
dotnet_naming_rule.private_fields_with_underscore.symbols = private_fields
dotnet_naming_rule.private_fields_with_underscore.style = prefix_underscore
dotnet_naming_rule.private_fields_with_underscore.severity = warning
23 changes: 23 additions & 0 deletions Aplib.Core/CompletionStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Aplib.Core
{
/// <summary>
/// Represents the state of a completable object.
/// </summary>
public enum CompletionStatus
{
/// <summary>
/// Represents the status of a completable object that is not yet completed.
/// </summary>
Unfinished,

/// <summary>
/// Represents the status of a completable object that has been successfully completed.
/// </summary>
Success,

/// <summary>
/// Represents the status of a completable object that has failed to complete.
/// </summary>
Failure
}
}
80 changes: 80 additions & 0 deletions Aplib.Core/Desire/FirstOfGoalStructure.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using Aplib.Core.Belief;
using Aplib.Core.Desire.Goals;
using System;
using System.Collections.Generic;

namespace Aplib.Core.Desire
{
/// <summary>
/// Represents a goal structure that will complete if any of its children complete.
/// </summary>
/// <remarks>
/// The children of this goal structure will be executed in the order they are given.
/// </remarks>
/// <typeparam name="TBeliefSet">The beliefset of the agent.</typeparam>
public class FirstOfGoalStructure<TBeliefSet> : GoalStructure<TBeliefSet>, IDisposable
where TBeliefSet : IBeliefSet
{
private IEnumerator<IGoalStructure<TBeliefSet>> _childrenEnumerator { get; }

/// <summary>
/// Initializes a new instance of the <see cref="FirstOfGoalStructure{TBeliefSet}" /> class.
/// </summary>
/// <param name="children">The children of the goal structure.</param>
public FirstOfGoalStructure(IList<IGoalStructure<TBeliefSet>> children) : base(children)
{
_childrenEnumerator = children.GetEnumerator();
_childrenEnumerator.MoveNext();
_currentGoalStructure = _childrenEnumerator.Current;
}

/// <inheritdoc />
public override IGoal GetCurrentGoal(TBeliefSet beliefSet) => _currentGoalStructure!.GetCurrentGoal(beliefSet);

/// <inheritdoc />
public override void UpdateStatus(TBeliefSet beliefSet)
{
// Loop through all the children until one of them is unfinished or successful.
// This loop is here to prevent tail recursion.
while (true)
{
if (Status == CompletionStatus.Success) return;
_currentGoalStructure!.UpdateStatus(beliefSet);

switch (_currentGoalStructure.Status)
{
case CompletionStatus.Unfinished:
return;
case CompletionStatus.Success:
Status = CompletionStatus.Success;
return;
}

if (_childrenEnumerator.MoveNext())
{
_currentGoalStructure = _childrenEnumerator.Current;
Status = CompletionStatus.Unfinished;

// Update the Status of the new goal structure
continue;
}

Status = CompletionStatus.Failure;
return;
}
}

/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// Disposes of the goal structure.
/// </summary>
/// <param name="disposing">Whether we are actually disposing.</param>
protected virtual void Dispose(bool disposing) => _childrenEnumerator.Dispose();
}
}
44 changes: 44 additions & 0 deletions Aplib.Core/Desire/GoalStructure.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Aplib.Core.Belief;
using Aplib.Core.Desire.Goals;
using System.Collections.Generic;

namespace Aplib.Core.Desire
{
/// <summary>
/// Describes a structure of goals that need to be fulfilled.
/// </summary>
public abstract class GoalStructure<TBeliefSet> : IGoalStructure<TBeliefSet> where TBeliefSet : IBeliefSet
{
/// <inheritdoc />
public CompletionStatus Status { get; protected set; }

/// <summary>
/// The children of the goal structure.
/// </summary>
protected readonly IEnumerable<IGoalStructure<TBeliefSet>> _children;

/// <summary>
/// The goal structure that is currently being fulfilled.
/// </summary>
protected IGoalStructure<TBeliefSet>? _currentGoalStructure;

/// <summary>
/// Initializes a new instance of the <see cref="GoalStructure{TBeliefSet}" /> class.
/// </summary>
/// <param name="children">The children of the goal structure.</param>
protected GoalStructure(IEnumerable<IGoalStructure<TBeliefSet>> children) => _children = children;

/// <summary>
/// Gets the current goal using the given <see cref="IBeliefSet" />.
/// </summary>
/// <param name="beliefSet">The belief set of the agent.</param>
/// <returns>The current goal to be fulfilled.</returns>
public abstract IGoal GetCurrentGoal(TBeliefSet beliefSet);

/// <summary>
/// Updates the state of the goal structure.
/// </summary>
/// <param name="beliefSet">The belief set of the agent.</param>
public abstract void UpdateStatus(TBeliefSet beliefSet);
}
}
Loading