Speech-Rule-Engine/speech-rule-engine

Units Improvements

Opened this issue · 2 comments

  • Move over some of the MathSpeak rules to Clearspeak (#358)
  • Check plural considerations (#301)
  • Add currencies.
  • Integrate PossibleUnit heuristic.
  • Finish new SI unit handling on all locales.

I was looking at MathSpeak vs Clearspeak rules and how they dealt with imperial units and found a few oddities. Some common units are missing and pluralization is off in a few places as well. I was working up some examples and thought I'd share here. I hope you find this useful, even if just for testing.

Imperial Linear Units of Length (US)

<math>
  <mrow>
    <mn>63360</mn>
    <mi class="MathML-Unit">in</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>63360</mn>
    <mi class="MathML-Unit">in.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <msup>
      <mn>63360</mn>
      <mo>&Prime;</mo>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>63360</mn>
    <mi class="MathML-Unit">inches</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>5280</mn>
    <mi class="MathML-Unit">ft</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>5280</mn>
    <mi class="MathML-Unit">ft.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <msup>
      <mn>5280</mn>
      <mo>&prime;</mo>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>5280</mn>
    <mi class="MathML-Unit">feet</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1760</mn>
    <mi class="MathML-Unit">yd</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1760</mn>
    <mi class="MathML-Unit">yd.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1760</mn>
    <mi class="MathML-Unit">yards</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mi</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mi.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mile</mi>
  </mrow>
</math>

Imperial Survey Units of Length (US)

<math>
  <mrow>
    <mn>8000</mn>
    <mi class="MathML-Unit">li</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8000</mn>
    <mi class="MathML-Unit">li.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8000</mn>
    <mi class="MathML-Unit">links</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>320</mn>
    <mi class="MathML-Unit">rd</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>320</mn>
    <mi class="MathML-Unit">rd.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>320</mn>
    <mi class="MathML-Unit">rods</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>80</mn>
    <mi class="MathML-Unit">ch</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>80</mn>
    <mi class="MathML-Unit">ch.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>80</mn>
    <mi class="MathML-Unit">chains</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">fur</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">fur.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">furlongs</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mi</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mi.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">mile</mi>
  </mrow>
</math>

Imperial Units of Area (US)

<math>
  <mrow>
    <mn>43560</mn>
    <mi class="MathML-Unit">sq ft</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>43560</mn>
    <mi class="MathML-Unit">sq. ft.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>43560</mn>
    <msup>
      <mi class="MathML-Unit">ft</mi>
      <mn>2</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <msup>
      <mn>43560</mn>
      <msup>
        <mo>&prime;</mo>
        <mn>2</mn>
      </msup>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>43560</mn>
    <mi class="MathML-Unit">square feet</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4840</mn>
    <mi class="MathML-Unit">sq yd</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4840</mn>
    <mi class="MathML-Unit">sq. yd.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4840</mn>
    <msup>
      <mi class="MathML-Unit">yd</mi>
      <mn>2</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4840</mn>
    <mi class="MathML-Unit">square yards</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>160</mn>
    <mi class="MathML-Unit">sq rd</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>160</mn>
    <mi class="MathML-Unit">sq. rd.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>160</mn>
    <msup>
      <mi class="MathML-Unit">rd</mi>
      <mn>2</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>160</mn>
    <mi class="MathML-Unit">square rods</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">ac</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">ac.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">acre</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mfrac>
      <mn>1</mn>
      <mn>640</mn>
    </mfrac>
    <mi class="MathML-Unit">sq mi</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mfrac>
      <mn>1</mn>
      <mn>640</mn>
    </mfrac>
    <mi class="MathML-Unit">sq. mi.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mfrac>
      <mn>1</mn>
      <mn>640</mn>
    </mfrac>
    <msup>
      <mi class="MathML-Unit">mi</mi>
      <mn>2</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mfrac>
      <mn>1</mn>
      <mn>640</mn>
    </mfrac>
    <mi class="MathML-Unit">square miles</mi>
  </mrow>
</math>

Imperial Units of Dry Volume (US)

<math>
  <mrow>
    <mn>46656</mn>
    <mi class="MathML-Unit">cu in</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>46656</mn>
    <mi class="MathML-Unit">cu. in.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>46656</mn>
    <msup>
      <mi class="MathML-Unit">in</mi>
      <mn>3</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <msup>
      <mn>46656</mn>
      <msup>
        <mo>&Prime;</mo>
        <mn>3</mn>
      </msup>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>46656</mn>
    <mi class="MathML-Unit">cubic inches</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>27</mn>
    <mi class="MathML-Unit">cu ft</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>27</mn>
    <mi class="MathML-Unit">cu. ft.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>27</mn>
    <msup>
      <mi class="MathML-Unit">ft</mi>
      <mn>3</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <msup>
      <mn>27</mn>
      <msup>
        <mo>&prime;</mo>
        <mn>3</mn>
      </msup>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>27</mn>
    <mi class="MathML-Unit">cubic feet</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">cu yd</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">cu. yd.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <msup>
      <mi class="MathML-Unit">yd</mi>
      <mn>3</mn>
    </msup>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">cubic yard</mi>
  </mrow>
</math>

Imperial Units of Liquid Volume (US)

<math>
  <mrow>
    <mn>1024</mn>
    <mi class="MathML-Unit">fl dr</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1024</mn>
    <mi class="MathML-Unit">fl. dr.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1024</mn>
    <mi class="MathML-Unit">fluid drams</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>768</mn>
    <mi class="MathML-Unit">tsp</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>768</mn>
    <mi class="MathML-Unit">tsp.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>768</mn>
    <mi class="MathML-Unit">teaspoons</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">Tbsp</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">Tbsp.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">tablespoons</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>128</mn>
    <mi class="MathML-Unit">fl oz</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>128</mn>
    <mi class="MathML-Unit">fl. oz.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>128</mn>
    <mi class="MathML-Unit">fluid ounces</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">cp</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">cp.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">cups</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">pt</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">pt.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>8</mn>
    <mi class="MathML-Unit">pints</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4</mn>
    <mi class="MathML-Unit">qt</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4</mn>
    <mi class="MathML-Unit">qt.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>4</mn>
    <mi class="MathML-Unit">quarts</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">gal</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">gal.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">gallon</mi>
  </mrow>
</math>

Imperial Units of Weight (US)

<math>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">dr</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">dr.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>256</mn>
    <mi class="MathML-Unit">drams</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">oz</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">oz.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>16</mn>
    <mi class="MathML-Unit">ounces</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi mathvariant="normal" class="MathML-Unit">#</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">lb</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">lb.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>1</mn>
    <mi class="MathML-Unit">pounds</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>100</mn>
    <mi class="MathML-Unit">cwt</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>100</mn>
    <mi class="MathML-Unit">cwt.</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>100</mn>
    <mi class="MathML-Unit">hundredweights</mi>
  </mrow>
  <mo>=</mo>
  <mrow>
    <mn>2000</mn>
    <mi class="MathML-Unit">tons</mi>
  </mrow>
</math>

Thanks @klobetime for all these Imperial measures. Some were quite new to me!
I have just pushed a v3.0.1 release which contains a number of fixes for units.

As for Mathspeak vs Clearspeak; Mathspeak is the more literal of the two grammars, there are a couple of points that are worth pointing out:

  • All units are always spoken in plural form; Rule 13.1.
  • Powers are not interpreted wrt. the unit. I.e., it is meters squared and not square meter (Examples 5 above)
  • Symbols are not interpreted as units, i.e., the primes will be spoken as primes.