| | | 1 | | using System.Diagnostics; |
| | | 2 | | using Intentum.Core.Behavior; |
| | | 3 | | using Intentum.Core.Contracts; |
| | | 4 | | using Intentum.Runtime.Engine; |
| | | 5 | | using Intentum.Runtime.Policy; |
| | | 6 | | |
| | | 7 | | namespace Intentum.Simulation; |
| | | 8 | | |
| | | 9 | | /// <summary> |
| | | 10 | | /// Runs behavior scenarios through intent model and policy using BehaviorSpaceSimulator. |
| | | 11 | | /// </summary> |
| | 5 | 12 | | public sealed class IntentScenarioRunner(IBehaviorSpaceSimulator simulator) : IScenarioRunner |
| | | 13 | | { |
| | 5 | 14 | | private readonly IBehaviorSpaceSimulator _simulator = simulator ?? throw new ArgumentNullException(nameof(simulator) |
| | | 15 | | |
| | | 16 | | /// <inheritdoc /> |
| | | 17 | | public async Task<IReadOnlyList<ScenarioRunResult>> RunAsync( |
| | | 18 | | IReadOnlyList<BehaviorScenario>? scenarios, |
| | | 19 | | IIntentModel model, |
| | | 20 | | IntentPolicy policy, |
| | | 21 | | CancellationToken cancellationToken = default) |
| | 4 | 22 | | { |
| | 4 | 23 | | var results = new List<ScenarioRunResult>(); |
| | 19 | 24 | | foreach (var scenario in scenarios ?? []) |
| | 4 | 25 | | { |
| | 4 | 26 | | cancellationToken.ThrowIfCancellationRequested(); |
| | | 27 | | |
| | 4 | 28 | | var space = BuildSpace(scenario); |
| | 3 | 29 | | var sw = Stopwatch.StartNew(); |
| | 3 | 30 | | var intent = model.Infer(space); |
| | 3 | 31 | | var decision = IntentPolicyEngine.Evaluate(intent, policy); |
| | 3 | 32 | | sw.Stop(); |
| | | 33 | | |
| | 3 | 34 | | results.Add(new ScenarioRunResult( |
| | 3 | 35 | | scenario.Id, |
| | 3 | 36 | | intent, |
| | 3 | 37 | | decision, |
| | 3 | 38 | | sw.Elapsed.TotalMilliseconds)); |
| | 3 | 39 | | } |
| | 3 | 40 | | return await Task.FromResult(results).ConfigureAwait(false); |
| | 3 | 41 | | } |
| | | 42 | | |
| | | 43 | | private BehaviorSpace BuildSpace(BehaviorScenario scenario) |
| | 4 | 44 | | { |
| | 4 | 45 | | if (scenario.Sequence is { Count: > 0 }) |
| | 2 | 46 | | { |
| | 4 | 47 | | var seq = scenario.Sequence.Select(t => (t.Actor, t.Action)).ToList(); |
| | 2 | 48 | | return _simulator.FromSequence(seq); |
| | | 49 | | } |
| | 2 | 50 | | if (scenario is { Actors: { Count: > 0 }, Actions.Count: > 0 }) |
| | 1 | 51 | | return _simulator.GenerateRandom(scenario.Actors, scenario.Actions, scenario.EventCount, scenario.RandomSeed |
| | 1 | 52 | | throw new ArgumentException($"Scenario {scenario.Id}: provide Sequence or (Actors + Actions).", nameof(scenario) |
| | 3 | 53 | | } |
| | | 54 | | } |