<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Towards a Technique of Incorporating Domain Knowledge for Unit Conversion in Scientific Reasoning Systems</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Joseph Phillips</string-name>
          <email>jphillips@cdm.depaul.edu</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>De Paul University School of Computing and Digital Media 243 S. Wabash Ave Chicago</institution>
          ,
          <addr-line>IL 60604</addr-line>
          ,
          <country country="US">USA</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>Unit conversion is often considered a straightforward task using analytical knowledge like the definition of centimeters in terms of meters. However, conversions like the computation of a photon's frequency from its wavelength implicitly use domain knowledge. We present an update on ongoing work on how a scientific reasoning system may intelligently convert between units using domain knowledge and tag data thus produced as dependent upon this domain knowledge. This is part of a project to intelligently use meta-data for scientific value manipulation (Phillips 2010).</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Computers should be made to understand scientists, not
other way around! Unfortunately scientists are far from
uniform in their notation, even within a single domain.</p>
      <p>A good example of this non-uniformity is with unit
usage. True, the metric system is widely used. However
even here there are some applications where
meters/kilograms/seconds (giving energy units Joules) are
preferred, and others where centimeters/grams/seconds
(giving energy units dynes) are common.</p>
      <p>Beyond this we see some applications where different
units are used, even for the same dimension, to keep the
system on a common or intuitive scale and/or so that
values naturally fall between ranges 0.1 to 1.0, or 1.0 to 10.
Examples include the agricultural rainfall or irrigation unit
hectare-mm (as opposed to liters), the electrical energy unit
kilowatt-hours (as opposed to Joules), and the astronomical
unit parsecs, from parallax seconds (as opposed to meters).</p>
      <p>A third class of units actually changes dimensions.
Domain knowledge is needed implicitly to convert
between the dimensions. This is often seen with light,
where a photon's wavenumbers (in inverse centimeters),
wavelength (in meters, millimeters, microns, or
nanometers), or its energy (in electron-volts) all may be
taken as stand-ins for its frequency.</p>
      <p>Relying on domain knowledge is particularly tricky
because it can change. For example, since the
development of special relativity we believe that the speed
of light, the “c” in the equation =c/ needed to convert
from wavelength or wavenumbers to frequency, is constant
for all observers in any reference frame. Prior to Einstein
this would not have been a common belief.</p>
      <p>Lastly, some units are actually for dimensionless values
that have been normalized by being divided by some
common standard. For example, the masses of planets in
locations other than in orbit around our own Sun are
commonly given in terms of how many “Jupiters” they are,
rather than in kilograms. Also, the energy released in
powerful events like large detonations is commonly given
in kilotons of trinitrotoluene (TNT).</p>
      <p>
        Herein we describe knowledge and algorithms to
interconvert between pairs of units of the four cases given
above. This work is a continuation and elaboration of on
going work into writing a computer language which can
reason about scientific meta-data intelligently
        <xref ref-type="bibr" rid="ref8">(Phillips
2010)</xref>
        .
      </p>
      <p>
        The outline is as follows. We briefly discuss previous
attempts to handle meta-data in the next section and follow
with a brief description of the language we are building for
scientific representation and reasoning. With this
background we then present our approach and algorithms.
We follow with a discussion of its limitations, and then
conclude.
Several extensions exist to popular numeric and symbolic
packages like Mathematica
        <xref ref-type="bibr" rid="ref4">(Khanin 2001)</xref>
        and Matlab
        <xref ref-type="bibr" rid="ref3">(deCarvalho 2006)</xref>
        enabling them to do dimensional
analysis and unit conversion. Prior to that the Unix™
command units could do some multiplicative dimension
and unit recognition, like converting 1000 cm3 to 1 liter
        <xref ref-type="bibr" rid="ref9">(SunOS 1992)</xref>
        <xref ref-type="bibr" rid="ref5">(Mariano 2004)</xref>
        . Also, systems that do
scientific discovery like the Bacon series of programs are
able to invent new units to describe new phenomena
(Langley et al 1987). To the best of our knowledge,
however, such systems do not tag the resulting calculations
as dependent upon the correctness of the domain
knowledge used to convert between dimensions (e.g. from
wavenumbers to frequency), or are unable to do such
dimension-changing conversions at all.
      </p>
      <p>Fundamentally all these systems make the same mistake
