File indexing completed on 2025-01-18 10:05:55
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <iostream>
0011 #include <ostream>
0012 #include <variant>
0013 #include <vector>
0014
0015 #include "corecel/io/EnumStringMapper.hh"
0016
0017 namespace celeritas
0018 {
0019 namespace orangeinp
0020 {
0021 namespace detail
0022 {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 class NodeReplacer
0033 {
0034 public:
0035 enum NodeRepl
0036 {
0037 unvisited,
0038 unknown,
0039 known_false,
0040 known_true
0041 };
0042
0043
0044
0045 using VecRepl = std::vector<NodeRepl>;
0046
0047
0048 public:
0049
0050 inline NodeReplacer(VecRepl* state, NodeId n);
0051
0052
0053 inline bool operator()(Aliased const& n);
0054 inline bool operator()(Negated const& n);
0055 inline bool operator()(Joined const& n);
0056
0057
0058 inline bool operator()(True const&);
0059 inline bool operator()(False const&);
0060
0061
0062 inline bool operator()(Surface const&) { return {}; }
0063
0064 private:
0065 VecRepl* state_;
0066 NodeRepl repl_;
0067
0068
0069 inline bool update(NodeId n, NodeRepl repl);
0070 };
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 NodeReplacer::NodeReplacer(VecRepl* state, NodeId n) : state_{state}
0081 {
0082 CELER_EXPECT(state_);
0083 repl_ = (*state_)[n.unchecked_get()];
0084 }
0085
0086
0087
0088
0089
0090 bool NodeReplacer::operator()(True const&)
0091 {
0092 CELER_ASSERT(repl_ == NodeRepl::known_true);
0093 return false;
0094 }
0095
0096
0097
0098
0099
0100 bool NodeReplacer::operator()(False const&)
0101 {
0102 CELER_ASSERT(repl_ == NodeRepl::known_false);
0103 return false;
0104 }
0105
0106
0107
0108
0109
0110
0111
0112 bool NodeReplacer::operator()(Aliased const& n)
0113 {
0114 return this->update(n.node, repl_);
0115 }
0116
0117
0118
0119
0120
0121
0122
0123 bool NodeReplacer::operator()(Negated const& n)
0124 {
0125 NodeRepl repl = [r = repl_] {
0126 switch (r)
0127 {
0128 case NodeRepl::known_false:
0129 return NodeRepl::known_true;
0130 case NodeRepl::known_true:
0131 return NodeRepl::known_false;
0132 default:
0133 return r;
0134 }
0135 }();
0136
0137 return this->update(n.node, repl);
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147 bool NodeReplacer::operator()(Joined const& n)
0148 {
0149 NodeRepl repl = repl_;
0150 if ((repl == NodeRepl::known_true && n.op == op_or)
0151 || (repl == NodeRepl::known_false && n.op == op_and))
0152 {
0153
0154
0155 repl = NodeRepl::unknown;
0156 }
0157
0158 bool updated{false};
0159 for (NodeId d : n.nodes)
0160 {
0161
0162
0163 bool daughter_updated = this->update(d, repl);
0164 updated = updated || daughter_updated;
0165 }
0166 return updated;
0167 }
0168
0169
0170
0171
0172
0173 bool NodeReplacer::update(NodeId n, NodeRepl repl)
0174 {
0175 CELER_EXPECT(n < state_->size());
0176 NodeRepl& dest = (*state_)[n.unchecked_get()];
0177 CELER_VALIDATE(
0178 !(dest == NodeRepl::known_true && repl == NodeRepl::known_false)
0179 && !(dest == NodeRepl::known_false && repl == NodeRepl::known_true),
0180 << "encountered logical contradiction in CSG operation");
0181 if (dest < repl)
0182 {
0183 dest = repl;
0184 return true;
0185 }
0186 return false;
0187 }
0188
0189
0190 }
0191 }
0192 }