From eebb35aea91928630b77fe501a0d1ec22fd4c8ec Mon Sep 17 00:00:00 2001
From: MaZiFAU <63099053+MaZiFAU@users.noreply.github.com>
Date: Sat, 8 Jul 2023 00:45:13 +0200
Subject: [PATCH] Changed ListFact to be more like TupelFact

---
 .../FactHandling/Facts/MMTTypes.cs            | 127 +++++++++++-------
 Assets/Scripts/SOMDocManager.cs               |  18 +--
 2 files changed, 85 insertions(+), 60 deletions(-)

diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
index f1a57a51..f8a17a56 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
@@ -11,7 +11,9 @@
 /// <remarks>Needed to refere to lists serverside</remarks>
 public class ListFact : FactWrappedCRTP<ListFact>
 {
-    public string[] lids;
+    public string[] lids = new string[0];
+
+    public SOMDoc[] payload = new SOMDoc[0];
 
     public string typeURI;
     [JsonIgnore]
@@ -22,59 +24,58 @@ public Type ListType
     }
 
 
-    public ListFact() : base()
-    {
-        lids = new string[0];
-    }
+    public ListFact() : base() { }
 
-    public ListFact(string[] lids, Type ListType, FactOrganizer organizer) : base(organizer)
+    public ListFact(string[] lids, SOMDoc[] payload, Type ListType, FactOrganizer organizer) : base(organizer)
     {
-        this.lids = lids;
         this.ListType = ListType;
+        Init(lids, payload);
         SendToMMT();
     }
 
-    public ListFact(string[] lids, string typeURI, string backendURI, FactOrganizer organizer) : base(organizer)
+    public ListFact(string[] lids, SOMDoc[] payload, string typeURI, string backendURI, FactOrganizer organizer) : base(organizer)
     {
-        this.lids = lids;
         this.typeURI = typeURI;
+        Init(lids, payload);
         _URI = backendURI;
     }
 