that Logical Positivists philosophers of science made when
ignoring the extent to which data is theory-laden. They
strive to carry forward only as much meta-data as needed
to ensure the numeric or algebraic stability of the answer.
They do not, however, even bother to capture, ask for,
carry-forward, or exploit much domain knowledge1.</p>
    </sec>
    <sec id="sec-2">
      <title>3. A Brief Introduction to StructProc</title>
      <p>StructProc is our language for a frame representation for
scientific knowledge. Like other frame representations,
StructProc knowledge is built around the
&lt;subject,attribute,value&gt; triplet. StructProc, however, has
a feature which may be less common. Numbers are not
represented as being objects distinct from “symbols”
(called “ideas” in StructProc) – rather numbers are
represented as a special sort of idea. This allows numbers
to be given properties (&lt;attribute,value&gt; pairs) like any
other idea, for numbers to be queried on their properties
like any other idea, etc.</p>
      <p>The chief property to assign to numbers is their domain.
A domain is an idea with corresponding dimensions, units,
limits, etc. which is distinct from but obviously related to
the attribute. For example, a building may be said to have
a length, width and height. In general, all are distinct
numbers corresponding to the attributes lengthA,
widthA, and heightA (the postfixed A is StructProc's
recommended way to designate attributes). Though they
are three different numbers, all have the same domain
(defaultMetersDomain) with the unit being
meters, dimension being length, and limitation being
that values less than 0 are illegal.</p>
      <p>Besides being annotated by their domains, numbers (and
any other idea) may have subjects, attributes and
assumptions specified. The StructProc expression
45.4{defaultMetersDomain,
heightA,
dePaulCenter,
^assumeS
{measure1-&gt;angleOfElevationA =
45.0{defaultDegreesDomain},
measure1-&gt;distanceA =
41.0 {defaultMetersDomain},
measure1-&gt;heightA =
1.4 {defaultMetersDomain}
}
1 With the exception of perhaps boundary conditions for
differential equations and simple notions of units and
dimensions.</p>
      <p>}
represents the number 45.4 which has been annotated as
being the height of the building the DePaul Center in
meters. Further, this value assumes the validity of three
other measurements gathered under frame measure1:
that 44.0 meters away from the building its top was sighted
at an angle of 45.0 degrees above the horizon, and that the
angle was measured from 1.4 meters above the ground.</p>
    </sec>
    <sec id="sec-3">
      <title>4. Our Approach</title>
      <p>The basic algorithm that underpins our approach is a
straightforward conversion from one of unit to another of
the same “fundamental” dimension as detailed in
sameSingleDimensionalConvert(). Because
both units share the same dimension, and because the
compatibility of their subjects and attributes is checked
elsewhere, no other checks need to be done or knowledge
needs to be assumed.</p>
      <p>The function
sameSingleDimensionalConvert() returns linear
conversion expression that converts from a value in
fromUnits to one in toUnits. It does this by
attempting to convert to the primary units of the
“fundamental” dimension as an intermediate step. If it
successfully finds a conversion then it saves it so it can be
easily applied next time. (The expression
thisExpr.sub(expr) takes the algebraic expressions
expr(x1) and thisExpr(x2) and returns the new
expression thisExpr(expr(x1)). The expression
subject.get(attrA) returns the first found value of
subject's attribute attrA, or returns null if none are
found. The expression covertToA(units) builds an
attribute that represents a conversion to the specified
units.)</p>
      <p>This function allows the conversion from parsecs to
kilometers by way of meters, and from Celsius to Kelvin
with a slope of 1 and intercept of 273.15.</p>
      <p>LinearExpression
sameSingleDimensionalConvert</p>
      <p>(Units fromUnits, Units toUnits)
begin
LinearExpression expr, thisExpr;
Dimension dim;
Units prime;
if (fromUnits == toUnits)</p>
      <p>Number slope := 1;
