diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
index 7435fa2f6ce93105a41c79d4eb7aed2a35a2800f..d39acd0fbfcb9f0314f44155bedaf5ba3a36131c 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractLineFact.cs
@@ -16,9 +16,9 @@ public abstract class AbstractLineFact : FactWrappedCRTP<AbstractLineFact>
     /// @}
 
     [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)_Facts[Pid1]; }
+    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
     [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)_Facts[Pid2]; }
+    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
 
     /// <summary> Distance between <see cref="AbstractLineFact.Pid1"/> and <see cref="AbstractLineFact.Pid2"/></summary>
     [JsonIgnore]
@@ -98,22 +98,12 @@ protected override void RecalulateTransform()
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override bool hasDependentFacts()
-    {
-        return true;
-    }
+    public override bool hasDependentFacts() 
+        => true;
 
     /// \copydoc Fact.getDependentFactIds
-    public override string[] getDependentFactIds()
-    {
-        return new string[] { Pid1, Pid2 };
-    }
-
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-    {
-        return this.Pid1.GetHashCode() ^ this.Pid2.GetHashCode();
-    }
+    public override string[] getDependentFactIds() 
+        => new string[] { Pid1, Pid2 };
 }
 
 /// <summary>
@@ -206,28 +196,21 @@ private void init(string pid1, string pid2)
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "[" + _Facts[Pid1].Label + _Facts[Pid2].Label + "]";
+        => "[" + Point1.Label + Point2.Label + "]";
 
     /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(LineFact f1, LineFact f2)
-    {
-        if ((f1.Pid1 == f2.Pid1 && f1.Pid2 == f2.Pid2))// || 
-            //(f1.Pid1 == f2.Pid2 && f1.Pid2 == f2.Pid1))
-            return true;
-
-        return (f1.Point1.Equivalent(f2.Point1) && f1.Point2.Equivalent(f2.Point2))
-            ;//|| (p1f1.Equivalent(p2f2) && p2f1.Equivalent(p1f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -304,7 +287,7 @@ protected override string generateLabel()
     {
         // TODO this string is too large to properly depict on scrolls. 
         // return "]" + _Facts[Pid1].Label + _Facts[Pid2].Label + "[";
-        return _Facts[Pid1].Label + _Facts[Pid2].Label;
+        return Point1.Label + Point2.Label;
     }
 
     /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
@@ -322,11 +305,7 @@ protected override bool EquivalentWrapped(RayFact f1, RayFact f2)
         if (!Math3d.IsApproximatelyParallel(f1.Dir, f2.Dir))
             return false;
 
-        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
-        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
-
-        return Math3d.IsPointApproximatelyOnLine(p1f1.Point, f1.Dir, p1f2.Point)
-            && Math3d.IsPointApproximatelyOnLine(p1f1.Point, f1.Dir, p2f2.Point);
+        return Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point1.Point)
+            && Math3d.IsPointApproximatelyOnLine(f1.Point1.Point, f1.Dir, f2.Point2.Point);
     }
 }
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
index e9931839a8a21d0e2b2116e9917e387cdefb934b..f15d885aeb62c267582c1eb75313ddf7828e8952 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
@@ -8,6 +8,8 @@
 using static CommunicationEvents;
 using JsonSubTypes;
 using UnityEngine.ProBuilder;
+using System.Linq;
+using MoreLinq;
 
 public class ParsingDictionary
 {
@@ -333,7 +335,10 @@ public bool rename(string newLabel)
     /// canonical
     /// </summary>
     /// <returns>unique-ish Hash</returns>
-    public abstract override int GetHashCode();
+    public new virtual int GetHashCode()
+        => getDependentFactIds()
+            .Select(id => id.GetHashCode())
+            .Aggregate((hash1, hash2) => hash1 ^ hash2);
 
     /// <summary>
     /// auto-generates <see cref="Label"/> using generation variable(s) e.g. <see cref="LabelId"/>;
@@ -416,6 +421,15 @@ public override bool Equivalent(Fact f1, Fact f2)
 
     /// <summary>CRTP step of <see cref="Equivalent(Fact)"/> and <see cref="Equivalent(Fact, Fact)"/></summary>
     protected abstract bool EquivalentWrapped(T f1, T f2);
+
+    protected bool DependentFactsEquivalent(T f1, T f2)
+        => f1.getDependentFactIds()
+            .Zip(f2.getDependentFactIds(),
+                (id1, id2) =>
+                    id1.Equals(id2)
+                    || FactOrganizer.AllFacts[id1].Equivalent(FactOrganizer.AllFacts[id2])
+            )
+            .All(b => b);
 }
 
 /// <summary>
