From 7c44542aeeaf8ca19611b17be94cb1bbbcd3a3d0 Mon Sep 17 00:00:00 2001
From: MaZiFAU <63099053+MaZiFAU@users.noreply.github.com>
Date: Mon, 18 Sep 2023 19:41:30 +0200
Subject: [PATCH] Simplification of TupleAccess/ProjLR

---
 .../FactHandling/Facts/FunctionFact.cs        |  4 +-
 .../TBD/CanonBallCalculator2D.cs              |  2 +-
 .../TBD/CanonBallCalculator3D.cs              |  2 +-
 .../SOMDocToLambdaExpression.cs               | 60 +++++++++++++------
 .../CommunicationProtocoll/SOMDocs.cs         | 14 +++--
 .../Extensions/IEnumerableExtensions.cs       |  4 +-
 Assets/Scripts/Utility/Math3d.cs              |  7 +++
 7 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
index f4415907..6eb37e82 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
@@ -60,7 +60,7 @@ protected override bool EquivalentWrapped(FunctionCallFact f1, FunctionCallFact
 
         if (f1.Function.Signature[^1] != f2.Function.Signature[^1])
             return false;
-
+        return false;
         int samplenumber = 3;
         float stepsizef1 = (f1.Domain.t_n - f1.Domain.t_0) / (samplenumber - 1);
         float stepsizef2 = (f2.Domain.t_n - f2.Domain.t_0) / (samplenumber - 1);
@@ -71,7 +71,7 @@ protected override bool EquivalentWrapped(FunctionCallFact f1, FunctionCallFact
             object[] c1 = f1.Call(f1step);
             object[] c2 = f2.Call(f2step);
             if (c1 == null || c2 == null
-            || !c1.SequenceEqual(c2, new ApproximationComparer()))
+            || !c1.SequenceEqual(c2, new ApproximationComparer(1e-3d)))
                 return false;
         }
         return true;