Number intercept := 0;
return new LinearExpression(slope,intercept);
endif
expr := store.retrieve(fromUnits,toUnits)
if (expr != null)
return(expr);
endif
dim := fromUnits.get(dimensionA);
prime := dim.get(primaryUnitsA);
expr := fromUnits.get(covertToA(prime))
if (expr == null)</p>
      <p>throw new InsufficientInformation();
endIf
thisExpr := prime.get(covertToA(toUnits));
if (thisExpr == null)</p>
      <p>throw new InsufficientInformation();
endIf
expr := thisExpr.sub(expr);
store.save(fromUnits,toUnits,expr);
return expr;
end;</p>
      <p>Two functions are used to convert between
multidimensional units. The function
incorporateUnits() is given a list of dimension
entries (dimList). Each entry tells a dimension and
itself has a list of basic units of that dimension and the
powers to which those units have been raised. The
function adds to this list the new dimensions and basic
units it finds for the unit parameter it has been given.
The basic units of unit are incorporated into dimList,
but their powers are multiplied by sign: either +1 or -1.
This allows basic units that appear in both a fromUnits
(line 2 with sign -1) and toUnits (line 3 with sign +1) to
cancel each other at line 1.</p>
      <p>DimList
incorporateUnits</p>
      <p>(DimList dimList, Units unit, int sign)
begin
Units basicU;
int power;
DimEntry dimEntry;
UnitEntry unitEntry;
Dimension dimen;
forall basic unit pairs (basicU,power) in unit do
dimen := basicU.get(dimension);
dimEntry := dimList.find(dimen);
if (dimEntry == null)
dimEntry := new DimEntry(dimen);
dimList.prepend(dimEntry);
endif
unitEntry := dimEntry.unitList.find(basicU);
if (unitEntry == null)
unitEntry := new UnitEntry(basicU);
dimEntry.unitList.prepend(unitEntry);
unitEntry.addPower(power*sign); // Line 1
endfor
return(dimList);
end;</p>
      <p>The function sameMultiDimensionalConvert()
uses both incorporateUnits() and
sameSingleDimensionalConvert() to return a
conversion expression from a value in fromUnits to one
in toUnits. It uses the former function to decompose
(and hopefully partially cancel) both incoming units into
their basic units, isolated by their dimensions (lines 2 and
3).</p>
      <p>For each dimension it does the following. It finds the
next occurrences of both a basic unit raised to a positive
power (loop 4) and raised to a negative power (loop 5).
They are different units of the same dimension, so they
should be converted. If there are no more units to convert
then it goes on to the next dimension (line 6).</p>
      <p>When it finds units to convert it uses
sameSingleDimensionalConvert(). Allowances
are made when the units are raised to higher powers (lines
7, 8), those units are cancelled (lines 9, 10), and then it
continues looking more units to convert. It also checks the
expression returned from
sameSingleDimensionalConvert() (not shown)
to see if it has an added constant other than zero. It must
do so because it builds an expression of multiplied (and
divided terms): added terms would throw-off the
computation. Also, they probably signify that the wrong
units were used in the expression. For example, the
Maxwell-Boltzmann distribution equation uses
temperature in Kelvin (with an absolute 0) instead of in
Celsius (with the additive term 273.15).</p>
      <p>At the very end it returns an algebraic expression that
uses the product of the slopes of all conversions.
Expression
sameMultiDimensionalConvert</p>
      <p>(Units fromUnits, Units toUnits)
begin
DimList dimList := null;
double product := 1.0;
DimEntry dimEntry;
UnitEntry posEntry, negEntry;
int power;
Expression expr;
// Line 2
dimList:= incorporateUnits(dimList,fromUnits,-1);
// Line 3
dimList:= incorporateUnits(dimList, toUnits,+1);
forall dimEntry in dimList do
posEntry := negEntry := dimEntry.unitList.head;
while (true)
// Loop 4
while (posEntry!=null AND posEntry.power&lt;=0)
posEntry := posEntry.next;
endwhile
// Loop 5
while (negEntry!=null AND negEntry.power&gt;=0)
negEntry := negEntry.next;
endwhile
if (posEntry == negEntry == null)</p>
      <p>break;
endif
// Line 6
expr := sameSingleDimensionalConvert</p>
      <p>(negEntry.unit,posEntry.unit);
