forked from celeritas-project/celeritas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NodeReplacementInserter.hh
149 lines (133 loc) · 4.28 KB
/
NodeReplacementInserter.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//----------------------------------*-C++-*----------------------------------//
// Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file orange/orangeinp/detail/NodeReplacementInserter.hh
//---------------------------------------------------------------------------//
#pragma once
#include <variant>
#include <vector>
#include "../CsgTree.hh"
#include "../CsgTypes.hh"
namespace celeritas
{
namespace orangeinp
{
namespace detail
{
//---------------------------------------------------------------------------//
/*!
* Add a node ID and its "replaced" value.
*
* This implementation detail of the "replace down" algorithm adds daughters
* to a queue of nodes to visit, along with their replacement values.
*/
class NodeReplacementInserter
{
public:
//!@{
//! \name Type aliases
using VecNode = std::vector<std::pair<NodeId, Node>>;
//!@}
public:
// Construct with pointers to the stack and replacement
inline NodeReplacementInserter(VecNode* stack, Node const& repl);
// Simplify node types that reference other nodes
inline void operator()(Aliased const& n);
inline void operator()(Negated const& n);
inline void operator()(Joined const& n);
// Check that replacement matches our stored boolean
inline void operator()(True const&);
inline void operator()(False const&);
// Surfaces cannot be simplified further
void operator()(Surface const&) {}
private:
VecNode* stack_;
Node const& repl_;
Node negated_;
OperatorToken join_token_;
};
//---------------------------------------------------------------------------//
// INLINE DEFINITIONS
//---------------------------------------------------------------------------//
/*!
* Construct with pointer to the stack and the replacement value.
*
* For now the replacement must be a boolean.
*/
NodeReplacementInserter::NodeReplacementInserter(VecNode* stack,
Node const& repl)
: stack_{stack}, repl_{repl}
{
CELER_EXPECT(stack_);
CELER_EXPECT(is_boolean_node(repl_));
// Save "negated" node and "join" implication for daughters
if (std::holds_alternative<True>(repl_))
{
negated_ = Node{False{}};
join_token_ = op_and; // all{...} = true
}
else
{
negated_ = Node{True{}};
join_token_ = op_or; // any{...} = false
}
}
//---------------------------------------------------------------------------//
/*!
* Check that the replacement node matches this queued node.
*/
void NodeReplacementInserter::operator()(True const&)
{
CELER_ASSERT(std::holds_alternative<True>(repl_));
}
//---------------------------------------------------------------------------//
/*!
* Check that the replacement node matches this queued node.
*/
void NodeReplacementInserter::operator()(False const&)
{
CELER_ASSERT(std::holds_alternative<False>(repl_));
}
//---------------------------------------------------------------------------//
/*!
* Push the target of an aliased node onto the stack.
*
* Aliasing a node implies the alias has the same value.
*/
void NodeReplacementInserter::operator()(Aliased const& n)
{
stack_->emplace_back(n.node, repl_);
}
//---------------------------------------------------------------------------//
/*!
* Push a negated node onto the stack.
*
* Negating a node implies its daughter has the opposite value.
*/
void NodeReplacementInserter::operator()(Negated const& n)
{
stack_->emplace_back(n.node, negated_);
}
//---------------------------------------------------------------------------//
/*!
* Some 'join' operations imply requirements for the daughters.
*
* If this node is "true" and it uses an "and" operation, all daughters must be
* true. Likewise, "false" with "or" implies all daughters are false.
*/
void NodeReplacementInserter::operator()(Joined const& n)
{
if (n.op == join_token_)
{
for (NodeId d : n.nodes)
{
stack_->emplace_back(d, repl_);
}
}
}
//---------------------------------------------------------------------------//
} // namespace detail
} // namespace orangeinp
} // namespace celeritas