Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected sub_element_spec_iter() behavior #27

Closed
EdVanDance opened this issue Jan 15, 2025 · 2 comments
Closed

Unexpected sub_element_spec_iter() behavior #27

EdVanDance opened this issue Jan 15, 2025 · 2 comments

Comments

@EdVanDance
Copy link

Hi.

I was tinkering around with the new sub_elements_spec interface from DanielT/autosar-data-py#8 and noticed some unexpected results. It isn't related to the bindings though. I reproduced the issue with rust too.

So I'm trying to visit the ElementType for every ElementName (except adaptive) ... I noticed that at least one ElementName (maybe there is more) was never encountered. It's TARGET-REQUIRED-OPERATION-REF.

But it becomes even more strange ... If I remove the std_restriction condition (marked with THISONE) both types I'm checking for are not encountered.

Am I doing something wrong?

Example:

use autosar_data::*;
use autosar_data_specification::{ElementType, StdRestrict};

static PROVIDED: &str = "TARGET-PROVIDED-OPERATION-REF";
static REQUIRED: &str = "TARGET-REQUIRED-OPERATION-REF";

fn main() {
    let mut seen: Vec<&str> = Vec::new();
    let m = AutosarModel::new();

    let _ = m.create_file("dummy", AutosarVersion::Autosar_00048);

    let root = m.root_element();
    let root_name = root.element_name();
    let root_type = root.element_type();

    visit(&mut seen, &root_name, &root_type);

    println!("\n{}", seen.len());

    if seen.contains(&PROVIDED) {
        println!("  seen {}", PROVIDED);  // only seen with std_restriction
    }
    if seen.contains(&REQUIRED) {
        println!("  seen {}", REQUIRED);  // never seen
    }
}

fn visit(seen: &mut Vec<&str>, e: &ElementName, et: &ElementType) {
    let name = e.to_str();

    if seen.contains(&name) {
        return;
    }

    seen.push(name);

    for (n, t, _, _) in et.sub_element_spec_iter() {
        if t.std_restriction() != StdRestrict::AdaptivePlatform {  // THISONE
            visit(seen, &n, &t);
        }
    }
}
@DanielT
Copy link
Owner

DanielT commented Jan 15, 2025

Yes, I'm pretty sure you're doing something wrong.

If you take a look in the repo, you'll find the code in examples/generate_files/main.rs which tries to generate arxml files that contain at least one instance of each valid element - basically what you're trying to do, but with full files as output.

I just added a condition to this code to reject elements from the adaptive spec, and still got TARGET-PROVIDED-OPERATION-REF in the output.

One problem I know of is that element names can occur with different content (i.e. different ElementType) in different contexts.
This means that your simple filtering mechanism using only the names in the seen Vec is not good enough.
That's probably the whole problem, but I haven't actually tun your code.

My suggestion would be to take a look at the example code.
It uses a HashSet<(ElementName, ElementName)> to perform the same filtering, there the pair is (parent, child) - a child element is only considered to be "already seen" if it occurred within the parent. If it occurred in some other parent, then it still needs to be considered.

@EdVanDance
Copy link
Author

I wasn't aware that sub_element_spec_iter is context-sensitive.

But it makes total sense, generic collections like ELEMENTS and SUB-ELEMENTS are potentially all over the place.

Considering the parent as well fixed the problem I was facing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants