From 85082b1ed70bc3da49e2839ddb5d860c4aab131c Mon Sep 17 00:00:00 2001
From: MaZiFAU <63099053+MaZiFAU@users.noreply.github.com>
Date: Tue, 4 Jul 2023 22:05:49 +0200
Subject: [PATCH] First attempted at ListFact

---
 .../FactHandling/Facts/AbstractAngleFact.cs   |   4 +-
 .../FactHandling/Facts/AbstractLineFact.cs    |   4 +-
 .../FactHandling/Facts/Fact.cs                | 111 +++++--
 .../FactHandling/Facts/FunctionFact.cs        |   6 +-
 .../Scripts/InventoryStuff/ScrollDetails.cs   |   4 +-
 Assets/Scripts/SOMDocManager.cs               | 297 +++++++++++++-----
 6 files changed, 318 insertions(+), 108 deletions(-)

diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs
index ba128199..47915699 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs
@@ -147,7 +147,7 @@ public AngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer)
     public AngleFact(string Pid1, string Pid2, string Pid3, float angle, string backendURI, FactOrganizer organizer) 
         : base(Pid1, Pid2, Pid3, angle, backendURI, organizer) { }
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -239,7 +239,7 @@ public RightAngleFact(string pid1, string pid2, string pid3, FactOrganizer organ
     public RightAngleFact(string Pid1, string Pid2, string Pid3, string backendURI, FactOrganizer organizer)
         : base(Pid1, Pid2, Pid3, 90f, backendURI, organizer) { }
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp =
             new OMA(
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
index 1779f77d..eaf2c9d7 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
@@ -137,7 +137,7 @@ public LineFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1,
         SendToMMT();
     }
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -201,7 +201,7 @@ public RayFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, p
         SendToMMT();
     }
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc type = new OMS(MMT_OMS_URI.LineType);
         SOMDoc defines = 
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
index e6cfd7aa..a52e837f 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
@@ -56,7 +56,7 @@ public static class ParsingDictionary
         { MMT_OMS_URI.EqualityCircles,
             EqualCirclesFact.parseFact },
         { MMT_OMS_URI.UnEqualityCircles,
-            UnEqualCirclesFact.parseFact }
+            UnEqualCirclesFact.parseFact },
     };
 
     // TODO: get rid of this
@@ -214,7 +214,7 @@ protected set
             _Position = value;
         }
     }
-    private Vector3 _Position;
+    private Vector3 _Position = Vector3.zero;
 
     [JsonIgnore]
     public Quaternion Rotation
@@ -231,7 +231,7 @@ protected set
             _Rotation = value;
         }
     }
-    private Quaternion _Rotation;
+    private Quaternion _Rotation = Quaternion.identity;
 
     [JsonIgnore]
     public Vector3 LocalScale
@@ -248,7 +248,7 @@ protected set
             _LocalScale = value;
         }
     }
-    private Vector3 _LocalScale;
+    private Vector3 _LocalScale = Vector3.one;
 
     /// <summary>
     /// Only being used by [JsonReader](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonReader.htm) to initiate empty \ref Fact "Facts".
@@ -323,7 +323,7 @@ public bool rename(string newLabel)
 
     protected abstract void RecalculateTransform();
 
-    protected abstract MMTDeclaration MakeMMTDeclaration();
+    public abstract MMTDeclaration MakeMMTDeclaration();
 
     /// <summary>
     /// Frees ressources e.g. <see cref="Label"/> and will eventually delete %Fact Server-Side in far-near future when feature is supported.
@@ -423,7 +423,7 @@ public void SendToMMT()
             _SendAdd(
                 CommunicationEvents.ServerAdress + "/fact/add",
                 mmtDecl.ToJson()
-                //,(string uri) => _SendURICallback(mmtDecl, uri)
+        //,(string uri) => _SendURICallback(mmtDecl, uri)
         );//);
 
         //return;
@@ -432,8 +432,8 @@ public void SendToMMT()
         //{
         //    _URI = uri;
 
-            if (mmtDecl is MMTSymbolDeclaration mMTSymbol && mMTSymbol.defines != null)
-                ParsingDictionary.parseTermsToId[mMTSymbol.defines.ToString()] = _URI;
+        if (mmtDecl is MMTSymbolDeclaration mMTSymbol && mMTSymbol.defines != null)
+            ParsingDictionary.parseTermsToId[mMTSymbol.defines.ToString()] = _URI;
         //}
 
         /*IEnumerator*/
