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