mirror of https://github.com/KLayout/klayout.git
WIP: some bug fixes, tests for deep mode - some refinement needed.
This commit is contained in:
parent
6c9d16c221
commit
fe1d520d0c
|
|
@ -57,9 +57,10 @@ DeepShapeCollectionDelegateBase::apply_property_translator (const db::Properties
|
||||||
db::Shapes &shapes = c->shapes (m_deep_layer.layer ());
|
db::Shapes &shapes = c->shapes (m_deep_layer.layer ());
|
||||||
|
|
||||||
db::Shapes new_shapes (shapes.is_editable ());
|
db::Shapes new_shapes (shapes.is_editable ());
|
||||||
new_shapes.assign (shapes, pt);
|
|
||||||
shapes.swap (new_shapes);
|
shapes.swap (new_shapes);
|
||||||
|
|
||||||
|
shapes.assign (new_shapes, pt);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,32 @@ static db::Region complex_region (const db::RecursiveShapeIterator *iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void enable_properties (db::RecursiveShapeIterator *c)
|
||||||
|
{
|
||||||
|
c->apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_properties (db::RecursiveShapeIterator *c)
|
||||||
|
{
|
||||||
|
c->apply_property_translator (db::PropertiesTranslator::make_remove_all ());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void filter_properties (db::RecursiveShapeIterator *c, const std::vector<tl::Variant> &keys)
|
||||||
|
{
|
||||||
|
if (c->layout ()) {
|
||||||
|
std::set<tl::Variant> kf;
|
||||||
|
kf.insert (keys.begin (), keys.end ());
|
||||||
|
c->apply_property_translator (db::PropertiesTranslator::make_filter (const_cast<db::Layout *> (c->layout ())->properties_repository (), kf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void map_properties (db::RecursiveShapeIterator *c, const std::map<tl::Variant, tl::Variant> &map)
|
||||||
|
{
|
||||||
|
if (c->layout ()) {
|
||||||
|
c->apply_property_translator (db::PropertiesTranslator::make_key_mapper (const_cast<db::Layout *> (c->layout ())->properties_repository (), map));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("db", "RecursiveShapeIterator",
|
Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("db", "RecursiveShapeIterator",
|
||||||
gsi::constructor ("new", &new_si1, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("layer"),
|
gsi::constructor ("new", &new_si1, gsi::arg ("layout"), gsi::arg ("cell"), gsi::arg ("layer"),
|
||||||
"@brief Creates a recursive, single-layer shape iterator.\n"
|
"@brief Creates a recursive, single-layer shape iterator.\n"
|
||||||
|
|
@ -547,6 +573,20 @@ Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("db", "RecursiveS
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.25.3."
|
"This method has been introduced in version 0.25.3."
|
||||||
) +
|
) +
|
||||||
|
gsi::method ("prop_id", &db::RecursiveShapeIterator::prop_id,
|
||||||
|
"@brief Gets the effective properties ID\n"
|
||||||
|
"The shape iterator supports property filtering and translation. This method will deliver "
|
||||||
|
"the effective property ID after translation. The original property ID can be obtained from "
|
||||||
|
"'shape.prop_id' and is not changed by installing filters or mappers.\n"
|
||||||
|
"\n"
|
||||||
|
"\\prop_id is evaluated by \\Region objects for example, when they are created "
|
||||||
|
"from a shape iterator.\n"
|
||||||
|
"\n"
|
||||||
|
"See \\enable_properties, \\filter_properties, \\remove_properties and \\map_properties for "
|
||||||
|
"details on this feature.\n"
|
||||||
|
"\n"
|
||||||
|
"This attribute has been introduced in version 0.28.4."
|
||||||
|
) +
|
||||||
gsi::method ("shape", &db::RecursiveShapeIterator::shape,
|
gsi::method ("shape", &db::RecursiveShapeIterator::shape,
|
||||||
"@brief Gets the current shape\n"
|
"@brief Gets the current shape\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
@ -592,6 +632,51 @@ Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("db", "RecursiveS
|
||||||
"@brief Comparison of iterators - inequality\n"
|
"@brief Comparison of iterators - inequality\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Two iterators are not equal if they do not point to the same shape.\n"
|
"Two iterators are not equal if they do not point to the same shape.\n"
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("enable_properties", &enable_properties,
|
||||||
|
"@brief Enables properties for the given iterator.\n"
|
||||||
|
"Afer enabling properties, \\prop_id will deliver the effective properties ID for the current shape. "
|
||||||
|
"By default, properties are not enabled and \\prop_id will always return 0 (no properties attached). "
|
||||||
|
"Alternatively you can apply \\filter_properties "
|
||||||
|
"or \\map_properties to enable properties with a specific name key.\n"
|
||||||
|
"\n"
|
||||||
|
"Note that property filters/mappers are additive and act in addition (after) the currently installed filter.\n"
|
||||||
|
"\n"
|
||||||
|
"This feature has been introduced in version 0.28.4."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("remove_properties", &remove_properties,
|
||||||
|
"@brief Removes properties for the given container.\n"
|
||||||
|
"This will remove all properties and \\prop_id will deliver 0 always (no properties attached).\n"
|
||||||
|
"Alternatively you can apply \\filter_properties "
|
||||||
|
"or \\map_properties to enable properties with a specific name key.\n"
|
||||||
|
"\n"
|
||||||
|
"Note that property filters/mappers are additive and act in addition (after) the currently installed filter.\n"
|
||||||
|
"So effectively after 'remove_properties' you cannot get them back.\n"
|
||||||
|
"\n"
|
||||||
|
"This feature has been introduced in version 0.28.4."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("filter_properties", &filter_properties, gsi::arg ("keys"),
|
||||||
|
"@brief Filters properties by certain keys.\n"
|
||||||
|
"Calling this method will reduce the properties to values with name keys from the 'keys' list.\n"
|
||||||
|
"As a side effect, this method enables properties.\n"
|
||||||
|
"As with \\enable_properties or \\remove_properties, this filter has an effect on the value returned "
|
||||||
|
"by \\prop_id, not on the properties ID attached to the shape directly.\n"
|
||||||
|
"\n"
|
||||||
|
"Note that property filters/mappers are additive and act in addition (after) the currently installed filter.\n"
|
||||||
|
"\n"
|
||||||
|
"This feature has been introduced in version 0.28.4."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("map_properties", &map_properties, gsi::arg ("key_map"),
|
||||||
|
"@brief Maps properties by name key.\n"
|
||||||
|
"Calling this method will reduce the properties to values with name keys from the 'keys' hash and "
|
||||||
|
"renames the properties. Property values with keys not listed in the key map will be removed.\n"
|
||||||
|
"As a side effect, this method enables properties.\n"
|
||||||
|
"As with \\enable_properties or \\remove_properties, this filter has an effect on the value returned "
|
||||||
|
"by \\prop_id, not on the properties ID attached to the shape directly.\n"
|
||||||
|
"\n"
|
||||||
|
"Note that property filters/mappers are additive and act in addition (after) the currently installed filter.\n"
|
||||||
|
"\n"
|
||||||
|
"This feature has been introduced in version 0.28.4."
|
||||||
),
|
),
|
||||||
"@brief An iterator delivering shapes recursively\n"
|
"@brief An iterator delivering shapes recursively\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,30 @@ module DRC
|
||||||
DRCNegative::new
|
DRCNegative::new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enable_props
|
||||||
|
DRCPropertySelector::new(:enable_properties)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_props
|
||||||
|
DRCPropertySelector::new(:remove_properties)
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_props(*keys)
|
||||||
|
self._context("select_props") do
|
||||||
|
keys.each do |k|
|
||||||
|
k.is_a?(String) || k.is_a?(1.class) || raise("Key values need to be integers or strings (got '#{k.inspect}')")
|
||||||
|
end
|
||||||
|
DRCPropertySelector::new(:filter_properties, keys)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def map_props(hash)
|
||||||
|
self._context("map_props") do
|
||||||
|
hash.is_a?(Hash) || raise("Argument needs to be a hash (got '#{hash.inspect}')")
|
||||||
|
DRCPropertySelector::new(:map_properties, hash)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def pattern(p)
|
def pattern(p)
|
||||||
self._context("pattern") do
|
self._context("pattern") do
|
||||||
DRCPattern::new(true, p)
|
DRCPattern::new(true, p)
|
||||||
|
|
@ -2806,7 +2830,7 @@ CODE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def _input(layout, cell_index, layers, sel, box, clip, overlapping, shape_flags, global_trans, cls)
|
def _input(layout, cell_index, layers, sel, box, clip, overlapping, shape_flags, global_trans, prop_sel, cls)
|
||||||
|
|
||||||
if layers.empty? && ! @deep
|
if layers.empty? && ! @deep
|
||||||
|
|
||||||
|
|
@ -2819,6 +2843,7 @@ CODE
|
||||||
else
|
else
|
||||||
iter = RBA::RecursiveShapeIterator::new(layout, layout.cell(cell_index), layers)
|
iter = RBA::RecursiveShapeIterator::new(layout, layout.cell(cell_index), layers)
|
||||||
end
|
end
|
||||||
|
prop_sel.each { |p| p.apply_to(iter) }
|
||||||
iter.shape_flags = shape_flags
|
iter.shape_flags = shape_flags
|
||||||
iter.global_dtrans = global_trans
|
iter.global_dtrans = global_trans
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4783,37 +4783,35 @@ CODE
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name select_props
|
# @name select_props
|
||||||
# @brief Enables or selects properties from original or property-annotated layers
|
# @brief Enables or selects properties from a property-annotated layer
|
||||||
# @synopsis layer.select_props
|
|
||||||
# @synopsis layer.select_props(keys)
|
# @synopsis layer.select_props(keys)
|
||||||
#
|
#
|
||||||
# This method will enable user properties or select specific property keys
|
# This method will select specific property keys
|
||||||
# from layers. It returns a new layer with properties enabled. The
|
# from layers. It returns a new layer with the new properties. The
|
||||||
# original layer is not modified.
|
# original layer is not modified.
|
||||||
#
|
#
|
||||||
# When used on original layers, this method will enable properties on input.
|
|
||||||
# By default, properties are not read:
|
|
||||||
#
|
|
||||||
# @code
|
|
||||||
# layer1 = input(1, 0)
|
|
||||||
# layer1_with_props = input(1, 0).select_props
|
|
||||||
# @/code
|
|
||||||
#
|
|
||||||
# You can specify the user property keys (names) to use. As user properties
|
# You can specify the user property keys (names) to use. As user properties
|
||||||
# in general are a set of key/value pairs and may carry multiple information
|
# in general are a set of key/value pairs and may carry multiple values
|
||||||
# under different keys, this feature can be handy to filter out a specific
|
# under different keys, this feature can be handy to filter out a specific
|
||||||
# aspect. To get only the values from key 1 (integer), use:
|
# aspect. To get only the values from key 1 (integer), use:
|
||||||
#
|
#
|
||||||
# @code
|
# @code
|
||||||
# layer1_with_props = input(1, 0).select_props(1)
|
# layer1 = input(1, 0, enable_properties)
|
||||||
|
# layer1_filtered = layer1.select_props(1)
|
||||||
# @/code
|
# @/code
|
||||||
#
|
#
|
||||||
# To get the combined key 1 and 2 properties, use:
|
# To get the combined key 1 and 2 properties, use:
|
||||||
#
|
#
|
||||||
# @code
|
# @code
|
||||||
# layer1_with_props = input(1, 0).select_props(1, 2)
|
# layer1 = input(1, 0, enable_properties)
|
||||||
|
# layer1_filtered = layer1.select_props(1, 2)
|
||||||
# @/code
|
# @/code
|
||||||
#
|
#
|
||||||
|
# Without any arguments, this method will remove all properties.
|
||||||
|
# Note that you can directly filter or map properties on input
|
||||||
|
# which is more efficient than first loading all and then selecting some
|
||||||
|
# properties. See \DRCSource#input for details.
|
||||||
|
#
|
||||||
# \map_props is a way to change property keys and \remove_props
|
# \map_props is a way to change property keys and \remove_props
|
||||||
# will entirely remove all user properties.
|
# will entirely remove all user properties.
|
||||||
|
|
||||||
|
|
@ -4822,7 +4820,7 @@ CODE
|
||||||
# @brief Selects properties with certain keys and allows key mapping
|
# @brief Selects properties with certain keys and allows key mapping
|
||||||
# @synopsis layer.map_props({ key => key_new, .. })
|
# @synopsis layer.map_props({ key => key_new, .. })
|
||||||
#
|
#
|
||||||
# Similar to \select_props, this method will enable user properties
|
# Similar to \select_props, this method will map or filter properties and
|
||||||
# and take the values from certain keys. In addition, this method allows
|
# and take the values from certain keys. In addition, this method allows
|
||||||
# mapping keys to new keys. Specify a hash argument with old to new keys.
|
# mapping keys to new keys. Specify a hash argument with old to new keys.
|
||||||
#
|
#
|
||||||
|
|
@ -4835,7 +4833,8 @@ CODE
|
||||||
# use:
|
# use:
|
||||||
#
|
#
|
||||||
# @code
|
# @code
|
||||||
# layer1_with_props = input(1, 0).map_props({ 2 => 1 })
|
# layer1 = input(1, 0, enable_properties)
|
||||||
|
# layer1_mapped = layer1.map_props({ 2 => 1 })
|
||||||
# @/code
|
# @/code
|
||||||
#
|
#
|
||||||
# See also \select_props and \remove_props.
|
# See also \select_props and \remove_props.
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,7 @@ CODE
|
||||||
# @synopsis source.input(layer, datatype)
|
# @synopsis source.input(layer, datatype)
|
||||||
# @synopsis source.input(layer_into)
|
# @synopsis source.input(layer_into)
|
||||||
# @synopsis source.input(filter, ...)
|
# @synopsis source.input(filter, ...)
|
||||||
|
# @synopsis source.input(props_spec, ...)
|
||||||
# Creates a layer with the shapes from the given layer of the source.
|
# Creates a layer with the shapes from the given layer of the source.
|
||||||
# The layer can be specified by layer and optionally datatype, by a RBA::LayerInfo
|
# The layer can be specified by layer and optionally datatype, by a RBA::LayerInfo
|
||||||
# object or by a sequence of filters.
|
# object or by a sequence of filters.
|
||||||
|
|
@ -410,12 +411,27 @@ CODE
|
||||||
#
|
#
|
||||||
# "input" without any arguments will create a new, empty original layer.
|
# "input" without any arguments will create a new, empty original layer.
|
||||||
#
|
#
|
||||||
|
# If you want to use user properties - for example with properties constraints in DRC checks -
|
||||||
|
# you need to enable properties on input:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# input1_with_props = input(1, 0, enable_props)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# You can also filter or map property keys, similar to the functions available on
|
||||||
|
# layers (\DRCLayer#map_props, \DRCLayer#select_props). For example to select
|
||||||
|
# property values with key 17 (numerical) only, use:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# input1_with_props = input(1, 0, select_props(17))
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
# Use the global version of "input" without a source object to address the default source.
|
# Use the global version of "input" without a source object to address the default source.
|
||||||
|
|
||||||
def input(*args)
|
def input(*args)
|
||||||
@engine._context("input") do
|
@engine._context("input") do
|
||||||
layers = parse_input_layers(*args)
|
layers, prop_selectors = parse_input_layers(*args)
|
||||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SAll, @global_trans, RBA::Region))
|
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SAll, @global_trans, prop_selectors, RBA::Region))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -441,8 +457,8 @@ CODE
|
||||||
|
|
||||||
def labels(*args)
|
def labels(*args)
|
||||||
@engine._context("labels") do
|
@engine._context("labels") do
|
||||||
layers = parse_input_layers(*args)
|
layers, prop_selectors = parse_input_layers(*args)
|
||||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::STexts, @global_trans, RBA::Texts))
|
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::STexts, @global_trans, prop_selectors, RBA::Texts))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -467,8 +483,8 @@ CODE
|
||||||
|
|
||||||
def polygons(*args)
|
def polygons(*args)
|
||||||
@engine._context("polygons") do
|
@engine._context("polygons") do
|
||||||
layers = parse_input_layers(*args)
|
layers, prop_selectors = parse_input_layers(*args)
|
||||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SBoxes | RBA::Shapes::SPaths | RBA::Shapes::SPolygons | RBA::Shapes::SEdgePairs, @global_trans, RBA::Region))
|
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SBoxes | RBA::Shapes::SPaths | RBA::Shapes::SPolygons | RBA::Shapes::SEdgePairs, @global_trans, prop_selectors, RBA::Region))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -496,8 +512,8 @@ CODE
|
||||||
|
|
||||||
def edges(*args)
|
def edges(*args)
|
||||||
@engine._context("edges") do
|
@engine._context("edges") do
|
||||||
layers = parse_input_layers(*args)
|
layers, prop_selectors = parse_input_layers(*args)
|
||||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SBoxes | RBA::Shapes::SPaths | RBA::Shapes::SPolygons | RBA::Shapes::SEdgePairs | RBA::Shapes::SEdges, @global_trans, RBA::Edges))
|
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SBoxes | RBA::Shapes::SPaths | RBA::Shapes::SPolygons | RBA::Shapes::SEdgePairs | RBA::Shapes::SEdges, @global_trans, prop_selectors, RBA::Edges))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -525,8 +541,8 @@ CODE
|
||||||
|
|
||||||
def edge_pairs(*args)
|
def edge_pairs(*args)
|
||||||
@engine._context("edge_pairs") do
|
@engine._context("edge_pairs") do
|
||||||
layers = parse_input_layers(*args)
|
layers, prop_selectors = parse_input_layers(*args)
|
||||||
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SEdgePairs, @global_trans, RBA::EdgePairs))
|
DRCLayer::new(@engine, @engine._cmd(@engine, :_input, @layout_var, @cell.cell_index, layers, @sel, @box, @clip, @overlapping, RBA::Shapes::SEdgePairs, @global_trans, prop_selectors, RBA::EdgePairs))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -581,6 +597,9 @@ CODE
|
||||||
def parse_input_layers(*args)
|
def parse_input_layers(*args)
|
||||||
|
|
||||||
layers = []
|
layers = []
|
||||||
|
prop_selectors = args.select { |a| a.is_a?(DRCPropertySelector) }
|
||||||
|
|
||||||
|
args = args.select { |a| !a.is_a?(DRCPropertySelector) }
|
||||||
|
|
||||||
if args.size == 0
|
if args.size == 0
|
||||||
|
|
||||||
|
|
@ -615,7 +634,7 @@ CODE
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
layers
|
[ layers, prop_selectors ]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,19 @@ module DRC
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Property selector for "input"
|
||||||
|
class DRCPropertySelector
|
||||||
|
attr_accessor :method
|
||||||
|
attr_accessor :args
|
||||||
|
def apply_to(iter)
|
||||||
|
iter.send(self.method, *self.args)
|
||||||
|
end
|
||||||
|
def initialize(method, *args)
|
||||||
|
self.method = method
|
||||||
|
self.args = args
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# A wrapper for a pair of limit values
|
# A wrapper for a pair of limit values
|
||||||
# This class is used to identify projection limits for DRC
|
# This class is used to identify projection limits for DRC
|
||||||
# functions
|
# functions
|
||||||
|
|
|
||||||
|
|
@ -1401,3 +1401,8 @@ TEST(70_props)
|
||||||
{
|
{
|
||||||
run_test (_this, "70", false);
|
run_test (_this, "70", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(70d_props)
|
||||||
|
{
|
||||||
|
run_test (_this, "70", true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,37 @@ if $drc_test_deep
|
||||||
deep
|
deep
|
||||||
end
|
end
|
||||||
|
|
||||||
l1 = input(1, 0)
|
# properties on input
|
||||||
l2 = input(2, 0)
|
l1 = input(1, 0)
|
||||||
l3 = input(3, 0)
|
l2 = input(2, 0)
|
||||||
l4 = input(4, 0)
|
l3_wp = input(3, 0, enable_props)
|
||||||
|
l3_wp1_input = input(3, 0, select_props(1))
|
||||||
|
l3_wp2as1_input = input(3, 0, map_props({ 2 => 1 }))
|
||||||
|
l3 = input(3, 0)
|
||||||
|
l4_wp = input(4, 0, enable_props)
|
||||||
|
l4 = input(4, 0)
|
||||||
|
|
||||||
|
# derived properties
|
||||||
|
l3_wp1 = l3_wp.select_props(1)
|
||||||
|
l3_wp2as1 = l3_wp.map_props({ 2 => 1 })
|
||||||
|
l3_nowp = l3_wp.remove_props
|
||||||
|
|
||||||
|
# dump to output
|
||||||
|
|
||||||
l1.output(1, 0)
|
l1.output(1, 0)
|
||||||
l2.output(2, 0)
|
l2.output(2, 0)
|
||||||
l3.output(3, 0)
|
l3.output(3, 0)
|
||||||
l4.output(4, 0)
|
l4.output(4, 0)
|
||||||
|
|
||||||
l3_wp = l3.select_props
|
|
||||||
l3_wp1 = l3.select_props(1)
|
|
||||||
l3_wp2as1 = l3.map_props({ 2 => 1 })
|
|
||||||
l3_nowp = l3_wp.remove_props
|
|
||||||
|
|
||||||
l4_wp = l4.select_props
|
|
||||||
|
|
||||||
l3_wp.output(10, 0)
|
l3_wp.output(10, 0)
|
||||||
l3_wp1.output(11, 0)
|
l3_wp1.output(11, 0)
|
||||||
l3_wp2as1.output(12, 0)
|
l3_wp2as1.output(12, 0)
|
||||||
l3_nowp.output(13, 0)
|
l3_nowp.output(13, 0)
|
||||||
l4_wp.output(14, 0)
|
l3_wp1_input.output(14, 0)
|
||||||
|
l3_wp2as1_input.output(15, 0)
|
||||||
|
l4_wp.output(16, 0)
|
||||||
|
|
||||||
|
# booleans with properties constraints
|
||||||
|
|
||||||
l3_wp.and(l4_wp, props_eq).output(20, 0)
|
l3_wp.and(l4_wp, props_eq).output(20, 0)
|
||||||
l3_wp1.and(l4_wp, props_eq).output(21, 0)
|
l3_wp1.and(l4_wp, props_eq).output(21, 0)
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue