GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/util/datatype_black.cpp Lines: 353 353 100.0 %
Date: 2021-09-15 Branches: 1099 3104 35.4 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Aina Niemetz, Andrew Reynolds, Morgan Deters
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Black box testing of cvc5::DType.
14
 */
15
16
#include <sstream>
17
18
#include "expr/dtype.h"
19
#include "expr/dtype_cons.h"
20
#include "expr/type_node.h"
21
#include "test_smt.h"
22
#include "util/rational.h"
23
24
namespace cvc5 {
25
namespace test {
26
27
44
class TestUtilBlackDatatype : public TestSmt
28
{
29
 public:
30
22
  void SetUp() override
31
  {
32
22
    TestSmt::SetUp();
33
22
    Debug.on("datatypes");
34
22
    Debug.on("groundterms");
35
22
  }
36
};
37
38
20
TEST_F(TestUtilBlackDatatype, enumeration)
39
{
40
4
  DType colors("colors");
41
42
  std::shared_ptr<DTypeConstructor> yellow =
43
4
      std::make_shared<DTypeConstructor>("yellow");
44
  std::shared_ptr<DTypeConstructor> blue =
45
4
      std::make_shared<DTypeConstructor>("blue");
46
  std::shared_ptr<DTypeConstructor> green =
47
4
      std::make_shared<DTypeConstructor>("green");
48
  std::shared_ptr<DTypeConstructor> red =
49
4
      std::make_shared<DTypeConstructor>("red");
50
51
2
  colors.addConstructor(yellow);
52
2
  colors.addConstructor(blue);
53
2
  colors.addConstructor(green);
54
2
  colors.addConstructor(red);
55
56
2
  Debug("datatypes") << colors << std::endl;
57
4
  TypeNode colorsType = d_nodeManager->mkDatatypeType(colors);
58
2
  Debug("datatypes") << colorsType << std::endl;
59
60
4
  Node ctor = colorsType.getDType()[1].getConstructor();
61
4
  Node apply = d_nodeManager->mkNode(kind::APPLY_CONSTRUCTOR, ctor);
62
2
  Debug("datatypes") << apply << std::endl;
63
64
2
  ASSERT_FALSE(colorsType.getDType().isParametric());
65
2
  ASSERT_TRUE(colorsType.getDType().isFinite());
66
2
  ASSERT_EQ(colorsType.getDType().getCardinality().compare(4),
67
2
            Cardinality::EQUAL);
68
2
  ASSERT_EQ(ctor.getType().getCardinality().compare(1), Cardinality::EQUAL);
69
2
  ASSERT_TRUE(colorsType.getDType().isWellFounded());
70
4
  Debug("groundterms") << "ground term of " << colorsType.getDType().getName()
71
2
                       << std::endl
72
2
                       << "  is " << colorsType.mkGroundTerm() << std::endl;
73
2
  ASSERT_EQ(colorsType.mkGroundTerm().getType(), colorsType);
74
}
75
76
20
TEST_F(TestUtilBlackDatatype, nat)
77
{
78
4
  DType nat("nat");
79
80
  std::shared_ptr<DTypeConstructor> succ =
81
4
      std::make_shared<DTypeConstructor>("succ");
82
2
  succ->addArgSelf("pred");
83
2
  nat.addConstructor(succ);
84
85
  std::shared_ptr<DTypeConstructor> zero =
86
4
      std::make_shared<DTypeConstructor>("zero");
87
2
  nat.addConstructor(zero);
88
89
2
  Debug("datatypes") << nat << std::endl;
90
4
  TypeNode natType = d_nodeManager->mkDatatypeType(nat);
91
2
  Debug("datatypes") << natType << std::endl;
92
93
4
  Node ctor = natType.getDType()[1].getConstructor();
94
4
  Node apply = d_nodeManager->mkNode(kind::APPLY_CONSTRUCTOR, ctor);
95
2
  Debug("datatypes") << apply << std::endl;
96
97
2
  ASSERT_FALSE(natType.getDType().isParametric());
98
2
  ASSERT_FALSE(natType.getDType().isFinite());
99
2
  ASSERT_TRUE(natType.getDType().getCardinality().compare(Cardinality::INTEGERS)
100
2
              == Cardinality::EQUAL);
101
2
  ASSERT_TRUE(natType.getDType().isWellFounded());
102
4
  Debug("groundterms") << "ground term of " << natType.getDType().getName()
103
2
                       << std::endl
104
2
                       << "  is " << natType.mkGroundTerm() << std::endl;
105
2
  ASSERT_TRUE(natType.mkGroundTerm().getType() == natType);
106
}
107
108
20
TEST_F(TestUtilBlackDatatype, tree)
109
{
110
4
  DType tree("tree");
111
4
  TypeNode integerType = d_nodeManager->integerType();
112
113
  std::shared_ptr<DTypeConstructor> node =
114
4
      std::make_shared<DTypeConstructor>("node");
115
2
  node->addArgSelf("left");
116
2
  node->addArgSelf("right");
117
2
  tree.addConstructor(node);
118
119
  std::shared_ptr<DTypeConstructor> leaf =
120
4
      std::make_shared<DTypeConstructor>("leaf");
121
2
  leaf->addArg("leaf", integerType);
122
2
  tree.addConstructor(leaf);
123
124
2
  Debug("datatypes") << tree << std::endl;
125
4
  TypeNode treeType = d_nodeManager->mkDatatypeType(tree);
126
2
  Debug("datatypes") << treeType << std::endl;
127
128
2
  ASSERT_FALSE(treeType.getDType().isParametric());
129
2
  ASSERT_FALSE(treeType.getDType().isFinite());
130
2
  ASSERT_TRUE(
131
      treeType.getDType().getCardinality().compare(Cardinality::INTEGERS)
132
2
      == Cardinality::EQUAL);
133
2
  ASSERT_TRUE(treeType.getDType().isWellFounded());
134
4
  Debug("groundterms") << "ground term of " << treeType.getDType().getName()
135
2
                       << std::endl
136
2
                       << "  is " << treeType.mkGroundTerm() << std::endl;
137
2
  ASSERT_TRUE(treeType.mkGroundTerm().getType() == treeType);
138
}
139
140
20
TEST_F(TestUtilBlackDatatype, list_int)
141
{
142
4
  DType list("list");
143
4
  TypeNode integerType = d_nodeManager->integerType();
144
145
  std::shared_ptr<DTypeConstructor> cons =
146
4
      std::make_shared<DTypeConstructor>("cons");
147
2
  cons->addArg("car", integerType);
148
2
  cons->addArgSelf("cdr");
149
2
  list.addConstructor(cons);
150
151
  std::shared_ptr<DTypeConstructor> nil =
152
4
      std::make_shared<DTypeConstructor>("nil");
153
2
  list.addConstructor(nil);
154
155
2
  Debug("datatypes") << list << std::endl;
156
4
  TypeNode listType = d_nodeManager->mkDatatypeType(list);
157
2
  Debug("datatypes") << listType << std::endl;
158
159
2
  ASSERT_FALSE(listType.getDType().isParametric());
160
2
  ASSERT_FALSE(listType.getDType().isFinite());
161
2
  ASSERT_TRUE(
162
      listType.getDType().getCardinality().compare(Cardinality::INTEGERS)
163
2
      == Cardinality::EQUAL);
164
2
  ASSERT_TRUE(listType.getDType().isWellFounded());
165
4
  Debug("groundterms") << "ground term of " << listType.getDType().getName()
166
2
                       << std::endl
167
2
                       << "  is " << listType.mkGroundTerm() << std::endl;
168
2
  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
169
}
170
171
20
TEST_F(TestUtilBlackDatatype, list_real)
172
{
173
4
  DType list("list");
174
4
  TypeNode realType = d_nodeManager->realType();
175
176
  std::shared_ptr<DTypeConstructor> cons =
177
4
      std::make_shared<DTypeConstructor>("cons");
178
2
  cons->addArg("car", realType);
179
2
  cons->addArgSelf("cdr");
180
2
  list.addConstructor(cons);
181
182
  std::shared_ptr<DTypeConstructor> nil =
183
4
      std::make_shared<DTypeConstructor>("nil");
184
2
  list.addConstructor(nil);
185
186
2
  Debug("datatypes") << list << std::endl;
187
4
  TypeNode listType = d_nodeManager->mkDatatypeType(list);
188
2
  Debug("datatypes") << listType << std::endl;
189
190
2
  ASSERT_FALSE(listType.getDType().isParametric());
191
2
  ASSERT_FALSE(listType.getDType().isFinite());
192
2
  ASSERT_TRUE(listType.getDType().getCardinality().compare(Cardinality::REALS)
193
2
              == Cardinality::EQUAL);
194
2
  ASSERT_TRUE(listType.getDType().isWellFounded());
195
4
  Debug("groundterms") << "ground term of " << listType.getDType().getName()
196
2
                       << std::endl
197
2
                       << "  is " << listType.mkGroundTerm() << std::endl;
198
2
  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
199
}
200
201
20
TEST_F(TestUtilBlackDatatype, list_boolean)
202
{
203
4
  DType list("list");
204
4
  TypeNode booleanType = d_nodeManager->booleanType();
205
206
  std::shared_ptr<DTypeConstructor> cons =
207
4
      std::make_shared<DTypeConstructor>("cons");
208
2
  cons->addArg("car", booleanType);
209
2
  cons->addArgSelf("cdr");
210
2
  list.addConstructor(cons);
211
212
  std::shared_ptr<DTypeConstructor> nil =
213
4
      std::make_shared<DTypeConstructor>("nil");
214
2
  list.addConstructor(nil);
215
216
2
  Debug("datatypes") << list << std::endl;
217
4
  TypeNode listType = d_nodeManager->mkDatatypeType(list);
218
2
  Debug("datatypes") << listType << std::endl;
219
220
2
  ASSERT_FALSE(listType.getDType().isFinite());
221
2
  ASSERT_TRUE(
222
      listType.getDType().getCardinality().compare(Cardinality::INTEGERS)
223
2
      == Cardinality::EQUAL);
224
2
  ASSERT_TRUE(listType.getDType().isWellFounded());
225
4
  Debug("groundterms") << "ground term of " << listType.getDType().getName()
226
2
                       << std::endl
227
2
                       << "  is " << listType.mkGroundTerm() << std::endl;
228
2
  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
229
}
230
231
20
TEST_F(TestUtilBlackDatatype, listIntUpdate)
232
{
233
4
  DType list("list");
234
4
  TypeNode integerType = d_nodeManager->integerType();
235
236
  std::shared_ptr<DTypeConstructor> cons =
237
4
      std::make_shared<DTypeConstructor>("cons");
238
2
  cons->addArg("car", integerType);
239
2
  cons->addArgSelf("cdr");
240
2
  list.addConstructor(cons);
241
242
  std::shared_ptr<DTypeConstructor> nil =
243
4
      std::make_shared<DTypeConstructor>("nil");
244
2
  list.addConstructor(nil);
245
246
4
  TypeNode listType = d_nodeManager->mkDatatypeType(list);
247
2
  const DType& ldt = listType.getDType();
248
4
  Node updater = ldt[0][0].getUpdater();
249
4
  Node gt = listType.mkGroundTerm();
250
4
  Node zero = d_nodeManager->mkConst(Rational(0));
251
4
  Node truen = d_nodeManager->mkConst(true);
252
  // construct an update term
253
4
  Node uterm = d_nodeManager->mkNode(kind::APPLY_UPDATER, updater, gt, zero);
254
  // construct a non well-formed update term
255
2
  ASSERT_THROW(d_nodeManager->mkNode(kind::APPLY_UPDATER, updater, gt, truen)
256
                   .getType(true),
257
2
               TypeCheckingExceptionPrivate);
258
}
259
260
20
TEST_F(TestUtilBlackDatatype, mutual_list_trees1)
261
{
262
  /* Create two mutual datatypes corresponding to this definition
263
   * block:
264
   *
265
   *   DATATYPE
266
   *     tree = node(left: tree, right: tree) | leaf(list),
267
   *     list = cons(car: tree, cdr: list) | nil
268
   *   END;
269
   */
270
4
  std::set<TypeNode> unresolvedTypes;
271
  TypeNode unresList =
272
4
      d_nodeManager->mkSort("list", NodeManager::SORT_FLAG_PLACEHOLDER);
273
2
  unresolvedTypes.insert(unresList);
274
  TypeNode unresTree =
275
4
      d_nodeManager->mkSort("tree", NodeManager::SORT_FLAG_PLACEHOLDER);
276
2
  unresolvedTypes.insert(unresTree);
277
278
4
  DType tree("tree");
279
  std::shared_ptr<DTypeConstructor> node =
280
4
      std::make_shared<DTypeConstructor>("node");
281
2
  node->addArgSelf("left");
282
2
  node->addArgSelf("right");
283
2
  tree.addConstructor(node);
284
285
  std::shared_ptr<DTypeConstructor> leaf =
286
4
      std::make_shared<DTypeConstructor>("leaf");
287
2
  leaf->addArg("leaf", unresList);
288
2
  tree.addConstructor(leaf);
289
290
2
  Debug("datatypes") << tree << std::endl;
291
292
4
  DType list("list");
293
  std::shared_ptr<DTypeConstructor> cons =
294
4
      std::make_shared<DTypeConstructor>("cons");
295
2
  cons->addArg("car", unresTree);
296
2
  cons->addArgSelf("cdr");
297
2
  list.addConstructor(cons);
298
299
  std::shared_ptr<DTypeConstructor> nil =
300
4
      std::make_shared<DTypeConstructor>("nil");
301
2
  list.addConstructor(nil);
302
303
2
  Debug("datatypes") << list << std::endl;
304
305
2
  ASSERT_FALSE(tree.isResolved());
306
2
  ASSERT_FALSE(list.isResolved());
307
308
4
  std::vector<DType> dts;
309
2
  dts.push_back(tree);
310
2
  dts.push_back(list);
311
  std::vector<TypeNode> dtts =
312
4
      d_nodeManager->mkMutualDatatypeTypes(dts, unresolvedTypes);
313
314
2
  ASSERT_TRUE(dtts[0].getDType().isResolved());
315
2
  ASSERT_TRUE(dtts[1].getDType().isResolved());
316
317
2
  ASSERT_FALSE(dtts[0].getDType().isFinite());
318
2
  ASSERT_TRUE(dtts[0].getDType().getCardinality().compare(Cardinality::INTEGERS)
319
2
              == Cardinality::EQUAL);
320
2
  ASSERT_TRUE(dtts[0].getDType().isWellFounded());
321
4
  Debug("groundterms") << "ground term of " << dtts[0].getDType().getName()
322
2
                       << std::endl
323
2
                       << "  is " << dtts[0].mkGroundTerm() << std::endl;
324
2
  ASSERT_TRUE(dtts[0].mkGroundTerm().getType() == dtts[0]);
325
326
2
  ASSERT_FALSE(dtts[1].getDType().isFinite());
327
2
  ASSERT_TRUE(dtts[1].getDType().getCardinality().compare(Cardinality::INTEGERS)
328
2
              == Cardinality::EQUAL);
329
2
  ASSERT_TRUE(dtts[1].getDType().isWellFounded());
330
4
  Debug("groundterms") << "ground term of " << dtts[1].getDType().getName()
331
2
                       << std::endl
332
2
                       << "  is " << dtts[1].mkGroundTerm() << std::endl;
333
2
  ASSERT_TRUE(dtts[1].mkGroundTerm().getType() == dtts[1]);
334
}
335
336
20
TEST_F(TestUtilBlackDatatype, mutual_list_trees2)
337
{
338
4
  std::set<TypeNode> unresolvedTypes;
339
  TypeNode unresList =
340
4
      d_nodeManager->mkSort("list", NodeManager::SORT_FLAG_PLACEHOLDER);
341
2
  unresolvedTypes.insert(unresList);
342
  TypeNode unresTree =
343
4
      d_nodeManager->mkSort("tree", NodeManager::SORT_FLAG_PLACEHOLDER);
344
2
  unresolvedTypes.insert(unresTree);
345
346
4
  DType tree("tree");
347
  std::shared_ptr<DTypeConstructor> node =
348
4
      std::make_shared<DTypeConstructor>("node");
349
2
  node->addArgSelf("left");
350
2
  node->addArgSelf("right");
351
2
  tree.addConstructor(node);
352
353
  std::shared_ptr<DTypeConstructor> leaf =
354
4
      std::make_shared<DTypeConstructor>("leaf");
355
2
  leaf->addArg("leaf", unresList);
356
2
  tree.addConstructor(leaf);
357
358
4
  DType list("list");
359
  std::shared_ptr<DTypeConstructor> cons =
360
4
      std::make_shared<DTypeConstructor>("cons");
361
2
  cons->addArg("car", unresTree);
362
2
  cons->addArgSelf("cdr");
363
2
  list.addConstructor(cons);
364
365
  std::shared_ptr<DTypeConstructor> nil =
366
4
      std::make_shared<DTypeConstructor>("nil");
367
2
  list.addConstructor(nil);
368
369
  // add another constructor to list datatype resulting in an
370
  // "otherNil-list"
371
  std::shared_ptr<DTypeConstructor> otherNil =
372
4
      std::make_shared<DTypeConstructor>("otherNil");
373
2
  list.addConstructor(otherNil);
374
375
4
  std::vector<DType> dts;
376
2
  dts.push_back(tree);
377
2
  dts.push_back(list);
378
  // remake the types
379
  std::vector<TypeNode> dtts2 =
380
4
      d_nodeManager->mkMutualDatatypeTypes(dts, unresolvedTypes);
381
382
2
  ASSERT_FALSE(dtts2[0].getDType().isFinite());
383
2
  ASSERT_TRUE(
384
      dtts2[0].getDType().getCardinality().compare(Cardinality::INTEGERS)
385
2
      == Cardinality::EQUAL);
386
2
  ASSERT_TRUE(dtts2[0].getDType().isWellFounded());
387
4
  Debug("groundterms") << "ground term of " << dtts2[0].getDType().getName()
388
2
                       << std::endl
389
2
                       << "  is " << dtts2[0].mkGroundTerm() << std::endl;
390
2
  ASSERT_TRUE(dtts2[0].mkGroundTerm().getType() == dtts2[0]);
391
392
2
  ASSERT_FALSE(dtts2[1].getDType().isParametric());
393
2
  ASSERT_FALSE(dtts2[1].getDType().isFinite());
394
2
  ASSERT_TRUE(
395
      dtts2[1].getDType().getCardinality().compare(Cardinality::INTEGERS)
396
2
      == Cardinality::EQUAL);
397
2
  ASSERT_TRUE(dtts2[1].getDType().isWellFounded());
398
4
  Debug("groundterms") << "ground term of " << dtts2[1].getDType().getName()
399
2
                       << std::endl
400
2
                       << "  is " << dtts2[1].mkGroundTerm() << std::endl;
401
2
  ASSERT_TRUE(dtts2[1].mkGroundTerm().getType() == dtts2[1]);
402
}
403
404
20
TEST_F(TestUtilBlackDatatype, not_so_well_founded)
405
{
406
4
  DType tree("tree");
407
408
  std::shared_ptr<DTypeConstructor> node =
409
4
      std::make_shared<DTypeConstructor>("node");
410
2
  node->addArgSelf("left");
411
2
  node->addArgSelf("right");
412
2
  tree.addConstructor(node);
413
414
2
  Debug("datatypes") << tree << std::endl;
415
4
  TypeNode treeType = d_nodeManager->mkDatatypeType(tree);
416
2
  Debug("datatypes") << treeType << std::endl;
417
418
2
  ASSERT_FALSE(treeType.getDType().isParametric());
419
2
  ASSERT_FALSE(treeType.getDType().isFinite());
420
2
  ASSERT_TRUE(
421
      treeType.getDType().getCardinality().compare(Cardinality::INTEGERS)
422
2
      == Cardinality::EQUAL);
423
2
  ASSERT_FALSE(treeType.getDType().isWellFounded());
424
2
  ASSERT_TRUE(treeType.mkGroundTerm().isNull());
425
2
  ASSERT_TRUE(treeType.getDType().mkGroundTerm(treeType).isNull());
426
}
427
428
20
TEST_F(TestUtilBlackDatatype, parametric_DType)
429
{
430
4
  std::vector<TypeNode> v;
431
4
  TypeNode t1, t2;
432
2
  v.push_back(t1 = d_nodeManager->mkSort("T1"));
433
2
  v.push_back(t2 = d_nodeManager->mkSort("T2"));
434
4
  DType pair("pair", v);
435
436
  std::shared_ptr<DTypeConstructor> mkpair =
437
4
      std::make_shared<DTypeConstructor>("mk-pair");
438
2
  mkpair->addArg("first", t1);
439
2
  mkpair->addArg("second", t2);
440
2
  pair.addConstructor(mkpair);
441
4
  TypeNode pairType = d_nodeManager->mkDatatypeType(pair);
442
443
2
  ASSERT_TRUE(pairType.getDType().isParametric());
444
2
  v.clear();
445
2
  v.push_back(d_nodeManager->integerType());
446
2
  v.push_back(d_nodeManager->integerType());
447
4
  TypeNode pairIntInt = pairType.getDType().getTypeNode(v);
448
2
  v.clear();
449
2
  v.push_back(d_nodeManager->realType());
450
2
  v.push_back(d_nodeManager->realType());
451
4
  TypeNode pairRealReal = pairType.getDType().getTypeNode(v);
452
2
  v.clear();
453
2
  v.push_back(d_nodeManager->realType());
454
2
  v.push_back(d_nodeManager->integerType());
455
4
  TypeNode pairRealInt = pairType.getDType().getTypeNode(v);
456
2
  v.clear();
457
2
  v.push_back(d_nodeManager->integerType());
458
2
  v.push_back(d_nodeManager->realType());
459
4
  TypeNode pairIntReal = pairType.getDType().getTypeNode(v);
460
461
2
  ASSERT_NE(pairIntInt, pairRealReal);
462
2
  ASSERT_NE(pairIntReal, pairRealReal);
463
2
  ASSERT_NE(pairRealInt, pairRealReal);
464
2
  ASSERT_NE(pairIntInt, pairIntReal);
465
2
  ASSERT_NE(pairIntInt, pairRealInt);
466
2
  ASSERT_NE(pairIntReal, pairRealInt);
467
468
2
  ASSERT_TRUE(pairRealReal.isComparableTo(pairRealReal));
469
2
  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealReal));
470
2
  ASSERT_FALSE(pairRealInt.isComparableTo(pairRealReal));
471
2
  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealReal));
