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

Some specific intent examples #456

Closed
davidfarmer opened this issue Apr 1, 2023 · 61 comments
Closed

Some specific intent examples #456

davidfarmer opened this issue Apr 1, 2023 · 61 comments
Labels
intent Issues involving the proposed "intent" attr

Comments

@davidfarmer
Copy link
Contributor

This issue is to determine if we agree on some common examples of intent markup.
I encourage others to describe specific examples.

Example 1: multiline expressions with a big curly brace on the left.
This could be a system of equations, or it could be a "cases".
For example:
https://mathml-refresh.github.io/intent-lists/intent5.html#IDbracedsystemofequations

In that example, the intent is on the mo containing the left brace. I think it should
either be on the outer mrow, or it should be on the mtable. (I think mrow, but I can
implement whatever is better for AT.)
I also think it should be a property, meaning intent=":system-of-equations",
because otherwise AT has to know to treat it specially and not just say
system of equations instead of reading out the contents.

Example 2: open interval, as in
https://mathml-refresh.github.io/intent-lists/intent5.html#IDopen-openinvertedbracket

I think that example is good as-is. It is reasonable to expect that AT knows that open-interval
is in core and that the words "from" and "to" should be added (depending on the verbosity level).
If the notation had parentheses instead of reversed square brackets, the intent would be the same.
We should discourage any other way of marking that intent.

Example 3: superscripts which are not powers, as in the H^2 example here:
https://mathml-refresh.github.io/intent-lists/intent5.html#ID2ndCohomology
I do not think either of those examples are good, because (as we discussed on a call)
it is confusing for AT to say "H 2", because that hides the fact that the "2" is in
a superscript (and not a subscript).

I suggest that this is reasonable:
<msup><mi>H</mi><mi intent="superscript">2</mi></msup>
or (which I prefer)
<msup><mi>H</mi><mi intent="index">2</mi></msup>
Since AT has to examine the contents of the msup, to know whether to say "squared",
this markup conveys the information that the expression is not a power.

This example only works if AT knows the meaning of that intent, and that
the intent value is not supposed to be pronounced literally.
Should "superscript" or "index" be a property instead?

@dginev dginev added the intent Issues involving the proposed "intent" attr label Apr 2, 2023
@davidfarmer
Copy link
Contributor Author

davidfarmer commented Apr 2, 2023

These two examples are fairly simple, but I include them just
to confirm that we agree.

My interest is knowing that this markup is acceptable,
so it is okay for me to produce this markup. In both of
these cases, I think that what I write is the preferred way to
indicate that intent, and I suggest that the documentation
should indicate that preference.

Example 4. The expression "8 x 8" as in "chess is played
on an 8 by 8 grid". Note that I am intentionally using the
wrong symbol for the "by" character, because the specific
character is ignored by AT.

<mn>8</mn><mo intent="by">x</mo><mn>8</mn>

This is similar to some of the markup on lines 5-8 of the example list
https://mathml-refresh.github.io/intent-lists/intent1.html
except that I have not wrapped it in an mrow.

Some of those similar-looking examples also have a prefix
pronunciation, like "product of a and b", but this "by"
example only works (in english) with an infix reading.

Example 5: Absolute value. Exactly as here:
https://mathml-refresh.github.io/intent-lists/intent1.html#id10

It seems that there is no other good way to markup that intent?

@dginev
Copy link
Contributor

dginev commented Apr 2, 2023

Re: "by" value

To me "by" reads like a literal, since it is an English preposition rather than a concept. So I would write that _by. Similarly, I would use _по in Bulgarian, which is the matching preposition for this case, as in:

<mn>8</mn><mo intent="_по">x</mo><mn>8</mn>

The matrix wiki article claims that "2 by 3 matrix" and "matrix of dimension 2 by 3" are synonymous, so I would loosely guess the concept at play here is "dimension". From there I could imagine a Core value "dimension" used as:

<mrow intent="dimension($rows,$columns)">
  <mn arg="rows">8</mn>
  <mo>x</mo>
  <mn arg="columns">8</mn>
</mrow>

and vocalized by AT as "by" in English and "по" in Bulgarian. In case such a value didn't make it to Core, annotators would have to resort to the _by and similar literals.

@davidcarlisle
Copy link
Collaborator

<mn>8</mn><mo intent="by">x</mo><mn>8</mn>

looks OK to me. If you wanted to use a more mathematical name such as dimensional-product or some such it would have to be in core so it had a rule to get read as "by" and I'm not sure what standard name we'd pick so by seems fine.

but this "by" example only works (in english) with an infix reading.

yes so using it on the mo works, or if it is non-core and you want to place it on the mrow by:infix(8,8) is same.

It seems that there is no other good way to markup that intent [ absolute-value($x)]?

Probably not. If you had some horrible mathml with a long flat mrow and no specific container for |x| and you don't want to add an mrow just for the abolute value you could do this but I'm not sure it's "good"

  <mo intent='absolute-value'>|</mo>
  <mi>y</mi>
  <mo>-</mo>
  <mi>z</mi>
  <mo intent='end-absolute-value'>|</mo>

https://mathml-refresh.github.io/intent-lists/intent5.html#IDvertxabs

and

https://mathml-refresh.github.io/intent-lists/intent5.html#IDxplus2timestheabsolute-valueofyminusz

@NSoiffer
Copy link
Contributor

NSoiffer commented Apr 3, 2023

Example 1: multiline expressions with a big curly brace on the left.
This could be a system of equations, or it could be a "cases".

I just implemented something for David C and what seems logical is:

<mrow intent='$table'>
  <mo>{</mo>
  <mtable arg='table' intent=':cases'>
     ...
   </mtable>
</mrow>

The outer mrow is the decoration that gives some meaning to the table, but it is the table itself that carries the content to speak. Hence, that's where the property makes sense. Because we lack a way to refer to the children (i.e, we decided against allowing *, etc), it can't be something like intent=cases(*).

This pattern works for matrices and determinants also. For a system of equations, no outer mrow is relevant and a intent=':equations' works. Would you find that reasonable to generate?

Different topic:
I agree with Deyan that _by is probably more appropriate. However, I suspect almost any word used for an operator is really a literal and not the name of a concept except coincidentally. Hence, unless the spec works hard in some way to make it very evident that they are literals, the underscore won't get used on mos. It won't matter for the speech though.

@davidcarlisle
Copy link
Collaborator

I agree with Deyan that _by is probably more appropriate. However, I suspect almost any word used for an operator is really a literal and not the name of a concept except coincidentally. Hence, unless the spec works hard in some way to make it very evident that they are literals, the underscore won't get used on mos. It won't matter for the speech though.

Currently a "literal" is "any name not handled by the application" so I'd expect to see a leading _ used to force a literal interpretation used rather infrequently, mostly to avoid a core function. power(x,2) probably makes "x squared" but _power(x,2) is "power of x comma 2" if you need that .

@davidcarlisle
Copy link
Collaborator

@davidfarmer

I also think it should be a property, meaning intent=":system-of-equations",
because otherwise AT has to know to treat it specially and not just say
system of equations instead of reading out the contents.

Neil has now implemented this (as :equations) see

https://mathml-refresh.github.io/intent-lists/intent5.html#IDbracedsystemofequations

where this is used to give a "displayed equation" reading despite the leading { decoration that would otherwise make mathcat choose a "cases" reading, as seen in the (grey) column 2.

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

Btw @NSoiffer, don't be surprised very few entries look like concepts if you are consciously switching away from known concept names to shorthands. :system-of-equations was based on a search I did in wiki, where David C had also mentioned :simultaneous-equations which wiki redirects to the same concept page (it's another name for the same construct).

:equations is certainly shorter, but doesn't mean the same thing. This will be felt whenever the property gets used as an accessible description, where "equations" is a less informative description than "system of equations".

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 3, 2023

@dginev :system-of-equations .

Yes I wondered about that too. Also I was reading somewhere recently, but couldn't find it this morning, a discussion about how different communities use or do not use "equation" in this context to include inequalities. In tex, and in english it is sort of OK to refer to \begin{equation} x < y \end{equation} as "equation 1" but I gather calling an inequality an equation doesn't always translate well.

I'm not sure we'd want :system-of-equations , :system-of-inequations , :system-of-approximate-equations ...

The (french) systeme package for LaTeX calls these \systeme without implying what they are a system of.

@brucemiller
Copy link
Contributor

brucemiller commented Apr 3, 2023 via email

@davidfarmer
Copy link
Contributor Author

Since 8 × 8 could be "times" or "cross" or "by" or ..., it seems odd to me
that some of them would start with an underscore and not the others.
But maybe that is the same as arguing the difference between
intent="multiplication" and intent="_times".

For "cases" vs "system", I really like Neil's implementation of intent="$table"
on the mrow, and intent=":cases" on the mtable. (If there is no big
curly left bracket then there is no need for the mrow.)

For a system of equations or inequalities, in my work I have been
using "system" in all cases. I think that intent=":system" is reasonable terminology.
(Maybe I am assuming other languages have a common word for system of
equations and system of inequalities.) If it is necessary to say that those are
equations and not inequalities, we can just add another property:
intent=":system:equations".

A related situation I call a "derivation", as in

   (a+b)^2 = a^2 + 2 a b + b^2
           <= 2 a b + b^2
           = b (2 a + b)

Unlike a :system, in which each line is an independent expression,
in a :derivation each subsequent line starts with a relation and is
logically linked to the previous line. That needs to be read differently
because it is confusing to call each separate line an "equation".

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

@davidfarmer thumbs up for the mention of :derivation, there is a related discussion in #402 (comment)

In an ideal world I would expect an ambitious AT system to be aware of the common aliases used for standard constructs (as I've shown above, wikipedia is aware of some of them and adds redirects). The larger discussion about multiple possible names ties into w3c/mathml-docs#40 which got moved to a different repository, in wait of creative ideas. But having to do any additional reasoning to figure out that :system:equations, :system-of-equations, :simultaneous-equations and :simultaneous:equations all refer to the same conceptual structure is probably a little too heavy a burden. Some broad convention may help reduce the surface of possible legal names...

@davidcarlisle
Copy link
Collaborator

@davidfarmer

That needs to be read differently because it is confusing to call each separate line an "equation".

https://mathml-refresh.github.io/intent-lists/intent5.html#IDalignedderivation

Currently there is no specific property, but you can stop it saying "equation" Your example comes out as

derivation of, 3 lines,
line 1; .....
line 2; .....
line 3; ......

@davidfarmer
Copy link
Contributor Author

I had a mathematical conversation last week (meaning, standing around,
nothing written). The other person mentioned that something was an
element of "kew root kew". The first "kew" is the rational
numbers, often denoted ℚ . The second "kew" was the letter q , in this case
representing an integer. The object mentioned is $\mathbb Q(\sqrt{q})$,
which is notationally related to the free algebra discussed earlier.

After the math conversation ended, I mentioned our MathML discussions and
pointed out his potentially confusing "kew root kew" statement.
We both felt that "kew root kew" was unambiguous to anyone
who was able to understand the mathematics we were discussing.
(An expansive reading might be "the rationals adjoin the square root of q".
It is not uncommon to say things like "Q of root q", even though saying "of"
is not technically correct.)

Where I am headed is that there are many mathematical constructions
of the form X(a) which are not function evaluation. Instead,
that describes a new mathematical object which is a type of "extension"
of X. A field extension, like ℚ(<msqrt>q</msqrt>) is one example,
and a free algebra is another. Polynomial rings and formal power series are
other common examples. I propose that an :extension property is
sufficiently common to warrant spacial treatment.

One can use intent=":extension:free-algebra" or
intent=":extension:polynomial-ring" to indicate the type of extension.
Or just have intent=":extension" to clarify that it is not a function.

Would these go on an mrow and reference the contents, or on the mo
and not have any arguments?

@NSoiffer
Copy link
Contributor

NSoiffer commented Apr 3, 2023

Btw @NSoiffer, don't be surprised very few entries look like concepts if you are consciously switching away from known concept names to shorthands. :system-of-equations was based on a search I did in wiki, where David C had also mentioned :simultaneous-equations which wiki redirects to the same concept page (it's another name for the same construct).

:equations is certainly shorter, but doesn't mean the same thing. This will be felt whenever the property gets used as an accessible description, where "equations" is a less informative description than "system of equations".

I'm definitely not locked in on the names. I choose "equations" to be consistent with the other names "lines", "cases", etc., which are the names used to announce the table and rows ("3 equations, equation 1, ..."). The name of the property or concept doesn't need to match the name used in speech.

I also realized that we have two ways of doing the same thing... something that is worrisome to me since it adds to confusion ("an author will ask which is right/better?") and adds to implementation burden. One way that is pretty natural for matrix and determinant is to put an intent on the mrow as in:

<mrow intent='matrix($table)'>
  <mo>(</mo>
  <mtable arg='table'>
     ...
   </mtable>
   <mo>)</mo>
</mrow>

and the other method is to use properties:

<mrow intent='$table'>
  <mo>(</mo>
  <mtable arg='table' intent=':matrix'>
     ...
   </mtable>
   <mo>)</mo>
</mrow>

The problem cases are when there aren't "decorations" around the table to indicate that you want it read as "lines", "equations", or something else. In those cases, there isn't an mrow around the table so it would seem that only properties can be used. However, it could be done by adding an mrow just to hold the intent:

<mrow intent='system-of-equations($table)'>
  <mtable arg='table'>
     ...
   </mtable>
</mrow>

Is one easier to generate than the other? What are the pros/cons of using a concept name vs a property for these tabular notations?

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

To me there is a very clear ARIA-like distinction: matrix($table) contributes "matrix" to the accessible name for that element, while intent=":matrix" contributes "matrix" to the accessible description for that element.

Where "contributes to X" is meant loosely as in "should take action that will impact X", and is not exclusive:

  • [optional] both Name and Description can be impacted, if AT desires to do so

Neil's example above shows :matrix changing the main speech (accessible name), but one could also imagine the matrix($table) variant used as a cue for AT to auto-add properties :n-rows:m-columns as a summary of the matrix, changing the accessible description.

@davidcarlisle
Copy link
Collaborator

Is one easier to generate than the other? What are the pros/cons of using a concept name vs a property for these tabular notations?

I see them as separate and have used both on the same term in some of the examples.

The properties are a fixed list of supported reading styles, like fixity hints, the names of the properties are or could be, unrelated to speech just as :infix is never spoken as infix.

So I can have rank($m) with <mtable arg='m' intent=':matrix'

and the non-core function rank gets read as usual, and the mtable gets read in matrix style

so rank of the 2 by 2 matrix ....

Of course some core functions may be "expecting" a matrix or a system of equations or whatever so not need the property, that's OK and same as saying some core functions default :infix or whatever

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

@davidfarmer I would suggest that if you can imagine :extension, I think it is an easy step from that to also imagine :restriction, as in $\mathbb{R}_{&gt;0}$.

@davidcarlisle
Copy link
Collaborator

@NSoiffer or to put it another way rank($m) is the rank function applied to a matrix. :matrix says this is-a matrix, and matrix($m) is probably sub-optimal.

@brucemiller
Copy link
Contributor

brucemiller commented Apr 3, 2023 via email

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

@davidcarlisle is vector() also sub-optimal compared to :vector ?

<mrow intent="vector(1,0,0)">
  <mo>(</mo>
  <mn>1</mn><mo>,</mo><mn>0</mn><mo>,</mo><mn>0</mn>
  <mo>)</mo>
</mrow>
<mrow intent=":vector">
  <mo>(</mo>
  <mn>1</mn><mo>,</mo><mn>0</mn><mo>,</mo><mn>0</mn>
  <mo>)</mo>
</mrow>

@davidcarlisle
Copy link
Collaborator

@dginev no that's like the equation example Bruce just gave. vector there just coincidentally has the same name. The function form is taking arguments that construct the vector, whereas the matrix() example above was not taking the elements (or rows) as arguments but the whole matrix. It was not a function making a matrix from something, it is just an assertion that something is a matrix, written in functional form.

[well the names are not coincidentally the same, it is common for an object constructor to have the same name as the object but they are still different things]

@brucemiller
Copy link
Contributor

brucemiller commented Apr 3, 2023 via email

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 3, 2023

Practically speaking there may be some core functions but all other function names are valid and read as literal, so

vector($a,$b) will get read as vector of a comma b

:vector will have no effect on speech (but may affect other things)

Obviously the list of properties that affect speech is fluid at the moment but it is currently

prefix infix postix function silent
equations cases lines matrix determinant

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

You didn't ask me, but :>

Oh hello! :>

So, if your example had involved an mtable with a
single row or column, I'd say that they were essentially equivalent, and
I'd have no strong preference.

I see. Wait, a vector in an mtable? They get spaced a bit oddly, but I guess one could try:

  • row vector:

    <mrow intent="vector($table)">
      <mo>(</mo>
      <mtable arg="table"><mtr>
        <mtd><mn>1</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
      </mtr></mtable>
      <mo>)</mo>
    </mrow>
    
    <mtable intent="vector($row)">
      <mtr arg="row">
        <mtd><mo>(</mo></mtd>
        <mtd><mn>1</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>)</mo></mtd>
      </mtr>
    </mtable>
    
    <mrow>
      <mo>(</mo>
      <mtable intent=":vector"><mtr>
        <mtd><mn>1</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
      </mtr></mtable>
      <mo>)</mo>
    </mrow>
    
    <mtable intent=":vector">
      <mtr intent=":vector"> <!-- let's mark both just in case -->
        <mtd><mo>(</mo></mtd>
        <mtd><mn>1</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>,</mo></mtd>
        <mtd><mn>0</mn></mtd>
        <mtd><mo>)</mo></mtd>
      </mtr>
    </mtable>
  • Edit: column vectors render much better

    <mrow intent="vector($table)">
      <mo>(</mo>
      <mtable arg="table">
        <mtr><mtd><mn>1</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
      </mtable>
      <mo>)</mo>
    </mrow>
    
    <mrow>
      <mo>(</mo>
      <mtable intent=":vector">
        <mtr><mtd><mn>1</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
      </mtable>
      <mo>)</mo>
    </mrow>
    
    <mrow intent=":vector">
      <mo>(</mo>
      <mtable>
        <mtr><mtd><mn>1</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
        <mtr><mtd><mn>0</mn></mtd></mtr>
      </mtable>
      <mo>)</mo>
    </mrow>
    

I think another conclusion from these examples is to prefer the intent form over the property form for any "unusual" markup that is likely to be unsupported by AT.

Both your and David's reply seem to indicate this notion of a "marker" usage for intent, where "matrix($arg)" marks the inner argument as a matrix.

That's a bit surprising to me, since in my mind the function heads were always either self-voicing ("matrix of $arg") in the Open realm or "specially handled" due to Core. But how I imagined the special handling was exactly AT reaching into $arg and checking if the element is an mtable, then going through the rows and cells. Compare to a use that is not on the mtable:

<mrow intent="matrix@prefix($arg)">
  <msup arg="arg" intent="M-star">
   <mi>M</mi>
   <mo>*</mo>
  </msup>
</mrow>

How does an implementation have the right behavior without checking the presentation tree behind $arg? Or is the Core use of matrix tied to the <mtable> arg?

@brucemiller
Copy link
Contributor

Well, I was thinking more of:

<mtable intent=":vector">
<mtr><mtd><mn>1</mn></mtd></mtr>
<mtr><mtd><mn>0</mn></mtd></mtr>
<mtr><mtd><mn>0</mn></mtd></mtr>
</mtable>

I don't quite understand what you mean by "marker", but I think it's the opposite of what you're saying.
I would use the property <mtable intent=":matrix">... to mark the mtable as being a matrix, and use the intent form <mxxx intent="matrix($row1,$row2,...)">... to specify a matrix with the given rows. The construct matrix($m) where $m refers to an mtable strikes me as somewhat non-sensical (or unintentional); a matrix of a matrix?

@dginev
Copy link
Contributor

dginev commented Apr 3, 2023

a matrix of a matrix?

a matrix of a table, being the key difference (if it's not annotated, the mtable isn't a matrix). Also, not how I've thought about it either, mostly following up on David C's description:

whereas the matrix() example above was not taking the elements (or rows) as arguments but the whole matrix. It was not a function making a matrix from something, it is just an assertion that something is a matrix, written in functional form.

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 3, 2023

@dginev

<mrow intent="matrix:prefix($arg)">
  <msup arg="arg" intent="M-star">
   <mi>M</mi>
   <mo>*</mo>
  </msup>
</mrow>

How does an implementation have the right behavior without checking the presentation tree behind $arg?

Currently (and I think correctly) there isn't a core matrix function, so the above makes

matrix m star

There is nothing to check.

Not relevant to this example, but currently the :matrix property only has an effect on mtable and would be valid but ignored elsewhere, just as :infix is ignored if not used with a function.

  <msup intent="M-star:matrix">
   <mi  intent=":matrix">M</mi>
   <mo>*</mo>
  </msup>

would give is-a matrix properties on M and M* if you wanted that (but they wouldn't affect the speech)

@brucemiller
Copy link
Contributor

I'm suspecting that @davidcarlisle 's mention of matrix($table) wasn't actually supporting the idea that a matrix function should take an mtable as an argument, but that several layers of counter-examples and lost context may make it look that way. My use of that sample was intended to indicate that I found it non-optimal, but that tone may have gotten lost in the shuffle.

@davidcarlisle
Copy link
Collaborator

I'm suspecting that @davidcarlisle 's mention of matrix($table) wasn't actually supporting the idea that a matrix function should take an mtable as an argument, but that several layers of counter-examples and lost context may make it look that way. My use of that sample was intended to indicate that I found it non-optimal, but that tone may have gotten lost in the shuffle.

yes exactly. I'd want foo($table) to be a function applied to the matrix so rank or inverse but for the suggested use of "read this table as a matrix" a :matrix property seems more natural. Going back to @NSoiffer question of whether to use properties or functions here.

@NSoiffer
Copy link
Contributor

NSoiffer commented Apr 4, 2023

Your always thinking of specifying text to speak ;-)

@dginev
Copy link
Contributor

dginev commented Apr 4, 2023

Just that kind of a long Monday... As a token of good will, I offer arXiv:1501.06430, where you will find a function <mi>I</mi> that constructs closed real intervals over its point argument. So, while not strictly needed in that paper, an extension of that technique would be:

<mrow intent="open-interval($x)">
  <mi>I</mi>
  <mo>(</mo>
  <mi arg="x">x</mi>
  <mo>)</mo>
</mrow>

for the "open interval of x". Although this is tricky, since it's really "assigned to x" or "at x" or "around x", and I'd likely be reaching for underscores again while proof-listening.

The good news is that I(x) is perfectly readable without any intent annotations, as far as 1501.06430 is concerned, so this isn't a required remediation. Likely the mrow in this example is better helped by a couple of properties (where applicable), e.g. intent=":open-interval:closed-real-interval".

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 4, 2023

Aren't properties meant to be used with Core intent to modify the narration?

Er, I think so, although you effectively quoted bits from @NSoiffer and and bits from me which is probably showing some different emphasis.

Recent changes in the spec and in mathcat have brought things in to much closer alignment and I think show a path to a final workable system but we aren't there yet. The spec wording there is vague as properties were changing at the time it was written, and we have never really tied down how properties or arity affect matching against a system's dictionary.

As other parts of the spec are hopefully more stable it probably makes sense to decide what we want to happen here.

In my head, a system's intent concept dictionary can match against name+arity+properties eg a sketch for transpose is here

https://mathml-refresh.github.io/intent-lists/core/#transpose

by which transpose:function($arg) should match and make transpose of x

Currently as seen here

https://mathml-refresh.github.io/intent-lists/intent5.html#id-0-3ac78e651639dc54379e9f69563d6bd1

the property is ignored and it makes x transpose.

_($op, _of, $arg) makes transpose of x but I really never want to do that:-)