diff --git a/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator2D.cs b/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator2D.cs
index 2e9c16ac..49349cff 100644
--- a/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator2D.cs
+++ b/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator2D.cs
@@ -179,7 +179,7 @@ float SolveForDistanceOnPlane(Vector3 Pos, Vector3 Vel, LineFact Top, float t)
 
             Result_ArgsFunc_Id.Add(
                 FactOrganizer.Add(
-                    new FunctionFact(BuildOMAPath(pos, vel, last_t), FactOrganizer),
+                    new FunctionFact(BuildOMAPath(pos, vel, last_t - (float)Math3d.vectorPrecission), FactOrganizer),
                     out _, true, null, null));
 
             Result_FuncCall_Id.Add(
diff --git a/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator3D.cs b/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator3D.cs
index ae01fa14..aa16e5ae 100644
--- a/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator3D.cs
+++ b/Assets/Scripts/InteractionEngine/TBD/CanonBallCalculator3D.cs
@@ -254,7 +254,7 @@ bool HitOnPlane(Vector3 Pos, Vector3 Vel, QuadFact Top, float t)
 
             Result_ArgsFunc_Id.Add(
                 FactOrganizer.Add(
-                    new FunctionFact(BuildOMAPath(pos, vel, last_t), FactOrganizer),
+                    new FunctionFact(BuildOMAPath(pos, vel, last_t - (float)Math3d.vectorPrecission), FactOrganizer),
                     out _, true, null, null));
 
             Result_FuncCall_Id.Add(
diff --git a/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocToLambdaExpression.cs b/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocToLambdaExpression.cs
index 47308153..b39aae22 100644
--- a/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocToLambdaExpression.cs
+++ b/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocToLambdaExpression.cs
@@ -6,6 +6,7 @@
 using System.Reflection;
 using UnityEditor;
 using System.Collections.ObjectModel;
+using Unity.Burst.Intrinsics;
 
 namespace REST_JSON_API
 {
@@ -409,28 +410,51 @@ public static LambdaExpression MakeRoot(LambdaExpression[] lambda_applicant, Lam
                     );
 
             public static LambdaExpression ProjLVecTupel(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
-                => (
-                    lambda_applicant[0].ReturnType == typeof(Vector3)
-                    ? GetPropertyOrField("x")
-                    : GetPropertyOrField("Item1")
-                    )
-                    (lambda_applicant, lambda_arguments, bound_params);
+            {
+                if (lambda_applicant[0].Body is MethodCallExpression meth
+                 && meth.Method.DeclaringType == typeof(Tuple)
+                 && meth.Method.Name == "Create") // Access Values Directly
+                {
+                    return Expression.Lambda(meth.Arguments.First(), bound_params);
+                }
+
+                return (
+                        lambda_applicant[0].ReturnType == typeof(Vector3)
+                        ? GetPropertyOrField("x")
+                        : GetPropertyOrField("Item1")
+                        )
+                        (lambda_applicant, lambda_arguments, bound_params);
+            }
 
             public static LambdaExpression ProjRVecTupel(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             {
-                LambdaExpression[] Items_applicant =
-                    lambda_applicant[0].ReturnType == typeof(Vector3)
-                    ? new string[] { "y", "z" }
-                        .Select(prop => GetPropertyOrField(prop)(lambda_applicant, lambda_arguments, bound_params))
-                        .ToArray()
-                    : lambda_applicant[0].ReturnType.GetProperties()
-                        .OrderBy(fi => fi.Name)
-                        .Skip(1) // Item1
-                        .Select(fi =>
-                            Expression.Lambda(
-                                Expression.Property(lambda_applicant[0].Body, fi),
-                                bound_params))
+                LambdaExpression[] Items_applicant;
+
+                if (lambda_applicant[0].Body is MethodCallExpression meth
+                 && meth.Method.DeclaringType == typeof(Tuple)
+                 && meth.Method.Name == "Create") // Access Values Directly
+                {
+                    Items_applicant = meth.Arguments
+                        .Skip(1)
+                        .Select(arg => Expression.Lambda(arg, bound_params))
                         .ToArray();
+                }
+                else
+                {
+                    Items_applicant =
+                        lambda_applicant[0].ReturnType == typeof(Vector3)
+                        ? new string[] { "y", "z" }
+                            .Select(prop => GetPropertyOrField(prop)(lambda_applicant, lambda_arguments, bound_params))
+                            .ToArray()
+                        : lambda_applicant[0].ReturnType.GetProperties()
+                            .OrderBy(fi => fi.Name)
+                            .Skip(1) // Item1
+                            .Select(fi =>
+                                Expression.Lambda(
+                                    Expression.Property(lambda_applicant[0].Body, fi),
+                                    bound_params))
+                            .ToArray();
+                }
 
                 return Items_applicant.Length == 1
                     ? Items_applicant[0]
diff --git a/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocs.cs b/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocs.cs
index 8f70b595..59b6c254 100644
--- a/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocs.cs
+++ b/Assets/Scripts/MMTServer/CommunicationProtocoll/SOMDocs.cs
@@ -12,6 +12,12 @@ namespace REST_JSON_API
     public class ApproximationComparer : EqualityComparer<object>
     {
         public static readonly ApproximationComparer Instance = new();
+        private double precission;
+
+        public ApproximationComparer(double precission = Math3d.vectorPrecission)
+        {
+            this.precission = precission;
+        }
 
         public override bool Equals(object x, object y)
         {
@@ -21,9 +27,9 @@ public override bool Equals(object x, object y)
                 return false;
 
             if (x is float fx)
-                return Mathf.Approximately(fx, (float)y);
+                return Math3d.Approximately(fx, (float)y, (float)precission);
             if (x is Vector3 vx)
-                return Math3d.IsApproximatelyEqual(vx, (Vector3)y);
+                return Math3d.IsApproximatelyEqual(vx, (Vector3)y, precission);
 
             return false;
         }
@@ -98,7 +104,7 @@ public static SOMDoc SOMDocType(Type type)
 
             if (type.IsAnonymousType())
                 return new OMA(
-                    new OMS(MMTConstants.MakeTypeType), 
+                    new OMS(MMTConstants.MakeTypeType),
                     type.GetFields()
                         .Select(mem => new OML_Member(mem.Name, SOMDocType(mem.FieldType), null))
                         .ToArray());
@@ -564,7 +570,7 @@ protected internal override Type ToType(Type[] args, (string name, Type type)[]
         {
             if (FactRecorder.AllFacts.TryGetValue(uri, out Fact found))
                 return found.GetType();
-            
+
             if (MMTConstants.HeterogenApplication_TO_TypeOF.TryGetValue(uri, out string s_type))
             {
                 Type type = MMTConstants.OMS_TO_TYPE[s_type];
diff --git a/Assets/Scripts/Utility/Extensions/IEnumerableExtensions.cs b/Assets/Scripts/Utility/Extensions/IEnumerableExtensions.cs
index ac9f5a5a..bdaaa52a 100644
--- a/Assets/Scripts/Utility/Extensions/IEnumerableExtensions.cs
+++ b/Assets/Scripts/Utility/Extensions/IEnumerableExtensions.cs
@@ -27,11 +27,11 @@ public static IEnumerable<TAccumulate> FeedForwardUntil<TAccumulate>
         Func<TAccumulate, bool> predicate
     )
     {
-        int i = 0;
+        //int i = 0;
         TAccumulate previous = seed;
         while (!predicate(previous))
         {
-            if (i++ > 100) break;
+            //if (i++ > 100) break;
             yield return previous;
             previous = func(previous);
         }
diff --git a/Assets/Scripts/Utility/Math3d.cs b/Assets/Scripts/Utility/Math3d.cs
index e701a8c2..220fa8ce 100644
--- a/Assets/Scripts/Utility/Math3d.cs
+++ b/Assets/Scripts/Utility/Math3d.cs
@@ -562,6 +562,13 @@ public static bool IsApproximatelyEqual(Vector3 vectorA, Vector3 vectorB, double
         return (vectorA - vectorB).sqrMagnitude < precission;
     }
 
+    //This function returns true if two floats are approximately Equal
+    //seealso: Mathf.Approximately
+    public static bool Approximately(float a, float b, float precission = (float)Math3d.vectorPrecission)
+    {
+        return MathF.Abs(b - a) < MathF.Max(precission * MathF.Max(MathF.Abs(a), MathF.Abs(b)), precission);
+    }
+
     //This function returns a point which is a projection from a point to a line segment.
     //If the projected point lies outside of the line segment, the projected point will 
     //be clamped to the appropriate line edge.
-- 
GitLab