@@ -558,12 +572,12 @@ public class OnLineFact : FactWrappedCRTP<OnLineFact>
     /// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary>
     public string Pid;
     [JsonIgnore]
-    public PointFact Point { get => (PointFact)_Facts[Pid]; }
+    public PointFact Point { get => (PointFact)FactOrganizer.AllFacts[Pid]; }
 
     /// <summary> <see cref="AbstractLineFact"/>.<see cref="Fact.Id">Id</see> </summary>
     public string Rid;
     [JsonIgnore]
-    public AbstractLineFact Ray { get => (AbstractLineFact)_Facts[Rid]; }
+    public AbstractLineFact Ray { get => (AbstractLineFact)FactOrganizer.AllFacts[Rid]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public OnLineFact() : base()
@@ -677,10 +691,10 @@ public OnLineFact(string pid, string rid, string uri, FactOrganizer organizer) :
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Pid].Label + "∈" + _Facts[Rid].Label;
+        => Point.Label + "∈" + Ray.Label;
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -691,29 +705,14 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Rid].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Pid.GetHashCode() ^ this.Rid.GetHashCode();
-
-    /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
-    {
-        if (f1.Pid == f2.Pid && f1.Rid == f2.Rid)
-            return true;
-
-        PointFact pf1 = (PointFact)_Facts[f1.Pid];
-        RayFact rf1 = (RayFact)_Facts[f1.Rid];
-        PointFact pf2 = (PointFact)_Facts[f2.Pid];
-        RayFact rf2 = (RayFact)_Facts[f2.Rid];
-
-        return pf1.Equivalent(pf2) && rf1.Equivalent(rf2);
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -728,11 +727,11 @@ public class AngleFact : FactWrappedCRTP<AngleFact>
     /// @}
 
     [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)_Facts[Pid1]; }
+    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
     [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)_Facts[Pid2]; }
+    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
     [JsonIgnore]
-    public PointFact Point3 { get => (PointFact)_Facts[Pid3]; }
+    public PointFact Point3 { get => (PointFact)FactOrganizer.AllFacts[Pid3]; }
 
     /// <summary> <see langword="true"/>, if AngleFact is approximately 90° or 270°</summary>
     public bool is_right_angle;
@@ -886,7 +885,7 @@ public AngleFact(string Pid1, string Pid2, string Pid3, float angle, string back
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => (is_right_angle ? "⊾" : "∠") + _Facts[Pid1].Label + _Facts[Pid2].Label + _Facts[Pid3].Label;
+        => (is_right_angle ? "⊾" : "∠") + Point1.Label + Point2.Label + Point3.Label;
 
     /// <summary>
     /// Computes smallest angle and sets <see cref="is_right_angle"/>
@@ -894,11 +893,7 @@ protected override string generateLabel()
     /// <returns>Smallets angle between [<see cref="Pid1"/>, <see cref="Pid2"/>] and [<see cref="Pid2"/>, <see cref="Pid3"/>]</returns>
     private float ComputeAngle()
     {
-        PointFact pf1 = _Facts[Pid1] as PointFact;
-        PointFact pf2 = _Facts[Pid2] as PointFact;
-        PointFact pf3 = _Facts[Pid3] as PointFact;
-
-        angle = Vector3.Angle((pf1.Point - pf2.Point), (pf3.Point - pf2.Point));
+        angle = Vector3.Angle((Point1.Point - Point2.Point), (Point3.Point - Point2.Point));
         this.is_right_angle = Mathf.Abs(angle - 90.0f) < 0.01;
 
         return is_right_angle ? 90f : angle;
@@ -974,34 +969,16 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid2].Label;
-        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid3].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
+        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Pid1.GetHashCode() ^ this.Pid2.GetHashCode() ^ this.Pid3.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
-    protected override bool EquivalentWrapped(AngleFact f1, AngleFact f2)
-    {
-        if ((f1.Pid1 == f2.Pid1 && f1.Pid2 == f2.Pid2 && f1.Pid3 == f2.Pid3))// || 
-            //(f1.Pid1 == f2.Pid3 && f1.Pid2 == f2.Pid2 && f1.Pid3 == f2.Pid1))
-            return true;
-
-        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
-        PointFact p2f1 = (PointFact)_Facts[f1.Pid2];
-        PointFact p3f1 = (PointFact)_Facts[f1.Pid3];
-        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
-        PointFact p3f2 = (PointFact)_Facts[f2.Pid3];
-
-        return (p1f1.Equivalent(p1f2) && p2f1.Equivalent(p2f2) && p3f1.Equivalent(p3f2));
-        //|| (p1f1.Equivalent(p3f2) && p2f1.Equivalent(p2f2) && p1f1.Equivalent(p3f2));
-    }
+    protected override bool EquivalentWrapped(AngleFact f1, AngleFact f2) 
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -1013,11 +990,11 @@ public class RightAngleFact : FactWrappedCRTP<RightAngleFact>
     public string Pid1, Pid2, Pid3;
 
     [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)_Facts[Pid1]; }