So there are certainly gaps here. We need to decide how this is supposed to work and adjust the spec to say whatever is decided.

@davidfarmer
Copy link
Contributor Author

We have been talking about "transpose" as a core intent which goes on the msup, as in:
<msup intent="transpose($a)"><mi arg="a">x</mi><mi>T</mi></msup>.

Is it also possible to do it as a property on the superscript? As in:
<msup><mi>x</mi><mi intent=":transpose">T</mi></msup>.

We said that we don't like having two ways to do the same thing, so which of
these is better?

I think it is relevant that some people write the "T" on the left. One can have
"x transpose inverse" written with a "T" on the left and a "-1" on the right.
(People who advocate for putting the "T" on the left cite that example to support
their claim that the "T" on the left is better and more natural.)

@davidfarmer
Copy link
Contributor Author

A similar but more common situation is the transpose of a subscripted matrix, in LaTeX:
x_i^T .

If I put the transpose intent on the msubsup then the argument of the intent
has to be the x_i, but that is not something I can directly reference.
But it works fine to put the :transpose property on the mi.

@davidcarlisle
Copy link
Collaborator

I think transpose needs to be a function, unlike "read like a displayed equation" or "read in postfix order" it does relate to function and needs to generate translate as text.

There are examples of $X^T$ and ${}^T X$ at