// Line 7
power := min(posEntry.power,-negEntry.power);
for (i := 0; i &lt; power; i := i+1)</p>
      <p>product := product * expr.slope; //Line 8
endfor
posEntry.addPower(-power); // Line 9
negEntry.addPower(+power); // Line 10
endwhile
endfor
expr := new LinearExpression(product,0);
store.save(fromUnits,toUnits,expr);
return(expr);
end;</p>
      <p>This function allows the conversion from hectare-mm to
liters by restating hectares as being hundred-meters
squared, restating liters as decimeters cubed, and
converting millimeters to decimeters (once) and
hundredmeters to decimeters (twice). The second conversion from
hundred-meters to decimeters benefits from the cached
results generated by the first conversion.</p>
      <p>Similarly, it can also convert kilowatt-hours to Joules.
This particular conversion highlights the generality of the
algorithm. Our system knows kilowatt-hours as:
(kilograms)*(meters)*(kilometers)*(hours)</p>
      <p>(seconds3)
The kilograms, meters, kilometers and inverse cubed
seconds terms multiply to give kilowatts, and multiplying
that by hours gives kilowatt-hours.</p>
      <p>This is a natural way to define kilowatt-hours but it
represents the time dimension in an atypical fashion as
hours/seconds3. Hours and seconds do not need to be
converted between fromUnits and toUnits but within
fromUnits itself.</p>
      <p>However, because our algorithm builds just one list
(dimEntry.unitList) of units to convert for each
dimension, whether the units to convert are between
fromUnits and toUnits or within either makes no
difference.</p>
      <p>Conversion between units of different dimensions
necessarily uses domain knowledge. This knowledge
includes the expression used to tie the two dimensions (and
thus implicitly any knowledge on which the stating of that
expression depends). This expression has some limited
scope for which it holds, thus the search for a dimension
converting expression starts with an ontological search
from a most specific (among the smallest) ontological sets
that encompass the subjects of both values and
systematically considers increasingly broader sets.</p>
      <p>At each set it considers all stated dimension conversions
looking for one that converts from the from attribute to the
to attribute. Unlike the algorithms for
sameSingleDimensionalConvert() and
sameMultiDimensionalConvert() which just
used the units being converted, we now must use the
attributes because we are trying to convert between
different but specific aspects of the subject objects.
Further, we assume the attributes imply specific
dimensions.</p>
      <p>Upon finding a candidate dimensional conversion we use
sameMultiDimensionalConvert() to see if we
can convert from the given fromUnits to the units
expected by the expression, and from the units returned by
the expression to the given toUnits. If we find such an
expression and its required auxiliary conversions then we
return that expression in which both auxiliary conversions
have been substituted. We throw an exception otherwise.
This algorithm is given as
differentDimensionalConvert().</p>
      <p>While differentDimensionalConvert() can
use any expression for which it is clever enough to
algebraically manipulate we anticipate many of its
expressions will be simple linear or inverse linear 1/x
functions. For example, conversion from either a photon's
wavenumber in inverse centimeters (as is common in
infrared spectroscopy) or its energy in electron volts (as is
common in material science) to its frequency in Hertz
(inverse seconds) would be built around a simple linear
dimension conversion in which the from units would either
be pre-converted to inverse meters (from cm-1) or to joules
(from eV). Conversion from wavenumbers would tag the
result as depending on the assumptions related to =c/,
including those related to the speed of light c. Conversion
from energy would tag the result as depending on
assumptions related to =E/h, including those related to
Planck's constant h. Conversion from a photon's
wavelength to its frequency would be very similar to its
conversion from wavenumbers, except that it would use an
inverse linear dimension conversion.
&lt;Expression,AssumptionSet&gt;
differentDimensionalConvert
(Subject fromSubj,
Attribute fromAttr,
Units fromUnits,
Subject toSubj,
Attribute toAttr,</p>
      <p>Units toUnits)
