1 /********************* */
2 /*! \file datatype_black.h
4 ** Top contributors (to current version):
5 ** Morgan Deters, Andrew Reynolds, Andres Noetzli
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief Black box testing of CVC4::DType
14 ** Black box testing of CVC4::DType.
17 #include <cxxtest/TestSuite.h>
21 #include "api/cvc4cpp.h"
22 #include "expr/dtype.h"
23 #include "expr/expr.h"
24 #include "expr/expr_manager.h"
25 #include "expr/expr_manager_scope.h"
26 #include "expr/type_node.h"
31 class DatatypeBlack
: public CxxTest::TestSuite
{
35 d_slv
= new api::Solver();
36 d_nm
= d_slv
->getNodeManager();
37 d_scope
= new NodeManagerScope(d_nm
);
38 Debug
.on("datatypes");
39 Debug
.on("groundterms");
42 void tearDown() override
48 void testEnumeration() {
49 DType
colors("colors");
51 std::shared_ptr
<DTypeConstructor
> yellow
=
52 std::make_shared
<DTypeConstructor
>("yellow");
53 std::shared_ptr
<DTypeConstructor
> blue
=
54 std::make_shared
<DTypeConstructor
>("blue");
55 std::shared_ptr
<DTypeConstructor
> green
=
56 std::make_shared
<DTypeConstructor
>("green");
57 std::shared_ptr
<DTypeConstructor
> red
=
58 std::make_shared
<DTypeConstructor
>("red");
60 colors
.addConstructor(yellow
);
61 colors
.addConstructor(blue
);
62 colors
.addConstructor(green
);
63 colors
.addConstructor(red
);
65 Debug("datatypes") << colors
<< std::endl
;
66 TypeNode colorsType
= d_nm
->mkDatatypeType(colors
);
67 Debug("datatypes") << colorsType
<< std::endl
;
69 Node ctor
= colorsType
.getDType()[1].getConstructor();
70 Node apply
= d_nm
->mkNode(kind::APPLY_CONSTRUCTOR
, ctor
);
71 Debug("datatypes") << apply
<< std::endl
;
73 TS_ASSERT(!colorsType
.getDType().isParametric());
74 TS_ASSERT(colorsType
.getDType().isFinite());
75 TS_ASSERT(colorsType
.getDType().getCardinality().compare(4)
76 == Cardinality::EQUAL
);
77 TS_ASSERT(ctor
.getType().getCardinality().compare(1) == Cardinality::EQUAL
);
78 TS_ASSERT(colorsType
.getDType().isWellFounded());
79 Debug("groundterms") << "ground term of " << colorsType
.getDType().getName()
81 << " is " << colorsType
.mkGroundTerm() << endl
;
82 TS_ASSERT(colorsType
.mkGroundTerm().getType() == colorsType
);
88 std::shared_ptr
<DTypeConstructor
> succ
=
89 std::make_shared
<DTypeConstructor
>("succ");
90 succ
->addArgSelf("pred");
91 nat
.addConstructor(succ
);
93 std::shared_ptr
<DTypeConstructor
> zero
=
94 std::make_shared
<DTypeConstructor
>("zero");
95 nat
.addConstructor(zero
);
97 Debug("datatypes") << nat
<< std::endl
;
98 TypeNode natType
= d_nm
->mkDatatypeType(nat
);
99 Debug("datatypes") << natType
<< std::endl
;
101 Node ctor
= natType
.getDType()[1].getConstructor();
102 Node apply
= d_nm
->mkNode(kind::APPLY_CONSTRUCTOR
, ctor
);
103 Debug("datatypes") << apply
<< std::endl
;
105 TS_ASSERT(!natType
.getDType().isParametric());
106 TS_ASSERT(!natType
.getDType().isFinite());
107 TS_ASSERT(natType
.getDType().getCardinality().compare(Cardinality::INTEGERS
)
108 == Cardinality::EQUAL
);
109 TS_ASSERT(natType
.getDType().isWellFounded());
110 Debug("groundterms") << "ground term of " << natType
.getDType().getName()
112 << " is " << natType
.mkGroundTerm() << endl
;
113 TS_ASSERT(natType
.mkGroundTerm().getType() == natType
);
118 TypeNode integerType
= d_nm
->integerType();
120 std::shared_ptr
<DTypeConstructor
> node
=
121 std::make_shared
<DTypeConstructor
>("node");
122 node
->addArgSelf("left");
123 node
->addArgSelf("right");
124 tree
.addConstructor(node
);
126 std::shared_ptr
<DTypeConstructor
> leaf
=
127 std::make_shared
<DTypeConstructor
>("leaf");
128 leaf
->addArg("leaf", integerType
);
129 tree
.addConstructor(leaf
);
131 Debug("datatypes") << tree
<< std::endl
;
132 TypeNode treeType
= d_nm
->mkDatatypeType(tree
);
133 Debug("datatypes") << treeType
<< std::endl
;
135 TS_ASSERT(!treeType
.getDType().isParametric());
136 TS_ASSERT(!treeType
.getDType().isFinite());
138 treeType
.getDType().getCardinality().compare(Cardinality::INTEGERS
)
139 == Cardinality::EQUAL
);
140 TS_ASSERT(treeType
.getDType().isWellFounded());
141 Debug("groundterms") << "ground term of " << treeType
.getDType().getName()
143 << " is " << treeType
.mkGroundTerm() << endl
;
144 TS_ASSERT(treeType
.mkGroundTerm().getType() == treeType
);
149 TypeNode integerType
= d_nm
->integerType();
151 std::shared_ptr
<DTypeConstructor
> cons
=
152 std::make_shared
<DTypeConstructor
>("cons");
153 cons
->addArg("car", integerType
);
154 cons
->addArgSelf("cdr");
155 list
.addConstructor(cons
);
157 std::shared_ptr
<DTypeConstructor
> nil
=
158 std::make_shared
<DTypeConstructor
>("nil");
159 list
.addConstructor(nil
);
161 Debug("datatypes") << list
<< std::endl
;
162 TypeNode listType
= d_nm
->mkDatatypeType(list
);
163 Debug("datatypes") << listType
<< std::endl
;
165 TS_ASSERT(!listType
.getDType().isParametric());
166 TS_ASSERT(!listType
.getDType().isFinite());
168 listType
.getDType().getCardinality().compare(Cardinality::INTEGERS
)
169 == Cardinality::EQUAL
);
170 TS_ASSERT(listType
.getDType().isWellFounded());
171 Debug("groundterms") << "ground term of " << listType
.getDType().getName()
173 << " is " << listType
.mkGroundTerm() << endl
;
174 TS_ASSERT(listType
.mkGroundTerm().getType() == listType
);
177 void testListReal() {
179 TypeNode realType
= d_nm
->realType();
181 std::shared_ptr
<DTypeConstructor
> cons
=
182 std::make_shared
<DTypeConstructor
>("cons");
183 cons
->addArg("car", realType
);
184 cons
->addArgSelf("cdr");
185 list
.addConstructor(cons
);
187 std::shared_ptr
<DTypeConstructor
> nil
=
188 std::make_shared
<DTypeConstructor
>("nil");
189 list
.addConstructor(nil
);
191 Debug("datatypes") << list
<< std::endl
;
192 TypeNode listType
= d_nm
->mkDatatypeType(list
);
193 Debug("datatypes") << listType
<< std::endl
;
195 TS_ASSERT(!listType
.getDType().isParametric());
196 TS_ASSERT(!listType
.getDType().isFinite());
197 TS_ASSERT(listType
.getDType().getCardinality().compare(Cardinality::REALS
)
198 == Cardinality::EQUAL
);
199 TS_ASSERT(listType
.getDType().isWellFounded());
200 Debug("groundterms") << "ground term of " << listType
.getDType().getName()
202 << " is " << listType
.mkGroundTerm() << endl
;
203 TS_ASSERT(listType
.mkGroundTerm().getType() == listType
);
206 void testListBoolean() {
208 TypeNode booleanType
= d_nm
->booleanType();
210 std::shared_ptr
<DTypeConstructor
> cons
=
211 std::make_shared
<DTypeConstructor
>("cons");
212 cons
->addArg("car", booleanType
);
213 cons
->addArgSelf("cdr");
214 list
.addConstructor(cons
);
216 std::shared_ptr
<DTypeConstructor
> nil
=
217 std::make_shared
<DTypeConstructor
>("nil");
218 list
.addConstructor(nil
);
220 Debug("datatypes") << list
<< std::endl
;
221 TypeNode listType
= d_nm
->mkDatatypeType(list
);
222 Debug("datatypes") << listType
<< std::endl
;
224 TS_ASSERT(!listType
.getDType().isFinite());
226 listType
.getDType().getCardinality().compare(Cardinality::INTEGERS
)
227 == Cardinality::EQUAL
);
228 TS_ASSERT(listType
.getDType().isWellFounded());
229 Debug("groundterms") << "ground term of " << listType
.getDType().getName()
231 << " is " << listType
.mkGroundTerm() << endl
;
232 TS_ASSERT(listType
.mkGroundTerm().getType() == listType
);
235 void testMutualListTrees() {
236 /* Create two mutual datatypes corresponding to this definition
240 * tree = node(left: tree, right: tree) | leaf(list),
241 * list = cons(car: tree, cdr: list) | nil
244 std::set
<TypeNode
> unresolvedTypes
;
246 d_nm
->mkSort("list", ExprManager::SORT_FLAG_PLACEHOLDER
);
247 unresolvedTypes
.insert(unresList
);
249 d_nm
->mkSort("tree", ExprManager::SORT_FLAG_PLACEHOLDER
);
250 unresolvedTypes
.insert(unresTree
);
253 std::shared_ptr
<DTypeConstructor
> node
=
254 std::make_shared
<DTypeConstructor
>("node");
255 node
->addArgSelf("left");
256 node
->addArgSelf("right");
257 tree
.addConstructor(node
);
259 std::shared_ptr
<DTypeConstructor
> leaf
=
260 std::make_shared
<DTypeConstructor
>("leaf");
261 leaf
->addArg("leaf", unresList
);
262 tree
.addConstructor(leaf
);
264 Debug("datatypes") << tree
<< std::endl
;
267 std::shared_ptr
<DTypeConstructor
> cons
=
268 std::make_shared
<DTypeConstructor
>("cons");
269 cons
->addArg("car", unresTree
);
270 cons
->addArgSelf("cdr");
271 list
.addConstructor(cons
);
273 std::shared_ptr
<DTypeConstructor
> nil
=
274 std::make_shared
<DTypeConstructor
>("nil");
275 list
.addConstructor(nil
);
277 Debug("datatypes") << list
<< std::endl
;
279 TS_ASSERT(! tree
.isResolved());
280 TS_ASSERT(! list
.isResolved());
285 vector
<TypeNode
> dtts
= d_nm
->mkMutualDatatypeTypes(dts
, unresolvedTypes
);
287 TS_ASSERT(dtts
[0].getDType().isResolved());
288 TS_ASSERT(dtts
[1].getDType().isResolved());
290 TS_ASSERT(!dtts
[0].getDType().isFinite());
291 TS_ASSERT(dtts
[0].getDType().getCardinality().compare(Cardinality::INTEGERS
)
292 == Cardinality::EQUAL
);
293 TS_ASSERT(dtts
[0].getDType().isWellFounded());
294 Debug("groundterms") << "ground term of " << dtts
[0].getDType().getName()
296 << " is " << dtts
[0].mkGroundTerm() << endl
;
297 TS_ASSERT(dtts
[0].mkGroundTerm().getType() == dtts
[0]);
299 TS_ASSERT(!dtts
[1].getDType().isFinite());
300 TS_ASSERT(dtts
[1].getDType().getCardinality().compare(Cardinality::INTEGERS
)
301 == Cardinality::EQUAL
);
302 TS_ASSERT(dtts
[1].getDType().isWellFounded());
303 Debug("groundterms") << "ground term of " << dtts
[1].getDType().getName()
305 << " is " << dtts
[1].mkGroundTerm() << endl
;
306 TS_ASSERT(dtts
[1].mkGroundTerm().getType() == dtts
[1]);
308 void testMutualListTrees2()
310 std::set
<TypeNode
> unresolvedTypes
;
312 d_nm
->mkSort("list", ExprManager::SORT_FLAG_PLACEHOLDER
);
313 unresolvedTypes
.insert(unresList
);
315 d_nm
->mkSort("tree", ExprManager::SORT_FLAG_PLACEHOLDER
);
316 unresolvedTypes
.insert(unresTree
);
319 std::shared_ptr
<DTypeConstructor
> node
=
320 std::make_shared
<DTypeConstructor
>("node");
321 node
->addArgSelf("left");
322 node
->addArgSelf("right");
323 tree
.addConstructor(node
);
325 std::shared_ptr
<DTypeConstructor
> leaf
=
326 std::make_shared
<DTypeConstructor
>("leaf");
327 leaf
->addArg("leaf", unresList
);
328 tree
.addConstructor(leaf
);
331 std::shared_ptr
<DTypeConstructor
> cons
=
332 std::make_shared
<DTypeConstructor
>("cons");
333 cons
->addArg("car", unresTree
);
334 cons
->addArgSelf("cdr");
335 list
.addConstructor(cons
);
337 std::shared_ptr
<DTypeConstructor
> nil
=
338 std::make_shared
<DTypeConstructor
>("nil");
339 list
.addConstructor(nil
);
341 // add another constructor to list datatype resulting in an
343 std::shared_ptr
<DTypeConstructor
> otherNil
=
344 std::make_shared
<DTypeConstructor
>("otherNil");
345 list
.addConstructor(otherNil
);
351 vector
<TypeNode
> dtts2
= d_nm
->mkMutualDatatypeTypes(dts
, unresolvedTypes
);
353 TS_ASSERT(!dtts2
[0].getDType().isFinite());
355 dtts2
[0].getDType().getCardinality().compare(Cardinality::INTEGERS
)
356 == Cardinality::EQUAL
);
357 TS_ASSERT(dtts2
[0].getDType().isWellFounded());
358 Debug("groundterms") << "ground term of " << dtts2
[0].getDType().getName()
360 << " is " << dtts2
[0].mkGroundTerm() << endl
;
361 TS_ASSERT(dtts2
[0].mkGroundTerm().getType() == dtts2
[0]);
363 TS_ASSERT(!dtts2
[1].getDType().isParametric());
364 TS_ASSERT(!dtts2
[1].getDType().isFinite());
366 dtts2
[1].getDType().getCardinality().compare(Cardinality::INTEGERS
)
367 == Cardinality::EQUAL
);
368 TS_ASSERT(dtts2
[1].getDType().isWellFounded());
369 Debug("groundterms") << "ground term of " << dtts2
[1].getDType().getName()
371 << " is " << dtts2
[1].mkGroundTerm() << endl
;
372 TS_ASSERT(dtts2
[1].mkGroundTerm().getType() == dtts2
[1]);
375 void testNotSoWellFounded() {
378 std::shared_ptr
<DTypeConstructor
> node
=
379 std::make_shared
<DTypeConstructor
>("node");
380 node
->addArgSelf("left");
381 node
->addArgSelf("right");
382 tree
.addConstructor(node
);
384 Debug("datatypes") << tree
<< std::endl
;
385 TypeNode treeType
= d_nm
->mkDatatypeType(tree
);
386 Debug("datatypes") << treeType
<< std::endl
;
388 TS_ASSERT(!treeType
.getDType().isParametric());
389 TS_ASSERT(!treeType
.getDType().isFinite());
391 treeType
.getDType().getCardinality().compare(Cardinality::INTEGERS
)
392 == Cardinality::EQUAL
);
393 TS_ASSERT(!treeType
.getDType().isWellFounded());
394 TS_ASSERT(treeType
.mkGroundTerm().isNull());
395 TS_ASSERT(treeType
.getDType().mkGroundTerm(treeType
).isNull());
398 void testParametricDType()
402 v
.push_back(t1
= d_nm
->mkSort("T1"));
403 v
.push_back(t2
= d_nm
->mkSort("T2"));
404 DType
pair("pair", v
);
406 std::shared_ptr
<DTypeConstructor
> mkpair
=
407 std::make_shared
<DTypeConstructor
>("mk-pair");
408 mkpair
->addArg("first", t1
);
409 mkpair
->addArg("second", t2
);
410 pair
.addConstructor(mkpair
);
411 TypeNode pairType
= d_nm
->mkDatatypeType(pair
);
413 TS_ASSERT(pairType
.getDType().isParametric());
415 v
.push_back(d_nm
->integerType());
416 v
.push_back(d_nm
->integerType());
417 TypeNode pairIntInt
= pairType
.getDType().getTypeNode(v
);
419 v
.push_back(d_nm
->realType());
420 v
.push_back(d_nm
->realType());
421 TypeNode pairRealReal
= pairType
.getDType().getTypeNode(v
);
423 v
.push_back(d_nm
->realType());
424 v
.push_back(d_nm
->integerType());
425 TypeNode pairRealInt
= pairType
.getDType().getTypeNode(v
);
427 v
.push_back(d_nm
->integerType());
428 v
.push_back(d_nm
->realType());
429 TypeNode pairIntReal
= pairType
.getDType().getTypeNode(v
);
431 TS_ASSERT_DIFFERS(pairIntInt
, pairRealReal
);
432 TS_ASSERT_DIFFERS(pairIntReal
, pairRealReal
);
433 TS_ASSERT_DIFFERS(pairRealInt
, pairRealReal
);
434 TS_ASSERT_DIFFERS(pairIntInt
, pairIntReal
);
435 TS_ASSERT_DIFFERS(pairIntInt
, pairRealInt
);
436 TS_ASSERT_DIFFERS(pairIntReal
, pairRealInt
);
438 TS_ASSERT(pairRealReal
.isComparableTo(pairRealReal
));
439 TS_ASSERT(!pairIntReal
.isComparableTo(pairRealReal
));
440 TS_ASSERT(!pairRealInt
.isComparableTo(pairRealReal
));
441 TS_ASSERT(!pairIntInt
.isComparableTo(pairRealReal
));
442 TS_ASSERT(!pairRealReal
.isComparableTo(pairRealInt
));
443 TS_ASSERT(!pairIntReal
.isComparableTo(pairRealInt
));
444 TS_ASSERT(pairRealInt
.isComparableTo(pairRealInt
));
445 TS_ASSERT(!pairIntInt
.isComparableTo(pairRealInt
));
446 TS_ASSERT(!pairRealReal
.isComparableTo(pairIntReal
));
447 TS_ASSERT(pairIntReal
.isComparableTo(pairIntReal
));
448 TS_ASSERT(!pairRealInt
.isComparableTo(pairIntReal
));
449 TS_ASSERT(!pairIntInt
.isComparableTo(pairIntReal
));
450 TS_ASSERT(!pairRealReal
.isComparableTo(pairIntInt
));
451 TS_ASSERT(!pairIntReal
.isComparableTo(pairIntInt
));
452 TS_ASSERT(!pairRealInt
.isComparableTo(pairIntInt
));
453 TS_ASSERT(pairIntInt
.isComparableTo(pairIntInt
));
455 TS_ASSERT(pairRealReal
.isSubtypeOf(pairRealReal
));
456 TS_ASSERT(!pairIntReal
.isSubtypeOf(pairRealReal
));
457 TS_ASSERT(!pairRealInt
.isSubtypeOf(pairRealReal
));
458 TS_ASSERT(!pairIntInt
.isSubtypeOf(pairRealReal
));
459 TS_ASSERT(!pairRealReal
.isSubtypeOf(pairRealInt
));
460 TS_ASSERT(!pairIntReal
.isSubtypeOf(pairRealInt
));
461 TS_ASSERT(pairRealInt
.isSubtypeOf(pairRealInt
));
462 TS_ASSERT(!pairIntInt
.isSubtypeOf(pairRealInt
));
463 TS_ASSERT(!pairRealReal
.isSubtypeOf(pairIntReal
));
464 TS_ASSERT(pairIntReal
.isSubtypeOf(pairIntReal
));
465 TS_ASSERT(!pairRealInt
.isSubtypeOf(pairIntReal
));
466 TS_ASSERT(!pairIntInt
.isSubtypeOf(pairIntReal
));
467 TS_ASSERT(!pairRealReal
.isSubtypeOf(pairIntInt
));
468 TS_ASSERT(!pairIntReal
.isSubtypeOf(pairIntInt
));
469 TS_ASSERT(!pairRealInt
.isSubtypeOf(pairIntInt
));
470 TS_ASSERT(pairIntInt
.isSubtypeOf(pairIntInt
));
472 TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(pairRealReal
, pairRealReal
),
475 TypeNode::leastCommonTypeNode(pairIntReal
, pairRealReal
).isNull());
477 TypeNode::leastCommonTypeNode(pairRealInt
, pairRealReal
).isNull());
478 TS_ASSERT(TypeNode::leastCommonTypeNode(pairIntInt
, pairRealReal
).isNull());
480 TypeNode::leastCommonTypeNode(pairRealReal
, pairRealInt
).isNull());
481 TS_ASSERT(TypeNode::leastCommonTypeNode(pairIntReal
, pairRealInt
).isNull());
482 TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(pairRealInt
, pairRealInt
),
484 TS_ASSERT(TypeNode::leastCommonTypeNode(pairIntInt
, pairRealInt
).isNull());
486 TypeNode::leastCommonTypeNode(pairRealReal
, pairIntReal
).isNull());
487 TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(pairIntReal
, pairIntReal
),
489 TS_ASSERT(TypeNode::leastCommonTypeNode(pairRealInt
, pairIntReal
).isNull());
490 TS_ASSERT(TypeNode::leastCommonTypeNode(pairIntInt
, pairIntReal
).isNull());
491 TS_ASSERT(TypeNode::leastCommonTypeNode(pairRealReal
, pairIntInt
).isNull());
492 TS_ASSERT(TypeNode::leastCommonTypeNode(pairIntReal
, pairIntInt
).isNull());
493 TS_ASSERT(TypeNode::leastCommonTypeNode(pairRealInt
, pairIntInt
).isNull());
494 TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(pairIntInt
, pairIntInt
),
501 NodeManagerScope
* d_scope
;
502 }; /* class DTypeBlack */