github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/ssa/poset_test.go (about) 1 // Copyright 2018 The Go 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 ssa 6 7 import ( 8 "fmt" 9 "testing" 10 ) 11 12 const ( 13 SetOrder = "SetOrder" 14 SetOrder_Fail = "SetOrder_Fail" 15 SetOrderOrEqual = "SetOrderOrEqual" 16 SetOrderOrEqual_Fail = "SetOrderOrEqual_Fail" 17 Ordered = "Ordered" 18 Ordered_Fail = "Ordered_Fail" 19 OrderedOrEqual = "OrderedOrEqual" 20 OrderedOrEqual_Fail = "OrderedOrEqual_Fail" 21 SetEqual = "SetEqual" 22 SetEqual_Fail = "SetEqual_Fail" 23 Equal = "Equal" 24 Equal_Fail = "Equal_Fail" 25 SetNonEqual = "SetNonEqual" 26 SetNonEqual_Fail = "SetNonEqual_Fail" 27 NonEqual = "NonEqual" 28 NonEqual_Fail = "NonEqual_Fail" 29 Checkpoint = "Checkpoint" 30 Undo = "Undo" 31 ) 32 33 type posetTestOp struct { 34 typ string 35 a, b int 36 } 37 38 func vconst(i int) int { 39 if i < -128 || i >= 128 { 40 panic("invalid const") 41 } 42 return 1000 + 128 + i 43 } 44 45 func vconst2(i int) int { 46 if i < -128 || i >= 128 { 47 panic("invalid const") 48 } 49 return 1000 + 256 + i 50 } 51 52 func testPosetOps(t *testing.T, unsigned bool, ops []posetTestOp) { 53 var v [1512]*Value 54 for i := range v { 55 v[i] = new(Value) 56 v[i].ID = ID(i) 57 if i >= 1000 && i < 1256 { 58 v[i].Op = OpConst64 59 v[i].AuxInt = int64(i - 1000 - 128) 60 } 61 if i >= 1256 && i < 1512 { 62 v[i].Op = OpConst64 63 v[i].AuxInt = int64(i - 1000 - 256) 64 } 65 } 66 67 po := newPoset() 68 po.SetUnsigned(unsigned) 69 for idx, op := range ops { 70 t.Logf("op%d%v", idx, op) 71 switch op.typ { 72 case SetOrder: 73 if !po.SetOrder(v[op.a], v[op.b]) { 74 t.Errorf("FAILED: op%d%v failed", idx, op) 75 } 76 case SetOrder_Fail: 77 if po.SetOrder(v[op.a], v[op.b]) { 78 t.Errorf("FAILED: op%d%v passed", idx, op) 79 } 80 case SetOrderOrEqual: 81 if !po.SetOrderOrEqual(v[op.a], v[op.b]) { 82 t.Errorf("FAILED: op%d%v failed", idx, op) 83 } 84 case SetOrderOrEqual_Fail: 85 if po.SetOrderOrEqual(v[op.a], v[op.b]) { 86 t.Errorf("FAILED: op%d%v passed", idx, op) 87 } 88 case Ordered: 89 if !po.Ordered(v[op.a], v[op.b]) { 90 t.Errorf("FAILED: op%d%v failed", idx, op) 91 } 92 case Ordered_Fail: 93 if po.Ordered(v[op.a], v[op.b]) { 94 t.Errorf("FAILED: op%d%v passed", idx, op) 95 } 96 case OrderedOrEqual: 97 if !po.OrderedOrEqual(v[op.a], v[op.b]) { 98 t.Errorf("FAILED: op%d%v failed", idx, op) 99 } 100 case OrderedOrEqual_Fail: 101 if po.OrderedOrEqual(v[op.a], v[op.b]) { 102 t.Errorf("FAILED: op%d%v passed", idx, op) 103 } 104 case SetEqual: 105 if !po.SetEqual(v[op.a], v[op.b]) { 106 t.Errorf("FAILED: op%d%v failed", idx, op) 107 } 108 case SetEqual_Fail: 109 if po.SetEqual(v[op.a], v[op.b]) { 110 t.Errorf("FAILED: op%d%v passed", idx, op) 111 } 112 case Equal: 113 if !po.Equal(v[op.a], v[op.b]) { 114 t.Errorf("FAILED: op%d%v failed", idx, op) 115 } 116 case Equal_Fail: 117 if po.Equal(v[op.a], v[op.b]) { 118 t.Errorf("FAILED: op%d%v passed", idx, op) 119 } 120 case SetNonEqual: 121 if !po.SetNonEqual(v[op.a], v[op.b]) { 122 t.Errorf("FAILED: op%d%v failed", idx, op) 123 } 124 case SetNonEqual_Fail: 125 if po.SetNonEqual(v[op.a], v[op.b]) { 126 t.Errorf("FAILED: op%d%v passed", idx, op) 127 } 128 case NonEqual: 129 if !po.NonEqual(v[op.a], v[op.b]) { 130 t.Errorf("FAILED: op%d%v failed", idx, op) 131 } 132 case NonEqual_Fail: 133 if po.NonEqual(v[op.a], v[op.b]) { 134 t.Errorf("FAILED: op%d%v passed", idx, op) 135 } 136 case Checkpoint: 137 po.Checkpoint() 138 case Undo: 139 t.Log("Undo stack", po.undo) 140 po.Undo() 141 default: 142 panic("unimplemented") 143 } 144 145 if false { 146 po.DotDump(fmt.Sprintf("op%d.dot", idx), fmt.Sprintf("Last op: %v", op)) 147 } 148 149 po.CheckIntegrity() 150 } 151 152 // Check that the poset is completely empty 153 if err := po.CheckEmpty(); err != nil { 154 t.Error(err) 155 } 156 } 157 158 func TestPoset(t *testing.T) { 159 testPosetOps(t, false, []posetTestOp{ 160 {Ordered_Fail, 123, 124}, 161 162 // Dag #0: 100<101 163 {Checkpoint, 0, 0}, 164 {SetOrder, 100, 101}, 165 {Ordered, 100, 101}, 166 {Ordered_Fail, 101, 100}, 167 {SetOrder_Fail, 101, 100}, 168 {SetOrder, 100, 101}, // repeat 169 {NonEqual, 100, 101}, 170 {NonEqual, 101, 100}, 171 {SetEqual_Fail, 100, 101}, 172 173 // Dag #1: 4<=7<12 174 {Checkpoint, 0, 0}, 175 {SetOrderOrEqual, 4, 7}, 176 {OrderedOrEqual, 4, 7}, 177 {SetOrder, 7, 12}, 178 {Ordered, 7, 12}, 179 {Ordered, 4, 12}, 180 {Ordered_Fail, 12, 4}, 181 {NonEqual, 4, 12}, 182 {NonEqual, 12, 4}, 183 {NonEqual_Fail, 4, 100}, 184 {OrderedOrEqual, 4, 12}, 185 {OrderedOrEqual_Fail, 12, 4}, 186 {OrderedOrEqual, 4, 7}, 187 {OrderedOrEqual_Fail, 7, 4}, 188 189 // Dag #1: 1<4<=7<12 190 {Checkpoint, 0, 0}, 191 {SetOrder, 1, 4}, 192 {Ordered, 1, 4}, 193 {Ordered, 1, 12}, 194 {Ordered_Fail, 12, 1}, 195 196 // Dag #1: 1<4<=7<12, 6<7 197 {Checkpoint, 0, 0}, 198 {SetOrder, 6, 7}, 199 {Ordered, 6, 7}, 200 {Ordered, 6, 12}, 201 {SetOrder_Fail, 7, 4}, 202 {SetOrder_Fail, 7, 6}, 203 {SetOrder_Fail, 7, 1}, 204 205 // Dag #1: 1<4<=7<12, 1<6<7 206 {Checkpoint, 0, 0}, 207 {Ordered_Fail, 1, 6}, 208 {SetOrder, 1, 6}, 209 {Ordered, 1, 6}, 210 {SetOrder_Fail, 6, 1}, 211 212 // Dag #1: 1<4<=7<12, 1<4<6<7 213 {Checkpoint, 0, 0}, 214 {Ordered_Fail, 4, 6}, 215 {Ordered_Fail, 4, 7}, 216 {SetOrder, 4, 6}, 217 {Ordered, 4, 6}, 218 {OrderedOrEqual, 4, 6}, 219 {Ordered, 4, 7}, 220 {OrderedOrEqual, 4, 7}, 221 {SetOrder_Fail, 6, 4}, 222 {Ordered_Fail, 7, 6}, 223 {Ordered_Fail, 7, 4}, 224 {OrderedOrEqual_Fail, 7, 6}, 225 {OrderedOrEqual_Fail, 7, 4}, 226 227 // Merge: 1<4<6, 4<=7<12, 6<101 228 {Checkpoint, 0, 0}, 229 {Ordered_Fail, 6, 101}, 230 {SetOrder, 6, 101}, 231 {Ordered, 6, 101}, 232 {Ordered, 1, 101}, 233 234 // Merge: 1<4<6, 4<=7<12, 6<100<101 235 {Checkpoint, 0, 0}, 236 {Ordered_Fail, 6, 100}, 237 {SetOrder, 6, 100}, 238 {Ordered, 1, 100}, 239 240 // Undo: 1<4<6<7<12, 6<101 241 {Ordered, 100, 101}, 242 {Undo, 0, 0}, 243 {Ordered, 100, 101}, 244 {Ordered_Fail, 6, 100}, 245 {Ordered, 6, 101}, 246 {Ordered, 1, 101}, 247 248 // Undo: 1<4<6<7<12, 100<101 249 {Undo, 0, 0}, 250 {Ordered_Fail, 1, 100}, 251 {Ordered_Fail, 1, 101}, 252 {Ordered_Fail, 6, 100}, 253 {Ordered_Fail, 6, 101}, 254 255 // Merge: 1<4<6<7<12, 6<100<101 256 {Checkpoint, 0, 0}, 257 {Ordered, 100, 101}, 258 {SetOrder, 6, 100}, 259 {Ordered, 6, 100}, 260 {Ordered, 6, 101}, 261 {Ordered, 1, 101}, 262 263 // Undo 2 times: 1<4<7<12, 1<6<7 264 {Undo, 0, 0}, 265 {Undo, 0, 0}, 266 {Ordered, 1, 6}, 267 {Ordered, 4, 12}, 268 {Ordered_Fail, 4, 6}, 269 {SetOrder_Fail, 6, 1}, 270 271 // Undo 2 times: 1<4<7<12 272 {Undo, 0, 0}, 273 {Undo, 0, 0}, 274 {Ordered, 1, 12}, 275 {Ordered, 7, 12}, 276 {Ordered_Fail, 1, 6}, 277 {Ordered_Fail, 6, 7}, 278 {Ordered, 100, 101}, 279 {Ordered_Fail, 1, 101}, 280 281 // Undo: 4<7<12 282 {Undo, 0, 0}, 283 {Ordered_Fail, 1, 12}, 284 {Ordered_Fail, 1, 4}, 285 {Ordered, 4, 12}, 286 {Ordered, 100, 101}, 287 288 // Undo: 100<101 289 {Undo, 0, 0}, 290 {Ordered_Fail, 4, 7}, 291 {Ordered_Fail, 7, 12}, 292 {Ordered, 100, 101}, 293 294 // Recreated DAG #1 from scratch, reusing same nodes. 295 // This also stresses that Undo has done its job correctly. 296 // DAG: 1<2<(5|6), 101<102<(105|106<107) 297 {Checkpoint, 0, 0}, 298 {SetOrder, 101, 102}, 299 {SetOrder, 102, 105}, 300 {SetOrder, 102, 106}, 301 {SetOrder, 106, 107}, 302 {SetOrder, 1, 2}, 303 {SetOrder, 2, 5}, 304 {SetOrder, 2, 6}, 305 {SetEqual_Fail, 1, 6}, 306 {SetEqual_Fail, 107, 102}, 307 308 // Now Set 2 == 102 309 // New DAG: (1|101)<2==102<(5|6|105|106<107) 310 {Checkpoint, 0, 0}, 311 {SetEqual, 2, 102}, 312 {Equal, 2, 102}, 313 {SetEqual, 2, 102}, // trivially pass 314 {SetNonEqual_Fail, 2, 102}, // trivially fail 315 {Ordered, 1, 107}, 316 {Ordered, 101, 6}, 317 {Ordered, 101, 105}, 318 {Ordered, 2, 106}, 319 {Ordered, 102, 6}, 320 321 // Undo SetEqual 322 {Undo, 0, 0}, 323 {Equal_Fail, 2, 102}, 324 {Ordered_Fail, 2, 102}, 325 {Ordered_Fail, 1, 107}, 326 {Ordered_Fail, 101, 6}, 327 {Checkpoint, 0, 0}, 328 {SetEqual, 2, 100}, 329 {Ordered, 1, 107}, 330 {Ordered, 100, 6}, 331 332 // SetEqual with new node 333 {Undo, 0, 0}, 334 {Checkpoint, 0, 0}, 335 {SetEqual, 2, 400}, 336 {SetEqual, 401, 2}, 337 {Equal, 400, 401}, 338 {Ordered, 1, 400}, 339 {Ordered, 400, 6}, 340 {Ordered, 1, 401}, 341 {Ordered, 401, 6}, 342 {Ordered_Fail, 2, 401}, 343 344 // SetEqual unseen nodes and then connect 345 {Checkpoint, 0, 0}, 346 {SetEqual, 500, 501}, 347 {SetEqual, 102, 501}, 348 {Equal, 500, 102}, 349 {Ordered, 501, 106}, 350 {Ordered, 100, 500}, 351 {SetEqual, 500, 501}, 352 {Ordered_Fail, 500, 501}, 353 {Ordered_Fail, 102, 501}, 354 355 // SetNonEqual relations 356 {Undo, 0, 0}, 357 {Checkpoint, 0, 0}, 358 {SetNonEqual, 600, 601}, 359 {NonEqual, 600, 601}, 360 {SetNonEqual, 601, 602}, 361 {NonEqual, 601, 602}, 362 {NonEqual_Fail, 600, 602}, // non-transitive 363 {SetEqual_Fail, 601, 602}, 364 365 // Undo back to beginning, leave the poset empty 366 {Undo, 0, 0}, 367 {Undo, 0, 0}, 368 {Undo, 0, 0}, 369 {Undo, 0, 0}, 370 }) 371 } 372 373 func TestPosetStrict(t *testing.T) { 374 375 testPosetOps(t, false, []posetTestOp{ 376 {Checkpoint, 0, 0}, 377 // Build: 20!=30, 10<20<=30<40. The 20<=30 will become 20<30. 378 {SetNonEqual, 20, 30}, 379 {SetOrder, 10, 20}, 380 {SetOrderOrEqual, 20, 30}, // this is affected by 20!=30 381 {SetOrder, 30, 40}, 382 383 {Ordered, 10, 30}, 384 {Ordered, 20, 30}, 385 {Ordered, 10, 40}, 386 {OrderedOrEqual, 10, 30}, 387 {OrderedOrEqual, 20, 30}, 388 {OrderedOrEqual, 10, 40}, 389 390 {Undo, 0, 0}, 391 392 // Now do the opposite: first build the DAG and then learn non-equality 393 {Checkpoint, 0, 0}, 394 {SetOrder, 10, 20}, 395 {SetOrderOrEqual, 20, 30}, // this is affected by 20!=30 396 {SetOrder, 30, 40}, 397 398 {Ordered, 10, 30}, 399 {Ordered_Fail, 20, 30}, 400 {Ordered, 10, 40}, 401 {OrderedOrEqual, 10, 30}, 402 {OrderedOrEqual, 20, 30}, 403 {OrderedOrEqual, 10, 40}, 404 405 {Checkpoint, 0, 0}, 406 {SetNonEqual, 20, 30}, 407 {Ordered, 10, 30}, 408 {Ordered, 20, 30}, 409 {Ordered, 10, 40}, 410 {OrderedOrEqual, 10, 30}, 411 {OrderedOrEqual, 20, 30}, 412 {OrderedOrEqual, 10, 40}, 413 {Undo, 0, 0}, 414 415 {Checkpoint, 0, 0}, 416 {SetOrderOrEqual, 30, 35}, 417 {OrderedOrEqual, 20, 35}, 418 {Ordered_Fail, 20, 35}, 419 {SetNonEqual, 20, 35}, 420 {Ordered, 20, 35}, 421 {Undo, 0, 0}, 422 423 // Learn <= and >= 424 {Checkpoint, 0, 0}, 425 {SetOrderOrEqual, 50, 60}, 426 {SetOrderOrEqual, 60, 50}, 427 {OrderedOrEqual, 50, 60}, 428 {OrderedOrEqual, 60, 50}, 429 {Ordered_Fail, 50, 60}, 430 {Ordered_Fail, 60, 50}, 431 {Equal, 50, 60}, 432 {Equal, 60, 50}, 433 {NonEqual_Fail, 50, 60}, 434 {NonEqual_Fail, 60, 50}, 435 {Undo, 0, 0}, 436 437 {Undo, 0, 0}, 438 }) 439 } 440 441 func TestPosetCollapse(t *testing.T) { 442 testPosetOps(t, false, []posetTestOp{ 443 {Checkpoint, 0, 0}, 444 // Create a complex graph of <= relations among nodes between 10 and 25. 445 {SetOrderOrEqual, 10, 15}, 446 {SetOrderOrEqual, 15, 20}, 447 {SetOrderOrEqual, 20, vconst(20)}, 448 {SetOrderOrEqual, vconst(20), 25}, 449 {SetOrderOrEqual, 10, 12}, 450 {SetOrderOrEqual, 12, 16}, 451 {SetOrderOrEqual, 16, vconst(20)}, 452 {SetOrderOrEqual, 10, 17}, 453 {SetOrderOrEqual, 17, 25}, 454 {SetOrderOrEqual, 15, 18}, 455 {SetOrderOrEqual, 18, vconst(20)}, 456 {SetOrderOrEqual, 15, 19}, 457 {SetOrderOrEqual, 19, 25}, 458 459 // These are other paths not part of the main collapsing path 460 {SetOrderOrEqual, 10, 11}, 461 {SetOrderOrEqual, 11, 26}, 462 {SetOrderOrEqual, 13, 25}, 463 {SetOrderOrEqual, 100, 25}, 464 {SetOrderOrEqual, 101, 15}, 465 {SetOrderOrEqual, 102, 10}, 466 {SetOrderOrEqual, 25, 103}, 467 {SetOrderOrEqual, 20, 104}, 468 469 {Checkpoint, 0, 0}, 470 // Collapse everything by setting 10 >= 25: this should make everything equal 471 {SetOrderOrEqual, 25, 10}, 472 473 // Check that all nodes are pairwise equal now 474 {Equal, 10, 12}, 475 {Equal, 10, 15}, 476 {Equal, 10, 16}, 477 {Equal, 10, 17}, 478 {Equal, 10, 18}, 479 {Equal, 10, 19}, 480 {Equal, 10, vconst(20)}, 481 {Equal, 10, vconst2(20)}, 482 {Equal, 10, 25}, 483 484 {Equal, 12, 15}, 485 {Equal, 12, 16}, 486 {Equal, 12, 17}, 487 {Equal, 12, 18}, 488 {Equal, 12, 19}, 489 {Equal, 12, vconst(20)}, 490 {Equal, 12, vconst2(20)}, 491 {Equal, 12, 25}, 492 493 {Equal, 15, 16}, 494 {Equal, 15, 17}, 495 {Equal, 15, 18}, 496 {Equal, 15, 19}, 497 {Equal, 15, vconst(20)}, 498 {Equal, 15, vconst2(20)}, 499 {Equal, 15, 25}, 500 501 {Equal, 16, 17}, 502 {Equal, 16, 18}, 503 {Equal, 16, 19}, 504 {Equal, 16, vconst(20)}, 505 {Equal, 16, vconst2(20)}, 506 {Equal, 16, 25}, 507 508 {Equal, 17, 18}, 509 {Equal, 17, 19}, 510 {Equal, 17, vconst(20)}, 511 {Equal, 17, vconst2(20)}, 512 {Equal, 17, 25}, 513 514 {Equal, 18, 19}, 515 {Equal, 18, vconst(20)}, 516 {Equal, 18, vconst2(20)}, 517 {Equal, 18, 25}, 518 519 {Equal, 19, vconst(20)}, 520 {Equal, 19, vconst2(20)}, 521 {Equal, 19, 25}, 522 523 {Equal, vconst(20), vconst2(20)}, 524 {Equal, vconst(20), 25}, 525 526 {Equal, vconst2(20), 25}, 527 528 // ... but not 11/26/100/101/102, which were on a different path 529 {Equal_Fail, 10, 11}, 530 {Equal_Fail, 10, 26}, 531 {Equal_Fail, 10, 100}, 532 {Equal_Fail, 10, 101}, 533 {Equal_Fail, 10, 102}, 534 {OrderedOrEqual, 10, 26}, 535 {OrderedOrEqual, 25, 26}, 536 {OrderedOrEqual, 13, 25}, 537 {OrderedOrEqual, 13, 10}, 538 539 {Undo, 0, 0}, 540 {OrderedOrEqual, 10, 25}, 541 {Equal_Fail, 10, 12}, 542 {Equal_Fail, 10, 15}, 543 {Equal_Fail, 10, 25}, 544 545 {Undo, 0, 0}, 546 }) 547 548 testPosetOps(t, false, []posetTestOp{ 549 {Checkpoint, 0, 0}, 550 {SetOrderOrEqual, 10, 15}, 551 {SetOrderOrEqual, 15, 20}, 552 {SetOrderOrEqual, 20, 25}, 553 {SetOrder, 10, 16}, 554 {SetOrderOrEqual, 16, 20}, 555 // Check that we cannot collapse here because of the strict relation 10<16 556 {SetOrderOrEqual_Fail, 20, 10}, 557 {Undo, 0, 0}, 558 }) 559 } 560 561 func TestPosetSetEqual(t *testing.T) { 562 testPosetOps(t, false, []posetTestOp{ 563 // 10<=20<=30<40, 20<=100<110 564 {Checkpoint, 0, 0}, 565 {SetOrderOrEqual, 10, 20}, 566 {SetOrderOrEqual, 20, 30}, 567 {SetOrder, 30, 40}, 568 {SetOrderOrEqual, 20, 100}, 569 {SetOrder, 100, 110}, 570 {OrderedOrEqual, 10, 30}, 571 {OrderedOrEqual_Fail, 30, 10}, 572 {Ordered_Fail, 10, 30}, 573 {Ordered_Fail, 30, 10}, 574 {Ordered, 10, 40}, 575 {Ordered_Fail, 40, 10}, 576 577 // Try learning 10==20. 578 {Checkpoint, 0, 0}, 579 {SetEqual, 10, 20}, 580 {OrderedOrEqual, 10, 20}, 581 {Ordered_Fail, 10, 20}, 582 {Equal, 10, 20}, 583 {SetOrderOrEqual, 10, 20}, 584 {SetOrderOrEqual, 20, 10}, 585 {SetOrder_Fail, 10, 20}, 586 {SetOrder_Fail, 20, 10}, 587 {Undo, 0, 0}, 588 589 // Try learning 20==10. 590 {Checkpoint, 0, 0}, 591 {SetEqual, 20, 10}, 592 {OrderedOrEqual, 10, 20}, 593 {Ordered_Fail, 10, 20}, 594 {Equal, 10, 20}, 595 {Undo, 0, 0}, 596 597 // Try learning 10==40 or 30==40 or 10==110. 598 {Checkpoint, 0, 0}, 599 {SetEqual_Fail, 10, 40}, 600 {SetEqual_Fail, 40, 10}, 601 {SetEqual_Fail, 30, 40}, 602 {SetEqual_Fail, 40, 30}, 603 {SetEqual_Fail, 10, 110}, 604 {SetEqual_Fail, 110, 10}, 605 {Undo, 0, 0}, 606 607 // Try learning 40==110, and then 10==40 or 10=110 608 {Checkpoint, 0, 0}, 609 {SetEqual, 40, 110}, 610 {SetEqual_Fail, 10, 40}, 611 {SetEqual_Fail, 40, 10}, 612 {SetEqual_Fail, 10, 110}, 613 {SetEqual_Fail, 110, 10}, 614 {Undo, 0, 0}, 615 616 // Try learning 40<20 or 30<20 or 110<10 617 {Checkpoint, 0, 0}, 618 {SetOrder_Fail, 40, 20}, 619 {SetOrder_Fail, 30, 20}, 620 {SetOrder_Fail, 110, 10}, 621 {Undo, 0, 0}, 622 623 // Try learning 30<=20 624 {Checkpoint, 0, 0}, 625 {SetOrderOrEqual, 30, 20}, 626 {Equal, 30, 20}, 627 {OrderedOrEqual, 30, 100}, 628 {Ordered, 30, 110}, 629 {Undo, 0, 0}, 630 631 {Undo, 0, 0}, 632 }) 633 } 634 635 func TestPosetConst(t *testing.T) { 636 testPosetOps(t, false, []posetTestOp{ 637 {Checkpoint, 0, 0}, 638 {SetOrder, 1, vconst(15)}, 639 {SetOrderOrEqual, 100, vconst(120)}, 640 {Ordered, 1, vconst(15)}, 641 {Ordered, 1, vconst(120)}, 642 {OrderedOrEqual, 1, vconst(120)}, 643 {OrderedOrEqual, 100, vconst(120)}, 644 {Ordered_Fail, 100, vconst(15)}, 645 {Ordered_Fail, vconst(15), 100}, 646 647 {Checkpoint, 0, 0}, 648 {SetOrderOrEqual, 1, 5}, 649 {SetOrderOrEqual, 5, 25}, 650 {SetEqual, 20, vconst(20)}, 651 {SetEqual, 25, vconst(25)}, 652 {Ordered, 1, 20}, 653 {Ordered, 1, vconst(30)}, 654 {Undo, 0, 0}, 655 656 {Checkpoint, 0, 0}, 657 {SetOrderOrEqual, 1, 5}, 658 {SetOrderOrEqual, 5, 25}, 659 {SetEqual, vconst(-20), 5}, 660 {SetEqual, vconst(-25), 1}, 661 {Ordered, 1, 5}, 662 {Ordered, vconst(-30), 1}, 663 {Undo, 0, 0}, 664 665 {Checkpoint, 0, 0}, 666 {SetNonEqual, 1, vconst(4)}, 667 {SetNonEqual, 1, vconst(6)}, 668 {NonEqual, 1, vconst(4)}, 669 {NonEqual_Fail, 1, vconst(5)}, 670 {NonEqual, 1, vconst(6)}, 671 {Equal_Fail, 1, vconst(4)}, 672 {Equal_Fail, 1, vconst(5)}, 673 {Equal_Fail, 1, vconst(6)}, 674 {Equal_Fail, 1, vconst(7)}, 675 {Undo, 0, 0}, 676 677 {Undo, 0, 0}, 678 }) 679 680 testPosetOps(t, true, []posetTestOp{ 681 {Checkpoint, 0, 0}, 682 {SetOrder, 1, vconst(15)}, 683 {SetOrderOrEqual, 100, vconst(-5)}, // -5 is a very big number in unsigned 684 {Ordered, 1, vconst(15)}, 685 {Ordered, 1, vconst(-5)}, 686 {OrderedOrEqual, 1, vconst(-5)}, 687 {OrderedOrEqual, 100, vconst(-5)}, 688 {Ordered_Fail, 100, vconst(15)}, 689 {Ordered_Fail, vconst(15), 100}, 690 691 {Undo, 0, 0}, 692 }) 693 694 testPosetOps(t, false, []posetTestOp{ 695 {Checkpoint, 0, 0}, 696 {SetOrderOrEqual, 1, vconst(3)}, 697 {SetNonEqual, 1, vconst(0)}, 698 {Ordered_Fail, 1, vconst(0)}, 699 {Undo, 0, 0}, 700 }) 701 702 testPosetOps(t, false, []posetTestOp{ 703 // Check relations of a constant with itself 704 {Checkpoint, 0, 0}, 705 {SetOrderOrEqual, vconst(3), vconst2(3)}, 706 {Undo, 0, 0}, 707 {Checkpoint, 0, 0}, 708 {SetEqual, vconst(3), vconst2(3)}, 709 {Undo, 0, 0}, 710 {Checkpoint, 0, 0}, 711 {SetNonEqual_Fail, vconst(3), vconst2(3)}, 712 {Undo, 0, 0}, 713 {Checkpoint, 0, 0}, 714 {SetOrder_Fail, vconst(3), vconst2(3)}, 715 {Undo, 0, 0}, 716 717 // Check relations of two constants among them, using 718 // different instances of the same constant 719 {Checkpoint, 0, 0}, 720 {SetOrderOrEqual, vconst(3), vconst(4)}, 721 {OrderedOrEqual, vconst(3), vconst2(4)}, 722 {Undo, 0, 0}, 723 {Checkpoint, 0, 0}, 724 {SetOrder, vconst(3), vconst(4)}, 725 {Ordered, vconst(3), vconst2(4)}, 726 {Undo, 0, 0}, 727 {Checkpoint, 0, 0}, 728 {SetEqual_Fail, vconst(3), vconst(4)}, 729 {SetEqual_Fail, vconst(3), vconst2(4)}, 730 {Undo, 0, 0}, 731 {Checkpoint, 0, 0}, 732 {NonEqual, vconst(3), vconst(4)}, 733 {NonEqual, vconst(3), vconst2(4)}, 734 {Undo, 0, 0}, 735 {Checkpoint, 0, 0}, 736 {Equal_Fail, vconst(3), vconst(4)}, 737 {Equal_Fail, vconst(3), vconst2(4)}, 738 {Undo, 0, 0}, 739 {Checkpoint, 0, 0}, 740 {SetNonEqual, vconst(3), vconst(4)}, 741 {SetNonEqual, vconst(3), vconst2(4)}, 742 {Undo, 0, 0}, 743 }) 744 } 745 746 func TestPosetNonEqual(t *testing.T) { 747 testPosetOps(t, false, []posetTestOp{ 748 {Equal_Fail, 10, 20}, 749 {NonEqual_Fail, 10, 20}, 750 751 // Learn 10!=20 752 {Checkpoint, 0, 0}, 753 {SetNonEqual, 10, 20}, 754 {Equal_Fail, 10, 20}, 755 {NonEqual, 10, 20}, 756 {SetEqual_Fail, 10, 20}, 757 758 // Learn again 10!=20 759 {Checkpoint, 0, 0}, 760 {SetNonEqual, 10, 20}, 761 {Equal_Fail, 10, 20}, 762 {NonEqual, 10, 20}, 763 764 // Undo. We still know 10!=20 765 {Undo, 0, 0}, 766 {Equal_Fail, 10, 20}, 767 {NonEqual, 10, 20}, 768 {SetEqual_Fail, 10, 20}, 769 770 // Undo again. Now we know nothing 771 {Undo, 0, 0}, 772 {Equal_Fail, 10, 20}, 773 {NonEqual_Fail, 10, 20}, 774 775 // Learn 10==20 776 {Checkpoint, 0, 0}, 777 {SetEqual, 10, 20}, 778 {Equal, 10, 20}, 779 {NonEqual_Fail, 10, 20}, 780 {SetNonEqual_Fail, 10, 20}, 781 782 // Learn again 10==20 783 {Checkpoint, 0, 0}, 784 {SetEqual, 10, 20}, 785 {Equal, 10, 20}, 786 {NonEqual_Fail, 10, 20}, 787 {SetNonEqual_Fail, 10, 20}, 788 789 // Undo. We still know 10==20 790 {Undo, 0, 0}, 791 {Equal, 10, 20}, 792 {NonEqual_Fail, 10, 20}, 793 {SetNonEqual_Fail, 10, 20}, 794 795 // Undo. We know nothing 796 {Undo, 0, 0}, 797 {Equal_Fail, 10, 20}, 798 {NonEqual_Fail, 10, 20}, 799 }) 800 }