added Set.size;
authorwenzelm
Mon, 27 Mar 2023 22:11:26 +0200
changeset 77725 96a594e5e054
parent 77724 b4032c468d74
child 77726 6ae930c89143
added Set.size; tuned Set.merge: keep larger set stable;
src/Pure/General/set.ML
--- a/src/Pure/General/set.ML	Mon Mar 27 21:53:16 2023 +0200
+++ b/src/Pure/General/set.ML	Mon Mar 27 22:11:26 2023 +0200
@@ -8,6 +8,7 @@
 sig
   type elem
   type T
+  val size: T -> int
   val empty: T
   val build: (T -> T) -> T
   val is_empty: T -> bool
@@ -37,6 +38,19 @@
   Branch3 of T * elem * T * elem * T;
 
 
+(* size *)
+
+local
+  fun add_size Empty n = n
+    | add_size (Branch2 (left, _, right)) n =
+        n + 1 |> add_size left |> add_size right
+    | add_size (Branch3 (left, _, mid, _, right)) n =
+        n + 2 |> add_size left |> add_size mid |> add_size right;
+in
+  fun size set = add_size set 0;
+end;
+
+
 (* empty and single *)
 
 val empty = Empty;
@@ -162,7 +176,10 @@
 fun merge (set1, set2) =
   if pointer_eq (set1, set2) then set1
   else if is_empty set1 then set2
-  else fold_set insert set2 set1;
+  else if is_empty set2 then set1
+  else if size set1 >= size set2
+  then fold_set insert set2 set1
+  else fold_set insert set1 set2;
 
 
 (* remove *)