Hi,
The following model evaluates satisfy and requirements.
package parts {
private import ScalarValues::;
private import SI::;
private import ISQ::*;
package ‘base parts’ {
part def CadRepresentedPart {
attribute mass :> ISQ::mass;
}
}
part def Chassis :> 'base parts'::CadRepresentedPart {
attribute wheelbase : LengthValue default 1 [cm];
}
part def MOA_Crawler {
part chassis : Chassis {
:>> mass default 0.1 [kg];
}
attribute vehicleMass : MassValue = chassis.mass;
}
}
package CrawlerAnalysis {
private import ISQ::;
private import SI::;
private import parts::*;
requirement def VehicleMassRequirement {
subject ;
in attribute actualMass : ISQ::MassValue;
in attribute requiredMass : ISQ::MassValue;
require constraint {
actualMass < requiredMass
}
}
requirement def VehicleMassRequirementWithSubject {
subject crawler : MOA_Crawler;
attribute requiredMass : ISQ::MassValue = 0.5 [kg];
require constraint {
VehicleMassAnalysis(crawler) < requiredMass
}
}
analysis def VehicleMassAnalysis {
subject crawler : MOA_Crawler;
return calculatedMass : ISQ::MassValue = crawler.vehicleMass;
}
part tinycrawler : MOA_Crawler {
part :>> chassis {
attribute :>> mass = 0.4 [kg];
}
}
part medcrawler : MOA_Crawler {
part :>> chassis {
attribute :>> mass = 2.5 [kg];
}
}
part analysisContext {
satisfy requirement reqTiny : VehicleMassRequirementWithSubject by tinycrawler;
satisfy requirement reqMed : VehicleMassRequirementWithSubject by medcrawler;
attribute checkTiny = VehicleMassRequirement(actualMass = VehicleMassAnalysis(tinycrawler), requiredMass = 0.5 [kg]);
attribute checkMed = VehicleMassRequirement(actualMass = VehicleMassAnalysis(medcrawler), requiredMass = 0.5 [kg]);
}
}
However, the following code that uses evaluate expressions does not produce outputs for the satisfy and the atttributes checkMed, checkTiny. How can it be made working?
`def find_expression_attribute_values(element, syside_mod, level: int = 0) → None:
“”"
One expression per AttributeUsage — no duplicate lines.
Prefer feature.feature_value_expression (Sensmetry / rollups). If missing, use the CTO
rule: first owned child if it is an Expression (matches jl_sysmlv2_api).
"""
indent = " " * level
compiler = syside_mod.Compiler()
lib = syside_mod.Environment.get_default().lib
if hasattr(element, "try_cast") and element.try_cast(syside_mod.AttributeUsage):
attr = element.cast(syside_mod.AttributeUsage)
owner_scope = getattr(attr, "owner", attr)
expr = getattr(attr, "feature_value_expression", None) or getattr(
attr, "featureValueExpression", None
)
if expr is None:
try:
expression_a1 = next(iter(attr.owned_elements), None)
except Exception:
expression_a1 = None
if expression_a1 is not None and isinstance(
expression_a1, syside_mod.Expression
):
expr = expression_a1
if expr is not None and isinstance(expr, syside_mod.Expression):
try:
value, report = compiler.evaluate(
expr,
scope=owner_scope,
stdlib=lib,
experimental_quantities=True,
)
except TypeError:
value, report = compiler.evaluate(expr)
if not getattr(report, "fatal", False):
name = (
getattr(attr, "qualified_name", None)
or getattr(attr, "declared_name", None)
or getattr(attr, "name", None)
or "<unnamed>"
)
print(f"{indent}{name}: {value}")
try:
element.owned_elements.for_each(
lambda owned_element: find_expression_attribute_values(
owned_element, syside_mod, level + 1
)
)
except Exception:
try:
for owned_element in element.owned_elements:
find_expression_attribute_values(owned_element, syside_mod, level + 1)
except Exception:
pass
def run(model, syside_mod) → None:
attr_iter = None
if hasattr(model, “elements”) and callable(model.elements):
try:
attr_iter = model.elements(syside_mod.AttributeUsage) # type: ignore[arg-type]
except TypeError:
attr_iter = model.elements()
elif hasattr(model, “nodes”) and callable(model.nodes):
try:
attr_iter = model.nodes(syside_mod.AttributeUsage) # type: ignore[arg-type]
except TypeError:
attr_iter = model.nodes()
if attr_iter is None:
print(“Model exposes neither elements() nor nodes()”, file=sys.stderr)
return
for el in attr_iter:
try:
if hasattr(el, "try_cast") and el.try_cast(syside_mod.AttributeUsage):
find_expression_attribute_values(el, syside_mod)
except Exception:
pass`