https://mathml-refresh.github.io/intent-lists/intent5.html#IDxtranspose

and

https://mathml-refresh.github.io/intent-lists/intent5.html#IDxtransposepre-sup

arguably there could additionally be a property such as :annotation that tells msup not to generate superscript

@davidcarlisle
Copy link
Collaborator

$x_i^T$

Hmmm I put a couple of examples here

https://mathml-refresh.github.io/intent-lists/intent5.html#IDxsubtranspose

The second doesn't work at all, using a highly speculative :postfix property. Other suggestions on what the markup might be welcome.

@dginev
Copy link
Contributor

dginev commented Apr 7, 2023

To maximize the quality of speech+navigation, we would use as many references as possible and push the intent values as down as possible to the leaf nodes.

That is possible for matching up "T" and "transpose", but not for the index operation which is realized via the subscripted presentation (and i is its second argument). So "index", if mentioned explicitly, has to be annotated on the "msubsup" element.

Guessing on "msubsup" is probably too hard in general, as there are usually 2 content operations implied by the single presentation element. So the AT engine would have to guess the missing operation besides "transpose" and then guess the precedence. "M transpose at index i" and "M at index i, transpose" are different mathematical objects.

So, I would imagine:

<msubsup intent="index($op($M),$i)">
  <mi arg="M">M</mi>
  <mi arg="i">i</mi>
  <mi arg="op" intent="transpose">T</mi>
</msubsup>

and if we were indexing a specific cell, rather than a row or column, that could be:

<msubsup intent="index($op($M),$i,$j)">
  <mi arg="M">M</mi>
  <mrow>
    <mi arg="i">i</mi>
    <mi arg="j">j</mi>
  </mrow>
  <mi arg="op" intent="transpose">T</mi>
</msubsup>

@davidfarmer
Copy link
Contributor Author

If we are going to put a "transpose" attribute on an mi,
then AT has to know not to say "to the transpose", and we also
will have 1-argument transpose on the mrow and 0-argument
transpose on the mi.

I am missing what we can't do by always using the :transpose
property on the leaf. The property causes AT to say something,
which can be translated.

<msubsup>
  <mi>M</mi>
  <mi>i</mi>
  <mi intent=":transpose">T</mi>
</msubsup>

If double subscripts need to be specified as an index, then add
that property.

<msubsup>
  <mi>M</mi>
  <mrow intent=":index">
    <mi>i</mi>
    <mi>j</mi>
  </mrow>
  <mi intent=":transpose">T</mi>
</msubsup>

The typical meaning of B_{ij}^T is "the ij entry of B transpose".
If the author means "transpose of the ij entry of B",
the typography will have to be different because a sighted
person would misinterpret. Maybe {B_{ij}}^T of more clearly
(B_{ij})^T.

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 7, 2023 via email

