GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/theory/theory_bv_opt_white.cpp Lines: 73 73 100.0 %
Date: 2021-09-18 Branches: 172 424 40.6 %

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