472
2
  ASSERT_FALSE(pairRealReal.isComparableTo(pairRealInt));
473
2
  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealInt));
474
2
  ASSERT_TRUE(pairRealInt.isComparableTo(pairRealInt));
475
2
  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealInt));
476
2
  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntReal));
477
2
  ASSERT_TRUE(pairIntReal.isComparableTo(pairIntReal));
478
2
  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntReal));
479
2
  ASSERT_FALSE(pairIntInt.isComparableTo(pairIntReal));
480
2
  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntInt));
481
2
  ASSERT_FALSE(pairIntReal.isComparableTo(pairIntInt));
482
2
  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntInt));
483
2
  ASSERT_TRUE(pairIntInt.isComparableTo(pairIntInt));
484
485
2
  ASSERT_TRUE(pairRealReal.isSubtypeOf(pairRealReal));
486
2
  ASSERT_FALSE(pairIntReal.isSubtypeOf(pairRealReal));
487
2
  ASSERT_FALSE(pairRealInt.isSubtypeOf(pairRealReal));
488
2
  ASSERT_FALSE(pairIntInt.isSubtypeOf(pairRealReal));
489
2
  ASSERT_FALSE(pairRealReal.isSubtypeOf(pairRealInt));
490
2
  ASSERT_FALSE(pairIntReal.isSubtypeOf(pairRealInt));
