| 
16464
 | 
     1  | 
(*  Title:      Pure/General/ord_list.ML
  | 
| 
 | 
     2  | 
    Author:     Makarius
  | 
| 
 | 
     3  | 
  | 
| 
 | 
     4  | 
Ordered lists without duplicates -- a light-weight representation of
  | 
| 
16497
 | 
     5  | 
finite sets, all operations take linear time and economize heap usage.
  | 
| 
16464
 | 
     6  | 
*)
  | 
| 
 | 
     7  | 
  | 
| 
 | 
     8  | 
signature ORD_LIST =
  | 
| 
 | 
     9  | 
sig
  | 
| 
28354
 | 
    10  | 
  type 'a T = 'a list
  | 
| 
28626
 | 
    11  | 
  val make: ('a * 'a -> order) -> 'a list -> 'a T
 | 
| 
28354
 | 
    12  | 
  val member: ('b * 'a -> order) -> 'a T -> 'b -> bool
 | 
| 
 | 
    13  | 
  val insert: ('a * 'a -> order) -> 'a -> 'a T -> 'a T
 | 
| 
 | 
    14  | 
  val remove: ('b * 'a -> order) -> 'b -> 'a T -> 'a T
 | 
| 
 | 
    15  | 
  val subset: ('b * 'a -> order) -> 'b T * 'a T -> bool
 | 
| 
 | 
    16  | 
  val union: ('a * 'a -> order) -> 'a T -> 'a T -> 'a T
 | 
| 
 | 
    17  | 
  val inter: ('b * 'a -> order) -> 'b T -> 'a T -> 'a T
 | 
| 
 | 
    18  | 
  val subtract: ('b * 'a -> order) -> 'b T -> 'a T -> 'a T
 | 
| 
16464
 | 
    19  | 
end;
  | 
| 
 | 
    20  | 
  | 
| 
 | 
    21  | 
structure OrdList: ORD_LIST =
  | 
| 
 | 
    22  | 
struct
  | 
| 
 | 
    23  | 
  | 
| 
28354
 | 
    24  | 
type 'a T = 'a list;
  | 
| 
28626
 | 
    25  | 
fun make ord = sort_distinct ord;
  | 
| 
28354
 | 
    26  | 
  | 
| 
16511
 | 
    27  | 
  | 
| 
 | 
    28  | 
(* single elements *)
  | 
| 
 | 
    29  | 
  | 
| 
 | 
    30  | 
fun find_index ord list x =
  | 
| 
 | 
    31  | 
  let
  | 
| 
16811
 | 
    32  | 
    fun find i [] = ~ i
  | 
| 
16511
 | 
    33  | 
      | find i (y :: ys) =
  | 
| 
 | 
    34  | 
          (case ord (x, y) of
  | 
| 
16811
 | 
    35  | 
            LESS => ~ i
  | 
| 
16511
 | 
    36  | 
          | EQUAL => i
  | 
| 
 | 
    37  | 
          | GREATER => find (i + 1) ys);
  | 
| 
16811
 | 
    38  | 
  in find 1 list end;
  | 
| 
16497
 | 
    39  | 
  | 
| 
16811
 | 
    40  | 
fun member ord list x = find_index ord list x > 0;
  | 
| 
16464
 | 
    41  | 
  | 
| 
 | 
    42  | 
fun insert ord x list =
  | 
| 
 | 
    43  | 
  let
  | 
| 
16811
 | 
    44  | 
    fun insrt 1 ys = x :: ys
  | 
| 
16511
 | 
    45  | 
      | insrt i (y :: ys) = y :: insrt (i - 1) ys;
  | 
| 
16811
 | 
    46  | 
    val idx = find_index ord list x;
  | 
| 
 | 
    47  | 
  in if idx > 0 then list else insrt (~ idx) list end;
  | 
| 
16464
 | 
    48  | 
  | 
| 
 | 
    49  | 
fun remove ord x list =
  | 
| 
 | 
    50  | 
  let
  | 
| 
16811
 | 
    51  | 
    fun rmove 1 (_ :: ys) = ys
  | 
| 
16511
 | 
    52  | 
      | rmove i (y :: ys) = y :: rmove (i - 1) ys;
  | 
| 
16811
 | 
    53  | 
    val idx = find_index ord list x;
  | 
| 
 | 
    54  | 
  in if idx > 0 then rmove idx list else list end;
  | 
| 
16511
 | 
    55  | 
  | 
| 
 | 
    56  | 
  | 
| 
 | 
    57  | 