begin
Conversion convert;
Units givenFromUnits, givenToUnits;
Expression expr, exprTo, exprFrom;
Set s := mostSpecificCommonSet(fromSubj,toSubj);
while (s != null)
for all convert := s.get(diffDimConvA
(fromAttr,toAttr)
) do
givenFromUnits := convert.get(fromUnitsA);
givenToUnits := convert.get(toUnitsA);
expr := convert.get(exprA);
try
exprFrom :=
sameMultiDimensionalConvert</p>
      <p>(fromUnits,givenFromUnits);
exprTo :=
sameMultiDimensionalConvert</p>
      <p>(givenToUnits,toUnits);
catch InsufficientInformation</p>
      <p>continue;
endCatch
return &lt;exprTo.sub(expr.sub(exprFrom)),</p>
      <p>expr.get(assumptionsA)&gt;
endFor
s := s.get(nextMoreEncompassingSetA)
endWhile
throw new insufficientInformation();
end;</p>
      <p>The algorithm
differentDimensionalConvert() also lets us
handle dimensionless values that have been normalized by
some empirical standard. For example, since the
mid1990s astronomers have found about 500 or so
“exoplanets”, planets in places other than in orbit around our
Sun. One way to detect such planets is by looking for its
gravitational tug on the star which they orbit, and the more
massive the planet the larger the tug, thus many of the
planets that have been found are massive. To keep the
mass numbers in intuitive ranges rather than as “so many
kilograms times 10 to the such-and-such power” it is
common to express them as multiples of the mass of our
own giant, Jupiter.</p>
      <p>
        Conversion from the dimensionless unit MJ (how many
“Jupiters”) to the conventional mass unit kilograms can be
done with differentDimensionalConvert() by
giving the knowledge base a simple linear dimension
conversion rule telling it to convert from attributes with
dimensionless values but normalized units to attributes for
domains with units by multiplying by the normalization
factor (in this case the mass of Jupiter: 1.8986x1027 kg
        <xref ref-type="bibr" rid="ref10">(Williams 2010)</xref>
        ). Although this rule is analytically true
and thus makes no assumptions, many assumptions
probably went in to the normalization factor. Thus the
routine for expr.get(assumptionsA) must be clever
enough to gather the assumptions of normalization factor
too. Additionally, because assumptions are cumulative any
assumption that went into why, for example, we believe
planet Ara b to be 1.68 MJ
        <xref ref-type="bibr" rid="ref1">(Butler et al 2001)</xref>
        , such as our
estimate of the mass of its star Ara, this assumption
would also be included in the resulting value.
      </p>
      <p>This one rule covers a variety of normalizations. For
example, consider the domain of powerful events,
especially nuclear detonations, with its common unit
“kilotons of trinitrotoluene (kT)”. By stating that 1 kiloton
of TNT is 4.184*1012 joules, our system can convert such
values.</p>
    </sec>
    <sec id="sec-4">
      <title>6. Discussion</title>
      <p>We have presented the first automated approach, to the
best of our knowledge, that both tags values with metadata
describing the theory and measurements upon which their
computation depend, and that carries this metadata forward
for the computation of subsequent values.</p>
      <p>At least two outstanding issues remain including
handling data that contradict in terms of accuracy, and how
to handle conversions where the domain knowledge tells us
to consider three or more attributes.</p>
      <p>First, what should we do if one value assumes Jupiter's
mass is 1.8986x1027 kg while a later one assumes it is
1.89857x1027 kg? One could convert between the two by
dividing out what one considers the “less” accurate value
and multiplying with what considers the “more” accurate.
This is arithmetically sound, but what of the assumptions
that went into both kilogram figures for the mass of
Jupiter? They may be contradictory in a deeper manner
than “same formula with more precise numbers used” by,
for example, considering secondary effects (e.g. relativity)
or by being derived from a different formula altogether. In
such cases one could dig deeper to look for potential
contradictions, or take a precautionary stand and throw a
PotentiallyContradictoryAssumption
exception.</p>
      <p>A second problem occurs when we handle the special
relativity equation E=mc2. No dimension conversion is
necessary because both sides have the dimension “energy”.
However, the set applicability of
differentDimensionalConvert() is still needed
because only in certain circumstances like
matterantimatter annihilation do we observe mass to energy
interconversion.</p>
      <p>Even if we add this knowledge and its necessary