@davidfarmer
Copy link
Contributor Author

Are you saying that instead of the intent=":transpose" property on the leaf,
it would be better to have intent="transpose" on the leaf?

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 7, 2023

Are you saying that instead of the intent=":transpose" property on the leaf, it would be better to have intent="transpose" on the leaf?

you need that anyway so the function is pronouned transpose you (may) also need a property so it gets read as "x transpose" just as you (may) need a property on transpose(x) if you want "x transpose" rather than "transpose of x".

If transpose is core the property might be defaulted, but presumably H hermitian-transpose wouldn't be core.

@davidfarmer
Copy link
Contributor Author

It seems workable to me to put intent="transpose" on the leaf, so I will change
my code to produce that output. I like the fact that it is lower and does not have
an argument. I assume AT will know not to say "to the transpose".

If later it is decided that AT needs it to be on the msup with an argument,
I will switch it back (reluctantly, because I still don't see a good way to handle
a simultaneous subscript).

If I also put a :matrix property on the base, like this:

<msup>
<mi intent=":matrix">x</mi>
<mi intent="transpose">T</mi>
</msup>

does that conflict with the previous discussion about the :matrix property?

@davidcarlisle
Copy link
Collaborator

does that conflict with the previous discussion about the :matrix property?

No, although I think it has no defined effect on an mi (so far).

As Neil merged the latest changes, the spec says this about :matrix

https://w3c.github.io/mathml/spec.html#intent_table_hints

@davidcarlisle
Copy link
Collaborator

If later it is decided that AT needs it to be on the msup with an argument,
I will switch it back (reluctantly, because I still don't see a good way to handle
a simultaneous subscript).

This isn't so bad, and works now:

https://mathml-refresh.github.io/intent-lists/intent5.html#id-0-333306ff438b6b20371f34b4e4ab2898

@NSoiffer
Copy link
Contributor

NSoiffer commented Apr 7, 2023

I don't like index as a core name because it doesn't speak well if not known, something I think is an agreed (mostly?) unstated design principal. That leads me to think of it as a property. So my feeling is that the example is best written as:

<msubsup intent='transpose(msub($base, $sub))'>
  <mi arg='base'>M</mi>
  <mrow arg='sub' intent=':index'>
    <mi>i</mi>
    <mi>j</mi>
  </mrow>
  <mi>T</mi>
</msubsup>

where I'm assuming that all the MathML elements are in core and essentially recursively apply their rules. MathCAT doesn't do this, but I don't think it would be hard to do.

@dginev
Copy link
Contributor

dginev commented Apr 7, 2023

I don't like index as a core name because it doesn't speak well if not known

@NSoiffer You also shouldn't like power, times, plus, or divides by that reasoning.

Isn't the main point of Core to assume the values in the list are known?

In an open setting you can indeed expect:

<msubsup intent="_($op($M),_at,index,$i)">
  <mi arg="M">M</mi>
  <mi arg="i">i</mi>
  <mi arg="op" intent="transpose">T</mi>
</msubsup>

for authors that decide they want to ensure a good narration outcome for ATs that lack coverage of index.

@davidfarmer
Copy link
Contributor Author

If "index" is supposed to be a property and "transpose" is supposed to be in core
(or at least self-voicing if not in core), then we could have:

<msubsup>
  <mi>M</mi>
  <mrow intent=":index">
    <mi>i</mi>
    <mi>j</mi>
  </mrow>
  <mi intent="transpose">T</mi>
</msubsup>

Except for saying "to the transpose", Mathcat does okay on that already.

I don't see how the markup get any simpler than that.

@davidcarlisle
Copy link
Collaborator

I'm assuming that all the MathML elements are in core a

ooh seems possible (if a little weird). What works now and doesn't require anything in core is to use sub rather than msub

<msubsup intent='transpose(sub:infix($base, $sub))'>

see https://mathml-refresh.github.io/intent-lists/intent5.html#id-0-4dc5e6b2ea853d5abb0821f3494a7950

@davidcarlisle
Copy link
Collaborator

<msubsup intent="_($op($M),_at,index,$i)">

oh you are forcing the other nesting, we'd been assuming an interpretation of transpose of M_i not the transpose of M, indexed at i (although of course you need to be able to do either). Certainly we should be able to have a recommended markup without resorting to _(

@dginev
Copy link
Contributor

dginev commented Apr 7, 2023

oh you are forcing the other nesting, we'd been assuming ...

Indeed, I mentioned the alternative nesting leads to different speech here. And that, depending on how the pieces are composed together, the resulting speech conveys a different mathematical object.