+    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
     [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)_Facts[Pid2]; }
+    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
     [JsonIgnore]
-    public PointFact Point3 { get => (PointFact)_Facts[Pid2]; }
+    public PointFact Point3 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public RightAngleFact() : base()
@@ -1136,11 +1113,9 @@ public RightAngleFact(string Pid1, string Pid2, string Pid3, string backendURI,
             return null;
     }
 
-
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Pid1].Label + _Facts[Pid2].Label + _Facts[Pid3].Label + "⊥";
-
+        => Point1.Label + Point2.Label + Point3.Label + "⊥";
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -1169,7 +1144,7 @@ private MMTDeclaration generateMMTDeclaration(string p1URI, string p2URI, string
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -1180,35 +1155,17 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid2].Label;
-        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid3].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
+        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
 
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    /// uhhh is this a problem?
-    public override int GetHashCode()
-        => this.Pid1.GetHashCode() ^ this.Pid2.GetHashCode() ^ this.Pid3.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(RightAngleFact f1, RightAngleFact f2)
-    {
-        if (f1.Pid1 == f2.Pid1 && f1.Pid2 == f2.Pid2 && f1.Pid3 == f2.Pid3)
-            return true;
-
-        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
-        PointFact p2f1 = (PointFact)_Facts[f1.Pid2];
-        PointFact p3f1 = (PointFact)_Facts[f1.Pid3];
-
-        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
-        PointFact p3f2 = (PointFact)_Facts[f2.Pid3];
-
-        return (p1f1.Equivalent(p1f2) && p2f1.Equivalent(p2f2) && p3f1.Equivalent(p3f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -1223,9 +1180,9 @@ public class ParallelLineFact : FactWrappedCRTP<ParallelLineFact>
     /// @}
 
     [JsonIgnore]
-    public AbstractLineFact Ray1 { get => (AbstractLineFact)_Facts[Lid1]; }
+    public AbstractLineFact Ray1 { get => (AbstractLineFact)FactOrganizer.AllFacts[Lid1]; }
     [JsonIgnore]
-    public AbstractLineFact Ray2 { get => (AbstractLineFact)_Facts[Lid2]; }
+    public AbstractLineFact Ray2 { get => (AbstractLineFact)FactOrganizer.AllFacts[Lid2]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public ParallelLineFact() : base()
@@ -1263,18 +1220,10 @@ public ParallelLineFact(string lid1, string lid2, FactOrganizer organizer) : bas
     /// <param name="lid2">sets <see cref="Lid2"/></param>
     private void init(string lid1, string lid2)
     {
-
         this.Lid1 = lid1;
         this.Lid2 = lid2;
 
-        RayFact lf1 = _Facts[lid1] as RayFact;
-        RayFact lf2 = _Facts[lid2] as RayFact;
-
-        MMTDeclaration mmtDecl;
-        string l1URI = lf1.Id;
-        string l2URI = lf2.Id;
-        mmtDecl = generateParallelLineDeclaration(l1URI, l2URI);
-
+        MMTDeclaration mmtDecl = generateParallelLineDeclaration(lid1, lid2);
         AddFactResponse.sendAdd(mmtDecl, out this._URI);
     }
 
@@ -1340,7 +1289,7 @@ public ParallelLineFact(string Lid1, string Lid2, string backendURI, FactOrganiz
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Lid1].Label + "||" + _Facts[Lid2].Label;
+        => Ray1.Label + "||" + Ray2.Label;
 
     /// <summary>
     /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -1382,29 +1331,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Lid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Lid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Ray1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Lid1.GetHashCode() ^ this.Lid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
-    protected override bool EquivalentWrapped(ParallelLineFact f1, ParallelLineFact f2)
-    {
-        if ((f1.Lid1 == f2.Lid1 && f1.Lid2 == f2.Lid2))
-            return true;
-
-        RayFact r1f1 = (RayFact)_Facts[f1.Lid1];
-        RayFact r2f1 = (RayFact)_Facts[f1.Lid2];
-        RayFact r1f2 = (RayFact)_Facts[f2.Lid1];
-        RayFact r2f2 = (RayFact)_Facts[f2.Lid2];
-
-        return (r1f1.Equivalent(r1f2) && r2f1.Equivalent(r2f2));
-    }
+    protected override bool EquivalentWrapped(ParallelLineFact f1, ParallelLineFact f2) 
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -1418,9 +1353,9 @@ public class CircleFact : FactWrappedCRTP<CircleFact>
     public string Pid2;
 
     [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)_Facts[Pid1]; }
+    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
     [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)_Facts[Pid2]; }
+    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
 
     /// <summary>  radius of the circle </summary>
     public float radius;
@@ -1484,7 +1419,6 @@ protected override void RecalulateTransform()
         LocalScale = new Vector3(radius, 1, radius);
     }
 
-
     /// <summary>
     /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
     /// </summary>
@@ -1570,7 +1504,7 @@ public CircleFact(string Pid1, string Pid2, float radius, Vector3 normal, string
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "â—‹" + _Facts[Pid1].Label;
+        => "â—‹" + Point1.Label;
 
     /// <summary>
     /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -1621,7 +1555,7 @@ private MMTDeclaration generateCircleFactDeclaration(string p1URI, string p2URI,
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -1632,7 +1566,7 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point1.Label;
 
         // obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Lid2].Label;
 
@@ -1640,23 +1574,11 @@ public override GameObject instantiateDisplay(GameObject prefab, Transform trans
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => Pid1.GetHashCode() ^ Pid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
-    protected override bool EquivalentWrapped(CircleFact f1, CircleFact f2)
-    {
-        if (f1.Pid1 == f2.Pid1 && f1.normal == f2.normal && f1.radius == f2.radius)
-            return true;
-
-        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
-        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
-
-        return p1f1.Equivalent(p1f2)
-            && Math3d.IsApproximatelyEqual(f1.normal, f2.normal)
-            && Mathf.Approximately(f1.radius, f2.radius);
-    }
+    protected override bool EquivalentWrapped(CircleFact f1, CircleFact f2) 
+        => DependentFactsEquivalent(f1, f2)
+        && Math3d.IsApproximatelyEqual(f1.normal, f2.normal)
+        && f1.radius.IsApproximatelyEqual(f2.radius);
 }
 
 /// <summary>
@@ -1670,9 +1592,9 @@ public class OnCircleFact : FactWrappedCRTP<OnCircleFact>
     public string Cid;
 
     [JsonIgnore]
-    public PointFact Point { get => (PointFact)_Facts[Pid]; }
+    public PointFact Point { get => (PointFact)FactOrganizer.AllFacts[Pid]; }
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public OnCircleFact() : base()
@@ -1773,10 +1695,10 @@ public OnCircleFact(string pid, string cid, string uri, FactOrganizer organizer)
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Pid].Label + "∈" + _Facts[Cid].Label;
+        => Point.Label + "∈" + Circle.Label;
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -1787,30 +1709,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid].Label + "∈" + _Facts[this.Cid].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point.Label + "∈" + Circle.Label;
         obj.GetComponent<FactWrapper>().fact = this;
 
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => Pid.GetHashCode() ^ Cid.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(OnCircleFact c1, OnCircleFact c2)
-    {
-        if (c1.Pid == c2.Pid && c1.Cid == c2.Pid)
-            return true;
-
-        PointFact pc1 = (PointFact)_Facts[c1.Pid];
-        CircleFact cc1 = (CircleFact)_Facts[c1.Cid];
-
-        PointFact pc2 = (PointFact)_Facts[c2.Pid];
-        CircleFact cc2 = (CircleFact)_Facts[c2.Cid];
-
-        return pc1.Equivalent(pc2) && cc1.Equivalent(cc2);
-    }
+        => DependentFactsEquivalent(c1, c2);
 }
 
 /// <summary>