restrictions we still have handled only a special case of
matter-antimatter annihilation of particles at rest. If
particles have significant speed then their kinetic energy
also should be considered. This would necessitate revising
differentDimensionalConvert() or writing a
new function to handle multiple attributes (e.g. mass, rest
energy, and relative speed by, for example, the Lorentz
transformations).</p>
    </sec>
    <sec id="sec-5">
      <title>7. Conclusion</title>
      <p>We have presented algorithms and knowledge structures
needed to safely handle interconversion among four types
of units in common usage in the sciences. Further, we
have discussed its limitations.</p>
      <p>
        It would be a mistake to think the solution to the second
issue as merely extending an algorithm over more
attributes. Fundamentally we should give our system the
ability to (re-)define its own dimensions as needed. (The
StructProc knowledgebase is being built with an eye
towards this. This is the reason why we had the word
“fundamental” in quotes when describing dimensions.)
Thus, it should be able to define the Lorentz
transformations, not just apply them. Such searches for
both accurate and at least somewhat intuitive definitions of
time, space, etc. are at the heart of modern physics quest to
unify quantum mechanics with relativity
        <xref ref-type="bibr" rid="ref2 ref6">(Callender 2010,
Musser 2011)</xref>
        .
      </p>
      <p>Artificial intelligence may play a role this search through
the space of representations. If it does we must be clear
about what our systems actually represent and
symbolically manipulate. This paper attempts to do so for
a limited domain.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          <string-name>
            <surname>Butler</surname>
            , R. Paul; Tinney,
            <given-names>C. G.</given-names>
          </string-name>
          ; Marcy, Geoffrey W.; Jones,
          <string-name>
            <surname>Hugh R</surname>
          </string-name>
          . A.; Penny, Alan J.; Apps, Kevin.
          <year>2001</year>
          . “
          <article-title>Two new planets from the Anglo-Australian planet search”</article-title>
          <source>Astrophysical Journal</source>
          .
          <volume>555</volume>
          :
          <fpage>410</fpage>
          -
          <lpage>417</lpage>
          ,
          <year>2001</year>
          <article-title>July 1</article-title>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          <string-name>
            <surname>Callender</surname>
          </string-name>
          , Craig.
          <year>2010</year>
          . “
          <article-title>Is Time an Illusion?</article-title>
          ” Scientific American.
          <year>2010</year>
          June.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          deCarvalho, Rob.
          <year>2006</year>
          . “Simple Units and Dimensions for Matlab”http://www.mathworks.com/matlabcentral/fileexch ange /9873.
          <article-title>Originally appeared Feb 2, updated Mar 3</article-title>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          <string-name>
            <surname>Khanin</surname>
          </string-name>
          , Raya.
          <year>2001</year>
          . “
          <article-title>Dimensional analysis in computer algebra</article-title>
          .”
          <source>International Symposium on Symbolic and Algebraic Computation. ACM</source>
          .
          <year>2001</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          <string-name>
            <surname>Mariano</surname>
          </string-name>
          , Adrian. “
          <article-title>Manual page for GNU Units version 1</article-title>
          .85”
          <year>2004</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          <string-name>
            <surname>Musser</surname>
          </string-name>
          , George.
          <year>2011</year>
          . “
          <article-title>Forces to Reckon With: Does gravity muck up electromagnetism?” Scientific American</article-title>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>2011 February.</mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          <string-name>
            <surname>Phillips</surname>
          </string-name>
          , Joseph.
          <year>2010</year>
          .
          <article-title>“A Proposed Semantics for the Sampled Values and Metadata of Scientific Values</article-title>
          .
          <source>” Midwest Artificial Intelligence and Cognitive Science Conference.</source>
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          <article-title>SunOS “Manual page for SunOS' units command” 1992 Sep 14</article-title>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          <string-name>
            <surname>Williams</surname>
            ,
            <given-names>David R.</given-names>
          </string-name>
          <year>2010</year>
          . “Jupiter Fact Sheet.” http://nssdc.nasa.gov/planetary/factsheet/jupiterfact.html.
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          <source>Last updated 2010 November</source>
          <volume>17</volume>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>