491
2
  ASSERT_TRUE(pairRealInt.isSubtypeOf(pairRealInt));
492
2
  ASSERT_FALSE(pairIntInt.isSubtypeOf(pairRealInt));
493
2
  ASSERT_FALSE(pairRealReal.isSubtypeOf(pairIntReal));
494
2
  ASSERT_TRUE(pairIntReal.isSubtypeOf(pairIntReal));
495
2
  ASSERT_FALSE(pairRealInt.isSubtypeOf(pairIntReal));
496
2
  ASSERT_FALSE(pairIntInt.isSubtypeOf(pairIntReal));
497
2
  ASSERT_FALSE(pairRealReal.isSubtypeOf(pairIntInt));
498
2
  ASSERT_FALSE(pairIntReal.isSubtypeOf(pairIntInt));
499
2
  ASSERT_FALSE(pairRealInt.isSubtypeOf(pairIntInt));
500
2
  ASSERT_TRUE(pairIntInt.isSubtypeOf(pairIntInt));
501
502
2
  ASSERT_EQ(TypeNode::leastCommonTypeNode(pairRealReal, pairRealReal),
503
2
            pairRealReal);
504
2
  ASSERT_TRUE(
505
2
      TypeNode::leastCommonTypeNode(pairIntReal, pairRealReal).isNull());
