github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/cmd/compile/internal/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  		if err := po.CheckIntegrity(); err != nil {
   150  			t.Fatalf("op%d%v: integrity error: %v", idx, op, err)
   151  		}
   152  	}
   153  
   154  	// Check that the poset is completely empty
   155  	if err := po.CheckEmpty(); err != nil {
   156  		t.Error(err)
   157  	}
   158  }
   159  
   160  func TestPoset(t *testing.T) {
   161  	testPosetOps(t, false, []posetTestOp{
   162  		{Ordered_Fail, 123, 124},
   163  
   164  		// Dag #0: 100<101
   165  		{Checkpoint, 0, 0},
   166  		{SetOrder, 100, 101},
   167  		{Ordered, 100, 101},
   168  		{Ordered_Fail, 101, 100},
   169  		{SetOrder_Fail, 101, 100},
   170  		{SetOrder, 100, 101}, // repeat
   171  		{NonEqual, 100, 101},
   172  		{NonEqual, 101, 100},
   173  		{SetEqual_Fail, 100, 101},
   174  
   175  		// Dag #1: 4<=7<12
   176  		{Checkpoint, 0, 0},
   177  		{SetOrderOrEqual, 4, 7},
   178  		{OrderedOrEqual, 4, 7},
   179  		{SetOrder, 7, 12},
   180  		{Ordered, 7, 12},
   181  		{Ordered, 4, 12},
   182  		{Ordered_Fail, 12, 4},
   183  		{NonEqual, 4, 12},
   184  		{NonEqual, 12, 4},
   185  		{NonEqual_Fail, 4, 100},
   186  		{OrderedOrEqual, 4, 12},
   187  		{OrderedOrEqual_Fail, 12, 4},
   188  		{OrderedOrEqual, 4, 7},
   189  		{OrderedOrEqual, 7, 4},
   190  
   191  		// Dag #1: 1<4<=7<12
   192  		{Checkpoint, 0, 0},
   193  		{SetOrder, 1, 4},
   194  		{Ordered, 1, 4},
   195  		{Ordered, 1, 12},
   196  		{Ordered_Fail, 12, 1},
   197  
   198  		// Dag #1: 1<4<=7<12, 6<7
   199  		{Checkpoint, 0, 0},
   200  		{SetOrder, 6, 7},
   201  		{Ordered, 6, 7},
   202  		{Ordered, 6, 12},
   203  		{SetOrder_Fail, 7, 4},
   204  		{SetOrder_Fail, 7, 6},
   205  		{SetOrder_Fail, 7, 1},
   206  
   207  		// Dag #1: 1<4<=7<12, 1<6<7
   208  		{Checkpoint, 0, 0},
   209  		{Ordered_Fail, 1, 6},
   210  		{SetOrder, 1, 6},
   211  		{Ordered, 1, 6},
   212  		{SetOrder_Fail, 6, 1},
   213  
   214  		// Dag #1: 1<4<=7<12, 1<4<6<7
   215  		{Checkpoint, 0, 0},
   216  		{Ordered_Fail, 4, 6},
   217  		{Ordered_Fail, 4, 7},
   218  		{SetOrder, 4, 6},
   219  		{Ordered, 4, 6},
   220  		{OrderedOrEqual, 4, 6},
   221  		{Ordered, 4, 7},
   222  		{OrderedOrEqual, 4, 7},
   223  		{SetOrder_Fail, 6, 4},
   224  		{Ordered_Fail, 7, 6},
   225  		{Ordered_Fail, 7, 4},
   226  		{OrderedOrEqual_Fail, 7, 6},
   227  		{OrderedOrEqual_Fail, 7, 4},
   228  
   229  		// Merge: 1<4<6, 4<=7<12, 6<101
   230  		{Checkpoint, 0, 0},
   231  		{Ordered_Fail, 6, 101},
   232  		{SetOrder, 6, 101},
   233  		{Ordered, 6, 101},
   234  		{Ordered, 1, 101},
   235  
   236  		// Merge: 1<4<6, 4<=7<12, 6<100<101
   237  		{Checkpoint, 0, 0},
   238  		{Ordered_Fail, 6, 100},
   239  		{SetOrder, 6, 100},
   240  		{Ordered, 1, 100},
   241  
   242  		// Undo: 1<4<6<7<12, 6<101
   243  		{Ordered, 100, 101},
   244  		{Undo, 0, 0},
   245  		{Ordered, 100, 101},
   246  		{Ordered_Fail, 6, 100},
   247  		{Ordered, 6, 101},
   248  		{Ordered, 1, 101},
   249  
   250  		// Undo: 1<4<6<7<12, 100<101
   251  		{Undo, 0, 0},
   252  		{Ordered_Fail, 1, 100},
   253  		{Ordered_Fail, 1, 101},
   254  		{Ordered_Fail, 6, 100},
   255  		{Ordered_Fail, 6, 101},
   256  
   257  		// Merge: 1<4<6<7<12, 6<100<101
   258  		{Checkpoint, 0, 0},
   259  		{Ordered, 100, 101},
   260  		{SetOrder, 6, 100},
   261  		{Ordered, 6, 100},
   262  		{Ordered, 6, 101},
   263  		{Ordered, 1, 101},
   264  
   265  		// Undo 2 times: 1<4<7<12, 1<6<7
   266  		{Undo, 0, 0},
   267  		{Undo, 0, 0},
   268  		{Ordered, 1, 6},
   269  		{Ordered, 4, 12},
   270  		{Ordered_Fail, 4, 6},
   271  		{SetOrder_Fail, 6, 1},
   272  
   273  		// Undo 2 times: 1<4<7<12
   274  		{Undo, 0, 0},
   275  		{Undo, 0, 0},
   276  		{Ordered, 1, 12},
   277  		{Ordered, 7, 12},
   278  		{Ordered_Fail, 1, 6},
   279  		{Ordered_Fail, 6, 7},
   280  		{Ordered, 100, 101},
   281  		{Ordered_Fail, 1, 101},
   282  
   283  		// Undo: 4<7<12
   284  		{Undo, 0, 0},
   285  		{Ordered_Fail, 1, 12},
   286  		{Ordered_Fail, 1, 4},
   287  		{Ordered, 4, 12},
   288  		{Ordered, 100, 101},
   289  
   290  		// Undo: 100<101
   291  		{Undo, 0, 0},
   292  		{Ordered_Fail, 4, 7},
   293  		{Ordered_Fail, 7, 12},
   294  		{Ordered, 100, 101},
   295  
   296  		// Recreated DAG #1 from scratch, reusing same nodes.
   297  		// This also stresses that Undo has done its job correctly.
   298  		// DAG: 1<2<(5|6), 101<102<(105|106<107)
   299  		{Checkpoint, 0, 0},
   300  		{SetOrder, 101, 102},
   301  		{SetOrder, 102, 105},
   302  		{SetOrder, 102, 106},
   303  		{SetOrder, 106, 107},
   304  		{SetOrder, 1, 2},
   305  		{SetOrder, 2, 5},
   306  		{SetOrder, 2, 6},
   307  		{SetEqual_Fail, 1, 6},
   308  		{SetEqual_Fail, 107, 102},
   309  
   310  		// Now Set 2 == 102
   311  		// New DAG: (1|101)<2==102<(5|6|105|106<107)
   312  		{Checkpoint, 0, 0},
   313  		{SetEqual, 2, 102},
   314  		{Equal, 2, 102},
   315  		{SetEqual, 2, 102},         // trivially pass
   316  		{SetNonEqual_Fail, 2, 102}, // trivially fail
   317  		{Ordered, 1, 107},
   318  		{Ordered, 101, 6},
   319  		{Ordered, 101, 105},
   320  		{Ordered, 2, 106},
   321  		{Ordered, 102, 6},
   322  
   323  		// Undo SetEqual
   324  		{Undo, 0, 0},
   325  		{Equal_Fail, 2, 102},
   326  		{Ordered_Fail, 2, 102},
   327  		{Ordered_Fail, 1, 107},
   328  		{Ordered_Fail, 101, 6},
   329  		{Checkpoint, 0, 0},
   330  		{SetEqual, 2, 100},
   331  		{Ordered, 1, 107},
   332  		{Ordered, 100, 6},
   333  
   334  		// SetEqual with new node
   335  		{Undo, 0, 0},
   336  		{Checkpoint, 0, 0},
   337  		{SetEqual, 2, 400},
   338  		{SetEqual, 401, 2},
   339  		{Equal, 400, 401},
   340  		{Ordered, 1, 400},
   341  		{Ordered, 400, 6},
   342  		{Ordered, 1, 401},
   343  		{Ordered, 401, 6},
   344  		{Ordered_Fail, 2, 401},
   345  
   346  		// SetEqual unseen nodes and then connect
   347  		{Checkpoint, 0, 0},
   348  		{SetEqual, 500, 501},
   349  		{SetEqual, 102, 501},
   350  		{Equal, 500, 102},
   351  		{Ordered, 501, 106},
   352  		{Ordered, 100, 500},
   353  		{SetEqual, 500, 501},
   354  		{Ordered_Fail, 500, 501},
   355  		{Ordered_Fail, 102, 501},
   356  
   357  		// SetNonEqual relations
   358  		{Undo, 0, 0},
   359  		{Checkpoint, 0, 0},
   360  		{SetNonEqual, 600, 601},
   361  		{NonEqual, 600, 601},
   362  		{SetNonEqual, 601, 602},
   363  		{NonEqual, 601, 602},
   364  		{NonEqual_Fail, 600, 602}, // non-transitive
   365  		{SetEqual_Fail, 601, 602},
   366  
   367  		// Undo back to beginning, leave the poset empty
   368  		{Undo, 0, 0},
   369  		{Undo, 0, 0},
   370  		{Undo, 0, 0},
   371  		{Undo, 0, 0},
   372  	})
   373  }
   374  
   375  func TestPosetStrict(t *testing.T) {
   376  
   377  	testPosetOps(t, false, []posetTestOp{
   378  		{Checkpoint, 0, 0},
   379  		// Build: 20!=30, 10<20<=30<40. The 20<=30 will become 20<30.
   380  		{SetNonEqual, 20, 30},
   381  		{SetOrder, 10, 20},
   382  		{SetOrderOrEqual, 20, 30}, // this is affected by 20!=30
   383  		{SetOrder, 30, 40},
   384  
   385  		{Ordered, 10, 30},
   386  		{Ordered, 20, 30},
   387  		{Ordered, 10, 40},
   388  		{OrderedOrEqual, 10, 30},
   389  		{OrderedOrEqual, 20, 30},
   390  		{OrderedOrEqual, 10, 40},
   391  
   392  		{Undo, 0, 0},
   393  
   394  		// Now do the opposite: first build the DAG and then learn non-equality
   395  		{Checkpoint, 0, 0},
   396  		{SetOrder, 10, 20},
   397  		{SetOrderOrEqual, 20, 30}, // this is affected by 20!=30
   398  		{SetOrder, 30, 40},
   399  
   400  		{Ordered, 10, 30},
   401  		{Ordered_Fail, 20, 30},
   402  		{Ordered, 10, 40},
   403  		{OrderedOrEqual, 10, 30},
   404  		{OrderedOrEqual, 20, 30},
   405  		{OrderedOrEqual, 10, 40},
   406  
   407  		{Checkpoint, 0, 0},
   408  		{SetNonEqual, 20, 30},
   409  		{Ordered, 10, 30},
   410  		{Ordered, 20, 30},
   411  		{Ordered, 10, 40},
   412  		{OrderedOrEqual, 10, 30},
   413  		{OrderedOrEqual, 20, 30},
   414  		{OrderedOrEqual, 10, 40},
   415  		{Undo, 0, 0},
   416  
   417  		{Checkpoint, 0, 0},
   418  		{SetOrderOrEqual, 30, 35},
   419  		{OrderedOrEqual, 20, 35},
   420  		{Ordered_Fail, 20, 35},
   421  		{SetNonEqual, 20, 35},
   422  		{Ordered, 20, 35},
   423  		{Undo, 0, 0},
   424  
   425  		// Learn <= and >=
   426  		{Checkpoint, 0, 0},
   427  		{SetOrderOrEqual, 50, 60},
   428  		{SetOrderOrEqual, 60, 50},
   429  		{OrderedOrEqual, 50, 60},
   430  		{OrderedOrEqual, 60, 50},
   431  		{Ordered_Fail, 50, 60},
   432  		{Ordered_Fail, 60, 50},
   433  		{Equal, 50, 60},
   434  		{Equal, 60, 50},
   435  		{NonEqual_Fail, 50, 60},
   436  		{NonEqual_Fail, 60, 50},
   437  		{Undo, 0, 0},
   438  
   439  		{Undo, 0, 0},
   440  	})
   441  }
   442  
   443  func TestSetEqual(t *testing.T) {
   444  	testPosetOps(t, false, []posetTestOp{
   445  		// 10<=20<=30<40,  20<=100<110
   446  		{Checkpoint, 0, 0},
   447  		{SetOrderOrEqual, 10, 20},
   448  		{SetOrderOrEqual, 20, 30},
   449  		{SetOrder, 30, 40},
   450  		{SetOrderOrEqual, 20, 100},
   451  		{SetOrder, 100, 110},
   452  		{OrderedOrEqual, 10, 30},
   453  		{OrderedOrEqual, 30, 10},
   454  		{Ordered_Fail, 10, 30},
   455  		{Ordered_Fail, 30, 10},
   456  		{Ordered, 10, 40},
   457  		{Ordered_Fail, 40, 10},
   458  
   459  		// Try learning 10==20.
   460  		{Checkpoint, 0, 0},
   461  		{SetEqual, 10, 20},
   462  		{OrderedOrEqual, 10, 20},
   463  		{Ordered_Fail, 10, 20},
   464  		{Equal, 10, 20},
   465  		{SetOrderOrEqual, 10, 20},
   466  		{SetOrderOrEqual, 20, 10},
   467  		{SetOrder_Fail, 10, 20},
   468  		{SetOrder_Fail, 20, 10},
   469  		{Undo, 0, 0},
   470  
   471  		// Try learning 20==10.
   472  		{Checkpoint, 0, 0},
   473  		{SetEqual, 20, 10},
   474  		{OrderedOrEqual, 10, 20},
   475  		{Ordered_Fail, 10, 20},
   476  		{Equal, 10, 20},
   477  		{Undo, 0, 0},
   478  
   479  		// Try learning 10==40 or 30==40 or 10==110.
   480  		{Checkpoint, 0, 0},
   481  		{SetEqual_Fail, 10, 40},
   482  		{SetEqual_Fail, 40, 10},
   483  		{SetEqual_Fail, 30, 40},
   484  		{SetEqual_Fail, 40, 30},
   485  		{SetEqual_Fail, 10, 110},
   486  		{SetEqual_Fail, 110, 10},
   487  		{Undo, 0, 0},
   488  
   489  		// Try learning 40==110, and then 10==40 or 10=110
   490  		{Checkpoint, 0, 0},
   491  		{SetEqual, 40, 110},
   492  		{SetEqual_Fail, 10, 40},
   493  		{SetEqual_Fail, 40, 10},
   494  		{SetEqual_Fail, 10, 110},
   495  		{SetEqual_Fail, 110, 10},
   496  		{Undo, 0, 0},
   497  
   498  		// Try learning 40<20 or 30<20 or 110<10
   499  		{Checkpoint, 0, 0},
   500  		{SetOrder_Fail, 40, 20},
   501  		{SetOrder_Fail, 30, 20},
   502  		{SetOrder_Fail, 110, 10},
   503  		{Undo, 0, 0},
   504  
   505  		// Try learning 30<=20
   506  		{Checkpoint, 0, 0},
   507  		{SetOrderOrEqual, 30, 20},
   508  		{Equal, 30, 20},
   509  		{OrderedOrEqual, 30, 100},
   510  		{Ordered, 30, 110},
   511  		{Undo, 0, 0},
   512  
   513  		{Undo, 0, 0},
   514  	})
   515  }
   516  
   517  func TestPosetConst(t *testing.T) {
   518  	testPosetOps(t, false, []posetTestOp{
   519  		{Checkpoint, 0, 0},
   520  		{SetOrder, 1, vconst(15)},
   521  		{SetOrderOrEqual, 100, vconst(120)},
   522  		{Ordered, 1, vconst(15)},
   523  		{Ordered, 1, vconst(120)},
   524  		{OrderedOrEqual, 1, vconst(120)},
   525  		{OrderedOrEqual, 100, vconst(120)},
   526  		{Ordered_Fail, 100, vconst(15)},
   527  		{Ordered_Fail, vconst(15), 100},
   528  
   529  		{Checkpoint, 0, 0},
   530  		{SetOrderOrEqual, 1, 5},
   531  		{SetOrderOrEqual, 5, 25},
   532  		{SetEqual, 20, vconst(20)},
   533  		{SetEqual, 25, vconst(25)},
   534  		{Ordered, 1, 20},
   535  		{Ordered, 1, vconst(30)},
   536  		{Undo, 0, 0},
   537  
   538  		{Checkpoint, 0, 0},
   539  		{SetOrderOrEqual, 1, 5},
   540  		{SetOrderOrEqual, 5, 25},
   541  		{SetEqual, vconst(-20), 5},
   542  		{SetEqual, vconst(-25), 1},
   543  		{Ordered, 1, 5},
   544  		{Ordered, vconst(-30), 1},
   545  		{Undo, 0, 0},
   546  
   547  		{Checkpoint, 0, 0},
   548  		{SetNonEqual, 1, vconst(4)},
   549  		{SetNonEqual, 1, vconst(6)},
   550  		{NonEqual, 1, vconst(4)},
   551  		{NonEqual_Fail, 1, vconst(5)},
   552  		{NonEqual, 1, vconst(6)},
   553  		{Equal_Fail, 1, vconst(4)},
   554  		{Equal_Fail, 1, vconst(5)},
   555  		{Equal_Fail, 1, vconst(6)},
   556  		{Equal_Fail, 1, vconst(7)},
   557  		{Undo, 0, 0},
   558  
   559  		{Undo, 0, 0},
   560  	})
   561  
   562  	testPosetOps(t, true, []posetTestOp{
   563  		{Checkpoint, 0, 0},
   564  		{SetOrder, 1, vconst(15)},
   565  		{SetOrderOrEqual, 100, vconst(-5)}, // -5 is a very big number in unsigned
   566  		{Ordered, 1, vconst(15)},
   567  		{Ordered, 1, vconst(-5)},
   568  		{OrderedOrEqual, 1, vconst(-5)},
   569  		{OrderedOrEqual, 100, vconst(-5)},
   570  		{Ordered_Fail, 100, vconst(15)},
   571  		{Ordered_Fail, vconst(15), 100},
   572  
   573  		{Undo, 0, 0},
   574  	})
   575  
   576  	testPosetOps(t, false, []posetTestOp{
   577  		{Checkpoint, 0, 0},
   578  		{SetOrderOrEqual, 1, vconst(3)},
   579  		{SetNonEqual, 1, vconst(0)},
   580  		{Ordered_Fail, 1, vconst(0)},
   581  		{Undo, 0, 0},
   582  	})
   583  
   584  	testPosetOps(t, false, []posetTestOp{
   585  		// Check relations of a constant with itself
   586  		{Checkpoint, 0, 0},
   587  		{SetOrderOrEqual, vconst(3), vconst2(3)},
   588  		{Undo, 0, 0},
   589  		{Checkpoint, 0, 0},
   590  		{SetEqual, vconst(3), vconst2(3)},
   591  		{Undo, 0, 0},
   592  		{Checkpoint, 0, 0},
   593  		{SetNonEqual_Fail, vconst(3), vconst2(3)},
   594  		{Undo, 0, 0},
   595  		{Checkpoint, 0, 0},
   596  		{SetOrder_Fail, vconst(3), vconst2(3)},
   597  		{Undo, 0, 0},
   598  
   599  		// Check relations of two constants among them, using
   600  		// different instances of the same constant
   601  		{Checkpoint, 0, 0},
   602  		{SetOrderOrEqual, vconst(3), vconst(4)},
   603  		{OrderedOrEqual, vconst(3), vconst2(4)},
   604  		{Undo, 0, 0},
   605  		{Checkpoint, 0, 0},
   606  		{SetOrder, vconst(3), vconst(4)},
   607  		{Ordered, vconst(3), vconst2(4)},
   608  		{Undo, 0, 0},
   609  		{Checkpoint, 0, 0},
   610  		{SetEqual_Fail, vconst(3), vconst(4)},
   611  		{SetEqual_Fail, vconst(3), vconst2(4)},
   612  		{Undo, 0, 0},
   613  		{Checkpoint, 0, 0},
   614  		{NonEqual, vconst(3), vconst(4)},
   615  		{NonEqual, vconst(3), vconst2(4)},
   616  		{Undo, 0, 0},
   617  		{Checkpoint, 0, 0},
   618  		{Equal_Fail, vconst(3), vconst(4)},
   619  		{Equal_Fail, vconst(3), vconst2(4)},
   620  		{Undo, 0, 0},
   621  		{Checkpoint, 0, 0},
   622  		{SetNonEqual, vconst(3), vconst(4)},
   623  		{SetNonEqual, vconst(3), vconst2(4)},
   624  		{Undo, 0, 0},
   625  	})
   626  }
   627  
   628  func TestPosetNonEqual(t *testing.T) {
   629  	testPosetOps(t, false, []posetTestOp{
   630  		{Equal_Fail, 10, 20},
   631  		{NonEqual_Fail, 10, 20},
   632  
   633  		// Learn 10!=20
   634  		{Checkpoint, 0, 0},
   635  		{SetNonEqual, 10, 20},
   636  		{Equal_Fail, 10, 20},
   637  		{NonEqual, 10, 20},
   638  		{SetEqual_Fail, 10, 20},
   639  
   640  		// Learn again 10!=20
   641  		{Checkpoint, 0, 0},
   642  		{SetNonEqual, 10, 20},
   643  		{Equal_Fail, 10, 20},
   644  		{NonEqual, 10, 20},
   645  
   646  		// Undo. We still know 10!=20
   647  		{Undo, 0, 0},
   648  		{Equal_Fail, 10, 20},
   649  		{NonEqual, 10, 20},
   650  		{SetEqual_Fail, 10, 20},
   651  
   652  		// Undo again. Now we know nothing
   653  		{Undo, 0, 0},
   654  		{Equal_Fail, 10, 20},
   655  		{NonEqual_Fail, 10, 20},
   656  
   657  		// Learn 10==20
   658  		{Checkpoint, 0, 0},
   659  		{SetEqual, 10, 20},
   660  		{Equal, 10, 20},
   661  		{NonEqual_Fail, 10, 20},
   662  		{SetNonEqual_Fail, 10, 20},
   663  
   664  		// Learn again 10==20
   665  		{Checkpoint, 0, 0},
   666  		{SetEqual, 10, 20},
   667  		{Equal, 10, 20},
   668  		{NonEqual_Fail, 10, 20},
   669  		{SetNonEqual_Fail, 10, 20},
   670  
   671  		// Undo. We still know 10==20
   672  		{Undo, 0, 0},
   673  		{Equal, 10, 20},
   674  		{NonEqual_Fail, 10, 20},
   675  		{SetNonEqual_Fail, 10, 20},
   676  
   677  		// Undo. We know nothing
   678  		{Undo, 0, 0},
   679  		{Equal_Fail, 10, 20},
   680  		{NonEqual_Fail, 10, 20},
   681  	})
   682  }