File: regset.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (130 lines) | stat: -rw-r--r-- 3,422 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
(*
 * Register set datatype. Implemented as sorted lists.
 *
 * -- Allen
 *) 

structure RegSet :> REGISTER_SET =
struct

   type reg = int

   type regset = reg list

   val empty = [] 

   fun sort [] = []
     | sort (l as [_]) = l
     | sort (l as [x,y]) = if Int.<(x,y) then l else 
                           if x = y then [x] else [y,x]
     | sort l =
       let val (a,b) = split (l,[],[])
       in  mergeUniq(sort a, sort b)
       end

   and split ([],a,b)    = (a,b)
     | split (r::rs,a,b) = split(rs,r::b,a)

   and mergeUniq(l as u::us, l' as v::vs) =
         if u = v then mergeUniq(l,vs)
         else if Int.<(u,v) then u::mergeUniq(us,l')
         else v::mergeUniq(l,vs)
     | mergeUniq(l,[]) = l
     | mergeUniq([],l) = l

   fun union []      = []
     | union (r::rs) = mergeUniq(r,union rs)

   fun difference ([],_) = []
     | difference (set,[]) = set
     | difference (set as r::rs,set' as r'::rs') =
        if r = r' then difference(rs,set')
        else if r < r' then r::difference(rs,set')
        else (* r > r' *) difference(set,rs')

   fun intersect (set,[]) = []
     | intersect ([],set) = []
     | intersect (set as r::rs,set' as r'::rs') =
         if r = r' then r::intersect(rs,rs')
         else if r < r' then intersect(rs,set')
         else intersect(set,rs')

   fun intersects []  = []
     | intersects [a] = a
     | intersects (a::b) = intersect(a,intersects b)
   
   fun ==([],[]) = true
     | ==(r::rs,r'::rs') = (r : int) = r' andalso ==(rs,rs')
     | ==(_,_)   = false

   fun isEmpty [] = true
     | isEmpty _  = false

   val app = List.app

   fun contains ([], r)    = false
     | contains (r'::rs,r) = r' = r orelse (r > r' andalso contains(rs,r))

   fun exists (set, [])    = false
     | exists (set, r::rs) = contains(set,r) orelse exists(set,rs)

   fun insert([],r) = [r]
     | insert(set as r'::rs,r) =
         if r = r' then set
         else if r' < r then r'::insert(rs,r)
         else r::set

   fun insertChanged (set,r) = 
   let fun ins [] = ([r],true)
         | ins (set as r'::rs) =
             if r = r' then (set,false)
             else if r > r' then
                let val (rs,changed) = ins rs
                in  if changed then (r'::rs,true)
                               else (set,false)
                end
             else (r::set,true)
   in  ins set
   end

   fun remove ([],r) = []
     | remove (set as r'::rs,r) =
         if r' = r then rs
         else if r' < r then r'::remove(rs,r)
         else set
     
   fun removeChanged (set,r) =
   let fun rmv [] = ([],false)
         | rmv (set as r'::rs) =
              if r = r' then (rs,true)
              else if r > r' then
                   let val (rs,changed) = rmv rs
                   in  if changed then (r'::rs,true)
                                  else (set,false)
                   end
              else (set,false)
   in
       rmv set
   end

   fun fromList l       = sort l
   fun fromSortedList l = l
   fun toList set       = set

   fun toString set =
   let fun collect([],l) = l
         | collect(r::rs,l) = Int.toString r::collect'(rs,l)
       and collect'(rs,l) = 
           let val l = collect(rs,l)
           in  case l of [_] => l 
                       | l  => ","::l
           end
   in  String.concat("{"::collect(set,["}"]))
   end

   val op + = mergeUniq
   val op - = difference
   val op * = intersect

end