GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/theory/theory_bv_opt_white.cpp Lines: 73 73 100.0 %
Date: 2021-05-22 Branches: 167 414 40.3 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Yancheng Ou, Michael Chang
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
 * White-box testing for optimization module for BitVectors.
14
 */
15
#include <iostream>
16
17
#include "smt/optimization_solver.h"
18
#include "test_smt.h"
19
20
namespace cvc5 {
21
22
using namespace theory;
23
using namespace smt;
24
25
namespace test {
26
27
20
class TestTheoryWhiteBVOpt : public TestSmtNoFinishInit
28
{
29
 protected:
30
10
  void SetUp() override
31
  {
32
10
    TestSmtNoFinishInit::SetUp();
33
10
    d_smtEngine->setOption("produce-assertions", "true");
34
10
    d_smtEngine->finishInit();
35
36
10
    d_optslv.reset(new OptimizationSolver(d_smtEngine.get()));
37
10
    d_BV32Type.reset(new TypeNode(d_nodeManager->mkBitVectorType(32u)));
38
10
    d_BV16Type.reset(new TypeNode(d_nodeManager->mkBitVectorType(16u)));
39
10
  }
40
41
  std::unique_ptr<OptimizationSolver> d_optslv;
42
  std::unique_ptr<TypeNode> d_BV32Type;
43
  std::unique_ptr<TypeNode> d_BV16Type;
44
};
45
46
14
TEST_F(TestTheoryWhiteBVOpt, unsigned_min)
47
{
48
4
  Node x = d_nodeManager->mkVar(*d_BV32Type);
49
50
4
  Node a = d_nodeManager->mkConst(BitVector(32u, (unsigned)0x3FFFFFA1));
51
4
  Node b = d_nodeManager->mkConst(BitVector(32u, (unsigned)0xFFFFFFF1));
52
53
  // (unsigned)0x3FFFFFA1 <= x <= (unsigned)0xFFFFFFF1
54
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, a, x));
55
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, x, b));
56
57
2
  d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, false);
58
59
2
  OptimizationResult::ResultType r = d_optslv->checkOpt();
60
61
2
  ASSERT_EQ(r, OptimizationResult::OPTIMAL);
62
63
2
  ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
64
2
            BitVector(32u, (uint32_t)0x3FFFFFA1));
65
2
  d_optslv->popObjective();
66
}
67
68
14
TEST_F(TestTheoryWhiteBVOpt, signed_min)
69
{
70
4
  Node x = d_nodeManager->mkVar(*d_BV32Type);
71
72
4
  Node a = d_nodeManager->mkConst(BitVector(32u, (unsigned)0x80000000));
73
4
  Node b = d_nodeManager->mkConst(BitVector(32u, 2147483647u));
74
  // -2147483648 <= x <= 2147483647
75
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, a, x));
76
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, x, b));
77
78
2
  d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, true);
79
80
2
  OptimizationResult::ResultType r = d_optslv->checkOpt();
81
82
2
  ASSERT_EQ(r, OptimizationResult::OPTIMAL);
83
84
4
  BitVector val = d_optslv->getValues()[0].getValue().getConst<BitVector>();
85
2
  std::cout << "opt value is: " << val << std::endl;
86
87
  // expect the minimum x = -1
88
2
  ASSERT_EQ(val, BitVector(32u, (uint32_t)0x80000000));
89
2
  d_optslv->popObjective();
90
}
91
92
14
TEST_F(TestTheoryWhiteBVOpt, unsigned_max)
93
{
94
4
  Node x = d_nodeManager->mkVar(*d_BV32Type);
95
96
4
  Node a = d_nodeManager->mkConst(BitVector(32u, (unsigned)1));
97
4
  Node b = d_nodeManager->mkConst(BitVector(32u, (unsigned)2));
98
99
  // If the gap is too large, it will have a performance issue!!!
100
  // Need binary search!
101
  // (unsigned)1 <= x <= (unsigned)2
102
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, a, x));
103
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_ULE, x, b));
104
105
2
  d_optslv->pushObjective(x, OptimizationObjective::MAXIMIZE, false);
106
107
2
  OptimizationResult::ResultType r = d_optslv->checkOpt();
108
109
2
  ASSERT_EQ(r, OptimizationResult::OPTIMAL);
110
111
4
  BitVector val = d_optslv->getValues()[0].getValue().getConst<BitVector>();
112
2
  std::cout << "opt value is: " << val << std::endl;
113
114
2
  ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
115
2
            BitVector(32u, 2u));
116
2
  d_optslv->popObjective();
117
}
118
119
14
TEST_F(TestTheoryWhiteBVOpt, signed_max)
120
{
121
4
  Node x = d_nodeManager->mkVar(*d_BV32Type);
122
123
4
  Node a = d_nodeManager->mkConst(BitVector(32u, (unsigned)0x80000000));
124
4
  Node b = d_nodeManager->mkConst(BitVector(32u, 10u));
125
126
  // -2147483648 <= x <= 10
127
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, a, x));
128
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, x, b));
129
130
2
  d_optslv->pushObjective(x, OptimizationObjective::MAXIMIZE, true);
131
132
2
  OptimizationResult::ResultType r = d_optslv->checkOpt();
133
134
2
  ASSERT_EQ(r, OptimizationResult::OPTIMAL);
135
136
  // expect the maxmum x =
137
2
  ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
138
2
            BitVector(32u, 10u));
139
2
  d_optslv->popObjective();
140
}
141
142
14
TEST_F(TestTheoryWhiteBVOpt, min_boundary)
143
{
144
4
  Node x = d_nodeManager->mkVar(*d_BV32Type);
145
4
  Node y = d_nodeManager->mkVar(*d_BV32Type);
146
147
  // x <= 18
148
6
  d_smtEngine->assertFormula(d_nodeManager->mkNode(
149
4
      kind::BITVECTOR_ULE, d_nodeManager->mkConst(BitVector(32u, 18u)), x));
150
  // this perturbs the solver to trigger some boundary bug
151
  // that existed previously
152
2
  d_smtEngine->assertFormula(d_nodeManager->mkNode(kind::BITVECTOR_SLE, y, x));
153
154
2
  d_optslv->pushObjective(x, OptimizationObjective::MINIMIZE, false);
155
156
2
  OptimizationResult::ResultType r = d_optslv->checkOpt();
157
158
2
  ASSERT_EQ(r, OptimizationResult::OPTIMAL);
159
160
  // expect the maximum x = 18
161
2
  ASSERT_EQ(d_optslv->getValues()[0].getValue().getConst<BitVector>(),
162
2
            BitVector(32u, 18u));
163
2
  d_optslv->popObjective();
164
}
165
166
}  // namespace test
167
3335604
}  // namespace cvc5