GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/fp/type_enumerator.h Lines: 27 54 50.0 %
Date: 2021-08-16 Branches: 17 70 24.3 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Tim King, Martin Brain, Aina Niemetz
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
 * An enumerator for floating-point numbers.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__FP__TYPE_ENUMERATOR_H
19
#define CVC5__THEORY__FP__TYPE_ENUMERATOR_H
20
21
#include "expr/kind.h"
22
#include "expr/type_node.h"
23
#include "theory/type_enumerator.h"
24
#include "util/bitvector.h"
25
#include "util/floatingpoint.h"
26
27
namespace cvc5 {
28
namespace theory {
29
namespace fp {
30
31
30
class FloatingPointEnumerator
32
    : public TypeEnumeratorBase<FloatingPointEnumerator> {
33
 public:
34
15
  FloatingPointEnumerator(TypeNode type,
35
                          TypeEnumeratorProperties* tep = nullptr)
36
15
      : TypeEnumeratorBase<FloatingPointEnumerator>(type),
37
15
        d_e(type.getFloatingPointExponentSize()),
38
15
        d_s(type.getFloatingPointSignificandSize()),
39
15
        d_state(d_e + d_s, 0U),
40
60
        d_enumerationComplete(false) {}
41
42
  /** Throws NoMoreValuesException if the enumeration is complete. */
43
30
  Node operator*() override {
44
30
    if (d_enumerationComplete) {
45
      throw NoMoreValuesException(getType());
46
    }
47
30
    return NodeManager::currentNM()->mkConst(createFP());
48
  }
49
50
  FloatingPointEnumerator& operator++() override {
51
    const FloatingPoint current(createFP());
52
    if (current.isNaN()) {
53
      d_enumerationComplete = true;
54
    } else {
55
      d_state = d_state + BitVector(d_state.getSize(), 1U);
56
    }
57
    return *this;
58
  }
59
60
30
  bool isFinished() override { return d_enumerationComplete; }
61
62
 protected:
63
30
  FloatingPoint createFP(void) const {
64
    // Rotate the LSB into the sign so that NaN is the last value
65
30
    uint64_t vone = 1;
66
30
    uint64_t vmax = d_state.getSize() - 1;
67
    BitVector bva =
68
60
        d_state.logicalRightShift(BitVector(d_state.getSize(), vone));
69
60
    BitVector bvb = d_state.leftShift(BitVector(d_state.getSize(), vmax));
70
60
    const BitVector value = (bva | bvb);
71
72
60
    return FloatingPoint(d_e, d_s, value);
73
  }
74
75
 private:
76
  const unsigned d_e;
77
  const unsigned d_s;
78
  BitVector d_state;
79
  bool d_enumerationComplete;
80
}; /* FloatingPointEnumerator */
81
82
2
class RoundingModeEnumerator
83
    : public TypeEnumeratorBase<RoundingModeEnumerator> {
84
 public:
85
1
  RoundingModeEnumerator(TypeNode type, TypeEnumeratorProperties* tep = nullptr)
86
1
      : TypeEnumeratorBase<RoundingModeEnumerator>(type),
87
        d_rm(RoundingMode::ROUND_NEAREST_TIES_TO_EVEN),
88
1
        d_enumerationComplete(false)
89
  {
90
1
  }
91
92
  /** Throws NoMoreValuesException if the enumeration is complete. */
93
2
  Node operator*() override {
94
2
    if (d_enumerationComplete) {
95
      throw NoMoreValuesException(getType());
96
    }
97
2
    return NodeManager::currentNM()->mkConst(d_rm);
98
  }
99
100
  RoundingModeEnumerator& operator++() override {
101
    switch (d_rm) {
102
      case RoundingMode::ROUND_NEAREST_TIES_TO_EVEN:
103
        d_rm = RoundingMode::ROUND_TOWARD_POSITIVE;
104
        break;
105
      case RoundingMode::ROUND_TOWARD_POSITIVE:
106
        d_rm = RoundingMode::ROUND_TOWARD_NEGATIVE;
107
        break;
108
      case RoundingMode::ROUND_TOWARD_NEGATIVE:
109
        d_rm = RoundingMode::ROUND_TOWARD_ZERO;
110
        break;
111
      case RoundingMode::ROUND_TOWARD_ZERO:
112
        d_rm = RoundingMode::ROUND_NEAREST_TIES_TO_AWAY;
113
        break;
114
      case RoundingMode::ROUND_NEAREST_TIES_TO_AWAY:
115
        d_enumerationComplete = true;
116
        break;
117
      default: Unreachable() << "Unknown rounding mode?"; break;
118
    }
119
    return *this;
120
  }
121
122
2
  bool isFinished() override { return d_enumerationComplete; }
123
124
 private:
125
  RoundingMode d_rm;
126
  bool d_enumerationComplete;
127
}; /* RoundingModeEnumerator */
128
129
}  // namespace fp
130
}  // namespace theory
131
}  // namespace cvc5
132
133
#endif /* CVC5__THEORY__FP__TYPE_ENUMERATOR_H */