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

attempted multiple inheritance of attributes #2517

Open
sydb opened this issue Dec 27, 2023 · 5 comments
Open

attempted multiple inheritance of attributes #2517

sydb opened this issue Dec 27, 2023 · 5 comments

Comments

@sydb
Copy link
Member

sydb commented Dec 27, 2023

@martindholmes, @HelenaSabel, and I today ran into what we believe is an interesting and problematic underspecification of the ODD language.

Two (or more) attributes with the same name may be defined on two (or more) elements (i.e., inside two different <elementSpec>s that have different @ident attrs). Similarly, two (or more) attributes with the same name may be defined in two (or more) attribute classes (i.e., inside two different <classSpec type="atts">s that have different @ident attrs). This is not crazy, it is useful. It is done quite often in the TEI Guidelines themselves. (in 13 cases two attributes are defined separately with the same name; in 2 cases four attributes are defined separately with the same name.) For example, the @unit of att.citing has the same name as, but is defined somewhat diferently than the @unit of att.dimensions, att.measurement, or att.milestoneUnit.

But a) what happens (using the current Stylesheets), and b) what should happen (e.g., in ATOP) if either

  1. An element claims membership in more than one attribute class that defines the same attribute? —or—
  2. An attribute list refers to an attribute that has multiple definitions using only its name?

Further, if the answer to any of those 4 questions is “an error”, then shouldn’t the TEI Guidelines say it is not allowed, and maybe even enforce that with a schema?

In any case, I have (at @martindholmes’ and @HelenaSabel’s request) developed a little test ODD to ask questions a1 and a2. I will post the answers (and attach that little test ODD) to a post on this ticket, probably in a few hours. (Time for lunch, first. :-)

@sydb
Copy link
Member Author

sydb commented Dec 27, 2023

The entire ODD (and the RELAX NG and HTML derivatives thereof) are attached, below. But the important bit is also shown below right on this post.

The answer to question a1 (“What happens, using the current Stylesheets, when an element claims membership in more than one attribute class that defines the same attribute?”, which BTW, @martindholmes, @HelenaSabel, and I correctly predicted) is … an invalid RELAX NG schema is produced (due to duplicate attribute definions), and no warning or error message is produced (until you try to use the RELAX NG).

The answer to question a2 (“What happens, using the current Stylesheets, when an attribute list refers to an attribute that has multiple definitions using only its name?”) is … the attribute is summarily ignored (at least, does not show up in the RELAX NG), and no warning or error message is produced.

Here is the important bit of the ODD:

 <elementSpec ident="which_unit_do_I_have" ns="http://www.tei-c.org/ns/atop/test_suite">
   <desc>This useless element refers to the <att>unit</att> attribute
   without specifying which one</desc>
   <classes>
     <memberOf key="model.pLike"/>
     <memberOf key="att.global"/>
   </classes>
   <content>
     <empty/>
   </content>    
   <attList>
     <attRef name="unit"/>
   </attList>
 </elementSpec>
 <elementSpec ident="double_unit_via_membership_A" ns="http://www.tei-c.org/ns/atop/test_suite">
   <desc>This useless element tries to inherit the <att>unit</att>
   attribute twice, from both <name>att.milestoneUnit</name> and
   <name>att.citing</name></desc>
   <classes>
     <memberOf key="model.pLike"/>
     <memberOf key="att.global"/>
     <memberOf key="att.milestoneUnit"/>
     <memberOf key="att.citing"/>
   </classes>
   <content>
     <empty/>
   </content>
 </elementSpec>
 <elementSpec ident="double_unit_via_membership_B" ns="http://www.tei-c.org/ns/atop/test_suite">
   <desc>This useless element tries to inherit the <att>unit</att>
   attribute twice, from both <name>att.citing</name> and
   <name>att.milestoneUnit</name></desc>
   <classes>
     <memberOf key="model.pLike"/>
     <memberOf key="att.global"/>
     <memberOf key="att.citing"/>
     <memberOf key="att.milestoneUnit"/>
   </classes>
   <content>
     <empty/>
   </content>
 </elementSpec>

And here is the ODD and its derivatives:
issue_2517_mult_attr_inherit.zip

@ebeshero
Copy link
Member

You're spending the holiday deep in the weeds of the Durand conundrum I see. At least I think you identified a great example of how ODD generates pretty unhelpful Relax NG.

Reading the ODD, I wonder how often ODD writers run into a conflict without ever realizing it because they're experimenting with classes without realizing/noticing the same attribute is in that other class too?

Or if they are always using the current version of the TEI and Council lately added an attribute to a class (as we do now and again)-ODD writers run a risk of faulty validation that may be very tricky to debug.

Yes-I think we should raise an error-ideally on the ODD file and not just as we generate the schema output!

@joeytakeda
Copy link
Contributor

Re question 1b:

I think it would make sense to raise an error early on (either in the ODD itself, if that could be worked out ahead of time, or somewhere in the processing pipeline), but I'm currently unsure as to what the message would say / how the error would be resolved.

For instance, in this example:

<elementSpec ident="double_unit_via_membership_A" ns="http://www.tei-c.org/ns/atop/test_suite">
   <desc>This useless element tries to inherit the <att>unit</att>
   attribute twice, from both <name>att.milestoneUnit</name> and
   <name>att.citing</name></desc>
   <classes>
     <memberOf key="model.pLike"/>
     <memberOf key="att.global"/>
     <memberOf key="att.milestoneUnit"/>
     <memberOf key="att.citing"/>
   </classes>
   <content>
     <empty/>
   </content>
 </elementSpec>

Is there any way that I could specify that I wanted att.milestoneUnit's @unit and not att.citing's @unit? ATM, there's no @except on memberOf (and I don't really think there should be—that seems like it would become very complex very quickly), but I can't think of any way that one could refactor the element's definition so that I could pick which one I wanted.

Re question 2b:

An attribute list refers to an attribute that has multiple definitions using only its name?

IMO, I think @class should be mandatory in ATOP and at least recommended in the current ODD spec. (Though I would say that ideally, there would also be some way to specify that your attRef refers to an attribute defined on an element, too, but that's another ticket)

@martindholmes
Copy link
Contributor

@joey et al I actually think that if you find yourself trying to re-use an att from a different elementSpec, that's the definition of a need for an attribute class. When an att is defined on an element I think it inherits some semantics from the element; re-using it introduces some potential confusion. So I would say that you shouldn't be able to do that unless/until we have true class inheritance in ODD, which would change things a lot.

@ebeshero
Copy link
Member

ebeshero commented Dec 27, 2023

Thinking about current requests like this one #2516: I think we always have a lot of work to do with remodeling classes. It seems as if every time we want to apply an attribute like @unit or @scope in a new way, we find ourselves needing to reinvent the classes as we go, and getting a definition from a specific element is less helpful than trying to anticipate usage on a broader category of elements.

We have to do this a lot on Council as we think about documents differently, or realize that one kind of editing (e.g. for manuscripts) has intersecting interests with another (e.g. for linguistics). I think that's likely to be a persistent area where we do have to shift grounds in maintaining and updating the Guidelines. Would true class inheritance let us keep negotiating like we're doing and recognizing an application from one corner of the TEI can be used in another?

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

No branches or pull requests

5 participants