WIP: distance parameter for hierarchical processor.

This commit is contained in:
Matthias Koefferlein 2018-09-25 23:26:18 +02:00
parent 824888aaa6
commit defbf33d19
13 changed files with 272 additions and 38 deletions

View File

@ -289,8 +289,8 @@ struct InteractionRegistrationShape2Inst
: db::box_scanner_receiver2<db::PolygonRef, int, db::CellInstArray, int>
{
public:
InteractionRegistrationShape2Inst (db::Layout *layout, unsigned int intruder_layer, std::map<db::PolygonRef, std::vector<db::PolygonRef> > *result)
: mp_layout (layout), m_intruder_layer (intruder_layer), mp_result (result)
InteractionRegistrationShape2Inst (db::Layout *layout, unsigned int intruder_layer, db::Coord dist, std::map<db::PolygonRef, std::vector<db::PolygonRef> > *result)
: mp_layout (layout), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result)
{
// nothing yet ..
}
@ -300,11 +300,11 @@ public:
const db::Cell &intruder_cell = mp_layout->cell (inst->object ().cell_index ());
db::box_convert <db::CellInst, true> inst_bc (*mp_layout, m_intruder_layer);
for (db::CellInstArray::iterator n = inst->begin_touching (ref->box ().enlarged (db::Vector (-1, -1)), inst_bc); !n.at_end (); ++n) {
for (db::CellInstArray::iterator n = inst->begin_touching (ref->box ().enlarged (db::Vector (m_dist - 1, m_dist - 1)), inst_bc); !n.at_end (); ++n) {
db::ICplxTrans tn = inst->complex_trans (*n);
db::Box region = ref->box ().transformed (tn.inverted ()) & intruder_cell.bbox (m_intruder_layer);
db::Box region = ref->box ().transformed (tn.inverted ()).enlarged (db::Vector (m_dist, m_dist)) & intruder_cell.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist));
if (! region.empty ()) {
// @@@ TODO: should be lighter, cache, handle arrays ..
@ -312,7 +312,7 @@ public:
si.shape_flags (polygon_ref_flags ());
while (! si.at_end ()) {
// @@@ should be easier to transform references
// @@@ it should be easier to transform references
const db::PolygonRef *ref2 = si.shape ().basic_ptr (db::PolygonRef::tag ());
db::Polygon poly = ref2->obj ().transformed (tn * si.trans () * db::ICplxTrans (ref2->trans ()));
(*mp_result)[*ref].push_back (db::PolygonRef (poly, mp_layout->shape_repository()));
@ -329,11 +329,12 @@ public:
private:
db::Layout *mp_layout;
unsigned int m_intruder_layer;
db::Coord m_dist;
std::map<db::PolygonRef, std::vector<db::PolygonRef> > *mp_result;
};
static bool
instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, unsigned int layer1, const db::Layout *layout2, const db::CellInstArray *inst2, unsigned int layer2)
instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, unsigned int layer1, const db::Layout *layout2, const db::CellInstArray *inst2, unsigned int layer2, db::Coord dist)
{
// TODO: this algorithm is not in particular effective for identical arrays
@ -347,7 +348,7 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u
db::ICplxTrans tn1 = inst1->complex_trans (*n);
db::ICplxTrans tni1 = tn1.inverted ();
db::Box ibox1 = tn1 * cell1.bbox (layer1);
db::Box ibox1 = tn1 * cell1.bbox (layer1).enlarged (db::Vector (dist, dist));
if (! ibox1.empty ()) {
@ -361,7 +362,9 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u
}
db::ICplxTrans tn2 = inst2->complex_trans (*k);
db::Box ibox2 = tn2 * cell2.bbox (layer2);
// NOTE: we need to enlarge both subject *and* intruder boxes - either ubject comes close to intruder or the other way around
db::Box ibox2 = tn2 * cell2.bbox (layer2).enlarged (db::Vector (dist, dist));
db::ICplxTrans tn21 = tni1 * tn2;
if (! relative_trans_seen.insert (tn21).second) {
@ -396,8 +399,8 @@ struct InteractionRegistrationInst2Inst
: db::box_scanner_receiver2<db::CellInstArray, int, db::CellInstArray, int>
{
public:
InteractionRegistrationInst2Inst (const db::Layout *subject_layout, unsigned int subject_layer, const db::Layout *intruder_layout, unsigned int intruder_layer, std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *result)
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), mp_result (result)
InteractionRegistrationInst2Inst (const db::Layout *subject_layout, unsigned int subject_layer, const db::Layout *intruder_layout, unsigned int intruder_layer, db::Coord dist, std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *result)
: mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result)
{
// nothing yet ..
}
@ -408,7 +411,7 @@ public:
// NOTE: self-interactions are possible for arrays: different elements of the
// array may interact which is a cell-external interaction.
if ((*inst1 != *inst2 || inst1->size () > 1)
&& instances_interact (mp_subject_layout, inst1, m_subject_layer, mp_intruder_layout, inst2, m_intruder_layer)) {
&& instances_interact (mp_subject_layout, inst1, m_subject_layer, mp_intruder_layout, inst2, m_intruder_layer, m_dist)) {
(*mp_result) [inst1].first.insert (inst2);
}
}
@ -416,20 +419,21 @@ public:
private:
const db::Layout *mp_subject_layout, *mp_intruder_layout;
unsigned int m_subject_layer, m_intruder_layer;
db::Coord m_dist;
std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *mp_result;
};
static bool
instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const db::PolygonRef &ref)
instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const db::PolygonRef &ref, db::Coord dist)
{
const db::Cell &cell = layout->cell (inst->object ().cell_index ());
db::box_convert <db::CellInst, true> inst_bc (*layout, layer);
db::Box rbox = ref.box ();
for (db::CellInstArray::iterator n = inst->begin_touching (rbox.enlarged (db::Vector (-1, -1)), inst_bc); ! n.at_end (); ++n) {
for (db::CellInstArray::iterator n = inst->begin_touching (rbox.enlarged (db::Vector (dist - 1, dist - 1)), inst_bc); ! n.at_end (); ++n) {
db::ICplxTrans tn = inst->complex_trans (*n);
db::Box cbox = (tn * cell.bbox (layer)) & rbox;
db::Box cbox = (tn * cell.bbox (layer)).enlarged (db::Vector (dist, dist)) & rbox.enlarged (db::Vector (dist, dist));
if (! cbox.empty ()) {
@ -452,15 +456,15 @@ struct InteractionRegistrationInst2Shape
: db::box_scanner_receiver2<db::CellInstArray, int, db::PolygonRef, int>
{
public:
InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *result)
: mp_subject_layout (subject_layout), m_subject_layer (subject_layer), mp_result (result)
InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *result)
: mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result)
{
// nothing yet ..
}
void add (const db::CellInstArray *inst, int, const db::PolygonRef *ref, int)
{
if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref)) {
if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref, m_dist)) {
(*mp_result) [inst].second.insert (*ref);
}
}
@ -468,6 +472,7 @@ public:
private:
const db::Layout *mp_subject_layout;
unsigned int m_subject_layer;
db::Coord m_dist;
std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > > *mp_result;
};
@ -482,10 +487,10 @@ LocalProcessor::LocalProcessor (db::Layout *layout, db::Cell *top)
// .. nothing yet ..
}
void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer, db::Coord dist)
void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer)
{
LocalProcessorContexts contexts;
compute_contexts (contexts, op, subject_layer, intruder_layer, dist);
compute_contexts (contexts, op, subject_layer, intruder_layer);
compute_results (contexts, op, output_layer);
}
@ -496,7 +501,7 @@ void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, co
}
}
void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, db::Coord dist)
void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer)
{
tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Computing contexts for ")) + description ());
@ -506,10 +511,10 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const L
contexts.set_description (op->description ());
std::pair<std::set<db::CellInstArray>, std::set<db::PolygonRef> > intruders;
compute_contexts (contexts, 0, 0, mp_top, db::ICplxTrans (), dist, intruders);
compute_contexts (contexts, 0, 0, mp_top, db::ICplxTrans (), intruders, op->dist ());
}
void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, db::Coord dist, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders)
void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders, db::Coord dist)
{
if (tl::verbosity () >= 30) {
if (! parent) {
@ -549,7 +554,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc
{
db::box_scanner2<db::CellInstArray, int, db::CellInstArray, int> scanner;
InteractionRegistrationInst2Inst rec (mp_layout, contexts.subject_layer (), mp_layout, contexts.intruder_layer (), &interactions);
InteractionRegistrationInst2Inst rec (mp_layout, contexts.subject_layer (), mp_layout, contexts.intruder_layer (), dist, &interactions);
for (db::Cell::const_iterator i = cell->begin (); !i.at_end (); ++i) {
if (! inst_bcs (i->cell_inst ()).empty ()) {
@ -566,12 +571,12 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc
}
}
scanner.process (rec, 0, inst_bcs, inst_bci);
scanner.process (rec, dist, inst_bcs, inst_bci);
}
{
db::box_scanner2<db::CellInstArray, int, db::PolygonRef, int> scanner;
InteractionRegistrationInst2Shape rec (mp_layout, contexts.subject_layer (), &interactions);
InteractionRegistrationInst2Shape rec (mp_layout, contexts.subject_layer (), dist, &interactions);
for (db::Cell::const_iterator i = cell->begin (); !i.at_end (); ++i) {
if (! inst_bcs (i->cell_inst ()).empty ()) {
@ -586,7 +591,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc
scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), 0);
}
scanner.process (rec, 0, inst_bcs, db::box_convert<db::PolygonRef> ());
scanner.process (rec, dist, inst_bcs, db::box_convert<db::PolygonRef> ());
}
for (std::map<const db::CellInstArray *, std::pair<std::set<const db::CellInstArray *>, std::set<db::PolygonRef> > >::const_iterator i = interactions.begin (); i != interactions.end (); ++i) {
@ -597,7 +602,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc
db::ICplxTrans tn = i->first->complex_trans (*n);
db::ICplxTrans tni = tn.inverted ();
db::Box nbox = tn * child_cell.bbox (contexts.subject_layer ());
db::Box nbox = tn * child_cell.bbox (contexts.subject_layer ()).enlarged (db::Vector (dist, dist));
if (! nbox.empty ()) {
@ -619,7 +624,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc
}
}
compute_contexts (contexts, context, cell, &child_cell, tn, dist, intruders_below);
compute_contexts (contexts, context, cell, &child_cell, tn, intruders_below, dist);
}
@ -684,14 +689,14 @@ LocalProcessor::compute_local_cell (LocalProcessorContexts &contexts, db::Cell *
scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), 0);
}
scanner.process (rec, 0, db::box_convert<db::PolygonRef> (), db::box_convert<db::PolygonRef> ());
scanner.process (rec, op->dist (), db::box_convert<db::PolygonRef> (), db::box_convert<db::PolygonRef> ());
}
if (! shapes_subject.empty () && ! (cell->begin ().at_end () && intruders.first.empty ())) {
db::box_scanner2<db::PolygonRef, int, db::CellInstArray, int> scanner;
InteractionRegistrationShape2Inst rec (mp_layout, contexts.intruder_layer (), &interactions);
InteractionRegistrationShape2Inst rec (mp_layout, contexts.intruder_layer (), op->dist (), &interactions);
for (db::Shapes::shape_iterator i = shapes_subject.begin (polygon_ref_flags ()); !i.at_end (); ++i) {
scanner.insert1 (i->basic_ptr (db::PolygonRef::tag ()), 0);
@ -708,7 +713,7 @@ LocalProcessor::compute_local_cell (LocalProcessorContexts &contexts, db::Cell *
}
}
scanner.process (rec, 0, db::box_convert<db::PolygonRef> (), inst_bci);
scanner.process (rec, op->dist (), db::box_convert<db::PolygonRef> (), inst_bci);
}

