model/model_viz: use OrderedTree[MConcern]
[nit.git] / lib / poset.nit
index a5425dd..3288e5c 100644 (file)
@@ -71,7 +71,7 @@ module poset
 #
 # Thanks to the `[]` method, elements can be considered relatively to the poset.
 # SEE `POSetElement`
-class POSet[E: Object]
+class POSet[E]
        super Collection[E]
        super Comparator
 
@@ -149,20 +149,37 @@ class POSet[E: Object]
                # Update the transitive reduction
                if te.tos.has(f) then return # Skip the reduction if there is a loop
 
-               for x in te.dfroms.to_a do
+               # Remove transitive edges.
+               # Because the sets of direct is iterated, the list of edges to remove
+               # is stored and is applied after the iteration.
+               # The usual case is that no direct edges need to be removed,
+               # so start with a `null` list of edges.
+               var to_remove: nullable Array[E] = null
+               for x in te.dfroms do
                        var xe = self.elements[x]
                        if xe.tos.has(f) then
-                               te.dfroms.remove(x)
+                               if to_remove == null then to_remove = new Array[E]
+                               to_remove.add x
                                xe.dtos.remove(t)
                        end
                end
-               for x in fe.dtos.to_a do
+               if to_remove != null then
+                       for x in to_remove do te.dfroms.remove(x)
+                       to_remove.clear
+               end
+
+               for x in fe.dtos do
                        var xe = self.elements[x]
                        if xe.froms.has(t) then
                                xe.dfroms.remove(f)
-                               fe.dtos.remove(x)
+                               if to_remove == null then to_remove = new Array[E]
+                               to_remove.add x
                        end
                end
+               if to_remove != null then
+                       for x in to_remove do fe.dtos.remove(x)
+               end
+
                fe.dtos.add t
                te.dfroms.add f
        end
@@ -228,7 +245,7 @@ class POSet[E: Object]
        #
        # Nodes are labeled with their `to_s` so homonymous nodes may appear.
        # Edges are unlabeled.
-       fun write_dot(f: OStream)
+       fun write_dot(f: Writer)
        do
                f.write "digraph \{\n"
                var ids = new HashMap[E, Int]
@@ -258,7 +275,7 @@ class POSet[E: Object]
        # See `write_dot` for details.
        fun show_dot
        do
-               var f = new OProcess("dot", "-Txlib")
+               var f = new ProcessWriter("dot", "-Txlib")
                write_dot(f)
                f.close
                f.wait
@@ -379,7 +396,7 @@ end
 # # ...
 # t.in_some_relation.greaters
 # ~~~
-class POSetElement[E: Object]
+class POSetElement[E]
        # The poset self belong to
        var poset: POSet[E]