(* lists as sets *)
  | 
| 
 | 
    58  | 
  | 
| 
 | 
    59  | 
nonfix subset;
  | 
| 
 | 
    60  | 
fun subset ord (list1, list2) =
  | 
| 
 | 
    61  | 
  let
  | 
| 
 | 
    62  | 
    fun sub [] _ = true
  | 
| 
 | 
    63  | 
      | sub _ [] = false
  | 
| 
 | 
    64  | 
      | sub (lst1 as x :: xs) (y :: ys) =
  | 
| 
16464
 | 
    65  | 
          (case ord (x, y) of
  | 
| 
16511
 | 
    66  | 
            LESS => false
  | 
| 
 | 
    67  | 
          | EQUAL => sub xs ys
  | 
| 
 | 
    68  | 
          | GREATER => sub lst1 ys);
  | 
| 
 | 
    69  | 
  in sub list1 list2 end;
  | 
| 
 | 
    70  | 
  | 
| 
 | 
    71  | 
  | 
| 
 | 
    72  | 
(* algebraic operations *)
  | 
| 
 | 
    73  | 
  | 
| 
 | 
    74  | 
exception SAME;
  | 
| 
 | 
    75  | 
fun handle_same f x = f x handle SAME => x;
  | 
| 
16464
 | 
    76  | 
  | 
| 
16497
 | 
    77  | 
(*union: insert elements of first list into second list*)
  | 
| 
16464
 | 
    78  | 
nonfix union;
  | 
| 
16497
 | 
    79  | 
fun union ord list1 list2 =
  | 
| 
 | 
    80  | 
  let
  | 
| 
 | 
    81  | 
    fun unio [] _ = raise SAME
  | 
| 
 | 
    82  | 
      | unio xs [] = xs
  | 
| 
 | 
    83  | 
      | unio (lst1 as x :: xs) (lst2 as y :: ys) =
  | 
| 
 | 
    84  | 
          (case ord (x, y) of
  | 
| 
 | 
    85  | 
            LESS => x :: handle_same (unio xs) lst2
  | 
| 
 | 
    86  | 
          | EQUAL => y :: unio xs ys
  | 
| 
 | 
    87  | 
          | GREATER => y :: unio lst1 ys);
  | 
| 
16886
 | 
    88  | 
  in handle_same (unio list1) list2 end;
  | 
| 
16464
 | 
    89  | 
  | 
| 
16497
 | 
    90  | 
(*intersection: filter second list for elements present in first list*)
  | 
| 
16464
 | 
    91  | 
nonfix inter;
  | 
| 
16497
 | 
    92  | 
fun inter ord list1 list2 =
  | 
| 
 | 
    93  | 
  let
  | 
| 
 | 
    94  | 
    fun intr _ [] = raise SAME
  | 
| 
 | 
    95  | 
      | intr [] _ = []
  | 
| 
 | 
    96  | 
      | intr (lst1 as x :: xs) (lst2 as y :: ys) =
  | 
| 
 | 
    97  | 
          (case ord (x, y) of
  | 
| 
 | 
    98  | 
            LESS => intr xs lst2
  | 
| 
 | 
    99  | 
          | EQUAL => y :: intr xs ys
  | 
| 
 | 
   100  | 
          | GREATER => handle_same (intr lst1) ys);
  | 
| 
 | 
   101  | 
  in handle_same (intr list1) list2 end;
  | 
| 
 | 
   102  | 
  | 
| 
 | 
   103  | 
(*subtraction: filter second list for elements NOT present in first list*)
  | 
| 
 | 
   104  | 
fun subtract ord list1 list2 =
  | 
| 
 | 
   105  | 
  let
  | 
| 
 | 
   106  | 
    fun subtr [] _ = raise SAME
  | 
| 
 | 
   107  | 
      | subtr _ [] = raise SAME
  | 
| 
 | 
   108  | 
      | subtr (lst1 as x :: xs) (lst2 as y :: ys) =
  | 
| 
 | 
   109  | 
          (case ord (x, y) of
  | 
| 
 | 
   110  | 
            LESS => subtr xs lst2
  | 
| 
 | 
   111  | 
          | EQUAL => handle_same (subtr xs) ys
  | 
| 
 | 
   112  | 
          | GREATER => y :: subtr lst1 ys);
  | 
| 
 | 
   113  | 
  in handle_same (subtr list1) list2 end;
  | 
| 
16464
 | 
   114  | 
  | 
| 
 | 
   115  | 
end;
  |