View File

@ -52,6 +52,7 @@ public:
virtual void compute_local (db::Layout *layout, const std::map<db::PolygonRef, std::vector<db::PolygonRef> > &interactions, std::set<db::PolygonRef> &result) const = 0;
virtual on_empty_intruder_mode on_empty_intruder_hint () const = 0;
virtual std::string description () const = 0;
virtual db::Coord dist () const { return 0; }
};
class DB_PLUGIN_PUBLIC BoolAndOrNotLocalOperation
@ -212,8 +213,8 @@ class DB_PLUGIN_PUBLIC LocalProcessor
{
public:
LocalProcessor (db::Layout *layout, db::Cell *top);
void run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer, db::Coord dist = 0);
void compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, db::Coord dist = 0);
void run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer);
void compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer);
void compute_results (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int output_layer);
void set_description (const std::string &d)
@ -233,7 +234,7 @@ private:
db::Cell *mp_top;
std::string m_description;
void compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, db::Coord dist, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders);
void compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair<std::set<CellInstArray>, std::set<PolygonRef> > &intruders, db::Coord dist);
void push_results (db::Cell *cell, unsigned int output_layer, const std::set<db::PolygonRef> &result) const;
void compute_local_cell (LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, const std::pair<std::set<CellInstArray>, std::set<db::PolygonRef> > &intruders, std::set<db::PolygonRef> &result);
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -39,6 +39,41 @@ enum TestMode
TMNot = 1
};
/**
* @brief A new processor class which and/nots with a sized version of the intruder
*/
class BoolAndOrNotWithSizedLocalOperation
: public db::BoolAndOrNotLocalOperation
{
public:
BoolAndOrNotWithSizedLocalOperation (bool is_and, db::Coord dist)
: BoolAndOrNotLocalOperation (is_and), m_dist (dist)
{
// .. nothing yet ..
}
virtual void compute_local (db::Layout *layout, const std::map<db::PolygonRef, std::vector<db::PolygonRef> > &interactions, std::set<db::PolygonRef> &result) const
{
std::map<db::PolygonRef, std::vector<db::PolygonRef> > sized_interactions = interactions;
for (std::map<db::PolygonRef, std::vector<db::PolygonRef> >::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) {
for (std::vector<db::PolygonRef>::iterator j = i->second.begin (); j != i->second.end (); ++j) {
db::Polygon poly = j->obj ().transformed (j->trans ());
poly.size (m_dist, m_dist);
*j = db::PolygonRef (poly, layout->shape_repository ());
}
}
BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, result);
}
db::Coord dist () const
{
return m_dist;
}
private:
db::Coord m_dist;
};
/**
* @brief Turns a layer into polygons and polygon references
* The hierarchical processor needs polygon references and can't work on polygons directly.
@ -75,7 +110,7 @@ std::string contexts_to_s (db::Layout *layout, db::LocalProcessorContexts &conte
return res;
}
void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, db::Coord enl = 0, std::string *context_doc = 0)
void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc = 0)
{
db::Layout layout_org;
@ -120,7 +155,60 @@ void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int ou
proc.run (&op, l1, l2, lout);
} else {
db::LocalProcessorContexts contexts;
proc.compute_contexts (contexts, &op, l1, l2, enl);
proc.compute_contexts (contexts, &op, l1, l2);
*context_doc = contexts_to_s (&layout_org, contexts);
proc.compute_results (contexts, &op, lout);
}
db::compare_layouts (_this, layout_org, testdata (file), lmap, false /*skip other layers*/, db::AsPolygons);
}
void run_test_bool_with_size (tl::TestBase *_this, const char *file, TestMode mode, db::Coord dist, int out_layer_num, std::string *context_doc = 0)
{
db::Layout layout_org;
unsigned int l1 = 0, l2 = 0, lout = 0;
db::LayerMap lmap;
{
tl::InputStream stream (testdata (file));
db::Reader reader (stream);
db::LayerProperties p;
p.layer = 1;
p.datatype = 0;
lmap.map (db::LDPair (1, 0), l1 = layout_org.insert_layer ());
layout_org.set_properties (l1, p);
p.layer = 2;
p.datatype = 0;
lmap.map (db::LDPair (2, 0), l2 = layout_org.insert_layer ());
layout_org.set_properties (l2, p);
p.layer = out_layer_num;
p.datatype = 0;
lmap.map (db::LDPair (out_layer_num, 0), lout = layout_org.insert_layer ());
layout_org.set_properties (lout, p);
db::LoadLayoutOptions options;
options.get_options<db::CommonReaderOptions> ().layer_map = lmap;
options.get_options<db::CommonReaderOptions> ().create_other_layers = false;
reader.read (layout_org, options);
}
layout_org.clear_layer (lout);
normalize_layer (layout_org, l1);
normalize_layer (layout_org, l2);
BoolAndOrNotWithSizedLocalOperation op (mode == TMAnd, dist);
db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ()));
if (! context_doc) {
proc.run (&op, l1, l2, lout);
} else {
db::LocalProcessorContexts contexts;
proc.compute_contexts (contexts, &op, l1, l2);
*context_doc = contexts_to_s (&layout_org, contexts);
proc.compute_results (contexts, &op, lout);
}
@ -228,7 +316,7 @@ TEST(BasicAnd9)
{
// Top-level ring structure, AND
std::string doc;
run_test_bool (_this, "hlp9.oas", TMAnd, 100, 0, &doc);
run_test_bool (_this, "hlp9.oas", TMAnd, 100, &doc);
EXPECT_EQ (doc,
// This means: the interaction test is strong enough, so it does not see interactions between the
// ring and the cells embedded inside the ring. So there is only one cell context. Some shapes
@ -244,7 +332,7 @@ TEST(BasicNot9)
{
// Top-level ring structure, NOT
std::string doc;
run_test_bool (_this, "hlp9.oas", TMNot, 101, 0, &doc);
run_test_bool (_this, "hlp9.oas", TMNot, 101, &doc);
EXPECT_EQ (doc,
// This means: the interaction test is strong enough, so it does not see interactions between the
// ring and the cells embedded inside the ring. So there is only one cell context. Some shapes
@ -268,3 +356,143 @@ TEST(BasicNot10)
run_test_bool (_this, "hlp10.oas", TMNot, 101);
}
TEST(BasicAndWithSize1)
{
// Simple flat AND
run_test_bool_with_size (_this, "hlp1.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize1)
{
// Simple flat NOT
run_test_bool_with_size (_this, "hlp1.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize2)
{
// Up/down and down/up interactions, AND
run_test_bool_with_size (_this, "hlp2.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize2)
{
// Up/down and down/up interactions, NOT
run_test_bool_with_size (_this, "hlp2.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize3)
{
// Variant building, AND
run_test_bool_with_size (_this, "hlp3.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize3)
{
// Variant building, NOT
run_test_bool_with_size (_this, "hlp3.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize4)
{
// Sibling interactions, variant building, AND
run_test_bool_with_size (_this, "hlp4.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize4)
{
// Sibling interactions, variant building, NOT
run_test_bool_with_size (_this, "hlp4.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize5)
{
// Variant building with intermediate hierarchy, AND
run_test_bool_with_size (_this, "hlp5.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize5)
{
// Variant building with intermediate hierarchy, NOT
run_test_bool_with_size (_this, "hlp5.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize6)
{
// Extreme variants (copy, vanishing), AND
run_test_bool_with_size (_this, "hlp6.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize6)
{
// Extreme variants (copy, vanishing), NOT
run_test_bool_with_size (_this, "hlp6.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize7)
{
// Context replication - direct and indirect, AND
run_test_bool_with_size (_this, "hlp7.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize7)
{
// Context replication - direct and indirect, NOT
run_test_bool_with_size (_this, "hlp7.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize8)
{
// Mixed sibling-parent contexts, AND
run_test_bool_with_size (_this, "hlp8.oas", TMAnd, 1500, 102);
}
TEST(BasicNotWithSize8)
{
// Mixed sibling-parent contexts, NOT
run_test_bool_with_size (_this, "hlp8.oas", TMNot, 1500, 103);
}
TEST(BasicAndWithSize9)
{
// Top-level ring structure, AND
std::string doc;
run_test_bool_with_size (_this, "hlp9.oas", TMAnd, 1500, 102, &doc);
EXPECT_EQ (doc,
// This means: the interaction test is strong enough, so it does not see interactions between the
// ring and the cells embedded inside the ring. So there is only one cell context. Some shapes
// from atop the CHILD cell don't interact with shapes inside CHILD, so there are 4 shapes rather than
// 6. And the shapes from top inside the ring are not seen by the RING's subject shapes.
"TOP[1] 0 insts, 0 shapes (1 times)\n"
"RING[1] 0 insts, 0 shapes (1 times)\n"
"CHILD1[1] 0 insts, 6 shapes (2 times)\n"
);
}
TEST(BasicNotWithSize9)
{
// Top-level ring structure, NOT
std::string doc;
run_test_bool_with_size (_this, "hlp9.oas", TMNot, 1500, 103, &doc);
EXPECT_EQ (doc,
// This means: the interaction test is strong enough, so it does not see interactions between the
// ring and the cells embedded inside the ring. So there is only one cell context. Some shapes
// from atop the CHILD cell don't interact with shapes inside CHILD, so there are 4 shapes rather than
// 6. And the shapes from top inside the ring are not seen by the RING's subject shapes.
"TOP[1] 0 insts, 0 shapes (1 times)\n"
"RING[1] 0 insts, 0 shapes (1 times)\n"
"CHILD1[1] 0 insts, 6 shapes (2 times)\n"
);
}
TEST(BasicAndWithSize10)
{
// Array instances, AND
run_test_bool_with_size (_this, "hlp10.oas", TMAnd, 150, 102);
}
TEST(BasicNotWithSize10)
{
// Array instances, NOT
run_test_bool_with_size (_this, "hlp10.oas", TMNot, 150, 103);
}