@@ -1825,9 +1732,9 @@ public class AngleCircleLineFact : FactWrappedCRTP<AngleCircleLineFact>
     /// @}
 
     [JsonIgnore]
-    public AbstractLineFact Ray { get => (AbstractLineFact)_Facts[Rid2]; }
+    public AbstractLineFact Ray { get => (AbstractLineFact)FactOrganizer.AllFacts[Rid2]; }
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     //TODO? deg or rad?
     [JsonIgnore]
@@ -1959,7 +1866,7 @@ public AngleCircleLineFact(string Cid1, string Rid2, float angle, string backend
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "∠" + _Facts[Cid1].Label + _Facts[Rid2].Label;
+        => "∠" + Circle.Label + Ray.Label;
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -1998,30 +1905,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Rid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Rid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(AngleCircleLineFact f1, AngleCircleLineFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1 && f1.Rid2 == f2.Rid2)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        RayFact r2f1 = (RayFact)_Facts[f1.Rid2];
-
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-        RayFact r2f2 = (RayFact)_Facts[f2.Rid2];
-
-        return (c1f1.Equivalent(c1f2) && r2f1.Equivalent(r2f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2033,7 +1925,7 @@ public class RadiusFact : FactWrappedCRTP<RadiusFact>
     public string Cid1;
 
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     /// <summary> The radius as a float </summary>
     public float rad;
@@ -2069,9 +1961,7 @@ public RadiusFact(string cid1, FactOrganizer organizer) : base(organizer)
     private void init(string cid1)
     {
         this.Cid1 = cid1;
-
-        CircleFact cf1 = _Facts[cid1] as CircleFact;
-        this.rad = cf1.radius;
+        this.rad = Circle.radius;
 
         RecalulateTransform();
 
@@ -2117,7 +2007,7 @@ public RadiusFact(string Cid1, string backendURI, FactOrganizer organizer) : bas
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "r " + _Facts[Cid1].Label;
+        => "r " + Circle.Label;
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -2143,7 +2033,7 @@ private MMTDeclaration generateMMTDeclaration(string c1URI, float rad)
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -2154,25 +2044,14 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = "r: " + _Facts[this.Cid1].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = "r: " + Circle.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(RadiusFact f1, RadiusFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1) // if they correspond to the same circle, then automatically the radius has to be the same
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-        return (c1f1.Equivalent(c1f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2184,7 +2063,7 @@ public class AreaCircleFact : FactWrappedCRTP<AreaCircleFact>
     public string Cid1;
 
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     /// <summary> the area which is contained by the circle </summary>
     public float A;
@@ -2223,8 +2102,7 @@ private void init(string cid1)
     {
         this.Cid1 = cid1;
 
-        CircleFact cf1 = _Facts[cid1] as CircleFact;
-        this.A = cf1.radius * cf1.radius * ((float)System.Math.PI);
+        this.A = Circle.radius * Circle.radius * ((float)System.Math.PI);
 
         RecalulateTransform();
 
@@ -2268,7 +2146,7 @@ public AreaCircleFact(string Cid1, string backendURI, FactOrganizer organizer) :
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "A(" + _Facts[Cid1].Label + ")";
+        => "A(" + Circle.Label + ")";
 
     /// <summary>
     /// Constructs a response, that is sent to the MMT-Server
@@ -2304,7 +2182,7 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
@@ -2312,18 +2190,11 @@ public override GameObject instantiateDisplay(GameObject prefab, Transform trans
     /// \copydoc Fact.GetHashCode
     /// is this a problem?
     public override int GetHashCode()
-        => this.Cid1.GetHashCode();
+        => base.GetHashCode() ^ A.GetHashCode();
 
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(AreaCircleFact f1, AreaCircleFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-        return (c1f1.Equivalent(c1f2) && f1.A == f2.A);
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2334,12 +2205,12 @@ public class ConeVolumeFact : FactWrappedCRTP<ConeVolumeFact>
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary>
     public string Cid1;
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     ///  <summary> a <see cref="PointFact">PointFact</see> describing the apex point  </summary>
     public string Pid1;
     [JsonIgnore]
-    public PointFact Point { get => (PointFact)_Facts[Pid1]; }
+    public PointFact Point { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
 
     ///  <summary> the volume of the cone as a float </summary>
     public float vol;
@@ -2439,7 +2310,7 @@ public ConeVolumeFact(string Cid1, string Pid1, float volume, string backendURI,
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "V(" + _Facts[Cid1].Label + "," + _Facts[Pid1].Label + ")";
+        => "V(" + Circle.Label + "," + Point.Label + ")";
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -2482,31 +2353,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label + _Facts[this.Pid1].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle.Label + Point.Label;
         obj.GetComponent<FactWrapper>().fact = this;
 
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    /// uhhh is this a problem?
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Pid1.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(ConeVolumeFact f1, ConeVolumeFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1 && f1.Pid1 == f2.Pid1)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-
-        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
-        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
-
-        return (c1f1.Equivalent(c1f2) && p1f1.Equivalent(p1f2) && (Mathf.Abs(f1.vol - f2.vol) < 0.001));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2517,12 +2372,12 @@ public class OrthogonalCircleLineFact : FactWrappedCRTP<OrthogonalCircleLineFact
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary>
     public string Cid1;
     [JsonIgnore]
-    public CircleFact Circle { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     ///  <summary> a <see cref="RayFact">Rayfact</see> describing the line </summary>
     public string Lid1;
     [JsonIgnore]
-    public AbstractLineFact Ray { get => (AbstractLineFact)_Facts[Lid1]; }
+    public AbstractLineFact Ray { get => (AbstractLineFact)FactOrganizer.AllFacts[Lid1]; }
 
     //TODO? deg or rad?
     [JsonIgnore]
@@ -2632,7 +2487,7 @@ public OrthogonalCircleLineFact(string Cid1, string Lid1, string backendURI, Fac
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Cid1].Label + "⊥" + _Facts[Lid1].Label;
+        => Circle.Label + "⊥" + Ray.Label;
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -2661,7 +2516,7 @@ private MMTDeclaration generateMMTDeclaration(string c1URI, string l1URI)
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -2672,8 +2527,8 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Lid1].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray.Label;
 
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
@@ -2686,18 +2541,7 @@ public override int GetHashCode()
 
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(OrthogonalCircleLineFact f1, OrthogonalCircleLineFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1 && f1.Lid1 == f2.Lid1)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-
-        RayFact l1f1 = (RayFact)_Facts[f1.Lid1];
-        RayFact l1f2 = (RayFact)_Facts[f2.Lid1];
-
-        return (c1f1.Equivalent(c1f2) && l1f1.Equivalent(l1f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2708,12 +2552,12 @@ public class TruncatedConeVolumeFact : FactWrappedCRTP<TruncatedConeVolumeFact>
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary>
     public string Cid1;
     [JsonIgnore]
-    public CircleFact Circle1 { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle1 { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the top area  </summary>
     public string Cid2;
     [JsonIgnore]
-    public CircleFact Circle2 { get => (CircleFact)_Facts[Cid2]; }
+    public CircleFact Circle2 { get => (CircleFact)FactOrganizer.AllFacts[Cid2]; }
 
     ///  <summary> the volume of Truncated the cone as a float </summary>
     public float vol;
@@ -2826,7 +2670,7 @@ public TruncatedConeVolumeFact(string Cid1, string Cid2, float volume, string un
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "V(" + _Facts[Cid1].Label + "," + _Facts[Cid2].Label + ")";
+        => "V(" + Circle1.Label + "," + Circle2.Label + ")";
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -2867,31 +2711,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label + _Facts[this.Cid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle1.Label + Circle2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
 
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    /// uhhh is this a problem?
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Cid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(TruncatedConeVolumeFact f1, TruncatedConeVolumeFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1 && f1.Cid2 == f2.Cid2)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-
-        CircleFact c2f1 = (CircleFact)_Facts[f1.Cid2];
-        CircleFact c2f2 = (CircleFact)_Facts[f2.Cid2];
-
-        return c1f1.Equivalent(c1f2) && c2f1.Equivalent(c2f2) && Mathf.Approximately(f1.vol, f2.vol);
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -2902,12 +2730,12 @@ public class CylinderVolumeFact : FactWrappedCRTP<CylinderVolumeFact>
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the base area </summary>
     public string Cid1;
     [JsonIgnore]
-    public CircleFact Circle1 { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle1 { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
 
     ///  <summary> a <see cref="CircleFact">CircleFact</see> describing the top area  </summary>
     public string Cid2;
     [JsonIgnore]
-    public CircleFact Circle2 { get => (CircleFact)_Facts[Cid2]; }
+    public CircleFact Circle2 { get => (CircleFact)FactOrganizer.AllFacts[Cid2]; }
 
     ///  <summary> the volume of the cylinder as a float </summary>
     public float vol;
@@ -3018,7 +2846,7 @@ public CylinderVolumeFact(string Cid1, string Cid2, float volume, string eqProof
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => "V(" + _Facts[Cid1].Label + "," + _Facts[Cid2].Label + ")";
+        => "V(" + Circle1.Label + "," + Circle2.Label + ")";
 
     /// <summary>
     /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
@@ -3048,7 +2876,7 @@ private MMTDeclaration generateMMTDeclaration(string c1URI, string c2URI, float
     }
 
     /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
+    public override bool hasDependentFacts()
         => true;
 
     /// \copydoc Fact.getDependentFactIds
@@ -3059,31 +2887,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label + _Facts[this.Cid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle1.Label + Circle2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
 
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    /// uhhh is this a problem?
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Cid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(CylinderVolumeFact f1, CylinderVolumeFact f2)
-    {
-        if (f1.Cid1 == f2.Cid1 && f1.Cid2 == f2.Cid2)
-            return true;
-
-        CircleFact c1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact c1f2 = (CircleFact)_Facts[f2.Cid1];
-
-        CircleFact c2f1 = (CircleFact)_Facts[f1.Cid2];
-        CircleFact c2f2 = (CircleFact)_Facts[f2.Cid2];
-
-        return c1f1.Equivalent(c1f2) && c2f1.Equivalent(c2f2) && Mathf.Approximately(f1.vol, f2.vol);
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -3098,9 +2910,9 @@ public class EqualCirclesFact : FactWrappedCRTP<EqualCirclesFact>
     /// @}
 
     [JsonIgnore]
-    public CircleFact Circle1 { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle1 { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
     [JsonIgnore]
-    public CircleFact Circle2 { get => (CircleFact)_Facts[Cid2]; }
+    public CircleFact Circle2 { get => (CircleFact)FactOrganizer.AllFacts[Cid2]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public EqualCirclesFact() : base()
@@ -3200,7 +3012,7 @@ public EqualCirclesFact(string Cid1, string Cid2, string backendURI, FactOrganiz
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Cid1].Label + " ≠ " + _Facts[Cid2].Label;
+        => Circle1.Label + " ≠ " + Circle2.Label;
 
     /// <summary>
     /// Constructs struct for equalCirclesFact <see cref="AddFactResponse"/>
@@ -3243,29 +3055,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Circle2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Cid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(EqualCirclesFact f1, EqualCirclesFact f2)
-    {
-        if ((f1.Cid1 == f2.Cid1 && f1.Cid2 == f2.Cid2))
-            return true;
-
-        CircleFact e1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact e2f1 = (CircleFact)_Facts[f1.Cid2];
-        CircleFact e1f2 = (CircleFact)_Facts[f2.Cid1];
-        CircleFact e2f2 = (CircleFact)_Facts[f2.Cid2];
-
-        return (e1f1.Equivalent(e1f2) && e2f1.Equivalent(e2f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 /// <summary>
@@ -3280,9 +3078,9 @@ public class UnEqualCirclesFact : FactWrappedCRTP<UnEqualCirclesFact>
     /// @}
 
     [JsonIgnore]
-    public CircleFact Circle1 { get => (CircleFact)_Facts[Cid1]; }
+    public CircleFact Circle1 { get => (CircleFact)FactOrganizer.AllFacts[Cid1]; }
     [JsonIgnore]
-    public CircleFact Circle2 { get => (CircleFact)_Facts[Cid2]; }
+    public CircleFact Circle2 { get => (CircleFact)FactOrganizer.AllFacts[Cid2]; }
 
     /// <summary> \copydoc Fact.Fact </summary>
     public UnEqualCirclesFact() : base()
@@ -3382,7 +3180,7 @@ public UnEqualCirclesFact(string Cid1, string Cid2, string backendURI, FactOrgan
 
     /// \copydoc Fact.generateLabel
     protected override string generateLabel()
-        => _Facts[Cid1].Label + " = " + _Facts[Cid2].Label;
+        => Circle1.Label + " = " + Circle2.Label;
 
     /// <summary>
     /// Constructs struct for equalCirclesFact <see cref="AddFactResponse"/>
@@ -3420,29 +3218,15 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Cid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Circle1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Circle2.Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
 
-    /// \copydoc Fact.GetHashCode
-    public override int GetHashCode()
-        => this.Cid1.GetHashCode() ^ this.Cid2.GetHashCode();
-
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(UnEqualCirclesFact f1, UnEqualCirclesFact f2)
-    {
-        if ((f1.Cid1 == f2.Cid1 && f1.Cid2 == f2.Cid2))
-            return true;
-
-        CircleFact e1f1 = (CircleFact)_Facts[f1.Cid1];
-        CircleFact e2f1 = (CircleFact)_Facts[f1.Cid2];
-        CircleFact e1f2 = (CircleFact)_Facts[f2.Cid1];
-        CircleFact e2f2 = (CircleFact)_Facts[f2.Cid2];
-
-        return (e1f1.Equivalent(e1f2) && e2f1.Equivalent(e2f2));
-    }
+        => DependentFactsEquivalent(f1, f2);
 }
 
 
@@ -3550,8 +3334,8 @@ protected override string generateLabel()
     /// <returns>struct for <see cref="AddFactResponse"/></returns>
     private MMTDeclaration generateCircleFactDeclaration(string p1URI, string p2URI, float radius, Vector3 normal)
     {
-        PointFact p1 = _Facts[p1URI] as PointFact;
-        PointFact p2 = _Facts[p2URI] as PointFact;
+        PointFact p1 = FactOrganizer.AllFacts[p1URI] as PointFact;
+        PointFact p2 = FactOrganizer.AllFacts[p2URI] as PointFact;
 
 
         List<SOMDoc> normalArgs = new List<SOMDoc>
@@ -3622,13 +3406,13 @@ public override GameObject instantiateDisplay(GameObject prefab, Transform trans
     /// \copydoc Fact.GetHashCode
     public override int GetHashCode()
     {
-        return 112315414;// this.Pid1.GetHashCode() ^ this.Pid2.GetHashCode();
+        return base.GetHashCode();// this.Pid1.GetHashCode() ^ this.Pid2.GetHashCode();
     }
 
     /// \copydoc Fact.Equivalent(Fact, Fact)
     protected override bool EquivalentWrapped(TestFact f1, TestFact f2)
     {
-        return false;
+        return DependentFactsEquivalent(f1, f2);
     }
 }
 
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
index e1c2e52d599ae103578397fd9a611762dc4bf09d..43dfab4c45f76e0b5137dbfba9b91bf14984c358 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/FunctionFact.cs
@@ -195,7 +195,8 @@ public FunctionFactFloat(SOMDoc Function_MMT, (float, float) domain, string uri,
 
     /// \copydoc Fact.EquivalentWrapped
     protected override bool EquivalentWrapped(FunctionFactFloat<TResult> f1, FunctionFactFloat<TResult> f2)
-        => f1.Domain.t_0.IsApproximatelyEqual(f2.Domain.t_0)
+        => f1.Function_SOMDoc.Equivalent(f2.Function_SOMDoc)
+        && f1.Domain.t_0.IsApproximatelyEqual(f2.Domain.t_0)
         && f1.Domain.t_n.IsApproximatelyEqual(f2.Domain.t_n);
 }
 
@@ -206,10 +207,10 @@ public class AttachedPositionFunction : FactWrappedCRTP<AttachedPositionFunction
     public string[] funcids;
 
     [JsonIgnore]
-    public Fact Fact { get => _Facts[fid]; }
+    public Fact Fact { get => FactOrganizer.AllFacts[fid]; }
     [JsonIgnore]
     public FunctionFact<float, Vector3>[] FunctionFacts { 
-        get => funcids.Select(f => _Facts[f] as FunctionFact<float, Vector3>).ToArray(); 
+        get => funcids.Select(f => FactOrganizer.AllFacts[f] as FunctionFact<float, Vector3>).ToArray(); 
     }
 
     /// <summary>\copydoc Fact.Fact()</summary>
@@ -287,11 +288,7 @@ public override GameObject instantiateDisplay(GameObject prefab, Transform trans
     }
 
     protected override bool EquivalentWrapped(AttachedPositionFunction f1, AttachedPositionFunction f2)
-        => f1.Fact.Equivalent(f2.Fact)
-        && f1.FunctionFacts.Zip(
-                f2.FunctionFacts, 
-                (ff1, ff2) => ff1.Equivalent(ff2)
-            ).All(b => b);
+        => DependentFactsEquivalent(f1, f2);
 
     protected override void RecalulateTransform()
     {
diff --git a/Assets/Scripts/InteractionEngine/TBD/AttachedPositionFunctionBehaviour.cs b/Assets/Scripts/InteractionEngine/TBD/AttachedPositionFunctionBehaviour.cs
index 8769339a196286ca21f4d6540d75b4b27ca8d3ce..3a4b3f78dd063f19028556c540511bedae6b35af 100644
--- a/Assets/Scripts/InteractionEngine/TBD/AttachedPositionFunctionBehaviour.cs
+++ b/Assets/Scripts/InteractionEngine/TBD/AttachedPositionFunctionBehaviour.cs
@@ -48,8 +48,10 @@ public void NewExecutingInstance()
     {
         if (!original)
             return;
-        
-        var cloneComp = GameObject.Instantiate(gameObject).GetComponent<AttachedPositionFunctionBehaviour>();
+
+        AttachedPositionFunctionBehaviour cloneComp = 
+            GameObject.Instantiate(gameObject, gameObject.transform)
+            .GetComponent<AttachedPositionFunctionBehaviour>();
         cloneComp.Start();
         cloneComp.original = false;
         cloneComp.StartExecution();