├── AUTHORS ├── CONTRIBUTORS ├── LICENSE ├── Makefile ├── README.md ├── all_test.go ├── class_string.go ├── gen.go ├── gen_test.go └── interval.go /AUTHORS: -------------------------------------------------------------------------------- 1 | # This file lists authors for copyright purposes. This file is distinct from 2 | # the CONTRIBUTORS files. See the latter for an explanation. 3 | # 4 | # Names should be added to this file as: 5 | # Name or Organization 6 | # 7 | # The email address is not required for organizations. 8 | # 9 | # Please keep the list sorted. 10 | 11 | Jan Mercl <0xjnml@gmail.com> 12 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file lists people who contributed code to this repository. The AUTHORS 2 | # file lists the copyright holders; this file lists people. 3 | # 4 | # Names should be added to this file like so: 5 | # Name 6 | # 7 | # Please keep the list sorted. 8 | 9 | Jan Mercl <0xjnml@gmail.com> 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Interval Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the names of the authors nor the names of the 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Interval Authors. All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | .PHONY: all clean cover cpu editor internalError later mem nuke todo 6 | 7 | grep=--include=*.go --include=*.l --include=*.y 8 | 9 | all: editor 10 | go vet || true 11 | golint || true 12 | make todo 13 | 14 | class_string.go: interval.go 15 | stringer -type Class 16 | 17 | clean: 18 | go clean 19 | rm -f *~ cpu.test mem.test 20 | 21 | cover: 22 | t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t 23 | 24 | cpu: 25 | go test -c -o cpu.test 26 | ./cpu.test -noerr -test.cpuprofile cpu.out 27 | go tool pprof --lines cpu.test cpu.out 28 | 29 | edit: 30 | @ 1>/dev/null 2>/dev/null gvim -p Makefile *.go 31 | 32 | editor: class_string.go gen.go 33 | gofmt -l -s -w *.go 34 | go test 35 | go install 36 | 37 | gen.go: gen_test.go class_string.go interval.go 38 | go generate 39 | 40 | internalError: 41 | egrep -ho '"internal error.*"' *.go | sort | cat -n 42 | 43 | later: 44 | @grep -n $(grep) LATER * || true 45 | @grep -n $(grep) MAYBE * || true 46 | 47 | mem: 48 | go test -c -o mem.test 49 | ./mem.test -test.bench . -test.memprofile mem.out 50 | go tool pprof --lines --web --alloc_space mem.test mem.out 51 | 52 | nuke: clean 53 | go clean -i 54 | rm -f gen.go class_string.go 55 | 56 | todo: 57 | @grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * || true 58 | @grep -nr $(grep) TODO * || true 59 | @grep -nr $(grep) BUG * || true 60 | @grep -nr $(grep) [^[:alpha:]]println * || true 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `github.com/cznic/interval` has moved to [`modernc.org/interval`](https://godoc.org/modernc.org/interval) ([vcs](https://gitlab.com/cznic/interval)). 2 | 3 | Please update your import paths to `modernc.org/interval`. 4 | 5 | This repo is now archived. 6 | -------------------------------------------------------------------------------- /all_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The Interval Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package interval 6 | 7 | import ( 8 | "fmt" 9 | "math/big" 10 | "os" 11 | "path" 12 | "runtime" 13 | "strings" 14 | "testing" 15 | "time" 16 | 17 | "github.com/cznic/mathutil" 18 | ) 19 | 20 | func caller(s string, va ...interface{}) { 21 | _, fn, fl, _ := runtime.Caller(2) 22 | fmt.Fprintf(os.Stderr, "caller: %s:%d: ", path.Base(fn), fl) 23 | fmt.Fprintf(os.Stderr, s, va...) 24 | fmt.Fprintln(os.Stderr) 25 | _, fn, fl, _ = runtime.Caller(1) 26 | fmt.Fprintf(os.Stderr, "\tcallee: %s:%d: ", path.Base(fn), fl) 27 | fmt.Fprintln(os.Stderr) 28 | } 29 | 30 | func dbg(s string, va ...interface{}) { 31 | if s == "" { 32 | s = strings.Repeat("%v ", len(va)) 33 | } 34 | _, fn, fl, _ := runtime.Caller(1) 35 | fmt.Fprintf(os.Stderr, "dbg %s:%d: ", path.Base(fn), fl) 36 | fmt.Fprintf(os.Stderr, s, va...) 37 | fmt.Fprintln(os.Stderr) 38 | } 39 | 40 | func TODO(...interface{}) string { 41 | _, fn, fl, _ := runtime.Caller(1) 42 | return fmt.Sprintf("TODO: %s:%d:\n", path.Base(fn), fl) 43 | } 44 | 45 | func use(...interface{}) {} 46 | 47 | // ============================================================================ 48 | 49 | var int128 mathutil.Int128 50 | 51 | func TestIntersection(t *testing.T) { 52 | i := 0 53 | for xa := negInf; xa <= posInf; xa += 10 { 54 | for xb := xa + 10; xb <= posInf; xb += 10 { 55 | for _, xc := range classes { 56 | if (xa < negInf+10 || xb > posInf-10) && xc != Unbounded { 57 | continue 58 | } 59 | 60 | for ya := negInf; ya <= posInf; ya += 10 { 61 | for yb := ya + 10; yb <= posInf; yb += 10 { 62 | for _, yc := range classes { 63 | if (ya < negInf+10 || yb > posInf-10) && yc != Unbounded { 64 | continue 65 | } 66 | 67 | i++ 68 | x := &interval{xc, xa, xb} 69 | y := &interval{yc, ya, yb} 70 | m := map[int]bool{} 71 | for n := negInf; n <= posInf; n += 5 { 72 | if x.has(n) && y.has(n) { 73 | m[n] = true 74 | } 75 | } 76 | result := Intersection(x, y).(*interval) 77 | for n := negInf; n <= posInf; n += 5 { 78 | if g, e := result.has(n), m[n]; g != e { 79 | t.Log(hash(x, y)) 80 | t.Log(result) 81 | for n := negInf; n <= posInf; n += 5 { 82 | t.Log(n, x.has(n), y.has(n), result.has(n), m[n]) 83 | } 84 | t.Fatalf("%v, %d: %v %v %v %v", i, n, x, y, g, e) 85 | } 86 | } 87 | x2 := &Int{xc, xa, xb} 88 | y2 := &Int{yc, ya, yb} 89 | result2 := Intersection(x2, y2).(*Int) 90 | if g, e := result.String(), result2.String(); g != e { 91 | t.Fatal(x, y, g, e) 92 | } 93 | } 94 | } 95 | } 96 | } 97 | } 98 | } 99 | t.Log(i) 100 | } 101 | 102 | func TestUnion(t *testing.T) { 103 | i := 0 104 | for xa := negInf; xa <= posInf; xa += 10 { 105 | for xb := xa + 10; xb <= posInf; xb += 10 { 106 | for _, xc := range classes { 107 | if (xa < negInf+10 || xb > posInf-10) && xc != Unbounded { 108 | continue 109 | } 110 | 111 | x := &interval{xc, xa, xb} 112 | for ya := negInf; ya <= posInf; ya += 10 { 113 | for yb := ya + 10; yb <= posInf; yb += 10 { 114 | for _, yc := range classes { 115 | if (ya < negInf+10 || yb > posInf-10) && yc != Unbounded { 116 | continue 117 | } 118 | 119 | i++ 120 | y := &interval{yc, ya, yb} 121 | m := map[int]bool{} 122 | for n := negInf; n <= posInf; n += 5 { 123 | if x.has(n) || y.has(n) { 124 | m[n] = true 125 | } 126 | } 127 | result0 := Union(x, y) 128 | if result0 == nil { 129 | if g, e := true, isDisjointUnion(x, y); g != e { 130 | t.Fatal(i, x, y, g, e) 131 | } 132 | 133 | continue 134 | } 135 | 136 | result := result0.(*interval) 137 | for n := negInf; n <= posInf; n += 5 { 138 | if g, e := result.has(n), m[n]; g != e { 139 | t.Log(hash(x, y)) 140 | t.Log(result) 141 | for n := negInf; n <= posInf; n += 5 { 142 | t.Log(n, x.has(n), y.has(n), result.has(n), m[n]) 143 | } 144 | t.Fatalf("%v, %d: %v %v %v %v", i, n, x, y, g, e) 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | } 152 | } 153 | t.Log(i) 154 | } 155 | 156 | func isDisjointUnion(x, y *interval) bool { 157 | const ( 158 | initial = iota 159 | in 160 | after 161 | ) 162 | var state int 163 | for n := negInf; n <= posInf; n += 5 { 164 | if x.has(n) || y.has(n) { 165 | switch state { 166 | case initial: 167 | state = in 168 | case in: 169 | // nop 170 | case after: 171 | return true 172 | } 173 | 174 | continue 175 | } 176 | 177 | switch state { 178 | case initial: 179 | // nop 180 | case in: 181 | state = after 182 | case after: 183 | // nop 184 | } 185 | 186 | } 187 | return false 188 | } 189 | 190 | func ExampleBigInt() { 191 | x := &BigInt{LeftOpen, big.NewInt(1), big.NewInt(2)} 192 | y := &BigInt{LeftClosed, big.NewInt(2), big.NewInt(3)} 193 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 194 | // Output: 195 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 196 | } 197 | 198 | func ExampleBigRat() { 199 | x := &BigRat{LeftOpen, big.NewRat(1, 1), big.NewRat(2, 1)} 200 | y := &BigRat{LeftClosed, big.NewRat(2, 1), big.NewRat(3, 1)} 201 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 202 | // Output: 203 | // x (1/1, 2/1], y [2/1, 3/1): x ∩ y {2/1}, x ∪ y (1/1, 3/1) 204 | } 205 | 206 | func ExampleByte() { 207 | x := &Byte{LeftOpen, 1, 2} 208 | y := &Byte{LeftClosed, 2, 3} 209 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 210 | // Output: 211 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 212 | } 213 | 214 | func ExampleDuration() { 215 | x := &Duration{LeftOpen, 1, 2} 216 | y := &Duration{LeftClosed, 2, 3} 217 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 218 | // Output: 219 | // x (1ns, 2ns], y [2ns, 3ns): x ∩ y {2ns}, x ∪ y (1ns, 3ns) 220 | } 221 | 222 | func ExampleFloat32() { 223 | x := &Float32{LeftOpen, 1, 2} 224 | y := &Float32{LeftClosed, 2, 3} 225 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 226 | // Output: 227 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 228 | } 229 | 230 | func ExampleFloat64() { 231 | x := &Float32{LeftOpen, 1, 2} 232 | y := &Float32{LeftClosed, 2, 3} 233 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 234 | // Output: 235 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 236 | } 237 | 238 | func ExampleInt() { 239 | x := &Int{LeftOpen, 1, 2} 240 | y := &Int{LeftClosed, 2, 3} 241 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 242 | // Output: 243 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 244 | } 245 | 246 | func ExampleInt8() { 247 | x := &Int8{LeftOpen, 1, 2} 248 | y := &Int8{LeftClosed, 2, 3} 249 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 250 | // Output: 251 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 252 | } 253 | 254 | func ExampleInt16() { 255 | x := &Int16{LeftOpen, 1, 2} 256 | y := &Int16{LeftClosed, 2, 3} 257 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 258 | // Output: 259 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 260 | } 261 | 262 | func ExampleInt32() { 263 | x := &Int32{LeftOpen, 1, 2} 264 | y := &Int32{LeftClosed, 2, 3} 265 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 266 | // Output: 267 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 268 | } 269 | 270 | func ExampleInt64() { 271 | x := &Int64{LeftOpen, 1, 2} 272 | y := &Int64{LeftClosed, 2, 3} 273 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 274 | // Output: 275 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 276 | } 277 | 278 | func ExampleInt128() { 279 | x := &Int128{LeftOpen, int128.SetInt64(1), int128.SetInt64(2)} 280 | y := &Int128{LeftClosed, int128.SetInt64(2), int128.SetInt64(3)} 281 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 282 | // Output: 283 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 284 | } 285 | 286 | func ExampleUint() { 287 | x := &Uint{LeftOpen, 1, 2} 288 | y := &Uint{LeftClosed, 2, 3} 289 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 290 | // Output: 291 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 292 | } 293 | 294 | func ExampleUint16() { 295 | x := &Uint16{LeftOpen, 1, 2} 296 | y := &Uint16{LeftClosed, 2, 3} 297 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 298 | // Output: 299 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 300 | } 301 | 302 | func ExampleUint32() { 303 | x := &Uint32{LeftOpen, 1, 2} 304 | y := &Uint32{LeftClosed, 2, 3} 305 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 306 | // Output: 307 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 308 | } 309 | 310 | func ExampleUint64() { 311 | x := &Uint64{LeftOpen, 1, 2} 312 | y := &Uint64{LeftClosed, 2, 3} 313 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 314 | // Output: 315 | // x (1, 2], y [2, 3): x ∩ y {2}, x ∪ y (1, 3) 316 | } 317 | 318 | func ExampleString() { 319 | x := &String{LeftOpen, "aqua", "bar"} 320 | y := &String{LeftClosed, "bar", "closed"} 321 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 322 | // Output: 323 | // x (aqua, bar], y [bar, closed): x ∩ y {bar}, x ∪ y (aqua, closed) 324 | } 325 | 326 | func ExampleTime() { 327 | x := &Time{LeftOpen, time.Unix(1, 0), time.Unix(2, 0)} 328 | y := &Time{LeftClosed, time.Unix(2, 0), time.Unix(3, 0)} 329 | fmt.Printf("x %v, y %v: x ∩ y %v, x ∪ y %v", x, y, Intersection(x, y), Union(x, y)) 330 | // Output: 331 | // x (1970-01-01 01:00:01 +0100 CET, 1970-01-01 01:00:02 +0100 CET], y [1970-01-01 01:00:02 +0100 CET, 1970-01-01 01:00:03 +0100 CET): x ∩ y {1970-01-01 01:00:02 +0100 CET}, x ∪ y (1970-01-01 01:00:01 +0100 CET, 1970-01-01 01:00:03 +0100 CET) 332 | } 333 | -------------------------------------------------------------------------------- /class_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type Class"; DO NOT EDIT. 2 | 3 | package interval 4 | 5 | import "fmt" 6 | 7 | const _Class_name = "UnboundedEmptyDegenerateOpenClosedLeftOpenLeftClosedLeftBoundedOpenLeftBoundedClosedRightBoundedOpenRightBoundedClosednClasses" 8 | 9 | var _Class_index = [...]uint8{0, 9, 14, 24, 28, 34, 42, 52, 67, 84, 100, 118, 126} 10 | 11 | func (i Class) String() string { 12 | if i < 0 || i >= Class(len(_Class_index)-1) { 13 | return fmt.Sprintf("Class(%d)", i) 14 | } 15 | return _Class_name[_Class_index[i]:_Class_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /gen.go: -------------------------------------------------------------------------------- 1 | // generated by go generate; DO NOT EDIT 2 | 3 | // Copyright (c) 2015 The Interval Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | package interval 8 | 9 | // Intersection returns the intersection of x and y. 10 | func Intersection(x, y Interface) Interface { 11 | x, y, h := hash(x, y) 12 | switch h { 13 | case 9590, 9654, 9591, 9655, 10546, 10547, 10290, 10291, 10102, 10166, 10103, 10167, 9846, 9910, 9847, 9911, 9334, 9398, 9335, 9399, 11076, 11140, 10820, 10884: 14 | return setClass(x.Clone(), Open) 15 | case 22020, 15798, 15862, 15799, 15863, 16516, 16580, 10230, 10231, 9462, 9463, 10948: 16 | return setClass(setB(x.Clone(), y), Open) 17 | case 16178, 16179, 15922, 15923, 15734, 15735, 15478, 15542, 15479, 15543, 16708, 16772, 16452: 18 | return setClass(x.Clone(), LeftOpen) 19 | case 22276, 15606, 15607, 16836, 9718, 9719, 9974, 9975, 11204: 20 | return setClass(setB(x.Clone(), y), LeftOpen) 21 | case 21762, 21763, 21506, 21507: 22 | return setClass(x.Clone(), LeftBoundedOpen) 23 | case 18737, 18738, 10289, 9845, 9909, 9333, 9397: 24 | return setClass(setB(y.Clone(), x), Open) 25 | case 9461, 768: 26 | return setClass(y.Clone(), Open) 27 | case 13105, 13106, 12661, 12725, 12662, 12726, 15921, 15477, 15541: 28 | return setClass(setB(y.Clone(), x), LeftOpen) 29 | case 12789, 12790, 15605, 9973, 1280: 30 | return setClass(y.Clone(), LeftOpen) 31 | case 21505, 1792: 32 | return setClass(y.Clone(), LeftBoundedOpen) 33 | case 18994, 18995, 18739, 18550, 18614, 18551, 18615, 19524, 19588, 19268, 19332: 34 | return setClass(x.Clone(), LeftClosed) 35 | case 12982, 13046, 12983, 13047, 13700, 13764, 24836, 18678, 18679, 19396: 36 | return setClass(setB(x.Clone(), y), LeftClosed) 37 | case 12539, 12795, 14024, 6662, 6663, 6667, 6146, 7682, 7683, 7427, 7174, 7175, 6919, 6923, 6407, 8196, 8200, 7940, 25096, 19656: 38 | return setClass(x.Clone(), Degenerate) 39 | case 12406, 12470, 12407, 12471, 13362, 13363, 13107, 12918, 12919, 12663, 12727, 13892, 13956, 13636: 40 | return setClass(x.Clone(), Closed) 41 | case 12534, 12535, 12791, 14020, 25092, 19652: 42 | return setClass(setB(x.Clone(), y), Closed) 43 | case 24578, 24579: 44 | return setClass(x.Clone(), LeftBoundedClosed) 45 | case 12389, 13345, 12901, 16161, 15717: 46 | return setClass(setAB(x.Clone()), Degenerate) 47 | case 18993, 18549, 18613, 9589, 9653, 10545, 10101, 10165: 48 | return setClass(setB(y.Clone(), x), LeftClosed) 49 | case 12981, 13045, 18677, 15797, 15861, 10229, 1536: 50 | return setClass(y.Clone(), LeftClosed) 51 | case 12405, 12469, 13361, 12917, 16177, 15733: 52 | return setClass(setB(y.Clone(), x), Closed) 53 | case 512: 54 | return setClass(y.Clone(), Degenerate) 55 | case 12533, 9717, 1024: 56 | return setClass(y.Clone(), Closed) 57 | case 24577, 21761, 2048: 58 | return setClass(y.Clone(), LeftBoundedClosed) 59 | case 27968, 28032, 27712, 27776: 60 | return setClass(x.Clone(), RightBoundedOpen) 61 | case 27840, 2304: 62 | return setClass(y.Clone(), RightBoundedOpen) 63 | case 30784, 30848: 64 | return setClass(x.Clone(), RightBoundedClosed) 65 | case 30912, 28096, 2560: 66 | return setClass(y.Clone(), RightBoundedClosed) 67 | case 0: 68 | return setClass(x.Clone(), Unbounded) 69 | } 70 | return setClass(x.Clone(), Empty) 71 | } 72 | 73 | // Union returns the union of x and y. If the union is not an interval, nil is 74 | // returned instead. The union is not an interval if it is a disjoint set. 75 | func Union(x, y Interface) Interface { 76 | x, y, h := hash(x, y) 77 | switch h { 78 | case 12373, 12543, 13329, 13073, 12885, 13055, 12629, 12799, 14028, 13772, 6661, 6671, 6145, 6147, 7681, 7425, 7173, 7183, 6917, 6927, 6405, 6415, 8204, 7948, 25100, 24844, 22284, 22024, 22028, 18961, 18705, 18721, 18517, 18687, 19660, 19404, 16145, 15889, 15701, 15867, 15871, 15445, 15615, 16844, 16584, 16588, 9557, 9727, 10513, 10257, 10273, 10069, 10235, 10239, 9813, 9829, 9983, 9301, 9317, 9467, 9471, 11212, 10952, 10956: 79 | return nil 80 | case 9717, 10165, 10229, 9973, 9974, 9397, 9461, 9398, 9462: 81 | return setClass(x.Clone(), Open) 82 | case 15717, 15733, 10085, 10101, 9333, 9334: 83 | return setClass(setB(x.Clone(), y), Open) 84 | case 15797, 15861, 15541, 15605, 15542, 15606: 85 | return setClass(x.Clone(), LeftOpen) 86 | case 15461, 15477, 15478, 9573, 9589, 9653, 9845, 9909, 9846, 9910: 87 | return setClass(setB(x.Clone(), y), LeftOpen) 88 | case 21761, 21505, 21506, 16161, 16177, 15905, 15921, 15922, 10529, 10545, 10289, 10290: 89 | return setClass(x.Clone(), LeftBoundedOpen) 90 | case 9975, 9979, 9399, 9463: 91 | return setClass(setB(y.Clone(), x), Open) 92 | case 6407, 3584, 9335: 93 | return setClass(y.Clone(), Open) 94 | case 6923, 6411: 95 | return setClass(setBA(y.Clone(), x), LeftOpen) 96 | case 12727, 12791, 12795, 15543, 15607, 15611: 97 | return setClass(setB(y.Clone(), x), LeftOpen) 98 | case 12663, 6919, 4096, 15479, 9847, 9911: 99 | return setClass(y.Clone(), LeftOpen) 100 | case 13107, 7427, 4608, 21507, 18739, 15923, 10291: 101 | return setClass(y.Clone(), LeftBoundedOpen) 102 | case 18613, 18677, 18614, 18678: 103 | return setClass(x.Clone(), LeftClosed) 104 | case 12901, 12917, 12918, 7174, 6406, 18533, 18549, 18550: 105 | return setClass(setB(x.Clone(), y), LeftClosed) 106 | case 6146: 107 | return setClass(x.Clone(), Degenerate) 108 | case 12469, 12533, 12470, 12534, 12981, 13045, 12982, 13046, 12725, 12789, 12726, 12790: 109 | return setClass(x.Clone(), Closed) 110 | case 12389, 12405, 12406, 12645, 12661, 12662, 6662, 6918: 111 | return setClass(setB(x.Clone(), y), Closed) 112 | case 13345, 13361, 13362, 13089, 13105, 13106, 7682, 7426, 24577, 24578, 18977, 18993, 18994, 18737, 18738: 113 | return setClass(x.Clone(), LeftBoundedClosed) 114 | case 18615, 18679, 18683, 9718, 9719, 9723, 10166, 10230, 10167, 10231: 115 | return setClass(setB(y.Clone(), x), LeftClosed) 116 | case 12919, 7175, 4352, 18551, 15734, 15735, 10102, 10103: 117 | return setClass(y.Clone(), LeftClosed) 118 | case 6667, 7179: 119 | return setClass(setBA(y.Clone(), x), Closed) 120 | case 12471, 12535, 12539, 12983, 13047, 13051, 15798, 15862, 15799, 15863: 121 | return setClass(setB(y.Clone(), x), Closed) 122 | case 3328: 123 | return setClass(y.Clone(), Degenerate) 124 | case 12407, 6663, 3840, 9590, 9654, 9591, 9655: 125 | return setClass(y.Clone(), Closed) 126 | case 13363, 7683, 4864, 24579, 21762, 21763, 18995, 16178, 16179, 10546, 10547: 127 | return setClass(y.Clone(), LeftBoundedClosed) 128 | case 19652, 19656, 19332, 19396, 19400, 11204, 11208, 10884, 10948, 28096, 27776, 27840: 129 | return setClass(x.Clone(), RightBoundedOpen) 130 | case 13636, 7940, 5120, 19268, 16452, 10820, 27712: 131 | return setClass(y.Clone(), RightBoundedOpen) 132 | case 8200, 7944: 133 | return setClass(setBA(x.Clone(), x), RightBoundedClosed) 134 | case 13956, 14020, 14024, 13700, 13764, 13768, 16772, 16836, 16840, 16516, 16580, 30848, 30912: 135 | return setClass(x.Clone(), RightBoundedClosed) 136 | case 13892, 8196, 5376, 19524, 19588, 16708, 11076, 11140, 30784, 27968, 28032: 137 | return setClass(y.Clone(), RightBoundedClosed) 138 | case 25092, 25096, 24836, 24840, 22276, 22280, 22020, 1024, 512, 256, 2048, 1792, 1536, 1280, 768, 2560, 2304, 0: 139 | return setClass(x.Clone(), Unbounded) 140 | } 141 | return setClass(x.Clone(), Empty) 142 | } 143 | -------------------------------------------------------------------------------- /gen_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The Interval Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package interval 6 | 7 | import ( 8 | "bytes" 9 | "flag" 10 | "fmt" 11 | "go/format" 12 | "io/ioutil" 13 | "sort" 14 | "strconv" 15 | "strings" 16 | "testing" 17 | ) 18 | 19 | var ( 20 | _ Interface = (*interval)(nil) 21 | 22 | classes = []Class{ 23 | Unbounded, 24 | Empty, 25 | Degenerate, 26 | 27 | Open, 28 | Closed, 29 | LeftOpen, 30 | LeftClosed, 31 | 32 | LeftBoundedOpen, 33 | LeftBoundedClosed, 34 | RightBoundedOpen, 35 | RightBoundedClosed, 36 | } 37 | 38 | gen = flag.Bool("gen", false, "") 39 | ) 40 | 41 | func lclass(c Class) string { s := c.String(); return strings.ToLower(s[:1]) + s[1:] } 42 | 43 | func cmp(x, y int) int { 44 | if x < y { 45 | return -1 46 | } 47 | 48 | if x == y { 49 | return 0 50 | } 51 | 52 | return 1 53 | } 54 | 55 | type interval struct { 56 | cls Class 57 | a int 58 | b int 59 | } 60 | 61 | func (i *interval) Class() Class { return i.cls } 62 | func (i *interval) Clone() Interface { c := *i; return &c } 63 | func (i *interval) CompareAA(other Interface) int { return cmp(i.a, other.(*interval).a) } 64 | func (i *interval) CompareAB(other Interface) int { return cmp(i.a, other.(*interval).b) } 65 | func (i *interval) CompareBB(other Interface) int { return cmp(i.b, other.(*interval).b) } 66 | func (i *interval) SetAB() { i.a = i.b } 67 | func (i *interval) SetB(other Interface) { i.b = other.(*interval).b } 68 | func (i *interval) SetBA(other Interface) { i.b = other.(*interval).a } 69 | func (i *interval) SetClass(c Class) { i.cls = c } 70 | func (i *interval) String() string { return str(i.Class(), i.a, i.b) } 71 | 72 | func (i *interval) hasA() bool { 73 | switch i.Class() { 74 | case Degenerate, Open, Closed, LeftOpen, LeftClosed, LeftBoundedOpen, LeftBoundedClosed: 75 | return true 76 | default: 77 | return false 78 | } 79 | } 80 | 81 | func (i *interval) hasB() bool { 82 | switch i.Class() { 83 | case Open, Closed, LeftOpen, LeftClosed, RightBoundedOpen, RightBoundedClosed: 84 | return true 85 | default: 86 | return false 87 | } 88 | } 89 | 90 | func (i *interval) has(x int) bool { 91 | switch i.Class() { 92 | case Unbounded: 93 | return true 94 | case Empty: 95 | return false 96 | case Degenerate: 97 | return i.a == x 98 | case Open: 99 | return x > i.a && x < i.b 100 | case Closed: 101 | return x >= i.a && x <= i.b 102 | case LeftClosed: 103 | return x >= i.a && x < i.b 104 | case LeftOpen: 105 | return x > i.a && x <= i.b 106 | case LeftBoundedOpen: 107 | return x > i.a 108 | case LeftBoundedClosed: 109 | return x >= i.a 110 | case RightBoundedOpen: 111 | return x < i.b 112 | case RightBoundedClosed: 113 | return x <= i.b 114 | default: 115 | panic("internal error") 116 | } 117 | } 118 | 119 | func (i *interval) includesA() bool { 120 | switch i.cls { 121 | case Degenerate, Closed, LeftClosed, LeftBoundedClosed: 122 | return true 123 | default: 124 | return false 125 | } 126 | } 127 | 128 | func (i *interval) includesB() bool { 129 | switch i.cls { 130 | case Closed, LeftOpen, RightBoundedClosed: 131 | return true 132 | default: 133 | return false 134 | } 135 | } 136 | 137 | //go:generate stringer -type Class 138 | //go:generate go test gen_test.go interval.go class_string.go -run Gen -gen 139 | func TestGen(t *testing.T) { 140 | const prolog = `// generated by go generate; DO NOT EDIT 141 | 142 | // Copyright (c) 2015 The Interval Authors. All rights reserved. 143 | // Use of this source code is governed by a BSD-style 144 | // license that can be found in the LICENSE file. 145 | 146 | package interval 147 | ` 148 | if !*gen { 149 | return 150 | } 151 | 152 | buf := bytes.NewBuffer(nil) 153 | w := func(format string, arg ...interface{}) { 154 | fmt.Fprintf(buf, format, arg...) 155 | } 156 | 157 | w(prolog) 158 | genIntersection(w) 159 | genUnion(w) 160 | src, err := format.Source(buf.Bytes()) 161 | if err != nil { 162 | t.Logf("%s", buf.Bytes()) 163 | t.Fatal(err) 164 | } 165 | 166 | if err := ioutil.WriteFile("gen.go", src, 0666); err != nil { 167 | t.Fatal(err) 168 | } 169 | } 170 | 171 | func genIntersection(w func(string, ...interface{})) { 172 | w(`// Intersection returns the intersection of x and y. 173 | func Intersection(x, y Interface) Interface { 174 | `) 175 | w("x, y, h := hash(x, y)\n") 176 | w("switch h {\n") 177 | m := deriveRules(analyzeIntersection) 178 | var a []string 179 | for k := range m { 180 | a = append(a, k) 181 | } 182 | sort.Strings(a) 183 | for _, s := range a { 184 | if s == "{}" { 185 | continue 186 | } 187 | 188 | w("case") 189 | for i, k := range m[s] { 190 | switch i { 191 | case 0: 192 | w(" ") 193 | default: 194 | w(", ") 195 | } 196 | w("%d", k.hash()) 197 | } 198 | w(":\n") 199 | genResult(s, w) 200 | } 201 | w("}\n") 202 | w(`return setClass(x.Clone(), Empty) 203 | } 204 | `) 205 | } 206 | 207 | func genUnion(w func(string, ...interface{})) { 208 | w(`// Union returns the union of x and y. If the union is not an interval, nil is 209 | // returned instead. The union is not an interval if it is a disjoint set. 210 | func Union(x, y Interface) Interface { 211 | `) 212 | w("x, y, h := hash(x, y)\n") 213 | w("switch h {\n") 214 | m := deriveRules(analyzeUnion) 215 | var a []string 216 | for k := range m { 217 | a = append(a, k) 218 | } 219 | sort.Strings(a) 220 | for _, s := range a { 221 | if s == "{}" { 222 | continue 223 | } 224 | 225 | w("case") 226 | for i, k := range m[s] { 227 | switch i { 228 | case 0: 229 | w(" ") 230 | default: 231 | w(", ") 232 | } 233 | w("%d", k.hash()) 234 | } 235 | w(":\n") 236 | if s == "" { 237 | w("return nil\n") 238 | continue 239 | } 240 | 241 | genResult(s, w) 242 | } 243 | w("}\n") 244 | w(`return setClass(x.Clone(), Empty) 245 | } 246 | `) 247 | } 248 | 249 | func genResult(s string, w func(string, ...interface{})) { 250 | a := strings.Split(s, ", ") 251 | switch a[0] { 252 | case "inf": 253 | switch a[1] { 254 | case "inf": 255 | w("return setClass(x.Clone(), Unbounded)\n") 256 | case "[XA": 257 | w("return setClass(setBA(x.Clone(), x), RightBoundedClosed)\n") 258 | case "(XB": 259 | w("return setClass(x.Clone(), RightBoundedOpen)\n") 260 | case "[XB": 261 | w("return setClass(x.Clone(), RightBoundedClosed)\n") 262 | case "(YB": 263 | w("return setClass(y.Clone(), RightBoundedOpen)\n") 264 | case "[YB": 265 | w("return setClass(y.Clone(), RightBoundedClosed)\n") 266 | default: 267 | panic("internal error") 268 | } 269 | case "(XA": 270 | switch a[1] { 271 | case "inf": 272 | w("return setClass(x.Clone(), LeftBoundedOpen)\n") 273 | case "(XB": 274 | w("return setClass(x.Clone(), Open)\n") 275 | case "[XB": 276 | w("return setClass(x.Clone(), LeftOpen)\n") 277 | case "(YB": 278 | w("return setClass(setB(x.Clone(), y), Open)\n") 279 | case "[YB": 280 | w("return setClass(setB(x.Clone(), y), LeftOpen)\n") 281 | default: 282 | panic("internal error") 283 | } 284 | case "[XA": 285 | switch a[1] { 286 | case "inf": 287 | w("return setClass(x.Clone(), LeftBoundedClosed)\n") 288 | case "[XA": 289 | w("return setClass(x.Clone(), Degenerate)\n") 290 | case "(XB": 291 | w("return setClass(x.Clone(), LeftClosed)\n") 292 | case "[XB": 293 | w("return setClass(x.Clone(), Closed)\n") 294 | case "(YB": 295 | w("return setClass(setB(x.Clone(), y), LeftClosed)\n") 296 | case "[YB": 297 | w("return setClass(setB(x.Clone(), y), Closed)\n") 298 | default: 299 | panic("internal error") 300 | } 301 | case "[XB": 302 | switch a[1] { 303 | case "[XB": 304 | w("return setClass(setAB(x.Clone()), Degenerate)\n") 305 | default: 306 | panic("internal error") 307 | } 308 | case "(YA": 309 | switch a[1] { 310 | case "inf": 311 | w("return setClass(y.Clone(), LeftBoundedOpen)\n") 312 | case "[XA": 313 | w("return setClass(setBA(y.Clone(), x), LeftOpen)\n") 314 | case "(XB": 315 | w("return setClass(setB(y.Clone(), x), Open)\n") 316 | case "[XB": 317 | w("return setClass(setB(y.Clone(), x), LeftOpen)\n") 318 | case "(YB": 319 | w("return setClass(y.Clone(), Open)\n") 320 | case "[YB": 321 | w("return setClass(y.Clone(), LeftOpen)\n") 322 | default: 323 | panic("internal error") 324 | } 325 | case "[YA": 326 | switch a[1] { 327 | case "inf": 328 | w("return setClass(y.Clone(), LeftBoundedClosed)\n") 329 | case "[XA": 330 | w("return setClass(setBA(y.Clone(), x), Closed)\n") 331 | case "(XB": 332 | w("return setClass(setB(y.Clone(), x), LeftClosed)\n") 333 | case "[XB": 334 | w("return setClass(setB(y.Clone(), x), Closed)\n") 335 | case "[YA": 336 | w("return setClass(y.Clone(), Degenerate)\n") 337 | case "(YB": 338 | w("return setClass(y.Clone(), LeftClosed)\n") 339 | case "[YB": 340 | w("return setClass(y.Clone(), Closed)\n") 341 | default: 342 | panic("internal error") 343 | } 344 | default: 345 | panic("internal error") 346 | } 347 | } 348 | 349 | const ( 350 | negInf = -60 351 | posInf = 60 352 | ) 353 | 354 | func samples(c Class) (r []*interval) { 355 | switch c { 356 | case Unbounded, Empty: 357 | r = append(r, &interval{cls: c}) 358 | case Degenerate, LeftBoundedOpen, LeftBoundedClosed: 359 | for a := negInf + 10; a <= posInf-10; a += 5 { 360 | r = append(r, &interval{cls: c, a: a}) 361 | } 362 | case Open, Closed, LeftOpen, LeftClosed: 363 | for a := negInf + 10; a <= posInf-10; a += 5 { 364 | for b := a + 20; b <= posInf-10; b += 5 { 365 | r = append(r, &interval{cls: c, a: a, b: b}) 366 | } 367 | } 368 | case RightBoundedOpen, RightBoundedClosed: 369 | for b := negInf + 10; b <= posInf-10; b += 10 { 370 | r = append(r, &interval{cls: c, b: b}) 371 | } 372 | default: 373 | panic("internal error") 374 | } 375 | return r 376 | } 377 | 378 | func abs(n int) int { 379 | if n >= 0 { 380 | return n 381 | } 382 | 383 | return -n 384 | } 385 | 386 | type key struct { 387 | xc Class 388 | yc Class 389 | xaya string 390 | xayb string 391 | xbya string 392 | xbyb string 393 | } 394 | 395 | // -- 00 396 | // -1 01 397 | // 0 10 398 | // 1 11 399 | func (k *key) enc(s string) int { 400 | switch s { 401 | case "": 402 | return 0 403 | case "-1": 404 | return 1 405 | case "0": 406 | return 2 407 | case "1": 408 | return 3 409 | default: 410 | panic("internal error") 411 | } 412 | } 413 | 414 | func (k *key) String() string { 415 | return fmt.Sprintf("{%v %v %q %q %q %q}", k.xc, k.yc, k.xaya, k.xayb, k.xbya, k.xbyb) 416 | } 417 | 418 | func (k *key) hash() int { 419 | if k.xc > k.yc { 420 | panic("internal error") 421 | } 422 | 423 | return (int(k.xc)*int(nClasses)+int(k.yc))<<8 | k.enc(k.xbyb)<<6 | k.enc(k.xbya)<<4 | k.enc(k.xayb)<<2 | k.enc(k.xaya) 424 | } 425 | 426 | func deriveRules(f func(Class, Class) map[key]string) map[string][]key { 427 | m := map[string][]key{} 428 | for _, xc := range classes { 429 | for _, yc := range classes[xc:] { 430 | for k, s := range f(xc, yc) { 431 | k.xc = xc 432 | k.yc = yc 433 | m[s] = append(m[s], k) 434 | } 435 | } 436 | } 437 | for s, ks := range m { 438 | n := map[string]key{} 439 | for _, k := range ks { 440 | n[k.String()] = k 441 | } 442 | var a []string 443 | for s := range n { 444 | a = append(a, s) 445 | } 446 | sort.Strings(a) 447 | var nks []key 448 | for _, s := range a { 449 | nks = append(nks, n[s]) 450 | } 451 | m[s] = nks 452 | } 453 | return m 454 | } 455 | 456 | func analyzeIntersection(xc, yc Class) map[key]string { 457 | m := map[key][]string{} 458 | for _, x := range samples(xc) { 459 | for _, y := range samples(yc) { 460 | if x.hasA() && y.hasA() && x.a != y.a && abs(x.a-y.a) <= 10 || 461 | x.hasA() && y.hasB() && x.a != y.b && abs(x.a-y.b) <= 10 || 462 | x.hasB() && y.hasA() && x.b != y.a && abs(x.b-y.a) <= 10 || 463 | x.hasB() && y.hasB() && x.b != y.b && abs(x.b-y.b) <= 10 { 464 | continue 465 | } 466 | var from, to string 467 | for n := negInf; n <= posInf; n += 5 { 468 | if x.has(n) && y.has(n) { 469 | var s string 470 | switch { 471 | case n == negInf, n == posInf: 472 | s = "inf" 473 | case x.hasA() && x.includesA() && n == x.a: 474 | s = "[XA" 475 | case x.hasA() && !x.includesA() && n == x.a+5: 476 | s = "(XA" 477 | case x.hasB() && !x.includesB() && n == x.b-5: 478 | s = "(XB" 479 | case x.hasB() && x.includesB() && n == x.b: 480 | s = "[XB" 481 | case y.hasA() && y.includesA() && n == y.a: 482 | s = "[YA" 483 | case y.hasA() && !y.includesA() && n == y.a+5: 484 | s = "(YA" 485 | case y.hasB() && !y.includesB() && n == y.b-5: 486 | s = "(YB" 487 | case y.hasB() && y.includesB() && n == y.b: 488 | s = "[YB" 489 | } 490 | if from == "" { 491 | from = s 492 | } 493 | to = s 494 | } 495 | } 496 | var k key 497 | if x.hasA() && y.hasA() { 498 | k.xaya = strconv.Itoa(cmp(x.a, y.a)) 499 | } 500 | if x.hasA() && y.hasB() { 501 | k.xayb = strconv.Itoa(cmp(x.a, y.b)) 502 | } 503 | if x.hasB() && y.hasA() { 504 | k.xbya = strconv.Itoa(cmp(x.b, y.a)) 505 | } 506 | if x.hasB() && y.hasB() { 507 | k.xbyb = strconv.Itoa(cmp(x.b, y.b)) 508 | } 509 | if from != "" { 510 | m[k] = append(m[k], from+", "+to) 511 | continue 512 | } 513 | 514 | m[k] = append(m[k], "{}") 515 | } 516 | } 517 | r := map[key]string{} 518 | for k, v := range m { 519 | v0 := v[0] 520 | for _, v := range v[1:] { 521 | if v != v0 { 522 | panic("internal error") 523 | } 524 | } 525 | r[k] = v0 526 | } 527 | return r 528 | } 529 | 530 | func analyzeUnion(xc, yc Class) map[key]string { 531 | const ( 532 | initial = iota 533 | in 534 | after 535 | ) 536 | m := map[key][]string{} 537 | for _, x := range samples(xc) { 538 | for _, y := range samples(yc) { 539 | if x.hasA() && y.hasA() && x.a != y.a && abs(x.a-y.a) <= 10 || 540 | x.hasA() && y.hasB() && x.a != y.b && abs(x.a-y.b) <= 10 || 541 | x.hasB() && y.hasA() && x.b != y.a && abs(x.b-y.a) <= 10 || 542 | x.hasB() && y.hasB() && x.b != y.b && abs(x.b-y.b) <= 10 { 543 | continue 544 | } 545 | var from, to string 546 | ok := true 547 | var state int 548 | loop: 549 | for n := negInf; n <= posInf; n += 5 { 550 | if x.has(n) || y.has(n) { 551 | switch state { 552 | case initial: 553 | state = in 554 | case in: 555 | // nop 556 | case after: 557 | // Union is not an interval 558 | from = "" 559 | to = "" 560 | ok = false 561 | break loop 562 | } 563 | var s string 564 | switch { 565 | case n == negInf, n == posInf: 566 | s = "inf" 567 | case x.hasA() && x.includesA() && n == x.a: 568 | s = "[XA" 569 | case x.hasA() && !x.includesA() && n == x.a+5: 570 | s = "(XA" 571 | case x.hasB() && !x.includesB() && n == x.b-5: 572 | s = "(XB" 573 | case x.hasB() && x.includesB() && n == x.b: 574 | s = "[XB" 575 | case y.hasA() && y.includesA() && n == y.a: 576 | s = "[YA" 577 | case y.hasA() && !y.includesA() && n == y.a+5: 578 | s = "(YA" 579 | case y.hasB() && !y.includesB() && n == y.b-5: 580 | s = "(YB" 581 | case y.hasB() && y.includesB() && n == y.b: 582 | s = "[YB" 583 | } 584 | if from == "" { 585 | from = s 586 | } 587 | to = s 588 | continue 589 | } 590 | 591 | switch state { 592 | case initial: 593 | // nop 594 | case in: 595 | state = after 596 | case after: 597 | // nop 598 | } 599 | 600 | } 601 | var k key 602 | if x.hasA() && y.hasA() { 603 | k.xaya = strconv.Itoa(cmp(x.a, y.a)) 604 | } 605 | if x.hasA() && y.hasB() { 606 | k.xayb = strconv.Itoa(cmp(x.a, y.b)) 607 | } 608 | if x.hasB() && y.hasA() { 609 | k.xbya = strconv.Itoa(cmp(x.b, y.a)) 610 | } 611 | if x.hasB() && y.hasB() { 612 | k.xbyb = strconv.Itoa(cmp(x.b, y.b)) 613 | } 614 | if from != "" { 615 | m[k] = append(m[k], from+", "+to) 616 | continue 617 | } 618 | 619 | if ok { 620 | m[k] = append(m[k], "{}") 621 | continue 622 | } 623 | 624 | m[k] = append(m[k], "") 625 | } 626 | } 627 | r := map[key]string{} 628 | for k, v := range m { 629 | v0 := v[0] 630 | for _, v := range v[1:] { 631 | if v != v0 { 632 | panic("internal error") 633 | } 634 | } 635 | r[k] = v0 636 | } 637 | return r 638 | } 639 | -------------------------------------------------------------------------------- /interval.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The Interval Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package interval handles sets of ordered values laying between two, possibly 6 | // infinite, bounds. 7 | // 8 | // Note: Intervals are usually defined as a set of [extended] real numbers. 9 | // The model of the interval provided by Interface does not know - and thus 10 | // does not care about the type of the bounds, if any. That may lead to correct 11 | // but possibly surprising effects when the bounds domain is not ℝ. An interval 12 | // may be non empty, like for example the open interval (1, 2), but no integer 13 | // value lies between the bounds. 14 | // 15 | // See also: http://en.wikipedia.org/wiki/Interval_(mathematics) 16 | package interval 17 | 18 | import ( 19 | "fmt" 20 | "math/big" 21 | "time" 22 | 23 | "github.com/cznic/mathutil" 24 | ) 25 | 26 | var ( 27 | _ Interface = (*BigInt)(nil) 28 | _ Interface = (*BigRat)(nil) 29 | _ Interface = (*Byte)(nil) 30 | _ Interface = (*Duration)(nil) 31 | _ Interface = (*Float32)(nil) 32 | _ Interface = (*Float64)(nil) 33 | _ Interface = (*Int)(nil) 34 | _ Interface = (*Int128)(nil) 35 | _ Interface = (*Int16)(nil) 36 | _ Interface = (*Int32)(nil) 37 | _ Interface = (*Int64)(nil) 38 | _ Interface = (*Int8)(nil) 39 | _ Interface = (*String)(nil) 40 | _ Interface = (*Time)(nil) 41 | _ Interface = (*Uint)(nil) 42 | _ Interface = (*Uint16)(nil) 43 | _ Interface = (*Uint32)(nil) 44 | _ Interface = (*Uint64)(nil) 45 | ) 46 | 47 | // Class represent a type of an interval. 48 | type Class int 49 | 50 | // Interval classes. 51 | const ( 52 | Unbounded Class = iota // (-∞, ∞). 53 | Empty // {}. 54 | Degenerate // [a, a] = {a}. 55 | 56 | // Proper and bounded: 57 | Open // (a, b) = {x | a < x < b}. 58 | Closed // [a, b] = {x | a <= x <= b}. 59 | LeftOpen // (a, b] = {x | a < x <= b}. 60 | LeftClosed // [a, b) = {x | a <= x < b}. 61 | 62 | // Left-bounded and right-unbounded: 63 | LeftBoundedOpen // (a, ∞) = {x | x > a}. 64 | LeftBoundedClosed // [a, ∞) = {x | x >= a}. 65 | 66 | // Left-unbounded and right-bounded: 67 | RightBoundedOpen // (-∞, b) = {x | x < b}. 68 | RightBoundedClosed // (-∞, b] = {x | x <= b}. 69 | 70 | nClasses 71 | ) 72 | 73 | // Interface represents an unbounded, empty, degenerate, proper, left-bounded 74 | // or right-bounded interval. Where appropriate, the interval bounds are 75 | // defined by ordered values, named by convention a and b, when present. 76 | // 77 | // Proper intervals have an invariant: a < b. 78 | // 79 | // CompareXX return value must obey these rules 80 | // 81 | // < 0 if interval A or B < other interval A or B 82 | // 0 if interval A or B == other interval A or B 83 | // > 0 if interval A or B > other interval A or B 84 | type Interface interface { 85 | // Class returns the interval class. 86 | Class() Class 87 | // Clone clones the interval. 88 | Clone() Interface 89 | // CompareAA compares interval.A and other.A. 90 | CompareAA(other Interface) int 91 | // CompareAB compares interval.A and other.B. 92 | CompareAB(other Interface) int 93 | // CompareBB compares interval.B and other.B. 94 | CompareBB(other Interface) int 95 | // SetClass sets the interval class. 96 | SetClass(Class) 97 | // SetAB sets interval.A using interval.B. 98 | SetAB() 99 | // SetB sets interval.B using other.B. 100 | SetB(other Interface) 101 | // SetBA sets interval.B using other.A. 102 | SetBA(other Interface) 103 | } 104 | 105 | func compareBA(x, y Interface) int { return -y.CompareAB(x) } 106 | func setAB(x Interface) Interface { x.SetAB(); return x } 107 | func setB(x, y Interface) Interface { x.SetB(y); return x } 108 | func setBA(x, y Interface) Interface { x.SetBA(y); return x } 109 | func setClass(x Interface, c Class) Interface { x.SetClass(c); return x } 110 | 111 | func str(c Class, a, b interface{}) string { 112 | switch c { 113 | case Unbounded: 114 | return fmt.Sprintf("(-∞, ∞)") 115 | case Empty: 116 | return fmt.Sprintf("{}") 117 | case Degenerate: 118 | return fmt.Sprintf("{%v}", a) 119 | case Open: 120 | return fmt.Sprintf("(%v, %v)", a, b) 121 | case Closed: 122 | return fmt.Sprintf("[%v, %v]", a, b) 123 | case LeftOpen: 124 | return fmt.Sprintf("(%v, %v]", a, b) 125 | case LeftClosed: 126 | return fmt.Sprintf("[%v, %v)", a, b) 127 | case LeftBoundedOpen: 128 | return fmt.Sprintf("(%v, ∞)", a) 129 | case LeftBoundedClosed: 130 | return fmt.Sprintf("[%v, ∞)", a) 131 | case RightBoundedOpen: 132 | return fmt.Sprintf("(-∞, %v)", b) 133 | case RightBoundedClosed: 134 | return fmt.Sprintf("(-∞, %v]", b) 135 | } 136 | panic("internal error") 137 | } 138 | 139 | func hash(x, y Interface) (Interface, Interface, int) { 140 | xc := x.Class() 141 | yc := y.Class() 142 | if xc > yc { 143 | x, y = y, x 144 | xc, yc = yc, xc 145 | } 146 | var r int 147 | switch xc { 148 | case Degenerate, Open, Closed, LeftOpen, LeftClosed, LeftBoundedOpen, LeftBoundedClosed: // x has A 149 | switch yc { 150 | case Degenerate, Open, Closed, LeftOpen, LeftClosed, LeftBoundedOpen, LeftBoundedClosed: // y has A 151 | r |= enc(x.CompareAA(y)) 152 | } 153 | switch yc { 154 | case Open, Closed, LeftOpen, LeftClosed, RightBoundedOpen, RightBoundedClosed: // y has B 155 | r |= enc(x.CompareAB(y)) << 2 156 | } 157 | } 158 | switch xc { 159 | case Open, Closed, LeftOpen, LeftClosed, RightBoundedOpen, RightBoundedClosed: // x has B 160 | switch yc { 161 | case Degenerate, Open, Closed, LeftOpen, LeftClosed, LeftBoundedOpen, LeftBoundedClosed: // y has A 162 | r |= enc(compareBA(x, y)) << 4 163 | } 164 | switch yc { 165 | case Open, Closed, LeftOpen, LeftClosed, RightBoundedOpen, RightBoundedClosed: // y has B 166 | r |= enc(x.CompareBB(y)) << 6 167 | } 168 | } 169 | return x, y, r | (int(xc)*int(nClasses)+int(yc))<<8 170 | } 171 | 172 | // -- 00 173 | // -1 01 174 | // 0 10 175 | // 1 11 176 | func enc(n int) int { 177 | if n < 0 { 178 | return 1 179 | } 180 | 181 | if n == 0 { 182 | return 2 183 | } 184 | 185 | return 3 186 | } 187 | 188 | // Float32 is an interval having float32 bounds. 189 | // 190 | // Note: Using NaNs as bounds has undefined behavior. 191 | type Float32 struct { 192 | Cls Class 193 | A, B float32 194 | } 195 | 196 | // String implements fmt.Stringer. 197 | func (i *Float32) String() string { return str(i.Cls, i.A, i.B) } 198 | 199 | // Class implements Interface. 200 | func (i *Float32) Class() Class { return i.Cls } 201 | 202 | // SetClass implements Interface. 203 | func (i *Float32) SetClass(c Class) { i.Cls = c } 204 | 205 | // Clone implements Interface. 206 | func (i *Float32) Clone() Interface { j := *i; return &j } 207 | 208 | // CompareAA implements Interface. 209 | func (i *Float32) CompareAA(other Interface) int { 210 | if i.A < other.(*Float32).A { 211 | return -1 212 | } 213 | 214 | if i.A > other.(*Float32).A { 215 | return 1 216 | } 217 | 218 | return 0 219 | } 220 | 221 | // CompareAB implements Interface. 222 | func (i *Float32) CompareAB(other Interface) int { 223 | if i.A < other.(*Float32).B { 224 | return -1 225 | } 226 | 227 | if i.A > other.(*Float32).B { 228 | return 1 229 | } 230 | 231 | return 0 232 | } 233 | 234 | // CompareBB implements Interface. 235 | func (i *Float32) CompareBB(other Interface) int { 236 | if i.B < other.(*Float32).B { 237 | return -1 238 | } 239 | 240 | if i.B > other.(*Float32).B { 241 | return 1 242 | } 243 | 244 | return 0 245 | } 246 | 247 | // SetAB implements Interface. 248 | func (i *Float32) SetAB() { i.A = i.B } 249 | 250 | // SetB implements Interface. 251 | func (i *Float32) SetB(other Interface) { i.B = other.(*Float32).B } 252 | 253 | // SetBA implements Interface. 254 | func (i *Float32) SetBA(other Interface) { i.B = other.(*Float32).A } 255 | 256 | // Float64 is an interval having float64 bounds. 257 | // 258 | // Note: Using NaNs as bounds has undefined behavior. 259 | type Float64 struct { 260 | Cls Class 261 | A, B float64 262 | } 263 | 264 | // String implements fmt.Stringer. 265 | func (i *Float64) String() string { return str(i.Cls, i.A, i.B) } 266 | 267 | // Class implements Interface. 268 | func (i *Float64) Class() Class { return i.Cls } 269 | 270 | // SetClass implements Interface. 271 | func (i *Float64) SetClass(c Class) { i.Cls = c } 272 | 273 | // Clone implements Interface. 274 | func (i *Float64) Clone() Interface { j := *i; return &j } 275 | 276 | // CompareAA implements Interface. 277 | func (i *Float64) CompareAA(other Interface) int { 278 | if i.A < other.(*Float64).A { 279 | return -1 280 | } 281 | 282 | if i.A > other.(*Float64).A { 283 | return 1 284 | } 285 | 286 | return 0 287 | } 288 | 289 | // CompareAB implements Interface. 290 | func (i *Float64) CompareAB(other Interface) int { 291 | if i.A < other.(*Float64).B { 292 | return -1 293 | } 294 | 295 | if i.A > other.(*Float64).B { 296 | return 1 297 | } 298 | 299 | return 0 300 | } 301 | 302 | // CompareBB implements Interface. 303 | func (i *Float64) CompareBB(other Interface) int { 304 | if i.B < other.(*Float64).B { 305 | return -1 306 | } 307 | 308 | if i.B > other.(*Float64).B { 309 | return 1 310 | } 311 | 312 | return 0 313 | } 314 | 315 | // SetAB implements Interface. 316 | func (i *Float64) SetAB() { i.A = i.B } 317 | 318 | // SetB implements Interface. 319 | func (i *Float64) SetB(other Interface) { i.B = other.(*Float64).B } 320 | 321 | // SetBA implements Interface. 322 | func (i *Float64) SetBA(other Interface) { i.B = other.(*Float64).A } 323 | 324 | // Int8 is an interval having int8 bounds. 325 | type Int8 struct { 326 | Cls Class 327 | A, B int8 328 | } 329 | 330 | // String implements fmt.Stringer. 331 | func (i *Int8) String() string { return str(i.Cls, i.A, i.B) } 332 | 333 | // Class implements Interface. 334 | func (i *Int8) Class() Class { return i.Cls } 335 | 336 | // SetClass implements Interface. 337 | func (i *Int8) SetClass(c Class) { i.Cls = c } 338 | 339 | // Clone implements Interface. 340 | func (i *Int8) Clone() Interface { j := *i; return &j } 341 | 342 | // CompareAA implements Interface. 343 | func (i *Int8) CompareAA(other Interface) int { 344 | if i.A < other.(*Int8).A { 345 | return -1 346 | } 347 | 348 | if i.A > other.(*Int8).A { 349 | return 1 350 | } 351 | 352 | return 0 353 | } 354 | 355 | // CompareAB implements Interface. 356 | func (i *Int8) CompareAB(other Interface) int { 357 | if i.A < other.(*Int8).B { 358 | return -1 359 | } 360 | 361 | if i.A > other.(*Int8).B { 362 | return 1 363 | } 364 | 365 | return 0 366 | } 367 | 368 | // CompareBB implements Interface. 369 | func (i *Int8) CompareBB(other Interface) int { 370 | if i.B < other.(*Int8).B { 371 | return -1 372 | } 373 | 374 | if i.B > other.(*Int8).B { 375 | return 1 376 | } 377 | 378 | return 0 379 | } 380 | 381 | // SetAB implements Interface. 382 | func (i *Int8) SetAB() { i.A = i.B } 383 | 384 | // SetB implements Interface. 385 | func (i *Int8) SetB(other Interface) { i.B = other.(*Int8).B } 386 | 387 | // SetBA implements Interface. 388 | func (i *Int8) SetBA(other Interface) { i.B = other.(*Int8).A } 389 | 390 | // Int16 is an interval having int16 bounds. 391 | type Int16 struct { 392 | Cls Class 393 | A, B int16 394 | } 395 | 396 | // String implements fmt.Stringer. 397 | func (i *Int16) String() string { return str(i.Cls, i.A, i.B) } 398 | 399 | // Class implements Interface. 400 | func (i *Int16) Class() Class { return i.Cls } 401 | 402 | // SetClass implements Interface. 403 | func (i *Int16) SetClass(c Class) { i.Cls = c } 404 | 405 | // Clone implements Interface. 406 | func (i *Int16) Clone() Interface { j := *i; return &j } 407 | 408 | // CompareAA implements Interface. 409 | func (i *Int16) CompareAA(other Interface) int { 410 | if i.A < other.(*Int16).A { 411 | return -1 412 | } 413 | 414 | if i.A > other.(*Int16).A { 415 | return 1 416 | } 417 | 418 | return 0 419 | } 420 | 421 | // CompareAB implements Interface. 422 | func (i *Int16) CompareAB(other Interface) int { 423 | if i.A < other.(*Int16).B { 424 | return -1 425 | } 426 | 427 | if i.A > other.(*Int16).B { 428 | return 1 429 | } 430 | 431 | return 0 432 | } 433 | 434 | // CompareBB implements Interface. 435 | func (i *Int16) CompareBB(other Interface) int { 436 | if i.B < other.(*Int16).B { 437 | return -1 438 | } 439 | 440 | if i.B > other.(*Int16).B { 441 | return 1 442 | } 443 | 444 | return 0 445 | } 446 | 447 | // SetAB implements Interface. 448 | func (i *Int16) SetAB() { i.A = i.B } 449 | 450 | // SetB implements Interface. 451 | func (i *Int16) SetB(other Interface) { i.B = other.(*Int16).B } 452 | 453 | // SetBA implements Interface. 454 | func (i *Int16) SetBA(other Interface) { i.B = other.(*Int16).A } 455 | 456 | // Int32 is an interval having int32 bounds. 457 | type Int32 struct { 458 | Cls Class 459 | A, B int32 460 | } 461 | 462 | // String implements fmt.Stringer. 463 | func (i *Int32) String() string { return str(i.Cls, i.A, i.B) } 464 | 465 | // Class implements Interface. 466 | func (i *Int32) Class() Class { return i.Cls } 467 | 468 | // SetClass implements Interface. 469 | func (i *Int32) SetClass(c Class) { i.Cls = c } 470 | 471 | // Clone implements Interface. 472 | func (i *Int32) Clone() Interface { j := *i; return &j } 473 | 474 | // CompareAA implements Interface. 475 | func (i *Int32) CompareAA(other Interface) int { 476 | if i.A < other.(*Int32).A { 477 | return -1 478 | } 479 | 480 | if i.A > other.(*Int32).A { 481 | return 1 482 | } 483 | 484 | return 0 485 | } 486 | 487 | // CompareAB implements Interface. 488 | func (i *Int32) CompareAB(other Interface) int { 489 | if i.A < other.(*Int32).B { 490 | return -1 491 | } 492 | 493 | if i.A > other.(*Int32).B { 494 | return 1 495 | } 496 | 497 | return 0 498 | } 499 | 500 | // CompareBB implements Interface. 501 | func (i *Int32) CompareBB(other Interface) int { 502 | if i.B < other.(*Int32).B { 503 | return -1 504 | } 505 | 506 | if i.B > other.(*Int32).B { 507 | return 1 508 | } 509 | 510 | return 0 511 | } 512 | 513 | // SetAB implements Interface. 514 | func (i *Int32) SetAB() { i.A = i.B } 515 | 516 | // SetB implements Interface. 517 | func (i *Int32) SetB(other Interface) { i.B = other.(*Int32).B } 518 | 519 | // SetBA implements Interface. 520 | func (i *Int32) SetBA(other Interface) { i.B = other.(*Int32).A } 521 | 522 | // Int64 is an interval having int64 bounds. 523 | type Int64 struct { 524 | Cls Class 525 | A, B int64 526 | } 527 | 528 | // String implements fmt.Stringer. 529 | func (i *Int64) String() string { return str(i.Cls, i.A, i.B) } 530 | 531 | // Class implements Interface. 532 | func (i *Int64) Class() Class { return i.Cls } 533 | 534 | // SetClass implements Interface. 535 | func (i *Int64) SetClass(c Class) { i.Cls = c } 536 | 537 | // Clone implements Interface. 538 | func (i *Int64) Clone() Interface { j := *i; return &j } 539 | 540 | // CompareAA implements Interface. 541 | func (i *Int64) CompareAA(other Interface) int { 542 | if i.A < other.(*Int64).A { 543 | return -1 544 | } 545 | 546 | if i.A > other.(*Int64).A { 547 | return 1 548 | } 549 | 550 | return 0 551 | } 552 | 553 | // CompareAB implements Interface. 554 | func (i *Int64) CompareAB(other Interface) int { 555 | if i.A < other.(*Int64).B { 556 | return -1 557 | } 558 | 559 | if i.A > other.(*Int64).B { 560 | return 1 561 | } 562 | 563 | return 0 564 | } 565 | 566 | // CompareBB implements Interface. 567 | func (i *Int64) CompareBB(other Interface) int { 568 | if i.B < other.(*Int64).B { 569 | return -1 570 | } 571 | 572 | if i.B > other.(*Int64).B { 573 | return 1 574 | } 575 | 576 | return 0 577 | } 578 | 579 | // SetAB implements Interface. 580 | func (i *Int64) SetAB() { i.A = i.B } 581 | 582 | // SetB implements Interface. 583 | func (i *Int64) SetB(other Interface) { i.B = other.(*Int64).B } 584 | 585 | // SetBA implements Interface. 586 | func (i *Int64) SetBA(other Interface) { i.B = other.(*Int64).A } 587 | 588 | // Int128 is an interval having Int128 bounds. 589 | type Int128 struct { 590 | Cls Class 591 | A, B mathutil.Int128 592 | } 593 | 594 | // String implements fmt.Stringer. 595 | func (i *Int128) String() string { return str(i.Cls, i.A, i.B) } 596 | 597 | // Class implements Interface. 598 | func (i *Int128) Class() Class { return i.Cls } 599 | 600 | // SetClass implements Interface. 601 | func (i *Int128) SetClass(c Class) { i.Cls = c } 602 | 603 | // Clone implements Interface. 604 | func (i *Int128) Clone() Interface { j := *i; return &j } 605 | 606 | // CompareAA implements Interface. 607 | func (i *Int128) CompareAA(other Interface) int { return i.A.Cmp(other.(*Int128).A) } 608 | 609 | // CompareAB implements Interface. 610 | func (i *Int128) CompareAB(other Interface) int { return i.A.Cmp(other.(*Int128).B) } 611 | 612 | // CompareBB implements Interface. 613 | func (i *Int128) CompareBB(other Interface) int { return i.B.Cmp(other.(*Int128).B) } 614 | 615 | // SetAB implements Interface. 616 | func (i *Int128) SetAB() { i.A = i.B } 617 | 618 | // SetB implements Interface. 619 | func (i *Int128) SetB(other Interface) { i.B = other.(*Int128).B } 620 | 621 | // SetBA implements Interface. 622 | func (i *Int128) SetBA(other Interface) { i.B = other.(*Int128).A } 623 | 624 | // Int is an interval having int bounds. 625 | type Int struct { 626 | Cls Class 627 | A, B int 628 | } 629 | 630 | // String implements fmt.Stringer. 631 | func (i *Int) String() string { return str(i.Cls, i.A, i.B) } 632 | 633 | // Class implements Interface. 634 | func (i *Int) Class() Class { return i.Cls } 635 | 636 | // SetClass implements Interface. 637 | func (i *Int) SetClass(c Class) { i.Cls = c } 638 | 639 | // Clone implements Interface. 640 | func (i *Int) Clone() Interface { j := *i; return &j } 641 | 642 | // CompareAA implements Interface. 643 | func (i *Int) CompareAA(other Interface) int { 644 | if i.A < other.(*Int).A { 645 | return -1 646 | } 647 | 648 | if i.A > other.(*Int).A { 649 | return 1 650 | } 651 | 652 | return 0 653 | } 654 | 655 | // CompareAB implements Interface. 656 | func (i *Int) CompareAB(other Interface) int { 657 | if i.A < other.(*Int).B { 658 | return -1 659 | } 660 | 661 | if i.A > other.(*Int).B { 662 | return 1 663 | } 664 | 665 | return 0 666 | } 667 | 668 | // CompareBB implements Interface. 669 | func (i *Int) CompareBB(other Interface) int { 670 | if i.B < other.(*Int).B { 671 | return -1 672 | } 673 | 674 | if i.B > other.(*Int).B { 675 | return 1 676 | } 677 | 678 | return 0 679 | } 680 | 681 | // SetAB implements Interface. 682 | func (i *Int) SetAB() { i.A = i.B } 683 | 684 | // SetB implements Interface. 685 | func (i *Int) SetB(other Interface) { i.B = other.(*Int).B } 686 | 687 | // SetBA implements Interface. 688 | func (i *Int) SetBA(other Interface) { i.B = other.(*Int).A } 689 | 690 | // Byte is an interval having byte bounds. 691 | type Byte struct { 692 | Cls Class 693 | A, B byte 694 | } 695 | 696 | // String implements fmt.Stringer. 697 | func (i *Byte) String() string { return str(i.Cls, i.A, i.B) } 698 | 699 | // Class implements Interface. 700 | func (i *Byte) Class() Class { return i.Cls } 701 | 702 | // SetClass implements Interface. 703 | func (i *Byte) SetClass(c Class) { i.Cls = c } 704 | 705 | // Clone implements Interface. 706 | func (i *Byte) Clone() Interface { j := *i; return &j } 707 | 708 | // CompareAA implements Interface. 709 | func (i *Byte) CompareAA(other Interface) int { 710 | if i.A < other.(*Byte).A { 711 | return -1 712 | } 713 | 714 | if i.A > other.(*Byte).A { 715 | return 1 716 | } 717 | 718 | return 0 719 | } 720 | 721 | // CompareAB implements Interface. 722 | func (i *Byte) CompareAB(other Interface) int { 723 | if i.A < other.(*Byte).B { 724 | return -1 725 | } 726 | 727 | if i.A > other.(*Byte).B { 728 | return 1 729 | } 730 | 731 | return 0 732 | } 733 | 734 | // CompareBB implements Interface. 735 | func (i *Byte) CompareBB(other Interface) int { 736 | if i.B < other.(*Byte).B { 737 | return -1 738 | } 739 | 740 | if i.B > other.(*Byte).B { 741 | return 1 742 | } 743 | 744 | return 0 745 | } 746 | 747 | // SetAB implements Interface. 748 | func (i *Byte) SetAB() { i.A = i.B } 749 | 750 | // SetB implements Interface. 751 | func (i *Byte) SetB(other Interface) { i.B = other.(*Byte).B } 752 | 753 | // SetBA implements Interface. 754 | func (i *Byte) SetBA(other Interface) { i.B = other.(*Byte).A } 755 | 756 | // Uint16 is an interval having uint16 bounds. 757 | type Uint16 struct { 758 | Cls Class 759 | A, B uint16 760 | } 761 | 762 | // String implements fmt.Stringer. 763 | func (i *Uint16) String() string { return str(i.Cls, i.A, i.B) } 764 | 765 | // Class implements Interface. 766 | func (i *Uint16) Class() Class { return i.Cls } 767 | 768 | // SetClass implements Interface. 769 | func (i *Uint16) SetClass(c Class) { i.Cls = c } 770 | 771 | // Clone implements Interface. 772 | func (i *Uint16) Clone() Interface { j := *i; return &j } 773 | 774 | // CompareAA implements Interface. 775 | func (i *Uint16) CompareAA(other Interface) int { 776 | if i.A < other.(*Uint16).A { 777 | return -1 778 | } 779 | 780 | if i.A > other.(*Uint16).A { 781 | return 1 782 | } 783 | 784 | return 0 785 | } 786 | 787 | // CompareAB implements Interface. 788 | func (i *Uint16) CompareAB(other Interface) int { 789 | if i.A < other.(*Uint16).B { 790 | return -1 791 | } 792 | 793 | if i.A > other.(*Uint16).B { 794 | return 1 795 | } 796 | 797 | return 0 798 | } 799 | 800 | // CompareBB implements Interface. 801 | func (i *Uint16) CompareBB(other Interface) int { 802 | if i.B < other.(*Uint16).B { 803 | return -1 804 | } 805 | 806 | if i.B > other.(*Uint16).B { 807 | return 1 808 | } 809 | 810 | return 0 811 | } 812 | 813 | // SetAB implements Interface. 814 | func (i *Uint16) SetAB() { i.A = i.B } 815 | 816 | // SetB implements Interface. 817 | func (i *Uint16) SetB(other Interface) { i.B = other.(*Uint16).B } 818 | 819 | // SetBA implements Interface. 820 | func (i *Uint16) SetBA(other Interface) { i.B = other.(*Uint16).A } 821 | 822 | // Uint32 is an interval having uint32 bounds. 823 | type Uint32 struct { 824 | Cls Class 825 | A, B uint32 826 | } 827 | 828 | // String implements fmt.Stringer. 829 | func (i *Uint32) String() string { return str(i.Cls, i.A, i.B) } 830 | 831 | // Class implements Interface. 832 | func (i *Uint32) Class() Class { return i.Cls } 833 | 834 | // SetClass implements Interface. 835 | func (i *Uint32) SetClass(c Class) { i.Cls = c } 836 | 837 | // Clone implements Interface. 838 | func (i *Uint32) Clone() Interface { j := *i; return &j } 839 | 840 | // CompareAA implements Interface. 841 | func (i *Uint32) CompareAA(other Interface) int { 842 | if i.A < other.(*Uint32).A { 843 | return -1 844 | } 845 | 846 | if i.A > other.(*Uint32).A { 847 | return 1 848 | } 849 | 850 | return 0 851 | } 852 | 853 | // CompareAB implements Interface. 854 | func (i *Uint32) CompareAB(other Interface) int { 855 | if i.A < other.(*Uint32).B { 856 | return -1 857 | } 858 | 859 | if i.A > other.(*Uint32).B { 860 | return 1 861 | } 862 | 863 | return 0 864 | } 865 | 866 | // CompareBB implements Interface. 867 | func (i *Uint32) CompareBB(other Interface) int { 868 | if i.B < other.(*Uint32).B { 869 | return -1 870 | } 871 | 872 | if i.B > other.(*Uint32).B { 873 | return 1 874 | } 875 | 876 | return 0 877 | } 878 | 879 | // SetAB implements Interface. 880 | func (i *Uint32) SetAB() { i.A = i.B } 881 | 882 | // SetB implements Interface. 883 | func (i *Uint32) SetB(other Interface) { i.B = other.(*Uint32).B } 884 | 885 | // SetBA implements Interface. 886 | func (i *Uint32) SetBA(other Interface) { i.B = other.(*Uint32).A } 887 | 888 | // Uint64 is an interval having uint64 bounds. 889 | type Uint64 struct { 890 | Cls Class 891 | A, B uint64 892 | } 893 | 894 | // String implements fmt.Stringer. 895 | func (i *Uint64) String() string { return str(i.Cls, i.A, i.B) } 896 | 897 | // Class implements Interface. 898 | func (i *Uint64) Class() Class { return i.Cls } 899 | 900 | // SetClass implements Interface. 901 | func (i *Uint64) SetClass(c Class) { i.Cls = c } 902 | 903 | // Clone implements Interface. 904 | func (i *Uint64) Clone() Interface { j := *i; return &j } 905 | 906 | // CompareAA implements Interface. 907 | func (i *Uint64) CompareAA(other Interface) int { 908 | if i.A < other.(*Uint64).A { 909 | return -1 910 | } 911 | 912 | if i.A > other.(*Uint64).A { 913 | return 1 914 | } 915 | 916 | return 0 917 | } 918 | 919 | // CompareAB implements Interface. 920 | func (i *Uint64) CompareAB(other Interface) int { 921 | if i.A < other.(*Uint64).B { 922 | return -1 923 | } 924 | 925 | if i.A > other.(*Uint64).B { 926 | return 1 927 | } 928 | 929 | return 0 930 | } 931 | 932 | // CompareBB implements Interface. 933 | func (i *Uint64) CompareBB(other Interface) int { 934 | if i.B < other.(*Uint64).B { 935 | return -1 936 | } 937 | 938 | if i.B > other.(*Uint64).B { 939 | return 1 940 | } 941 | 942 | return 0 943 | } 944 | 945 | // SetAB implements Interface. 946 | func (i *Uint64) SetAB() { i.A = i.B } 947 | 948 | // SetB implements Interface. 949 | func (i *Uint64) SetB(other Interface) { i.B = other.(*Uint64).B } 950 | 951 | // SetBA implements Interface. 952 | func (i *Uint64) SetBA(other Interface) { i.B = other.(*Uint64).A } 953 | 954 | // Uint is an interval having uint bounds. 955 | type Uint struct { 956 | Cls Class 957 | A, B uint 958 | } 959 | 960 | // String implements fmt.Stringer. 961 | func (i *Uint) String() string { return str(i.Cls, i.A, i.B) } 962 | 963 | // Class implements Interface. 964 | func (i *Uint) Class() Class { return i.Cls } 965 | 966 | // SetClass implements Interface. 967 | func (i *Uint) SetClass(c Class) { i.Cls = c } 968 | 969 | // Clone implements Interface. 970 | func (i *Uint) Clone() Interface { j := *i; return &j } 971 | 972 | // CompareAA implements Interface. 973 | func (i *Uint) CompareAA(other Interface) int { 974 | if i.A < other.(*Uint).A { 975 | return -1 976 | } 977 | 978 | if i.A > other.(*Uint).A { 979 | return 1 980 | } 981 | 982 | return 0 983 | } 984 | 985 | // CompareAB implements Interface. 986 | func (i *Uint) CompareAB(other Interface) int { 987 | if i.A < other.(*Uint).B { 988 | return -1 989 | } 990 | 991 | if i.A > other.(*Uint).B { 992 | return 1 993 | } 994 | 995 | return 0 996 | } 997 | 998 | // CompareBB implements Interface. 999 | func (i *Uint) CompareBB(other Interface) int { 1000 | if i.B < other.(*Uint).B { 1001 | return -1 1002 | } 1003 | 1004 | if i.B > other.(*Uint).B { 1005 | return 1 1006 | } 1007 | 1008 | return 0 1009 | } 1010 | 1011 | // SetAB implements Interface. 1012 | func (i *Uint) SetAB() { i.A = i.B } 1013 | 1014 | // SetB implements Interface. 1015 | func (i *Uint) SetB(other Interface) { i.B = other.(*Uint).B } 1016 | 1017 | // SetBA implements Interface. 1018 | func (i *Uint) SetBA(other Interface) { i.B = other.(*Uint).A } 1019 | 1020 | // String is an interval having string bounds. 1021 | type String struct { 1022 | Cls Class 1023 | A, B string 1024 | } 1025 | 1026 | // String implements fmt.Stringer. 1027 | func (i *String) String() string { return str(i.Cls, i.A, i.B) } 1028 | 1029 | // Class implements Interface. 1030 | func (i *String) Class() Class { return i.Cls } 1031 | 1032 | // SetClass implements Interface. 1033 | func (i *String) SetClass(c Class) { i.Cls = c } 1034 | 1035 | // Clone implements Interface. 1036 | func (i *String) Clone() Interface { j := *i; return &j } 1037 | 1038 | // CompareAA implements Interface. 1039 | func (i *String) CompareAA(other Interface) int { 1040 | if i.A < other.(*String).A { 1041 | return -1 1042 | } 1043 | 1044 | if i.A > other.(*String).A { 1045 | return 1 1046 | } 1047 | 1048 | return 0 1049 | } 1050 | 1051 | // CompareAB implements Interface. 1052 | func (i *String) CompareAB(other Interface) int { 1053 | if i.A < other.(*String).B { 1054 | return -1 1055 | } 1056 | 1057 | if i.A > other.(*String).B { 1058 | return 1 1059 | } 1060 | 1061 | return 0 1062 | } 1063 | 1064 | // CompareBB implements Interface. 1065 | func (i *String) CompareBB(other Interface) int { 1066 | if i.B < other.(*String).B { 1067 | return -1 1068 | } 1069 | 1070 | if i.B > other.(*String).B { 1071 | return 1 1072 | } 1073 | 1074 | return 0 1075 | } 1076 | 1077 | // SetAB implements Interface. 1078 | func (i *String) SetAB() { i.A = i.B } 1079 | 1080 | // SetB implements Interface. 1081 | func (i *String) SetB(other Interface) { i.B = other.(*String).B } 1082 | 1083 | // SetBA implements Interface. 1084 | func (i *String) SetBA(other Interface) { i.B = other.(*String).A } 1085 | 1086 | // Time is an interval having time.Time bounds. 1087 | type Time struct { 1088 | Cls Class 1089 | A, B time.Time 1090 | } 1091 | 1092 | // String implements fmt.Stringer. 1093 | func (i *Time) String() string { return str(i.Cls, i.A, i.B) } 1094 | 1095 | // Class implements Interface. 1096 | func (i *Time) Class() Class { return i.Cls } 1097 | 1098 | // SetClass implements Interface. 1099 | func (i *Time) SetClass(c Class) { i.Cls = c } 1100 | 1101 | // Clone implements Interface. 1102 | func (i *Time) Clone() Interface { j := *i; return &j } 1103 | 1104 | // CompareAA implements Interface. 1105 | func (i *Time) CompareAA(other Interface) int { 1106 | if i.A.Before(other.(*Time).A) { 1107 | return -1 1108 | } 1109 | 1110 | if i.A.After(other.(*Time).A) { 1111 | return 1 1112 | } 1113 | 1114 | return 0 1115 | } 1116 | 1117 | // CompareAB implements Interface. 1118 | func (i *Time) CompareAB(other Interface) int { 1119 | if i.A.Before(other.(*Time).B) { 1120 | return -1 1121 | } 1122 | 1123 | if i.A.After(other.(*Time).B) { 1124 | return 1 1125 | } 1126 | 1127 | return 0 1128 | } 1129 | 1130 | // CompareBB implements Interface. 1131 | func (i *Time) CompareBB(other Interface) int { 1132 | if i.B.Before(other.(*Time).B) { 1133 | return -1 1134 | } 1135 | 1136 | if i.B.After(other.(*Time).B) { 1137 | return 1 1138 | } 1139 | 1140 | return 0 1141 | } 1142 | 1143 | // SetAB implements Interface. 1144 | func (i *Time) SetAB() { i.A = i.B } 1145 | 1146 | // SetB implements Interface. 1147 | func (i *Time) SetB(other Interface) { i.B = other.(*Time).B } 1148 | 1149 | // SetBA implements Interface. 1150 | func (i *Time) SetBA(other Interface) { i.B = other.(*Time).A } 1151 | 1152 | // Duration is an interval having time.Duration bounds. 1153 | type Duration struct { 1154 | Cls Class 1155 | A, B time.Duration 1156 | } 1157 | 1158 | // String implements fmt.Stringer. 1159 | func (i *Duration) String() string { return str(i.Cls, i.A, i.B) } 1160 | 1161 | // Class implements Interface. 1162 | func (i *Duration) Class() Class { return i.Cls } 1163 | 1164 | // SetClass implements Interface. 1165 | func (i *Duration) SetClass(c Class) { i.Cls = c } 1166 | 1167 | // Clone implements Interface. 1168 | func (i *Duration) Clone() Interface { j := *i; return &j } 1169 | 1170 | // CompareAA implements Interface. 1171 | func (i *Duration) CompareAA(other Interface) int { 1172 | if i.A < other.(*Duration).A { 1173 | return -1 1174 | } 1175 | 1176 | if i.A > other.(*Duration).A { 1177 | return 1 1178 | } 1179 | 1180 | return 0 1181 | } 1182 | 1183 | // CompareAB implements Interface. 1184 | func (i *Duration) CompareAB(other Interface) int { 1185 | if i.A < other.(*Duration).B { 1186 | return -1 1187 | } 1188 | 1189 | if i.A > other.(*Duration).B { 1190 | return 1 1191 | } 1192 | 1193 | return 0 1194 | } 1195 | 1196 | // CompareBB implements Interface. 1197 | func (i *Duration) CompareBB(other Interface) int { 1198 | if i.B < other.(*Duration).B { 1199 | return -1 1200 | } 1201 | 1202 | if i.B > other.(*Duration).B { 1203 | return 1 1204 | } 1205 | 1206 | return 0 1207 | } 1208 | 1209 | // SetAB implements Interface. 1210 | func (i *Duration) SetAB() { i.A = i.B } 1211 | 1212 | // SetB implements Interface. 1213 | func (i *Duration) SetB(other Interface) { i.B = other.(*Duration).B } 1214 | 1215 | // SetBA implements Interface. 1216 | func (i *Duration) SetBA(other Interface) { i.B = other.(*Duration).A } 1217 | 1218 | // BigInt is an interval having math/big.Int bounds. 1219 | type BigInt struct { 1220 | Cls Class 1221 | A, B *big.Int 1222 | } 1223 | 1224 | // String implements fmt.Stringer. 1225 | func (i *BigInt) String() string { return str(i.Cls, i.A, i.B) } 1226 | 1227 | // Class implements Interface. 1228 | func (i *BigInt) Class() Class { return i.Cls } 1229 | 1230 | // SetClass implements Interface. 1231 | func (i *BigInt) SetClass(c Class) { i.Cls = c } 1232 | 1233 | // Clone implements Interface. 1234 | func (i *BigInt) Clone() Interface { 1235 | j := &BigInt{Cls: i.Cls} 1236 | if i.A != nil { 1237 | j.A = big.NewInt(0).Set(i.A) 1238 | } 1239 | if i.B != nil { 1240 | j.B = big.NewInt(0).Set(i.B) 1241 | } 1242 | return j 1243 | } 1244 | 1245 | // CompareAA implements Interface. 1246 | func (i *BigInt) CompareAA(other Interface) int { 1247 | return i.A.Cmp(other.(*BigInt).A) 1248 | } 1249 | 1250 | // CompareAB implements Interface. 1251 | func (i *BigInt) CompareAB(other Interface) int { 1252 | return i.A.Cmp(other.(*BigInt).B) 1253 | } 1254 | 1255 | // CompareBB implements Interface. 1256 | func (i *BigInt) CompareBB(other Interface) int { 1257 | return i.B.Cmp(other.(*BigInt).B) 1258 | } 1259 | 1260 | // SetAB implements Interface. 1261 | func (i *BigInt) SetAB() { i.A.Set(i.B) } 1262 | 1263 | // SetB implements Interface. 1264 | func (i *BigInt) SetB(other Interface) { i.B.Set(other.(*BigInt).B) } 1265 | 1266 | // SetBA implements Interface. 1267 | func (i *BigInt) SetBA(other Interface) { i.B.Set(other.(*BigInt).A) } 1268 | 1269 | // BigRat is an interval having math/big.Rat bounds. 1270 | type BigRat struct { 1271 | Cls Class 1272 | A, B *big.Rat 1273 | } 1274 | 1275 | // String implements fmt.Stringer. 1276 | func (i *BigRat) String() string { return str(i.Cls, i.A, i.B) } 1277 | 1278 | // Class implements Interface. 1279 | func (i *BigRat) Class() Class { return i.Cls } 1280 | 1281 | // SetClass implements Interface. 1282 | func (i *BigRat) SetClass(c Class) { i.Cls = c } 1283 | 1284 | // Clone implements Interface. 1285 | func (i *BigRat) Clone() Interface { 1286 | j := &BigRat{Cls: i.Cls} 1287 | if i.A != nil { 1288 | j.A = big.NewRat(1, 1).Set(i.A) 1289 | } 1290 | if i.B != nil { 1291 | j.B = big.NewRat(1, 1).Set(i.B) 1292 | } 1293 | return j 1294 | } 1295 | 1296 | // CompareAA implements Interface. 1297 | func (i *BigRat) CompareAA(other Interface) int { 1298 | return i.A.Cmp(other.(*BigRat).A) 1299 | } 1300 | 1301 | // CompareAB implements Interface. 1302 | func (i *BigRat) CompareAB(other Interface) int { 1303 | return i.A.Cmp(other.(*BigRat).B) 1304 | } 1305 | 1306 | // CompareBB implements Interface. 1307 | func (i *BigRat) CompareBB(other Interface) int { 1308 | return i.B.Cmp(other.(*BigRat).B) 1309 | } 1310 | 1311 | // SetAB implements Interface. 1312 | func (i *BigRat) SetAB() { i.A.Set(i.B) } 1313 | 1314 | // SetB implements Interface. 1315 | func (i *BigRat) SetB(other Interface) { i.B.Set(other.(*BigRat).B) } 1316 | 1317 | // SetBA implements Interface. 1318 | func (i *BigRat) SetBA(other Interface) { i.B.Set(other.(*BigRat).A) } 1319 | --------------------------------------------------------------------------------