@@ -611,7 +611,7 @@ protected override bool EquivalentWrapped(PointFact f1, PointFact f2)
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new PointFact(this.Point, this.Normal, organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMS(MMT_OMS_URI.Point);
         SOMDoc df = new OMA(
@@ -733,7 +733,7 @@ protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new OnLineFact(old_to_new[this.Pid], old_to_new[this.Rid], organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMA(
             new OMS(MMT_OMS_URI.Ded),
@@ -828,7 +828,7 @@ public ParallelLineFact(string Lid1, string Lid2, string backendURI, FactOrganiz
     protected override string generateLabel()
         => Ray1.Label + "||" + Ray2.Label;
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMA(
             new OMS(MMT_OMS_URI.Ded),
@@ -1000,7 +1000,7 @@ protected override string generateLabel()
     /// <param name="p2URI"> <see cref="Pid2"/></param>
     /// <param name="radius"> <see cref="radius"/></param>
     /// <returns>struct for <see cref="AddFactResponse"/></returns>
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         List<SOMDoc> outerArguments = new List<SOMDoc>
         {
@@ -1147,7 +1147,7 @@ protected override bool EquivalentWrapped(OnCircleFact c1, OnCircleFact c2)
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new OnCircleFact(old_to_new[this.Pid], old_to_new[this.Cid], organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp =
             new OMA(
@@ -1285,7 +1285,7 @@ public AngleCircleLineFact(string Cid1, string Rid2, float angle, string backend
     protected override string generateLabel()
         => "∠" + Circle.Label + Ray.Label;
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -1393,7 +1393,7 @@ protected override string generateLabel()
     /// <param name="rad"> see <see cref="rad"/></param>
     /// <param name="c1URI"> see <see cref="Cid1"/></param>
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -1496,7 +1496,7 @@ public AreaCircleFact(string Cid1, string backendURI, FactOrganizer organizer) :
     protected override string generateLabel()
         => "A(" + Circle.Label + ")";
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -1622,7 +1622,7 @@ public ConeVolumeFact(string Cid1, string Pid1, float volume, string backendURI,
     protected override string generateLabel()
         => "V(" + Circle.Label + "," + Point.Label + ")";
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -1758,7 +1758,7 @@ public OrthogonalCircleLineFact(string Cid1, string Lid1, string backendURI, Fac
     protected override string generateLabel()
         => Circle.Label + "⊥" + Ray.Label;
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMA(
             new OMS(MMT_OMS_URI.Ded),
@@ -1894,7 +1894,7 @@ public TruncatedConeVolumeFact(string Cid1, string Cid2, float volume, string un
     protected override string generateLabel()
         => "V(" + Circle1.Label + "," + Circle2.Label + ")";
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -2028,7 +2028,7 @@ public CylinderVolumeFact(string Cid1, string Cid2, float volume, string eqProof
     protected override string generateLabel()
         => "V(" + Circle1.Label + "," + Circle2.Label + ")";
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc lhs =
             new OMA(
@@ -2145,7 +2145,7 @@ public EqualCirclesFact(string Cid1, string Cid2, string backendURI, FactOrganiz
     protected override string generateLabel()
         => Circle1.Label + " ≠ " + Circle2.Label;
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMA(
             new OMS(MMT_OMS_URI.Ded),
@@ -2262,7 +2262,7 @@ public UnEqualCirclesFact(string Cid1, string Cid2, string backendURI, FactOrgan
     protected override string generateLabel()
         => Circle1.Label + " = " + Circle2.Label;
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         SOMDoc tp = new OMA(
             new OMS(MMT_OMS_URI.Ded),
@@ -2293,6 +2293,71 @@ protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, F
         => new UnEqualCirclesFact(old_to_new[this.Cid1], old_to_new[this.Cid2], organizer);
 }
 
+/// <summary>
+/// 
+/// </summary>
+/// <remarks>Hopefully not needed <see cref="SOMDoc.MakeList(string[], string)"/></remarks>
+public class ListFact : FactWrappedCRTP<ListFact>
+{
+    public string[] lids = new string[0];
+
+    public string typeURI;
+
+    [JsonIgnore]
+    public Type type => MMT_OMS_URI.OMS_TO_TYPE[typeURI];
+
+
+    protected override bool EquivalentWrapped(ListFact f1, ListFact f2)
+        => f1.typeURI == f2.typeURI
+        && DependentFactsEquivalent(f1, f2);
+
+    public override bool HasDependentFacts
+        => true;
+
+    protected override string[] GetGetDependentFactIds()
+        => lids;
+
+    public override MMTDeclaration MakeMMTDeclaration()
+    {
+        OMA List = SOMDoc.MakeList(lids, typeURI);
+        return new MMTSymbolDeclaration(Label, List.applicant, List.applicant);
+    }
+
+    public static List<T> parseFactList<T>(MMTDeclaration decl)
+    {
+        if (decl is not MMTSymbolDeclaration mMTSymbol)
+            return null;
+
+        List<T> ret = new();
+        SOMDoc next_element = mMTSymbol.defines;
+        while (true)
+        {
+            if (next_element is not OMA current_element)
+                return ret;
+
+            switch (current_element.arguments.Count)
+            {
+                case 2:
+                    ret.Add((current_element.arguments[1].GetLambdaExpression().Compile() as Func<T>)());
+                    next_element = current_element.arguments[0];
+                    break;
+
+                case 0:
+                case 1:
+                default:
+                    return ret;
+            }
+        }
+    }
+
+    protected override void RecalculateTransform() { }
+
+    protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
+    {
+        throw new NotImplementedException();
+    }
+}
+
 
 #pragma warning disable // Testing...
 
@@ -2377,7 +2442,7 @@ protected override bool EquivalentWrapped(TestFact f1, TestFact f2)
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new TestFact(organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         throw new NotImplementedException();
     }
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
index 53304976..dfe302ee 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
@@ -57,7 +57,7 @@ protected override bool EquivalentWrapped(FunctionCallFact f1, FunctionCallFact
                 && f1.Function_args.Equivalent(f2.Function_args)
         ));
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         throw new NotImplementedException();
     }
@@ -173,7 +173,7 @@ protected override bool EquivalentWrapped(FunctionFact f1, FunctionFact f2)
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new FunctionFact(this.Function_SOMDoc.MapURIs(old_to_new), organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         throw new NotImplementedException();
     }
@@ -248,7 +248,7 @@ protected override void RecalculateTransform()
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
         => new AttachedPositionFunction(old_to_new[this.fid], this.func_call_ids.Select(id => old_to_new[id]).ToArray(), organizer);
 
-    protected override MMTDeclaration MakeMMTDeclaration()
+    public override MMTDeclaration MakeMMTDeclaration()
     {
         throw new NotImplementedException();
     }
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index 9da20bfb..7547bc98 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -138,8 +138,8 @@ private int[] PrePopulateActiveScroll()
     {
         switch (ActiveScroll.@ref)
         {
-            case MMT_OMS_URI.ScrollAngleSum:
-                return new int[0];
+            case MMT_OMS_URI.ScrollCannonBall:
+                return new int[] { 2 };
 
             default:
                 return new int[0];
diff --git a/Assets/Scripts/SOMDocManager.cs b/Assets/Scripts/SOMDocManager.cs
index 2cc38fef..a6b8c986 100644
--- a/Assets/Scripts/SOMDocManager.cs
+++ b/Assets/Scripts/SOMDocManager.cs
@@ -7,6 +7,7 @@
 using MoreLinq;
 using UnityEngine;
 using static Scroll;
+using UnityEngine.Purchasing;
 
 public static class SOMDocManager
 {
@@ -54,6 +55,10 @@ public static class MMT_OMS_URI
 
         public static readonly string TestType = "http://mathhub.info/FrameIT/frameworld?FrameITCircle?xcircleType3D";
 
+        public static readonly string ListType = "http://gl.mathhub.info/MMT/LFX/Datatypes?ListSymbols?ListType";
+        public static readonly string ListLiteral = "http://gl.mathhub.info/MMT/LFX/Datatypes?ListSymbols?cons";
+        public static readonly string ListEnd = "http://gl.mathhub.info/MMT/LFX/Datatypes?ListSymbols?nil_constant";
+
         public static readonly string Sin = "Sin";
         public static readonly string Cos = "Cos";
         public static readonly string Add = "Add";
@@ -77,6 +82,92 @@ public static class MMT_OMS_URI
         public const string ScrollCircleAreaScroll = "http://mathhub.info/FrameIT/frameworld?CircleAreaScroll";
         public const string ScrollConeVolumeScroll = "http://mathhub.info/FrameIT/frameworld?ConeVolumeScroll";
         public const string ScrollTruncatedConeVolumeScroll = "http://mathhub.info/FrameIT/frameworld?TruncatedConeVolumeScroll";
+        public const string ScrollCannonBall = "CannonBall";
+
+        public static readonly IReadOnlyDictionary<Type, string> TYPE_TO_OMS;
+        public static readonly IReadOnlyDictionary<string, Type> OMS_TO_TYPE = new Dictionary<string, Type>()
+        {
+            { Point,
+                typeof(PointFact) },
+            { Metric,
+                typeof(LineFact) },
+            { Angle,
+                typeof(AngleFact) },
+            { Eq,
+                typeof(AngleFact) },
+            { RightAngle,
+                typeof(RightAngleFact) },
+            { LineType,
+                typeof(RayFact) },
+            { LineOf,
+                typeof(RayFact) },
+            { OnLine,
+                typeof(OnLineFact) },
+            { ParallelLine,
+                typeof(ParallelLineFact) },
+            { CircleType3d,
+                typeof(CircleFact) },
+            { OnCircle,
+                typeof(OnCircleFact) },
+            { AnglePlaneLine,
+                typeof(AngleCircleLineFact) },
+            { RadiusCircleMetric,
+                typeof(RadiusFact) },
+            { AreaCircle,
+                typeof(AreaCircleFact) },
+            { OrthoCircleLine,
+                typeof(OrthogonalCircleLineFact) },
+            { VolumeCone,
+                typeof(ConeVolumeFact) },
+            { TruncatedVolumeCone,
+                typeof(TruncatedConeVolumeFact) },
+            { CylinderVolume,
+                typeof(CylinderVolumeFact) },
+            { TestType,
+                typeof(TestFact) },
+            { EqualityCircles,
+                typeof(EqualCirclesFact) },
+            { UnEqualityCircles,
+                typeof(UnEqualCirclesFact) },
+
+            { RealLit,
+                typeof(float) },
+            { Tuple,
+                typeof(Vector3) },
+            { ListType,
+                typeof(List<>) },
+
+            { MkCircle3d, null }, //typeof(CircleFact) },
+            { ConeOfCircleApex, null }, //typeof(ConeVolumeFact) },
+
+            { Ded, null },
+            { Sketch, null },
+            { TriangleMiddlePoint, null },
+            { ParametrizedPlane, null },
+            { pointNormalPlane, null },
+            { ParallelCircles, null },
+
+            { "R",
+                typeof(float) },
+            { typeof(float).ToString(),
+                typeof(float) },
+            { typeof(double).ToString(),
+                typeof(double) },
+            { typeof(string).ToString(),
+                typeof(string) },
+            { typeof(Vector3).ToString(),
+                typeof(Vector3) },
+        };
+
+        static MMT_OMS_URI()
+        {
+            Dictionary<Type, string> _TYPE_TO_OMS = new();
+            foreach (KeyValuePair<string, Type> KeyVal in OMS_TO_TYPE)
+                if (KeyVal.Value != null)
+                    _TYPE_TO_OMS.TryAdd(KeyVal.Value, KeyVal.Key);
+
+            TYPE_TO_OMS = _TYPE_TO_OMS;
+        }
     }
 
 
@@ -85,19 +176,27 @@ public static class SOMDoctoLambdaExpression<T>
         // TODO: Populate Dictionaries
         #region ExpressionDictionaries
 
-        delegate LambdaExpression CustomFunction(LambdaExpression[] args_lamda, ParameterExpression[] bound_params);
+        delegate LambdaExpression CustomFunction(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params);
         private static readonly Dictionary<string, CustomFunction> MMTtoLambdaMaker = new()
         {
             { MMT_OMS_URI.Sin,
-                MakeSin},
+                MakeSin },
             { MMT_OMS_URI.Cos,
-                MakeCos},
+                MakeCos },
             { MMT_OMS_URI.SquareRoot,
-                MakeCos},
+                MakeCos },
             { MMT_OMS_URI.Tuple,
-                MakeUnityEngineVector3},
+                MakeUnityEngineVector3 },
             { MMT_OMS_URI.MakeObjectArray,
-                MakeArray},
+                MakeArray },
+            { "InstantList",
+                MakeInstantList },
+            { MMT_OMS_URI.ListEnd,
+                MakeListEnd },
+            { MMT_OMS_URI.ListLiteral,
+                InsertFrontListLiteral },
+            { MMT_OMS_URI.ListType,
+                Identity0 },
         };
 
         private static readonly Dictionary<string, ExpressionType> MMTtoBinaryExpressionType = new()
@@ -213,21 +312,21 @@ public static class SOMDoctoLambdaExpression<T>
         #endregion ExpressionDictionaries
 
         //TODO: case ((f->x)->y) instead of  assumed (f->(x->y))
-        public static LambdaExpression MakeLambdaExpression(string URI, LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        public static LambdaExpression MakeLambdaExpression(string URI, LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
         {
             void ThrowArgumentException(ExpressionType expression_cast, int expected)
             {
                 throw new ArgumentException(string.Format(
                     "\"Wrong number of Arguments. Required: {2}. Supplied: {3}.\\n\\tFor URI:\\\"{0}\\\"\\n\\tmapped to:\\\"{1}\\\"\"",
-                    URI, expression_cast, expected, lambda_args.Count()
+                    URI, expression_cast, expected, lambda_applicant.Count()
                 ));
             }
 
             ParameterExpression[] lambda_params =
-                lambda_args
+                lambda_applicant
                 .SelectMany(l => l.Parameters)
                 .ToArray(); //PERF: .ToList().Sort() => .BinarySearch;
-            ParameterExpression[] found_bound_params = 
+            ParameterExpression[] found_bound_params =
                 bound_params
                 .Where(p => lambda_params.Contains(p))
                 .ToArray();
@@ -239,18 +338,25 @@ void ThrowArgumentException(ExpressionType expression_cast, int expected)
 
                 Type UnarySecondArgument = found_bound_params.Count() < 2 ? null : found_bound_params[1].Type;
 
-                return Expression.Lambda(Expression.MakeUnary(unnary_type, lambda_args[0].Body, UnarySecondArgument), found_bound_params);
+                return Expression.Lambda(Expression.MakeUnary(unnary_type, lambda_applicant[0].Body, UnarySecondArgument), found_bound_params);
             }
-            else if (MMTtoBinaryExpressionType.TryGetValue(URI, out var binary_type))
+            else
+            if (MMTtoBinaryExpressionType.TryGetValue(URI, out var binary_type))
             {
-                if (lambda_args.Count() != 2)
+                if (lambda_applicant.Count() != 2)
                     ThrowArgumentException(binary_type, 2);
 
-                return Expression.Lambda(Expression.MakeBinary(binary_type, lambda_args[0].Body, lambda_args[1].Body), found_bound_params);
+                return Expression.Lambda(Expression.MakeBinary(binary_type, lambda_applicant[0].Body, lambda_applicant[1].Body), found_bound_params);
             }
-            else if (MMTtoLambdaMaker.TryGetValue(URI, out var lamda_maker))
+            else
+            if (MMTtoLambdaMaker.TryGetValue(URI, out var lamda_maker))
             {
-                return lamda_maker(lambda_args, found_bound_params);
+                return lamda_maker(lambda_applicant, lambda_arguments, found_bound_params);
+            }
+            else
+            if (MMT_OMS_URI.OMS_TO_TYPE.TryGetValue(URI, out Type type))
+            {
+                return Expression.Lambda(Expression.Default(type), null);
             }
 
             throw new NotImplementedException("Could not map URI: \"" + URI + "\"");
@@ -262,7 +368,7 @@ private static LambdaExpression ExpresionFuncToLambda(LambdaExpression func, str
         private static LambdaExpression ParseFuncUUToExpression<U>(Func<U, U> func)
             => (Expression<Func<U, U>>)((U x) => func(x));
 
-        private static LambdaExpression MakeSin(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        private static LambdaExpression MakeSin(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => ExpresionFuncToLambda(
                     default(T) switch // TODO? cleaner switch
                     {
@@ -270,10 +376,10 @@ private static LambdaExpression MakeSin(LambdaExpression[] lambda_args, Paramete
                         double => ParseFuncUUToExpression<double>(Math.Sin),
                         _ => throw new NotImplementedException("Sinus for " + nameof(T) + "=" + typeof(T))
                     },
-                    "Sin", lambda_args, bound_params, 1
+                    "Sin", lambda_applicant, bound_params, 1
                 );
 
-        private static LambdaExpression MakeCos(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        private static LambdaExpression MakeCos(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => ExpresionFuncToLambda(
                     default(T) switch // TODO? cleaner switch
                     {
@@ -281,23 +387,53 @@ private static LambdaExpression MakeCos(LambdaExpression[] lambda_args, Paramete
                         double => ParseFuncUUToExpression<double>(Math.Cos),
                         _ => throw new NotImplementedException("Cosinus for " + nameof(T) + "=" + typeof(T))
                     },
-                    "Cos", lambda_args, bound_params, 1
+                    "Cos", lambda_applicant, bound_params, 1
                 );
 
-        private static LambdaExpression MakeUnityEngineVector3(LambdaExpression[] args_lamda, ParameterExpression[] bound_params)
+        private static LambdaExpression MakeUnityEngineVector3(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => ExpresionFuncToLambda(
                     (Expression<Func<float, float, float, Vector3>>)((x, y, z) => new Vector3(x, y, z)),
-                    "UnityEngineVector3", args_lamda, bound_params, 3
+                    "UnityEngineVector3", lambda_applicant, bound_params, 3
                 );
 
-        private static LambdaExpression MakeArray(LambdaExpression[] args_lamda, ParameterExpression[] bound_params)
+        private static LambdaExpression MakeArray(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => Expression.Lambda(
                     Expression.NewArrayInit(
-                        typeof(object), 
-                        args_lamda.Select(l => Expression.Convert(l.Body, typeof(object)))
+                        typeof(object),
+                        lambda_applicant.Select(l => Expression.Convert(l.Body, typeof(object)))
                     ),
                     bound_params
                 );
+
+        private static LambdaExpression MakeInstantList(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
+            => Expression.Lambda(
+                    Expression.ListInit(
+                        Expression.New(typeof(List<>).MakeGenericType(lambda_applicant[0].ReturnType)),
+                        lambda_arguments.Select(l => l.Body) // Expression.Convert(l.Body, lambda_applicant[0].ReturnType))
+                    ),
+                    bound_params
+                );
+
+        private static LambdaExpression InsertFrontListLiteral(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
+            => Expression.Lambda(
+                    Expression.Call(
+                        lambda_applicant[0].Body,
+                        lambda_applicant[0].ReturnType.GetMethod("Insert"),
+                        Expression.Constant(0, typeof(int)),
+                        lambda_applicant[1].Body
+                    ),
+                    bound_params
+                );
+
+        private static LambdaExpression MakeListEnd(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
+            => Expression.Lambda(
+                    Expression.New(typeof(List<>).MakeGenericType(lambda_applicant[0].ReturnType)),
+                    null
+                );
+
+        private static LambdaExpression Identity0(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
+            => lambda_applicant[0];
+
     }
 
 
@@ -318,33 +454,6 @@ abstract public class SOMDoc
     {
         public string kind;
 
-        [JsonIgnore]
-        protected static readonly IReadOnlyDictionary<string, Type> StringToType = new Dictionary<string, Type>() {
-            {"R",
-                typeof(float)},
-            {typeof(float).ToString(),
-                typeof(float)},
-            {typeof(double).ToString(),
-                typeof(double)},
-            {typeof(string).ToString(),
-                typeof(string)},
-            {MMT_OMS_URI.Tuple,
-                typeof(UnityEngine.Vector3)},
-            {typeof(UnityEngine.Vector3).ToString(),
-                typeof(UnityEngine.Vector3)},
-        };
-        [JsonIgnore]
-        protected static readonly IReadOnlyDictionary<Type, string> TypeToString;
-
-        static SOMDoc()
-        {
-            Dictionary<Type, string> _TypeToString = new();
-            foreach (KeyValuePair<string, Type> KeyVal in StringToType)
-                _TypeToString.TryAdd(KeyVal.Value, KeyVal.Key);
-            
-            TypeToString = _TypeToString;
-        }
-
         protected SOMDoc() { kind = this.GetType().Name; }
 
         public static bool Equivalent(SOMDoc sd1, SOMDoc sd2)
@@ -354,8 +463,7 @@ public static bool Equivalent(SOMDoc sd1, SOMDoc sd2)
 
         public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signature_args, object[] callArgs = null, bool[] useArgs = null)
         {
-            LambdaExpression lambda_orig =
-                GetLambdaExpression(new LambdaExpression[0], new ParameterExpression[0]);
+            LambdaExpression lambda_orig = GetLambdaExpression();
 
             signature_args = new Type[lambda_orig.Parameters.Count + 1];
 
@@ -365,7 +473,7 @@ public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signatur
             int n_params = 0;
             for (int i = 0; i < lambda_orig.Parameters.Count; i++)
             {
-                if (callArgs != null && callArgs.Length < i 
+                if (callArgs != null && callArgs.Length < i
                  && (useArgs == null || (useArgs.Length < i && useArgs[i])))
                 {
                     cast_new_to_signature[i] =
@@ -395,23 +503,22 @@ public LambdaExpression PartialInvokeCastingLambdaExpression(out Type[] signatur
                     : Expression.NewArrayInit(
                         typeof(object),
                         new Expression[] { Expression.Convert(Expression.Invoke(lambda_orig, cast_new_to_signature), typeof(object)) }),
-                
+
                 object_arr
                 );
         }
 
         public LambdaExpression GetLambdaExpression()
-            => GetLambdaExpression(new LambdaExpression[0], new ParameterExpression[0]);
+            => GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], new ParameterExpression[0]);
 
-        protected internal abstract LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params);
+        protected internal abstract LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params);
 
         public abstract override string ToString();
 
         public abstract SOMDoc MapURIs(Dictionary<string, string> old_to_new);
 
         #region MakeMMT_OMS_URItoSOMDoc
-
-        public static SOMDoc MakeUnityEngineVector3(Vector3 vec)
+        public static OMA MakeUnityEngineVector3(Vector3 vec)
             => new OMA(
                 new OMS(MMT_OMS_URI.Tuple),
                     new() {
@@ -421,6 +528,43 @@ public static SOMDoc MakeUnityEngineVector3(Vector3 vec)
                     }
                 );
 
+        public static OMA MakeList(string[] lids, Type type)
+            => MakeList(lids, MMT_OMS_URI.TYPE_TO_OMS[type]);
+
+        public static OMA MakeList(string[] lids, string typeURI)
+        {
+            List<SOMDoc> end_of_list = new() {
+                new OMA(
+                    new OMS(MMT_OMS_URI.ListEnd),
+                    new() {
+                        new OMS(typeURI),
+            }),};
+
+            if (lids.Length > 0)
+                end_of_list.Add(new OMS(lids[^1]));
+
+            SOMDoc defines = new OMA(
+                new OMS(MMT_OMS_URI.ListLiteral),
+                end_of_list
+            );
+
+            for (int i = lids.Length - 2; i >= 0; i--)
+            {
+                defines = new OMA(
+                    new OMS(MMT_OMS_URI.ListLiteral),
+                    new() {
+                        defines,
+                        new OMS(lids[i]),
+                });
+            }
+
+            SOMDoc type = new OMA(
+                new OMS(MMT_OMS_URI.ListType),
+                new() { new OMS(typeURI), }
+            );
+
+            return new OMA(type, new() { defines });
+        }
         #endregion MakeMMT_OMS_URItoSOMDoc
     }
 
@@ -454,8 +598,8 @@ public class OMBINDC : SOMDocCRTP<OMBINDC>
         /// <summary>Enables (especially <see cref="JsonConverter"/>) to read and set <see cref="type"/> by its <c>string</c> representation.</summary>
         public string typeString
         {
-            get => TypeToString[type];
-            set => type = StringToType[value];
+            get => MMT_OMS_URI.TYPE_TO_OMS[type];
+            set => type = MMT_OMS_URI.OMS_TO_TYPE[value];
         }
 
         [JsonConstructor]
@@ -474,17 +618,17 @@ public OMBINDC(string name, Type type, SOMDoc lambdabody) : base()
         }
 
         protected override bool EquivalentWrapped(OMBINDC sd2)
-            => this.type == sd2.type 
+            => this.type == sd2.type
             && this.name.Equals(sd2.name)
             && this.lambdabody.Equivalent(sd2.lambdabody);
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
         {
             ParameterExpression[] bind_me = bound_params.ShallowCloneAppend(
                 new[] { Expression.Parameter(type, name) }
             );
 
-            return lambdabody.GetLambdaExpression(lambda_args, bind_me);
+            return lambdabody.GetLambdaExpression(lambda_applicant, lambda_arguments, bind_me);
         }
 
         public override string ToString()
@@ -514,9 +658,10 @@ protected override bool EquivalentWrapped(OMA sd2)
                 .Zip(sd2.arguments, (arg1, arg2) => Equivalent(arg1, arg2))
                 .All(b => b);
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant_paps, LambdaExpression[] lambda_applicant_grands, ParameterExpression[] bound_params)
             => applicant.GetLambdaExpression(
-                arguments.Select(arg => arg.GetLambdaExpression(lambda_args, bound_params)).ToArray(),
+                arguments.Select(arg => arg.GetLambdaExpression(new LambdaExpression[0], new LambdaExpression[0], bound_params)).ToArray(),
+                lambda_applicant_paps,
                 bound_params
             );
 
@@ -545,8 +690,8 @@ public OMS(string uri) : base()
         protected override bool EquivalentWrapped(OMS sd2)
             => this.uri == sd2.uri;
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
-            => SOMDoctoLambdaExpression<float>.MakeLambdaExpression(uri, lambda_args, bound_params);
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
+            => SOMDoctoLambdaExpression<float>.MakeLambdaExpression(uri, lambda_applicant, lambda_arguments, bound_params);
 
         public override string ToString()
             => uri;
@@ -576,7 +721,7 @@ public OMSTR(string s) : base()
         protected override bool EquivalentWrapped(OMSTR sd2)
             => this.s == sd2.s;
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => Expression.Lambda(Expression.Constant(s, typeof(string)), null);
 
         public override string ToString()
@@ -602,7 +747,7 @@ public OMF(float f) : base()
         protected override bool EquivalentWrapped(OMF sd2)
             => Mathf.Approximately(@float, sd2.@float);
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => Expression.Lambda(Expression.Constant(@float, typeof(float)), null);
 
         public override string ToString()
@@ -630,7 +775,7 @@ protected override bool EquivalentWrapped(OMC<T> sd2)
             return this.value.Equals(value);
         }
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
             => Expression.Lambda(Expression.Constant(value, typeof(T)), null);
 
         public override string ToString()
@@ -655,7 +800,7 @@ public OMV(string name) : base()
         protected override bool EquivalentWrapped(OMV sd2)
             => this.name == sd2.name;
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
         {
             ParameterExpression v = bound_params.FirstOrDefault(param => param.Name.Equals(name));
             if (v == null)
@@ -701,7 +846,7 @@ public override string ToString()
         protected override bool EquivalentWrapped(RAW sd2)
             => throw new NotImplementedException(); //xml == sd2.xml; // only exact
 
-        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_args, ParameterExpression[] bound_params)
+        protected internal override LambdaExpression GetLambdaExpression(LambdaExpression[] lambda_applicant, LambdaExpression[] lambda_arguments, ParameterExpression[] bound_params)
         {
             throw new NotImplementedException();
         }
@@ -755,7 +900,7 @@ public MMTSymbolDeclaration(string label, SOMDoc type, SOMDoc defines)
             this.type = type;
             this.defines = defines;
         }
-        
+
         public override string getType()
         {
             return type switch
@@ -799,7 +944,7 @@ public MMTValueDeclaration(string label, SOMDoc lhs, SOMDoc valueType, SOMDoc va
             this.value = value;
             this.proof = proof;
         }
-        
+
         public override string getType()
         {
             return lhs switch
-- 
GitLab