506
2
  ASSERT_TRUE(
507
2
      TypeNode::leastCommonTypeNode(pairRealInt, pairRealReal).isNull());
508
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairIntInt, pairRealReal).isNull());
509
2
  ASSERT_TRUE(
510
2
      TypeNode::leastCommonTypeNode(pairRealReal, pairRealInt).isNull());
511
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairIntReal, pairRealInt).isNull());
512
2
  ASSERT_EQ(TypeNode::leastCommonTypeNode(pairRealInt, pairRealInt),
513
2
            pairRealInt);
514
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairIntInt, pairRealInt).isNull());
515
2
  ASSERT_TRUE(
516
2
      TypeNode::leastCommonTypeNode(pairRealReal, pairIntReal).isNull());
517
2
  ASSERT_EQ(TypeNode::leastCommonTypeNode(pairIntReal, pairIntReal),
518
2
            pairIntReal);
519
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairRealInt, pairIntReal).isNull());
520
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairIntInt, pairIntReal).isNull());
521
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairRealReal, pairIntInt).isNull());
522
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairIntReal, pairIntInt).isNull());
523
2
  ASSERT_TRUE(TypeNode::leastCommonTypeNode(pairRealInt, pairIntInt).isNull());
524
2
  ASSERT_EQ(TypeNode::leastCommonTypeNode(pairIntInt, pairIntInt), pairIntInt);
525
}
526
}  // namespace test
527
169508
}  // namespace cvc5