diff --git a/Sources/AngouriMath/Core/Exceptions/Interruptions.cs b/Sources/AngouriMath/Core/Exceptions/Interruptions.cs new file mode 100644 index 000000000..e802d37cc --- /dev/null +++ b/Sources/AngouriMath/Core/Exceptions/Interruptions.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace AngouriMath.Core.Exceptions +{ + public sealed class OutOfQuotaInterruption : Exception + { + [ConstantField] internal static OutOfQuotaInterruption Instance = new(); + } +} diff --git a/Sources/AngouriMath/Core/Multithreading/MultithreadingFunctional.cs b/Sources/AngouriMath/Core/Multithreading/MultithreadingFunctional.cs index cd8e742d7..8c2fe7517 100644 --- a/Sources/AngouriMath/Core/Multithreading/MultithreadingFunctional.cs +++ b/Sources/AngouriMath/Core/Multithreading/MultithreadingFunctional.cs @@ -23,6 +23,7 @@ internal static void ExitIfCancelled() var token = globalCancellationToken.Value; if (token is { } tok) tok.ThrowIfCancellationRequested(); + System.Console.WriteLine($"Token check at {System.DateTime.Now.Millisecond}"); } } } diff --git a/Sources/AngouriMath/Core/QuotaGC/QuotaCounter.cs b/Sources/AngouriMath/Core/QuotaGC/QuotaCounter.cs new file mode 100644 index 000000000..279fb9f52 --- /dev/null +++ b/Sources/AngouriMath/Core/QuotaGC/QuotaCounter.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Text; +using AngouriMath.Convenience; +using AngouriMath.Core.Exceptions; + +namespace AngouriMath.Core +{ + public sealed class QuotaLeft + { + private int left; + private int initial; + private bool infinite; + + public static QuotaLeft CreateFinite(int quotaInitial) + => new() { left = quotaInitial, initial = quotaInitial, infinite = false }; + + public static QuotaLeft CreateInfinite() + => new() { left = 0, infinite = true }; + + public void Reset() => left = initial; + + public bool DecreaseAndCheck() + { + if (infinite) + return true; + left--; + if (left is 0) + throw OutOfQuotaInterruption.Instance; + return true; + } + } + + public static class QuotaCounter + { + public static Setting QuotaLeft => quotaLeft ??= new(Core.QuotaLeft.CreateInfinite()); + [ThreadStatic] internal static Setting? quotaLeft; + } +} diff --git a/Sources/Samples/Samples/Playground.csproj b/Sources/Samples/Samples/Playground.csproj index 4f978e055..539fec829 100644 --- a/Sources/Samples/Samples/Playground.csproj +++ b/Sources/Samples/Samples/Playground.csproj @@ -15,4 +15,10 @@ + + + C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Microsoft.Build.Tasks.v4.0.dll + + + diff --git a/Sources/Samples/Samples/Program.cs b/Sources/Samples/Samples/Program.cs index 73ea6e40b..7f7d0ff36 100644 --- a/Sources/Samples/Samples/Program.cs +++ b/Sources/Samples/Samples/Program.cs @@ -1,18 +1,62 @@ using System; -using AngouriMath; -using AngouriMath.Extensions; -using static AngouriMath.MathS; -using static AngouriMath.Entity; -using System.Numerics; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; - -// Entity expr = "alpha_beta"; -// Console.WriteLine(Unsafe.SizeOf()); - - -// Console.WriteLine("[ [ 1, 2 ] ; [ 3, 4 ] ]".ToEntity()); -Matrix m = "[[3 - lambda, -1, 0, -2, 0], [-3, -4 - lambda, -2, 1, 3], [0, -7, 1 - lambda, -5, 2], [3, 4, 1, 1 - lambda, -2], [-6, -19, -5, -3, 10 - lambda]]"; -Console.WriteLine(m.Determinant.Simplify()); -// using var _ = MathS.Settings.MaxExpansionTermCount.Set(50); -// Console.WriteLine("(a + b)100".Expand()); \ No newline at end of file +using AngouriMath.Core; +using AngouriMath.Core.Exceptions; +using System.Collections.Generic; +using System.Linq; + + +Console.WriteLine(Simplify(expr: 0, quota: 40)); + + +static TOut? TryExecuteConstrained(TIn input, int quota, Func alg) +{ + using var _ = QuotaCounter.QuotaLeft.Set(QuotaLeft.CreateFinite(quota)); + try + { + return alg(input); + } + catch (OutOfQuotaInterruption) + { + return default; + } +} + +static void AssignIfCan(ref TIn toWhat, TIn? value) +{ + if (value is { } valid) + toWhat = valid; +} + +static int Simplify(int expr, int quota) +{ + var subQuota = 5; + while (quota > 0) + { + AssignIfCan(ref expr, TryExecuteConstrained(expr, subQuota, SubSim1)); + AssignIfCan(ref expr, TryExecuteConstrained(expr, subQuota, SubSim2)); + quota -= subQuota * 2; + subQuota += 2; + } + return expr; + + static int SubSim1(int curr) + { + for (int i = 0; i < 100; i++) + { + QuotaCounter.QuotaLeft.Value.DecreaseAndCheck(); + curr++; + } + return curr; + } + + static int SubSim2(int curr) + { + for (int i = 0; i < 70; i++) + { + QuotaCounter.QuotaLeft.Value.DecreaseAndCheck(); + curr += 2; + } + return curr; + } +} +