+    private void Init(string[] lids, SOMDoc[] payload)
+    {
+        this.lids = lids ?? new string[0];
+        if (!HasDependentFacts)
+        {
+            if (payload.Any(p => p == null))
+                throw new ArgumentException(nameof(payload) + "must not include null elements iff " + nameof(lids) + " is all nulls or empty!");
 
-    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;
+            this.payload = payload;
+        }
+        else
+        {
+            this.payload = new SOMDoc[Unity.Mathematics.math.max(lids.Length, payload.Length)];
 
-    public override MMTDeclaration MakeMMTDeclaration()
-    {
-        OMA List = SOMDoc.MakeList(lids, typeURI);
-        return new MMTSymbolDeclaration(Label, List.applicant, List.arguments[0]);
+            for (int i = 0; i < this.payload.Length; i++)
+                if (lids[i] != null)
+                    payload[i] = new OMS(lids[i]);
+                else
+                if (lids[i] == null && payload[i] == null)
+                    throw new ArgumentException(nameof(lids) + " and " + nameof(payload) + " have to be complementary not null!");
+        }
     }
 
-    public static new ListFact parseFact(MMTDeclaration fact)
-        => new(parseFactList(fact, out string typeURI).ToArray(), typeURI, fact.@ref.uri, StageStatic.stage.factState);
+    protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
+        => new ListFact(
+            lids.Select(id => id == null ? null : old_to_new[id]).ToArray(),
+            payload,
+            ListType, organizer);
 
-    public static List<string> parseFactList(MMTDeclaration decl, out string typeURI)
+    public static List<T> parseFactList<T>(MMTDeclaration decl)
     {
-        if (decl is not MMTSymbolDeclaration MMTSymbol
-         || MMTSymbol.type is not OMA listOMA
-         || listOMA.arguments[0] is not OMS typeOMS)
-        {
-            typeURI = null;
+        if (decl is not MMTSymbolDeclaration mMTSymbol)
             return null;
-        }
-
-        typeURI = typeOMS.uri;
 
-        List<string> ret = new();
-        SOMDoc next_element = MMTSymbol.defines;
+        List<T> ret = new();
+        SOMDoc next_element = mMTSymbol.defines;
         while (true)
         {
             if (next_element is not OMA current_element)
@@ -83,10 +84,7 @@ public static List<string> parseFactList(MMTDeclaration decl, out string typeURI
             switch (current_element.arguments.Length)
             {
                 case 2:
-                    if (current_element.arguments[1] is not OMS oMS)
-                        return ret;
-
-                    ret.Add(oMS.uri);
+                    ret.Add((current_element.arguments[1].GetLambdaExpression().Compile() as Func<T>)());
                     next_element = current_element.arguments[0];
                     break;
 
@@ -98,37 +96,62 @@ public static List<string> parseFactList(MMTDeclaration decl, out string typeURI
         }
     }
 
-    public static List<T> parseFactList<T>(MMTDeclaration decl)
+    public static new ListFact parseFact(MMTDeclaration fact)
     {
-        if (decl is not MMTSymbolDeclaration mMTSymbol)
+        if (fact is not MMTSymbolDeclaration MMTSymbol
+         || MMTSymbol.type is not OMA listOMA
+         || listOMA.arguments[0] is not OMS typeOMS)
+        {
             return null;
+        }
 
-        List<T> ret = new();
-        SOMDoc next_element = mMTSymbol.defines;
+        List<SOMDoc> payload = new();
+        SOMDoc next_element = MMTSymbol.defines;
         while (true)
         {
             if (next_element is not OMA current_element)
-                return ret;
+                goto while_end;
 
             switch (current_element.arguments.Length)
             {
                 case 2:
-                    ret.Add((current_element.arguments[1].GetLambdaExpression().Compile() as Func<T>)());
+                    payload.Add(current_element.arguments[1]);
                     next_element = current_element.arguments[0];
                     break;
 
                 case 0:
                 case 1:
                 default:
-                    return ret;
+                    goto while_end;
             }
         }
+    while_end:
+
+        return new(
+            payload.Select(p => (p as OMS)?.uri).ToArray(),
+            payload.ToArray(),
+            typeOMS.uri,
+            fact.@ref.uri, StageStatic.stage.factState);
     }
 
+    public override MMTDeclaration MakeMMTDeclaration()
+    {
+        OMA List = SOMDoc.MakeList(payload, typeURI);
+        return new MMTSymbolDeclaration(Label, List.applicant, List.arguments[0]);
+    }
+
+    protected override string[] GetGetDependentFactIds()
+        => lids.Where(lid => lid != null).ToArray();
+
     protected override void RecalculateTransform() { }
 
-    protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
-        => new ListFact(lids.Select(id => old_to_new[id]).ToArray(), ListType, organizer);
+    protected override bool EquivalentWrapped(ListFact f1, ListFact f2)
+        => f1.typeURI == f2.typeURI
+        && f1.payload.Length == f2.payload.Length
+        && DependentFactsEquivalent(f1, f2)
+        && f1.payload
+            .Zip(f2.payload, (p1, p2) => (p1 is OMS && p2 is OMS) || SOMDoc.Equivalent(p1, p2))
+            .All(b => b);
 }
 
 /// <summary>
@@ -181,7 +204,9 @@ private void Init(string[] lids, SOMDoc[] payload)
     }
 
     protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
-        => new TupelFact(lids.Select(id => old_to_new[id]).ToArray(), payload, organizer);
+        => new TupelFact(
+            lids.Select(id => id == null ? null : old_to_new[id]).ToArray(), 
+            payload, organizer);
 
     public static new TupelFact parseFact(MMTDeclaration fact)
     {
@@ -210,9 +235,9 @@ protected override string[] GetGetDependentFactIds()
     protected override void RecalculateTransform() { }
 
     protected override bool EquivalentWrapped(TupelFact f1, TupelFact f2)
-        //=> DependentFactsEquivalent(f1, f2)
         => f1.payload.Length == f2.payload.Length
+        && DependentFactsEquivalent(f1, f2)
         && f1.payload
-            .Zip(f2.payload, (p1, p2) => SOMDoc.Equivalent(p1, p2))
+            .Zip(f2.payload, (p1, p2) => (p1 is OMS && p2 is OMS) || SOMDoc.Equivalent(p1, p2))
             .All(b => b);
 }
\ No newline at end of file
diff --git a/Assets/Scripts/SOMDocManager.cs b/Assets/Scripts/SOMDocManager.cs
index 5f1da0ab..d84aacd3 100644
--- a/Assets/Scripts/SOMDocManager.cs
+++ b/Assets/Scripts/SOMDocManager.cs
@@ -548,10 +548,10 @@ public static OMA MakeTupel(SOMDoc[] args)
                     args
                 );
 
-        public static OMA MakeList(string[] lids, Type type)
-            => MakeList(lids, MMT_OMS_URI.TYPE_TO_OMS[type]);
+        public static OMA MakeList(SOMDoc[] args, Type type)
+            => MakeList(args, MMT_OMS_URI.TYPE_TO_OMS[type]);
 
-        public static OMA MakeList(string[] lids, string typeURI)
+        public static OMA MakeList(SOMDoc[] args, string typeURI)
         {
             SOMDoc[] end_of_list = new SOMDoc[] {
                 new OMA(
@@ -560,26 +560,26 @@ public static OMA MakeList(string[] lids, string typeURI)
                         new OMS(typeURI),
                     }
                 ),
-                lids.Length == 0
+                args.Length == 0
                     ? null
-                    : new OMS(lids[^1])
+                    : args[^1]
             };
 
-            if (lids.Length == 0)
-                end_of_list = end_of_list[..^1];
+            if (args.Length == 0)
+                end_of_list = end_of_list[..^0];
 
             SOMDoc defines = new OMA(
                 new OMS(MMT_OMS_URI.ListLiteral),
                 end_of_list
             );
 
-            for (int i = lids.Length - 2; i >= 0; i--)
+            for (int i = args.Length - 2; i >= 0; i--)
             {
                 defines = new OMA(
                     new OMS(MMT_OMS_URI.ListLiteral),
                     new[] {
                         defines,
-                        new OMS(lids[i]),
+                        args[i],
                 });
             }
 
-- 
GitLab