Certainly we should be able to have a recommended markup without resorting to _(

A dangerous certainty.

Custom ad-hoc properties can be painful in practice, since it appears hard to predict when they do or don't activate in AT, and if the composition with other partial annotations is going to produce high-quality narration (or not).

In David Farmer's last example:

<msubsup>
  <mi>M</mi>
  <mrow intent=":index">
    <mi>i</mi>
    <mi>j</mi>
  </mrow>
  <mi intent="transpose">T</mi>
</msubsup>

It is unspecified/unpredictable whether transpose or index have higher precedence (both in terms of what the author meant, and how AT would combine them).


For cases in the Open realm, we need the underscore form whenever a custom connector word (or several, or custom order) is needed. One could alternatively try to invent additional tiers of clarifying markup,
e.g. something new such as index:{at}infix($x,$i) for "$x at index $i" or index:infix{-ed in}($x,$i) for "$x indexed in $i", but to me it seems like we just increase the difficulty of intent for anyone not interested in Content forms.

The _() override solves that problem with a uniform natural treatment. It's quite a big help in practice, and tends to be quicker to piece together (as the phrase suggests).


Separately, sub:infix(a,b) seems artificial. Adding an infix fixity to a subscript word? If it was consistent with the general principle of :prefix,:postfix,:infix, this should be :sub or :subscript, likely also with :super/:superscript, so that one could preserve the concept symbol:

index:subscript(x,i)

The script words are a little bit like :silent, since the head remains silent, but they also carry with them a standard connector word between the (exactly) 2 arguments.

This also gave me an inkling that if someone was trying to stay close to the presentation elements :phantom may be more appropriate than :silent (thanks to mphantom).

So I am a lot more certain about using _() myself - it's a template form that is easy to explain, easy to learn, and lets the author write down the narration in the same linear order they already know.

@davidcarlisle
Copy link
Collaborator

davidcarlisle commented Apr 7, 2023

It is unspecified/unpredictable whether transpose or index have higher precedence

yes either we specify (say) subscript binds tightly, or we can use a functional form on the msup, nesting in whichever order is needed.

For cases in the Open realm, we need the underscore form whenever a custom connector word (or several, or custom order) is needed.

It's available if someone really wishes to force a particular word order, but forcing a specific wording is a non-aim of intent so I don't think there are any cases where using _( should be the recommended markup. It's just an escape hatch for exceptional cirumstances.

Separately, sub:infix(a,b) seems artificial. Adding an infix fixity to a subscript word?

It's an infix function for indexing I chose to call sub in that example, I could have called it subscript or index or other things. It fits the general scheme for intent, I'm surprised you find it artificial.

So I am a lot more certain about using _() myself - it's a template form that is easy to explain, easy to learn, and lets the author write down the narration in the same linear order they already know.

Using a function of _ destroys the entire design of a functional expression form. If specifying exact words in exact order was really part of the design aim we would be better just to use alttext or a templated string.

@dginev
Copy link
Contributor

dginev commented Apr 7, 2023

forcing a specific wording is a non-aim of intent

Any chance this can be softened? I would like to strive for aria-label parity, and that requires the ability to override with specific words. The aim of intent should be "high quality accessible outcomes", and sometimes specific wording is the path to achieving that in the short term.

The _() is a vehicle for a partial templated string without destroying the rest of the functional expression, but rather in synergy with it.

@davidcarlisle
Copy link
Collaborator

Any chance this can be softened?

Not really, it's just a statement of fact that it wasn't an aim of the design. That doesn't mean the end result can't include a mechanism to specfy words, but any such mechansm even without the weird _( syntax would really be anomalous compared to the rest of the design.

If foo is in core foo($a,$b) can generate pretty much anything. If it's not in core it can generate foo of a comma b, or foo of a and b, or foo applied to a and b, or whatever else the system chooses. <mtable intent=":matrix"> means "generate something appropriate for matrices". intent is fundamentally for disambiguating the meaning enough to allow the system to generate correct speech, it simply isn't about specifying text. We can graft in a mechansm to specify text but it if it ends up being used much it means we have failed in the design as if that were really a design aim there are far more natural ways to specify text that we could have used.

@brucemiller
Copy link
Contributor

I'm inclined to think that if you want to control exact speech and be like aria, you should use aria. That aria currently doesn't "see" the MathML doesn't seem like a valid reason to reinvent a second version of aria, but rather is a reason to get aria (or it's context) fixed.

@dginev
Copy link
Contributor

dginev commented Apr 20, 2023

@brucemiller We have a mandate/preference by the ARIA group to reach parity to relevant features of it in MathML itself, without resorting to ARIA, granted to us here:

w3c/aria#1723 (comment)

The main unresolved discussion appears to be whether exact speech overrides are a requirement for MathML Intent or not. In my view they are.

If the group leans otherwise, MathML Intent should have a note on inter-operating with aria-label for speech overrides, or alternatively, we could make alttext a global attribute and use it akin to aria-label.

@brucemiller
Copy link
Contributor

brucemiller commented Apr 20, 2023 via email

@davidcarlisle
Copy link
Collaborator

The main unresolved discussion appears to be whether exact speech overrides are a requirement for MathML Intent or not. In my view they are.

Certainly it is not a requirement but all versions of intent have provided this by making liberal use of the existing freedoms. Whether it is intent="just_say_this" or intent="_(_just, _say, _this)" or a combination. So I don't think there is any need for further attributes, or even an agreed position on whether this is useful to do. The facility will be there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
intent Issues involving the proposed "intent" attr
Projects
None yet
Development

No branches or pull requests

5 participants