1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-16 22:14:23 +03:00
inform7/docs/kinds-module/3-dmn.html

1681 lines
295 KiB
HTML
Raw Normal View History

2019-03-17 14:40:57 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
2020-04-14 19:56:54 +03:00
<title>Dimensions</title>
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-03-19 02:11:25 +02:00
<meta name="viewport" content="width=device-width initial-scale=1">
2019-03-17 14:40:57 +02:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
2020-05-03 03:01:21 +03:00
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-05-03 03:01:21 +03:00
<script>
MathJax = {
tex: {
inlineMath: '$', '$'], ['\\(', '\\)'
},
svg: {
fontCache: 'global'
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
</script>
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
2020-05-03 03:20:55 +03:00
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
2020-04-14 19:56:54 +03:00
2019-03-17 14:40:57 +02:00
</head>
2020-05-03 03:01:21 +03:00
<body class="commentary-font">
2020-03-19 02:11:25 +02:00
<nav role="navigation">
2020-04-14 19:56:54 +03:00
<h1><a href="../index.html">
2020-05-03 18:34:53 +03:00
<img src="../docs-assets/Inform.png" height=72">
2020-04-14 19:56:54 +03:00
</a></h1>
<ul><li><a href="../compiler.html">compiler tools</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
2020-04-14 19:56:54 +03:00
</ul><h2>Compiler Webs</h2><ul>
2020-03-19 02:11:25 +02:00
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
2020-04-14 19:56:54 +03:00
</ul><h2>Inbuild Modules</h2><ul>
<li><a href="../supervisor-module/index.html">supervisor</a></li>
</ul><h2>Inform7 Modules</h2><ul>
2020-03-19 02:11:25 +02:00
<li><a href="../core-module/index.html">core</a></li>
2020-04-14 19:56:54 +03:00
<li><a href="index.html"><span class="selectedlink">kinds</span></a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
2020-04-14 19:56:54 +03:00
</ul><h2>Inter Modules</h2><ul>
<li><a href="../bytecode-module/index.html">bytecode</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
2020-05-20 02:02:28 +03:00
</ul><h2>Services</h2><ul>
2020-04-14 19:56:54 +03:00
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../html-module/index.html">html</a></li>
2020-05-20 02:02:28 +03:00
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
2020-03-19 02:11:25 +02:00
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
2020-04-14 19:56:54 +03:00
</ul>
2020-03-19 02:11:25 +02:00
</nav>
<main role="main">
2020-05-03 03:01:21 +03:00
<!--Weave of 'Dimensions' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../compiler.html">Services</a></li><li><a href="index.html">kinds</a></li><li><a href="index.html#3">Chapter 3: Arithmetic</a></li><li><b>Dimensions</b></li></ul></div>
2020-05-03 03:01:21 +03:00
<p class="purpose">To keep a small database indicating the physical dimensions of numerical values, and how they combine: for instance, allowing us to specify that a length times a length is an area.</p>
2019-03-17 14:40:57 +02:00
<ul class="toc"><li><a href="3-dmn.html#SP13">&#167;13. Prior kinds</a></li><li><a href="3-dmn.html#SP14">&#167;14. Multiplication lists</a></li><li><a href="3-dmn.html#SP18">&#167;18. Unary operations</a></li><li><a href="3-dmn.html#SP19">&#167;19. Euclid's algorithm</a></li><li><a href="3-dmn.html#SP21">&#167;21. Unit sequences</a></li><li><a href="3-dmn.html#SP29">&#167;29. Performing derivations</a></li><li><a href="3-dmn.html#SP30">&#167;30. Classifying the units</a></li><li><a href="3-dmn.html#SP33">&#167;33. Scaling</a></li><li><a href="3-dmn.html#SP39">&#167;39. Arithmetic on kinds</a></li></ul><hr class="tocbar">
2019-03-17 14:40:57 +02:00
<p class="commentary firstcommentary"><a id="SP1"></a><b>&#167;1. </b>Dimension in this sense is a term drawn from physics. The idea is that when
2019-03-17 14:40:57 +02:00
quantities are multiplied together, their natures are combined as well as
the actual numbers involved. For instance, in
2020-04-14 19:56:54 +03:00
$$ v = f\lambda $$
if the frequency \(f\) of a wave is measured in Hz (counts per second), and
the wavelength \(\lambda\) in m, then the velocity \(v\) must be measured
2019-03-17 14:40:57 +02:00
in m/s: and that is indeed a measure of velocity, so this looks right.
We can tell that the formula
2020-04-14 19:56:54 +03:00
$$ v = f^2\lambda $$
2019-03-17 14:40:57 +02:00
must be wrong because it would result in an acceleration. Physicists use the
term "dimensions" much as Inform uses the term "kinds of value".
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Inform applies dimension-checking to all "quasinumerical" kinds &mdash; those
2019-03-17 14:40:57 +02:00
which can be expressed numerically. The choice of which kinds are quasinumerical
is all done in the I6 template, not built into Inform at the compiler level,
but the standard setup makes number, time, intermediate results of calculations
(see below), and what the Inform documentation calls "units" &mdash; kinds of
value specified by literal patterns.
</p>
<p class="commentary firstcommentary"><a id="SP2"></a><b>&#167;2. </b>Inform divides quasinumerical kinds into three: fundamental units, derived units
2019-03-17 14:40:57 +02:00
with dimensions, and dimensionless units. In the default setup provided by
the template, a typical run has one fundamental unit ("time"), one
dimensionless unit ("number") and &mdash; unless the source text does
something very strange &mdash; no derived units.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">It would no doubt be cool to distinguish these by applying Buckingham's
2020-04-14 19:56:54 +03:00
\(\pi\)-theorem to all the equations we need to use, but this is a tricky
2019-03-17 14:40:57 +02:00
technique and does not always produce the "natural" results which people
expect. Instead, Inform requires the writer to specify explicitly how units
combine.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Number and time are built-in special cases. Further fundamental units are created
2019-03-17 14:40:57 +02:00
every time source text like this is read:
</p>
<blockquote>
<p>Mass is a kind of value. 1kg specifies a mass.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">Derived units only come about when the source text specifies a multiplication
2019-03-17 14:40:57 +02:00
rule. For instance, when Inform reads
</p>
<blockquote>
<p>A mass times an acceleration specifies a force.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">it chooses one of the three units &mdash; say, force &mdash; and derives that from the
2019-03-17 14:40:57 +02:00
others.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Multiplication rules are stored in a linked list associated with left operand;
2020-04-14 19:56:54 +03:00
so that the rule \(A\) times \(B\) specifies \(C\) causes \((B, C)\) to be stored
2020-05-03 03:01:21 +03:00
in the list of <span class="extract"><span class="extract-syntax">multiplications</span></span> belonging to \(A\).
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">multiplications</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<ul class="endnotetexts"><li>The structure dimensional_rules is private to this section.</li><li>The structure dimensional_rule is accessed in 2/kc and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP3"></a><b>&#167;3. </b>The derivation process can be seen in action by feeding Inform
2020-05-03 03:01:21 +03:00
definitions of the SI units (see the test case <span class="extract"><span class="extract-syntax">SIUnits-G</span></span>) and looking at
2019-03-17 14:40:57 +02:00
the output of:
</p>
<blockquote>
<p>Test dimensions (internal) with --.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">(The dash is meaningless &mdash; this is a test with no input.) In the output, we
2019-03-17 14:40:57 +02:00
see that
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> Base units: time, length, mass, elapsed time, electric current, temperature, luminosity</span>
<span class="plain-syntax"> Derived units:</span>
<span class="plain-syntax"> frequency = (elapsed time)-1</span>
<span class="plain-syntax"> force = (length).(mass).(elapsed time)-2</span>
<span class="plain-syntax"> energy = (length)2.(mass).(elapsed time)-2</span>
<span class="plain-syntax"> pressure = (length)-1.(mass).(elapsed time)-2</span>
<span class="plain-syntax"> power = (length)2.(mass).(elapsed time)-3</span>
<span class="plain-syntax"> electric charge = (elapsed time).(electric current)</span>
<span class="plain-syntax"> voltage = (length)2.(mass).(elapsed time)-3.(electric current)-1</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<p class="commentary">...and so on. Those expressions on the right hand sides are "derived units",
2019-03-17 14:40:57 +02:00
where the numbers are powers, so that negative numbers mean division.
It's easy to see why we want to give names and notations for some of
these derived units &mdash; imagine going into a cycle shop and asking for a
2020-04-14 19:56:54 +03:00
\(5 {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-3}\cdot{\rm A}^{-1}\) battery.
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary firstcommentary"><a id="SP4"></a><b>&#167;4. </b>A "dimensionless" quantity is one which is just a number, and is not a
2019-03-17 14:40:57 +02:00
physical measurement as such. In an equation like
2020-04-14 19:56:54 +03:00
$$ K = {{mv^2}\over{2}} $$
2019-03-17 14:40:57 +02:00
the 2 is clearly dimensionless, but other possibilities also exist. The
2020-04-14 19:56:54 +03:00
arc length of part of a circle at radius \(r\) drawn out to angle \(\theta\)
2019-03-17 14:40:57 +02:00
(if measured in radians) is given by:
2020-04-14 19:56:54 +03:00
$$ A = \theta r $$
Here \(A\) and \(r\) are both lengths, so the angle \(\theta\) must be dimensionless.
2019-03-17 14:40:57 +02:00
But clearly it's not quite conceptually the same thing as an ordinary number.
Inform creates new dimensionless quantities this way, too:
</p>
<blockquote>
<p>Angle is a kind of value. 1 rad specifies an angle. Length times angle specifies a length.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">Inform is not quite so careful about distinguishing dimensionless quantities
2019-03-17 14:40:57 +02:00
as some physicists might be. The official SI units distinguish angle, measured
in radians, and solid angle, in steradians, writing them as having units
2020-04-14 19:56:54 +03:00
\({\rm m}\cdot{\rm m}^{-1}\) and \({\rm m}^2\cdot{\rm m}^{-2}\) respectively &mdash;
2019-03-17 14:40:57 +02:00
one is a ratio of lengths, the other of areas. Inform cancels the units
and sees them as dimensionally equal. So if we write:
</p>
<blockquote>
<p>Solid angle is a kind of value. 1 srad specifies an solid angle. Area times solid angle specifies an area.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">then Inform treats angle and solid angle as having the same multiplicative
2019-03-17 14:40:57 +02:00
properties &mdash; but it still allows variables to have either one as a kind of
value, and prints them differently.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Note that a dimensionless unit (other than number) can only get that way
2019-03-17 14:40:57 +02:00
by derivation, so it is always a derived unit, never a fundamental unit.
</p>
<p class="commentary firstcommentary"><a id="SP5"></a><b>&#167;5. </b>In the process of calculations, we often need to create other and nameless
2019-03-17 14:40:57 +02:00
units as partial answers of calculations. Consider the kinetic energy equation
2020-04-14 19:56:54 +03:00
$$ K = {{mv^2}\over{2}} $$
2019-03-17 14:40:57 +02:00
being evaluated the way a computer does it, one step at a time. One way takes
the mass, multiplies by the velocity to get a momentum, multiplies by the
velocity again to get energy, then divides by a dimensionless constant. But
another way would be to square the velocity first, then multiply by mass
to get energy, then halve. If we do it that way, what units are the squared
velocity in? The answer has to be
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> (length)2.(elapsed time)-2</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<p class="commentary">but that's a unit which isn't useful for much, and doesn't have any everyday
2019-03-17 14:40:57 +02:00
name. Inform creates what are called "intermediate kinds" like this in
order to be able to represent the kinds of intermediate values which turn
2020-05-03 03:01:21 +03:00
up in calculation. They use the special <span class="extract"><span class="extract-syntax">CON_INTERMEDIATE</span></span> construction, they
2019-03-17 14:40:57 +02:00
are nameless, and the user isn't allowed to store the results permanently.
(They can't be the kind of a global variable, a table column, and so on.)
If the user wants to deal with such values on a long-term basis, he must give
them a name, like this:
</p>
<blockquote>
<p>Funkiness is a kind of value. 1 Claude is a funkiness. A velocity times a velocity specifies a funkiness.</p>
</blockquote>
<p class="commentary firstcommentary"><a id="SP6"></a><b>&#167;6. </b>Expressions like \({\rm m}^2\cdot{\rm kg}\) are stored inside Inform as
2019-03-17 14:40:57 +02:00
sequences of ordered pairs in the form
2020-04-14 19:56:54 +03:00
$$ ((B_1, p_1), (B_2, p_2), ..., (B_k, p_k)) $$
where each \(B_i\) is the type ID of a fundamental unit, each \(p_i\) is a non-zero
integer, and \(B_1 &lt; B_2 &lt; ... &lt; B_k\). For instance, energy would be
$$ (({\rm length}, 2), ({\rm mass}, 1), ({\rm elapsed~time}, -2)). $$
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Every physically different derived unit has a unique and distinct sequence.
2019-03-17 14:40:57 +02:00
This is only true because a unit sequence is forbidden to contain derived
units. For instance, specific heat capacity looks as if it is written with
two different units in physics:
2020-05-03 03:01:21 +03:00
\(\) {\rm J}\cdot {\rm K}^{-1}\cdot {\rm kg}^{-1} \quad = \quad
{\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1} \(\)
2019-03-17 14:40:57 +02:00
But this is because the Joule is a derived unit. Substituting
2020-04-14 19:56:54 +03:00
\({\rm J} = {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\)
2019-03-17 14:40:57 +02:00
to get back to fundamental units shows that both sides would be computed as the
same unit sequence.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The case \(k=0\), the empty sequence, is not only legal but important: it is
2019-03-17 14:40:57 +02:00
the derivation for a dimensionless unit. (As discussed above, Inform doesn't
see different dimensionless units as being physically different.)
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">unit_pair</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="comment-syntax"> and this really must be a fundamental kind</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax">; </span><span class="comment-syntax"> a non-zero integer</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">unit_pair</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<ul class="endnotetexts"><li>The structure unit_pair is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP7"></a><b>&#167;7. </b>The following is a hard limit, but really not a problematic one. The
2019-03-17 14:40:57 +02:00
entire SI system has only 7 fundamental units, and the only named scientific
unit I've seen which has even 5 terms in its derivation is molar entropy, a
less than everyday chemical measure
2020-04-14 19:56:54 +03:00
(\({\rm kg}\cdot{\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1}\cdot{\rm mol}^{-1}\),
2019-03-17 14:40:57 +02:00
if you're taking notes).
</p>
2020-05-03 03:01:21 +03:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax"> </span><span class="constant-syntax">16</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="comment-syntax"> in range 0 to </span><span class="extract"><span class="extract-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">unit_pair</span><span class="plain-syntax"> </span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">scaling_factor</span><span class="plain-syntax">; </span><span class="comment-syntax"> see discussion of scaling below</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<ul class="endnotetexts"><li>The structure unit_sequence is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP8"></a><b>&#167;8. </b>Manipulating units like \({\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\) looks
2019-03-17 14:40:57 +02:00
a little like manipulating formal polynomials in several variables, and of
course that isn't an accident. Another way of thinking of the above is that
2020-04-14 19:56:54 +03:00
we have a ring \(R\) of underlying numbers but that all arithmetic is done
in a larger ring. For each unit extend by \(R\) by a pair of formal
variables \(U_i\) and \(U_i^{-1}\), and then quotient by the ideal generated
by \(U_jU_j^{-1}\) (so that they are indeed reciprocals of each other, as
2019-03-17 14:40:57 +02:00
the notation suggests) and also by all of the derivations we know of. Thus
Inform calculates in the ring:
2020-05-03 03:01:21 +03:00
\(\) I = R[U_1, U_2, ..., U_n, U_1^{-1}, ..., U_n^{-1}] /
(U_1U_1^{-1}, U_2U_2^{-1}, ..., U_nU_n^{-1}, D_1, D_2, ..., D_i). \(\)
2020-04-14 19:56:54 +03:00
It does that in practice by eliminating all of the \(U_i\) and \(U_i^{-1}\)
2019-03-17 14:40:57 +02:00
which are derived, so that it's left with just
2020-05-03 03:01:21 +03:00
\(\) I = R[U_1, U_2, ..., U_k, U_1^{-1}, ..., U_k^{-1}] /
(U_1U_1^{-1}, U_2U_2^{-1}, ..., U_kU_k^{-1}). \(\)
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">For instance, given seconds, Watts and Joules,
\(\) I = R[{\rm s}, {\rm s}^{-1}, {\rm W}, {\rm W}^{-1}, {\rm J}, {\rm J}^{-1}]/
2020-04-14 19:56:54 +03:00
({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1, {\rm J}{\rm J}^{-1} = 1,
2020-05-03 03:01:21 +03:00
{\rm s}{\rm W} = {\rm J}) \(\)
2020-04-14 19:56:54 +03:00
which by substituting all occurrences of {\rm J} can be reduced to:
2020-05-03 03:01:21 +03:00
\(\) I = R[{\rm s}, {\rm s}^{-1}, {\rm W}, {\rm W}^{-1}]/
({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1). \(\)
2020-04-14 19:56:54 +03:00
Of course there are other ways to calculate \(I\) &mdash; we could have
2019-03-17 14:40:57 +02:00
eliminated any of the three units and kept the other two.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">If the derivations were ever more complex than \(AB=C\), we might have to
2019-03-17 14:40:57 +02:00
use some elegant algorithms for calculating Gröbner bases in order to
2020-04-14 19:56:54 +03:00
determine \(I\). But Inform's syntax is such that the writer of the source
2019-03-17 14:40:57 +02:00
text gives us the simplest possible description of the ideal, so no such
fun occurs.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">What does this ring look like? Because we are not allowed to add terms with
2019-03-17 14:40:57 +02:00
different powers of the variables, we only ever deal with monomials. Thus
2020-04-14 19:56:54 +03:00
we can form \(2{\rm W}{\rm s}^{-1} + 7{\rm W}{\rm s}^{-1}\), but Inform forbids
us to form (say) \(6{\rm J} + 7{\rm W}\). We can therefore picture the ring \(I\)
as a great mass of parallel copies of \(R\). Dimensionless values all live
in \(R\) itself, while energies all live in \(R.{\rm s}.{\rm W}\), powers in \(R.{\rm W}\)
2019-03-17 14:40:57 +02:00
and so on. Addition and subtraction slide values around within their own
parallel copies, but multiplication and division move them from one to
2020-04-14 19:56:54 +03:00
another. The computation \(v_1v_2\) is done in general by calculating the
numerical part (in \(R\)) at run-time, and the units (the choice of which
copy of \(R\)) at compile-time.
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary firstcommentary"><a id="SP9"></a><b>&#167;9. </b>But enough abstraction: time for some arithmetic. Inform performs
2019-03-17 14:40:57 +02:00
checking whenever values from two different kinds are combined by any of
eight arithmetic operations, numbered as follows. The numbers must not
be changed without amending the definitions of "plus" and so on
in the Standard Rules.
</p>
2020-05-03 03:01:21 +03:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">NO_OPERATIONS</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PLUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment-syntax"> addition</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MINUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> subtraction</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="comment-syntax"> multiplication</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax"> </span><span class="comment-syntax"> division</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">REMAINDER_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span><span class="plain-syntax"> </span><span class="comment-syntax"> remainder after division</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">APPROXIMATION_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span><span class="plain-syntax"> </span><span class="comment-syntax"> "X to the nearest Y"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="comment-syntax"> square root &mdash; a unary operation</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">REALROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">7</span><span class="plain-syntax"> </span><span class="comment-syntax"> real-valued square root &mdash; a unary operation</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span><span class="plain-syntax"> </span><span class="comment-syntax"> cube root &mdash; similarly unary</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">EQUALS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">9</span><span class="plain-syntax"> </span><span class="comment-syntax"> set equal &mdash; used only in equations</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">POWER_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">10</span><span class="plain-syntax"> </span><span class="comment-syntax"> raise to integer power &mdash; used only in equations</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">UNARY_MINUS_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">11</span><span class="plain-syntax"> </span><span class="comment-syntax"> unary minus &mdash; used only in equations</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP10"></a><b>&#167;10. </b>The following is associated with "total...", as in "the total weight
2019-03-17 14:40:57 +02:00
of things on the table", but that's a dodge used in the Standard Rules,
and for dimensional purposes we ignore it.
</p>
2020-05-03 03:01:21 +03:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">TOTAL_OPERATION</span><span class="plain-syntax"> </span><span class="constant-syntax">12</span><span class="plain-syntax"> </span><span class="comment-syntax"> not really one of the above</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP11"></a><b>&#167;11. </b>There are two reasons why Inform monitors arithmetic: to keep track of
2019-03-17 14:40:57 +02:00
how it changes kinds, and to preserve scaling factors.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">We start from the principle that not every arithmetic operation can be done,
2019-03-17 14:40:57 +02:00
and that even when it can, the result may have a different kind than the
operand(s) had. For one thing, every arithmetic operation requires that its
operands are quasinumerical &mdash; Inform won't allow a text to be multiplied by
a sound effect. (Occasionally we have thought about allowing text to be
duplicated by multiplication &mdash; 2 times "zig" would be "zigzig", and
maybe similarly for lists &mdash; but it always seemed more likely to be used by
mistake than intentionally.)
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Other restrictions are also applied. For instance, a time cannot be added
2019-03-17 14:40:57 +02:00
to a number, or vice versa; addition, subtraction and approximation require
both operands to have the same units.
</p>
<p class="commentary firstcommentary"><a id="SP12"></a><b>&#167;12. </b>Finally, scaling. Number is straightforwardly an integer kind:
2019-03-17 14:40:57 +02:00
it holds whole numbers. But other quasinumerical kinds can be stored
using scaled, fixed-point arithmetic. In general for each named unit
2020-04-14 19:56:54 +03:00
\(U\) (fundamental or derived) there is a positive integer \(k_U\) such that the
true value \(v\) is stored at run-time as the I6 integer \(k_U v\). We call
2019-03-17 14:40:57 +02:00
this the scaled value.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">For example, if the text reads:
2019-03-17 14:40:57 +02:00
</p>
<blockquote>
<p>Force is a kind of value. 1N specifies a force scaled up by 1000.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">then \(k = 1000\) and the value 1N will be stored at run-time as <span class="extract"><span class="extract-syntax">1000</span></span>;
2019-03-17 14:40:57 +02:00
forces can thus be calculated to a true value accuracy of at best 0.001N,
2020-05-03 03:01:21 +03:00
stored at run-time as <span class="extract"><span class="extract-syntax">1</span></span>.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">It must be emphasised that this is scaled, fixed-point arithmetic: there
2019-03-17 14:40:57 +02:00
are no mantissas or exponents. In such schemes the scale factor is usually
2020-04-14 19:56:54 +03:00
\(2^{16}\) or some similar power of 2, but here we want to use exactly the
2019-03-17 14:40:57 +02:00
scale factors laid out by the source text &mdash; partly because the user
knows best, partly so that it is unambiguous how to print values, partly
so that source text like "0.001N" determines an exact value rather than
being approximated by a binary equivalent.
</p>
<p class="commentary firstcommentary"><a id="SP13"></a><b>&#167;13. Prior kinds. </b>It turns out to be convenient to have a definition ordering of fundamental kinds,
2020-04-14 19:56:54 +03:00
which is completely unlike the \(\leq\) relation; it just places them in
2019-03-17 14:40:57 +02:00
order of creation.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_prior</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></span>:<br/><a href="3-dmn.html#SP23_4">&#167;23.4</a>, <a href="3-dmn.html#SP29_1">&#167;29.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">A</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP8" class="function-link"><span class="function-syntax">Kinds::get_construct</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">A</span><span class="plain-syntax">)-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> &lt; </span><a href="2-knd.html#SP8" class="function-link"><span class="function-syntax">Kinds::get_construct</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">)-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP14"></a><b>&#167;14. Multiplication lists. </b>The linked lists of multiplication rules begin empty for every kind:
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::dim_initialise</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::dim_initialise</span></span>:<br/>Kind Constructors - <a href="2-kc2.html#SP6_1">&#167;6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">multiplications</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP15"></a><b>&#167;15. </b>And this adds a new one to the relevant list:
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::record_multiplication_rule</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::record_multiplication_rule</span></span>:<br/><a href="3-dmn.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP20" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dim_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplications</span><span class="plain-syntax">; </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">; </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">right</span><span class="plain-syntax"> == </span><span class="identifier-syntax">right</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionRedundant_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">right</span><span class="plain-syntax"> = </span><span class="identifier-syntax">right</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outcome</span><span class="plain-syntax"> = </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">)</span>
2020-05-11 17:21:29 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Node::get_text</span><span class="plain-syntax">(</span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">EMPTY_WORDING</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplications</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">multiplications</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP16"></a><b>&#167;16. </b>The following loop-header macro iterates through the possible triples
2020-04-14 19:56:54 +03:00
\((L, R, O)\) of multiplication rules \(L\times R = O\).
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">LOOP_OVER_MULTIPLICATIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rules</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">dimensional_rule</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP20" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dim_rules</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left_operand</span><span class="plain-syntax">),</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">multiplications</span><span class="plain-syntax">):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)):-1,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">right</span><span class="plain-syntax">):0,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outcome</span><span class="plain-syntax">):0;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wn</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)):-1,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">right_operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">right</span><span class="plain-syntax">):0,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">outcome_type</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">)?(</span><span class="identifier-syntax">dimr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outcome</span><span class="plain-syntax">):0)</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP17"></a><b>&#167;17. </b>And this is where the user asks for a multiplication to come out in a
2019-03-17 14:40:57 +02:00
particular way:
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::dim_set_multiplication</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="2-knd.html#SP10" class="function-link"><span class="function-syntax">Kinds::is_proper_constructor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionNotBaseKOV_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">NonDimensional_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP15" class="function-link"><span class="function-syntax">Kinds::Dimensions::record_multiplication_rule</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP29" class="function-link"><span class="function-syntax">Kinds::Dimensions::make_unit_derivation</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP18"></a><b>&#167;18. Unary operations. </b>All we need to know is which ones are unary, in fact, and:
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></span>:<br/><a href="3-dmn.html#SP39">&#167;39</a>, <a href="3-dmn.html#SP39_1">&#167;39.1</a>, <a href="3-dmn.html#SP39_2">&#167;39.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CUBEROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP19"></a><b>&#167;19. Euclid's algorithm. </b>In my entire life, I believe this is the only time I have ever actually
2019-03-17 14:40:57 +02:00
used Euclid's algorithm for the GCD of two natural numbers. I've never
quite understood why textbooks take this as somehow the typical algorithm.
My maths students always find it a little oblique, despite the almost
trivial proof that it works. I find it hard to visualise myself, for that
2020-04-14 19:56:54 +03:00
matter. And then, consider that the average number of iterations \(\tau_n\),
2019-03-17 14:40:57 +02:00
in effect its running time, is known to be
2020-04-14 19:56:54 +03:00
$$ \tau_n = {{12\log 2}\over{\pi^2}}\log n + (4P + 5/2) + O(n^{-1/6+\epsilon) $$
for any \(\epsilon&gt;0\), where \(P\) is defined in terms of an integral, Euler's
2019-03-17 14:40:57 +02:00
constant, and an evaluation of the derivative of the Riemann zeta function
&mdash; see D. E. Knuth, `Evaluation of Porter's Constant', reprinted in
"Selected Papers on Analysis of Algorithms" (Stanford: CSLI Lecture Notes
2020-04-14 19:56:54 +03:00
102, 2000). In practice, a shade under \(\log n\) steps, then, which is nicely
2019-03-17 14:40:57 +02:00
quick. But I don't look at the code and immediately see this, myself.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::gcd</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::gcd</span></span>:<br/><a href="3-dmn.html#SP20">&#167;20</a><br/>Scaled Arithmetic Values - <a href="3-sav.html#SP8_2_2">&#167;8.2.2</a>, <a href="3-sav.html#SP20_1_2">&#167;20.1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">m</span><span class="plain-syntax">&lt;1) || (</span><span class="identifier-syntax">n</span><span class="plain-syntax">&lt;1)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"applied Kinds::Dimensions::gcd outside natural numbers"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rem</span><span class="plain-syntax"> = </span><span class="identifier-syntax">m</span><span class="plain-syntax">%</span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rem</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">; </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rem</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP20"></a><b>&#167;20. </b>The sequence of operation here is to reduce the risk of integer overflows
2020-05-03 03:01:21 +03:00
when multiplying <span class="extract"><span class="extract-syntax">m</span></span> by <span class="extract"><span class="extract-syntax">n</span></span>.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::lcm</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::lcm</span></span>:<br/><a href="3-dmn.html#SP39_4">&#167;39.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m</span><span class="plain-syntax">/</span><a href="3-dmn.html#SP19" class="function-link"><span class="function-syntax">Kinds::Dimensions::gcd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">m</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">))*</span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP21"></a><b>&#167;21. Unit sequences. </b>Given a fundamental type \(B\), convert it to a unit sequence: \(B = B^1\), so we
2020-04-14 19:56:54 +03:00
get a sequence with a single pair: \(((B, 1))\). Uniquely, "number" is born
2019-03-17 14:40:57 +02:00
derived and dimensionless, though, so that comes out as the empty sequence.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::fundamental_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::fundamental_unit_sequence</span></span>:<br/>Kind Constructors - <a href="2-kc2.html#SP6_1">&#167;6.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_unit_pairs</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> redundant, but appeases </span><span class="extract"><span class="extract-syntax">gcc -O2</span></span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">no_unit_pairs</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="identifier-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">B</span><span class="plain-syntax">; </span><span class="identifier-syntax">us</span><span class="plain-syntax">.</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[0].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP22"></a><b>&#167;22. </b>As noted above, two units represent dimensionally equivalent physical
2019-03-17 14:40:57 +02:00
quantities if and only if they are identical, which makes comparison easy:
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></span>:<br/><a href="3-dmn.html#SP29_4">&#167;29.4</a>, <a href="3-dmn.html#SP39">&#167;39</a>, <a href="3-dmn.html#SP39_3">&#167;39.3</a><br/>Kind Checking - <a href="2-kc.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">ik2</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ik1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">ik2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> != </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
2020-05-09 15:07:39 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;ik1-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) ||</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax"> != </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP23"></a><b>&#167;23. </b>We now have three fundamental operations we can perform on unit sequences.
2020-05-03 03:01:21 +03:00
First, we can multiply them: that is, we store in <span class="extract"><span class="extract-syntax">result</span></span> the unit
2020-04-14 19:56:54 +03:00
sequence representing \(X_1^{s_1}X_2^{s_2}\), where \(X_1\) and \(X_2\) are
2020-05-03 03:01:21 +03:00
represented by unit sequences <span class="extract"><span class="extract-syntax">us1</span></span> and <span class="extract"><span class="extract-syntax">us2</span></span>.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">So the case \(s_1 = s_2 = 1\) represents multiplying \(X_1\) by \(X_2\), while
2020-04-14 19:56:54 +03:00
\(s_1 = 1, s_2 = -1\) represents dividing \(X_1\) by \(X_2\). But we can also
2019-03-17 14:40:57 +02:00
raise to higher powers.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Our method relies on noting that
\(\) X_1 = T_{11}^{p_{11}}\cdot T_{12}^{p_{12}}\cdots T_{1n}^{p_{1n}},\qquad
X_2 = T_{21}^{p_{21}}\cdot T_{22}^{p_{22}}\cdots T_{2m}^{p_{2m}} \(\)
2020-04-14 19:56:54 +03:00
where \(T_{11} &lt; T_{12} &lt; ... &lt; T_{1n}\) and \(T_{21}&lt;T_{22}&lt;...&lt;T_{2m}\). We
2019-03-17 14:40:57 +02:00
can therefore merge the two in a single pass.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">On each iteration of the loop the variables <span class="extract"><span class="extract-syntax">i1</span></span> and <span class="extract"><span class="extract-syntax">i2</span></span> are our current
2019-03-17 14:40:57 +02:00
read positions in each sequence, while we are currently looking at the
2020-05-03 03:01:21 +03:00
unit pairs (<span class="extract"><span class="extract-syntax">t1</span></span>, <span class="extract"><span class="extract-syntax">m1</span></span>) and (<span class="extract"><span class="extract-syntax">t2</span></span>, <span class="extract"><span class="extract-syntax">m2</span></span>). The following symmetrical
2019-03-17 14:40:57 +02:00
algorithm holds on to each pair until the one from the other sequence has had
a chance to catch up with it, because we always deal with the pair with the
2020-05-03 03:01:21 +03:00
numerically lower <span class="extract"><span class="extract-syntax">t</span></span> first. This also proves that the <span class="extract"><span class="extract-syntax">results</span></span> sequence comes
2019-03-17 14:40:57 +02:00
out in numerical order.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></span>:<br/><a href="3-dmn.html#SP25_2">&#167;25.2</a>, <a href="3-dmn.html#SP29_2">&#167;29.2</a>, <a href="3-dmn.html#SP29_4">&#167;29.4</a>, <a href="3-dmn.html#SP39">&#167;39</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us1</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s1</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">s2</span><span class="plain-syntax">,</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">result</span><span class="plain-syntax"> == </span><span class="identifier-syntax">us1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">result</span><span class="plain-syntax"> == </span><span class="identifier-syntax">us2</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"result must be different structure"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">i2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> read position in sequences 1, 2</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p1</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> start with no current term from sequence 1</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="comment-syntax"> start with no current term from sequence 2</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_1" class="named-paragraph-link"><span class="named-paragraph">If we have no current term from sequence 1, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_2" class="named-paragraph-link"><span class="named-paragraph">If we have no current term from sequence 2, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t1</span><span class="plain-syntax">, </span><span class="identifier-syntax">t2</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; </span><span class="comment-syntax"> both sequences have now run out</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3" class="named-paragraph-link"><span class="named-paragraph">Both terms refer to the same fundamental unit, so combine these into the result</span><span class="named-paragraph-number">23.3</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_4" class="named-paragraph-link"><span class="named-paragraph">The terms refer to different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">23.4</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">KIND_CREATIONS</span><span class="plain-syntax">, </span><span class="string-syntax">"Multiplication: $Q * $Q = $Q\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">us1</span><span class="plain-syntax">, </span><span class="identifier-syntax">us2</span><span class="plain-syntax">, </span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP23_1"></a><b>&#167;23.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If we have no current term from sequence 1, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">us1</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i1</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i1</span><span class="plain-syntax">].</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="identifier-syntax">p1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i1</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">i1</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">&#167;23</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23_2"></a><b>&#167;23.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">If we have no current term from sequence 2, and it hasn't run out, fetch a new one</span><span class="named-paragraph-number">23.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">us2</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">i2</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i2</span><span class="plain-syntax">].</span><span class="identifier-syntax">fund_unit</span><span class="plain-syntax">; </span><span class="identifier-syntax">p2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i2</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">i2</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">&#167;23</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23_3"></a><b>&#167;23.3. </b>So here the head of one sequence is \(T^{p_1}\) and the head of the other
2020-05-03 03:01:21 +03:00
is \(T^{p_2}\), so in the product we ought to see $(T^{p_1})^{s_1}\cdot
(T^{p_2})^{s_2} = T^{p_1s_1+p_2s_2}$. But we don't enter terms that have
2020-04-14 19:56:54 +03:00
cancelled out, that is, where \(p_1s_1+p_2s_2\) = 0.
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Both terms refer to the same fundamental unit, so combine these into the result</span><span class="named-paragraph-number">23.3</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p1</span><span class="plain-syntax">*</span><span class="identifier-syntax">s1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">p2</span><span class="plain-syntax">*</span><span class="identifier-syntax">s2</span><span class="plain-syntax">; </span><span class="comment-syntax"> combined power of </span><span class="extract"><span class="extract-syntax">t1</span></span><span class="comment-syntax"> </span>\(=\)<span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">t2</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of both terms as dealt with</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">&#167;23</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23_4"></a><b>&#167;23.4. </b>Otherwise we copy. By copying the numerically lower term, we can be sure
2019-03-17 14:40:57 +02:00
that it will never occur again in either sequence. So we can copy it straight
into the results.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The code is slightly warped by the fact that <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span>, representing the
2019-03-17 14:40:57 +02:00
end of the sequence, happens to be numerically lower than all the valid
kinds. We don't want to make use of facts like that, so we write code
2020-05-03 03:01:21 +03:00
to deal with <span class="extract"><span class="extract-syntax">UNKNOWN_NT</span></span> explicitly.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">The terms refer to different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">23.4</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || ((</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t1</span><span class="plain-syntax">, </span><span class="identifier-syntax">t2</span><span class="plain-syntax">)))) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p1</span><span class="plain-syntax">*</span><span class="identifier-syntax">s1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">t1</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of the head of sequence 1 as dealt with</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || ((</span><span class="identifier-syntax">t2</span><span class="plain-syntax"> != </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) &amp;&amp; (</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">t2</span><span class="plain-syntax">, </span><span class="identifier-syntax">t1</span><span class="plain-syntax">)))) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">MAX_BASE_UNITS_IN_SEQUENCE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP23_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax"> = </span><span class="identifier-syntax">t2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">++].</span><span class="element-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">p2</span><span class="plain-syntax">*</span><span class="identifier-syntax">s2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">t2</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="comment-syntax"> dispose of the head of sequence 1 as dealt with</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unit pairs disarrayed"</span><span class="plain-syntax">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">&#167;23</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP23_3_1"></a><b>&#167;23.3.1. </b>For reasons explained above, this is really never going to happen by
2019-03-17 14:40:57 +02:00
accident, but we'll be careful:
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Trip a unit sequence overflow</span><span class="named-paragraph-number">23.3.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">UnitSequenceOverflow_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23_3">&#167;23.3</a>, <a href="3-dmn.html#SP23_4">&#167;23.4</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP24"></a><b>&#167;24. </b>The second operation is taking roots.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Surprisingly, perhaps, it's much easier to compute \(\sqrt{X}\) or
2020-04-14 19:56:54 +03:00
\(^{3}\sqrt{X}\) for any unit \(X\) &mdash; it's just that it can't always be done.
2019-03-17 14:40:57 +02:00
Inform does not permit non-integer powers of units, so for instance
2020-04-14 19:56:54 +03:00
\(\sqrt{{\rm time}}\) does not exist, whereas \(\sqrt{{\rm length}^2\cdot{\rm mass}^{-2}}\)
2019-03-17 14:40:57 +02:00
does. Square roots exist if each power in the sequence is even, cube roots
2020-05-03 03:01:21 +03:00
exist if each is divisible by 3. We return <span class="extract"><span class="extract-syntax">TRUE</span></span> or <span class="extract"><span class="extract-syntax">FALSE</span></span> according to
whether the root could be taken, and if <span class="extract"><span class="extract-syntax">FALSE</span></span> then the contents of
<span class="extract"><span class="extract-syntax">result</span></span> are undefined.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></span>:<br/><a href="3-dmn.html#SP39">&#167;39</a>, <a href="3-dmn.html#SP40">&#167;40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pow</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">us</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">us</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">;</span>
2020-05-09 15:07:39 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;result-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">) % </span><span class="identifier-syntax">pow</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">result</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">)/</span><span class="identifier-syntax">pow</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP25"></a><b>&#167;25. </b>The final operation on unit sequences is substitution. Given a fundamental type
2020-04-14 19:56:54 +03:00
\(B\), we substitute \(B = K_D\) into an existing unit sequence \(K_E\). (This is
used when \(B\) is becoming a derived type &mdash; once we discover that \(B=K_D\),
we are no longer allowed to keep \(B\) in any unit sequence.)
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">We simply search for \(B^p\), and if we find it, we remove it and then
2020-04-14 19:56:54 +03:00
multiply by \(K_D^p\).
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::dim_substitute</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::dim_substitute</span></span>:<br/><a href="3-dmn.html#SP29_3">&#167;29.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">derived</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
2020-05-09 15:07:39 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;existing-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP25_1" class="named-paragraph-link"><span class="named-paragraph">Remove the B term from the existing sequence</span><span class="named-paragraph-number">25.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">found</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP25_2" class="named-paragraph-link"><span class="named-paragraph">Multiply the existing sequence by a suitable power of B's derivation</span><span class="named-paragraph-number">25.2</span></a></span><span class="plain-syntax">;</span>
2020-05-09 15:07:39 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP25_1"></a><b>&#167;25.1. </b>We shuffle the remaining terms in the sequence down by one, overwriting B:
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Remove the B term from the existing sequence</span><span class="named-paragraph-number">25.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-05-09 15:07:39 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=</span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="function-syntax">&lt;existing-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">-1; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">] = </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">+1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">--;</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP25_2"></a><b>&#167;25.2. </b>We now multiply by \(K_D^p\).
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Multiply the existing sequence by a suitable power of B's derivation</span><span class="named-paragraph-number">25.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">derived</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP25">&#167;25</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP26"></a><b>&#167;26. </b>For reasons which will be explained below, a unit sequence also has
2019-03-17 14:40:57 +02:00
a scale factor associated with it:
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::us_get_scaling_factor</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::us_get_scaling_factor</span></span>:<br/>Using Kinds - <a href="2-uk.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">us</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">us</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">scaling_factor</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP27"></a><b>&#167;27. </b>That just leaves, as usual, indexing...
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::index_unit_sequence</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::index_unit_sequence</span></span>:<br/><a href="3-dmn.html#SP31_2">&#167;31.2</a><br/>Describing Kinds - <a href="2-dk.html#SP24_1">&#167;24.1</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">briefly</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"dimensionless"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
2020-05-09 15:07:39 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="function-syntax">&lt;deriv-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax"> = </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax"> = </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">briefly</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"("</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> #</span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><a href="2-dk.html#SP22" class="function-link"><span class="function-syntax">Kinds::Textual::write</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> #</span><span class="identifier-syntax">endif</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">")"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;sup&gt;%d&lt;/sup&gt;"</span><span class="plain-syntax">, </span><span class="identifier-syntax">power</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" times "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">power</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">power</span><span class="plain-syntax">; </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"reciprocal of "</span><span class="plain-syntax">); }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP1" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">fundamental</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%W"</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" squared"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">: </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" cubed"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" to the power %d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">power</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP28"></a><b>&#167;28. </b>...and logging.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::logger</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::logger</span></span>:<br/>Kinds Module - <a href="1-km.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">vUS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">vUS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null-us&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"dimensionless"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">j</span><span class="function-syntax">&lt;deriv-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">&gt;0) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"(%u)"</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">fund_unit</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="identifier-syntax">power</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%d"</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">].</span><span class="element-syntax">power</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP29"></a><b>&#167;29. Performing derivations. </b>The following is called when the user specifies that \(L\) times \(R\) specifies
2020-04-14 19:56:54 +03:00
an \(O\). These are required all to be quasinumerical: any of the three might
2019-03-17 14:40:57 +02:00
be either a fundamental unit (so far) or a derived unit (already).
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">If two or more are fundamental units, we have a choice. That is, suppose we have
2019-03-17 14:40:57 +02:00
created three kinds already: mass, acceleration, force. Then we read:
</p>
<blockquote>
<p>Mass times acceleration specifies a force.</p>
</blockquote>
2020-05-03 03:01:21 +03:00
<p class="commentary">We could make this true in any of three ways: keep M and A as fundamental units
2019-03-17 14:40:57 +02:00
and derive F from them, keep A and F as fundamental units and derive M from those,
or keep M and F while deriving A. Inform always chooses the most recently
created unit as the one to derive, on the grounds that the source text has
probably set things out with what the user thinks are the most fundamental
units first.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::make_unit_derivation</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::make_unit_derivation</span></span>:<br/><a href="3-dmn.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">left</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">right</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outcome</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[3];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0] = </span><span class="identifier-syntax">left</span><span class="plain-syntax">; </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1] = </span><span class="identifier-syntax">right</span><span class="plain-syntax">; </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2] = </span><span class="identifier-syntax">outcome</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">newest_term</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_1" class="named-paragraph-link"><span class="named-paragraph">Find which (if any) of the three units is the newest-made fundamental unit</span><span class="named-paragraph-number">29.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_2" class="named-paragraph-link"><span class="named-paragraph">Derive the newest one by rearranging the equation in terms of the other two</span><span class="named-paragraph-number">29.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_3" class="named-paragraph-link"><span class="named-paragraph">Substitute this new derivation to eliminate this fundamental unit from other sequences</span><span class="named-paragraph-number">29.3</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP29_4" class="named-paragraph-link"><span class="named-paragraph">Check this derivation to make sure it is redundant, not contradictory</span><span class="named-paragraph-number">29.4</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP29_1"></a><b>&#167;29.1. </b>Data type IDs are allocated in creation order, so "newest" means largest ID.
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Find which (if any) of the three units is the newest-made fundamental unit</span><span class="named-paragraph-number">29.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;3; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP13" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_prior</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">max</span><span class="plain-syntax">, </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">])) &amp;&amp; (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::test_if_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">newest_term</span><span class="plain-syntax"> = </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">max</span><span class="plain-syntax"> = </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29_2"></a><b>&#167;29.2. </b>We need to ensure that the user's multiplication rule is henceforth true,
2019-03-17 14:40:57 +02:00
and we do that by fixing the newest unit to make it so.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Derive the newest one by rearranging the equation in terms of the other two</span><span class="named-paragraph-number">29.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, *</span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">; </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">sy</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(L\)<span class="comment-syntax"> is newest and we derive </span>\(L = R^{-1}O\)
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]); </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2]); </span><span class="identifier-syntax">sy</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(R\)<span class="comment-syntax"> is newest and we derive </span>\(R = L^{-1}O\)
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]); </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2]); </span><span class="identifier-syntax">sy</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span><span class="plain-syntax">: </span><span class="comment-syntax"> here </span>\(O\)<span class="comment-syntax"> is newest and we derive </span>\(O = LR\)
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]); </span><span class="identifier-syntax">sx</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ky</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]); </span><span class="identifier-syntax">sy</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kx</span><span class="plain-syntax">, </span><span class="identifier-syntax">sx</span><span class="plain-syntax">, </span><span class="identifier-syntax">ky</span><span class="plain-syntax">, </span><span class="identifier-syntax">sy</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> *</span><span class="identifier-syntax">derivation</span><span class="plain-syntax"> = </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::now_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">]);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29_3"></a><b>&#167;29.3. </b>Later in Inform's run, when we start compiling code, many more unit sequences
2019-03-17 14:40:57 +02:00
will exist on a temporary basis &mdash; as part of the kinds for intermediate results
in calculations &mdash; but early on, when we're here, the only unit sequences made
are the derivations of the units. So it is easy to cover all of them.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Substitute this new derivation to eliminate this fundamental unit from other sequences</span><span class="named-paragraph-number">29.3</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP25" class="function-link"><span class="function-syntax">Kinds::Dimensions::dim_substitute</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">terms</span><span class="plain-syntax">[</span><span class="identifier-syntax">newest_term</span><span class="plain-syntax">], </span><span class="identifier-syntax">derivation</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP29_4"></a><b>&#167;29.4. </b>If we have \(AB = C\) but all three of \(A\), \(B\), \(C\) are already derived,
2019-03-17 14:40:57 +02:00
that puts us in a bind. Their definitions are fixed already, so we can't
simply force the equation to come true by fixing one of them. That means
either the derivation is redundant &mdash; because it's already true that
2020-04-14 19:56:54 +03:00
\(AB = C\) &mdash; or contradictory &mdash; because we know \(AB\neq C\). We silently
2019-03-17 14:40:57 +02:00
allow a redundancy, as it may have been put in for clarity, or so that
the user can check the consistency of his own definitions, or to make
the Kinds index page more helpful. But we must reject a contradiction.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check this derivation to make sure it is redundant, not contradictory</span><span class="named-paragraph-number">29.4</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">product</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[0]), </span><span class="constant-syntax">1</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[1]), </span><span class="constant-syntax">1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">product</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">product</span><span class="plain-syntax">,</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">terms</span><span class="plain-syntax">[2])) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="1-km.html#SP5" class="function-link"><span class="function-syntax">KindsModule::problem_handler</span></a><span class="plain-syntax">(</span><span class="constant-syntax">DimensionsInconsistent_KINDERROR</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP29">&#167;29</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP30"></a><b>&#167;30. Classifying the units. </b>Some of the derived units are dimensionless, others not. Number
2019-03-17 14:40:57 +02:00
is always dimensionless; and any unit whose derivation is the empty
unit sequence must be dimensionless.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::dimensionless</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></span>:<br/><a href="3-dmn.html#SP31_2">&#167;31.2</a>, <a href="3-dmn.html#SP32">&#167;32</a>, <a href="3-dmn.html#SP39_1">&#167;39.1</a>, <a href="3-dmn.html#SP40">&#167;40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">));</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></span>:<br/><a href="3-dmn.html#SP39_2">&#167;39.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">us</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">us</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">us</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP31"></a><b>&#167;31. </b>Using these definitions, we can now print analyses of the units into the
2019-03-17 14:40:57 +02:00
index and the debugging log.
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::index_dimensional_rules</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG</span><span class="plain-syntax">(</span><span class="string-syntax">"hr"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_1" class="named-paragraph-link"><span class="named-paragraph">Index the rubric about quasinumerical kinds</span><span class="named-paragraph-number">31.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_2" class="named-paragraph-link"><span class="named-paragraph">Index the table of quasinumerical kinds</span><span class="named-paragraph-number">31.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_3" class="named-paragraph-link"><span class="named-paragraph">Index the table of multiplication rules</span><span class="named-paragraph-number">31.3</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP31_1"></a><b>&#167;31.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the rubric about quasinumerical kinds</span><span class="named-paragraph-number">31.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"a"</span><span class="plain-syntax">, </span><span class="string-syntax">"calculator"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_TAG_WITH</span><span class="plain-syntax">(</span><span class="string-syntax">"img"</span><span class="plain-syntax">, </span><span class="string-syntax">"border=0 src=inform:/doc_images/calc2.png"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;nbsp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"Kinds of value marked with the &lt;b&gt;calculator symbol&lt;/b&gt; are numerical - "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"these are values we can add, multiply and so on. The range of these "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"numbers depends on the Format setting for the project (Glulx format "</span>
<span class="plain-syntax"> </span><span class="string-syntax">"supports much higher numbers than Z-code)."</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_2"></a><b>&#167;31.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the table of quasinumerical kinds</span><span class="named-paragraph-number">31.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;kind of value&lt;/b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;minimum&lt;/b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;maximum&lt;/b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;b&gt;dimensions&lt;/b&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_2_1" class="named-paragraph-link"><span class="named-paragraph">Index the minimum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.1</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP31_2_2" class="named-paragraph-link"><span class="named-paragraph">Index the maximum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.2</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;i&gt;dimensionless&lt;/i&gt;"</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP27" class="function-link"><span class="function-syntax">Kinds::Dimensions::index_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">, </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_2_1"></a><b>&#167;31.2.1. </b>At run-time, the minimum positive value is of course <span class="extract"><span class="extract-syntax">1</span></span>, but because of
2019-03-17 14:40:57 +02:00
scaling this can appear to be much lower.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the minimum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"1"</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP35" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_index_minimum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31_2">&#167;31.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_2_2"></a><b>&#167;31.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the maximum positive value for a quasinumerical kind</span><span class="named-paragraph-number">31.2.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">())) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"32767"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"2147483647"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP35" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_index_maximum_value</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Str::len</span><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TargetVMs::is_16_bit</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::vm</span><span class="plain-syntax">()))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">32767</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::list_of_literal_forms</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">), </span><span class="constant-syntax">2147483647</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31_2">&#167;31.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP31_3"></a><b>&#167;31.3. </b>This is simply a table of all the multiplications declared in the source
2019-03-17 14:40:57 +02:00
text, sorted into kind order of left and then right operand.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Index the table of multiplication rules</span><span class="named-paragraph-number">31.3</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, *</span><span class="identifier-syntax">R</span><span class="plain-syntax">, *</span><span class="identifier-syntax">O</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">NP</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_MULTIPLICATIONS</span><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NP</span><span class="plain-syntax">++ == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"This is how multiplication changes kinds:"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML_OPEN</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_plain_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::first_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">wn</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">Index::link</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">wn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" x "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" = "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Kinds::Index::index_kind</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">, </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::next_html_column</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" x "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::begin_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"808080"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">" = "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_colour</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LiteralPatterns::index_benchmark_value</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">O</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HTML::end_html_row</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">NP</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">HTML::end_html_table</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">); </span><span class="identifier-syntax">HTML_CLOSE</span><span class="plain-syntax">(</span><span class="string-syntax">"p"</span><span class="plain-syntax">); }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">&#167;31</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP32"></a><b>&#167;32. </b>A simpler format for the debugging log, which is printed when we ask for
2019-03-17 14:40:57 +02:00
the internal "dimensions" test:
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::log_unit_analysis</span><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Dimensionless: "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">); }</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\nBase units: "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP32" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> { </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax">++ &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">", "</span><span class="plain-syntax">); </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">); }</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"\nDerived units:\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP32" class="function-link"><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)) &amp;&amp; (</span><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">deriv</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%u = $Q\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">deriv</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_is_derived</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP9" class="function-link"><span class="function-syntax">Kinds::is_intermediate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::is_quasinumerical</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::test_if_derived</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP33"></a><b>&#167;33. Scaling. </b>Recall that every quasinumerical kind \(U\) has a scale factor \(k_U\), by
2020-04-14 19:56:54 +03:00
default 1 and always \(\geq 1\), such that the true value \(v\) is represented
at runtime as the I6 integer \(k_U v\). For instance, if length is measured
2019-03-17 14:40:57 +02:00
in metres but has a scale factor of 1000 then the I6 integer 1 means the
true value 1mm, 10 means 1cm, 1000 means 1m. This I6 integer is called
2020-04-14 19:56:54 +03:00
the scaled value \(s\), and to reiterate, \(s = k_U v\).
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">Scaled values are convenient, and they have no effect on how we add, subtract,
2019-03-17 14:40:57 +02:00
approximate (that is, round off) or take remainder after division. If we
2020-04-14 19:56:54 +03:00
have true values \(v_1\) and \(v_2\) with scaled values \(s_1\) and \(s_2\),
and \(s_o\) is the scaled value for true value \(v_1+v_2\), then
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">$$ s_1 + s_2 = k_Uv_1 + k_Uv_2 = k_U(v_1+v_2) = s_o. $$
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">So ordinary I6 <span class="extract"><span class="extract-syntax">+</span></span> at run-time correctly adds scaled values. But that's
2019-03-17 14:40:57 +02:00
not true for all operations, and this is where we deal with that.
</p>
<p class="commentary firstcommentary"><a id="SP34"></a><b>&#167;34. </b>First, multiplication. This time the values \(v_1\) and \(v_2\) may have
2020-04-14 19:56:54 +03:00
different kinds, which we'll call \(X\) and \(Y\), and the result in general
will be a third kind, which we'll call \(O\) (for outcome). Then:
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">$$ s_1s_2 = k_Xv_1\cdot k_Yv_2 = k_Ov_1v_2\cdot\left({{k_Xk_Y}\over{k_O}}\right) = s_o\cdot\left({{k_Xk_Y}\over{k_O}}\right) $$
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">so that simply multiplying the scaled values produces an answer which is
2020-04-14 19:56:54 +03:00
too large by a factor of \(k_Xk_Y/k_O\). We need to correct for that, which
2019-03-17 14:40:57 +02:00
we do either by dividing by this factor or multiplying by its reciprocal.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">This is all a little delicate since rounding errors may be an issue and
2020-04-14 19:56:54 +03:00
since \(k_Xk_Y/k_O\) is itself evaluated in integer arithmetic. In an ideal
world we might use the same \(k\) for many units (e.g., \(k=1000\) throughout)
and then of course this cancels to just \(1000\). But in practice people
2019-03-17 14:40:57 +02:00
won't always do this &mdash; they may use some Babylonian, base 60, units, such
2020-04-14 19:56:54 +03:00
as minutes and degrees, for instance, where \(k=3600\) would be more natural.
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_multiplication</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"*%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_multiplication_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_multiplication_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
2020-07-01 02:58:55 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_O</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP35"></a><b>&#167;35. </b>Second, division, which is similar.
2020-05-03 03:01:21 +03:00
\(\) {{s_1}\over{s_2}} = {{k_Xv_1}\over{k_Yv_2}} = k_O{{v_1}\over{v_2}}\cdot\left({{k_X}\over{k_Ok_Y}}\right)
= s_o\cdot\left({{k_X}\over{k_Ok_Y}\right) \(\)
2020-04-14 19:56:54 +03:00
so this time the excess to correct is a factor of \(k_X/k_Ok_Y\).
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_division</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"*%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_division_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_division_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">kindy</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">kindy</span><span class="plain-syntax">, </span><span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindy</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
2020-07-01 02:58:55 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_Y</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP36"></a><b>&#167;36. </b>Third, the taking of \(p\)th roots, at any rate for \(p=2\) or \(p=3\).
2020-05-03 03:01:21 +03:00
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_root</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUTPUT_STREAM</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP36_1" class="named-paragraph-link"><span class="named-paragraph">Apply a scaling correction for square roots</span><span class="named-paragraph-number">36.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP36_2" class="named-paragraph-link"><span class="named-paragraph">Apply a scaling correction for cube roots</span><span class="named-paragraph-number">36.2</span></a></span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP36_1"></a><b>&#167;36.1. </b>For square roots,
2020-05-03 03:01:21 +03:00
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
2020-05-03 03:01:21 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
2019-03-17 14:40:57 +02:00
this way accuracy losses in taking the square root are much reduced.
Therefore this scaling operating is to be performed inside the root
2020-04-14 19:56:54 +03:00
function, not outside, and it scales by \(k^2\) not \(k\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Apply a scaling correction for square roots</span><span class="named-paragraph-number">36.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"*%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">));</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP36">&#167;36</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP36_2"></a><b>&#167;36.2. </b>For cube roots,
2020-05-03 03:01:21 +03:00
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
2020-05-03 03:01:21 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
the rooting function, we scale by \(k^3\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Apply a scaling correction for cube roots</span><span class="named-paragraph-number">36.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"*%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"/%d"</span><span class="plain-syntax">, (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">));</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP36">&#167;36</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP37"></a><b>&#167;37. </b></p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_root_emit_op</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP37_1" class="named-paragraph-link"><span class="named-paragraph">Emit a scaling correction for square roots</span><span class="named-paragraph-number">37.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP37_2" class="named-paragraph-link"><span class="named-paragraph">Emit a scaling correction for cube roots</span><span class="named-paragraph-number">37.2</span></a></span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP37_1"></a><b>&#167;37.1. </b>For square roots,
2020-05-03 03:01:21 +03:00
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
2020-05-03 03:01:21 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
2019-03-17 14:40:57 +02:00
this way accuracy losses in taking the square root are much reduced.
Therefore this scaling operating is to be performed inside the root
2020-04-14 19:56:54 +03:00
function, not outside, and it scales by \(k^2\) not \(k\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit a scaling correction for square roots</span><span class="named-paragraph-number">37.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP37">&#167;37</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP37_2"></a><b>&#167;37.2. </b>For cube roots,
2020-05-03 03:01:21 +03:00
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
2020-05-03 03:01:21 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
the rooting function, we scale by \(k^3\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit a scaling correction for cube roots</span><span class="named-paragraph-number">37.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">TIMES_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::inv_primitive</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">DIVIDE_BIP</span><span class="plain-syntax">); </span><span class="identifier-syntax">Produce::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP37">&#167;37</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38"></a><b>&#167;38. </b></p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">ifdef</span><span class="plain-syntax"> </span><span class="identifier-syntax">CORE_MODULE</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_rescale_root_emit_factor</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">power</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindx</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">ROOT_OPERATION</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">CUBEROOT_OPERATION</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">kindo</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_X</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindx</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">kindo</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP38_1" class="named-paragraph-link"><span class="named-paragraph">Emit factor for a scaling correction for square roots</span><span class="named-paragraph-number">38.1</span></a></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">power</span><span class="plain-syntax"> == </span><span class="constant-syntax">3</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP38_2" class="named-paragraph-link"><span class="named-paragraph">Emit factor for a scaling correction for cube roots</span><span class="named-paragraph-number">38.2</span></a></span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can only scale square and cube roots"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="plain-syntax">#</span><span class="identifier-syntax">endif</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP38_1"></a><b>&#167;38.1. </b>For square roots,
2020-05-03 03:01:21 +03:00
\(\) \sqrt{s} = \sqrt{k_Xv} = \sqrt{k_X}\sqrt{v} = k_O\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) = s_o \cdot
2020-05-03 03:01:21 +03:00
\left({{\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and now the overestimate is a factor of \(k = \sqrt{k_X}/k_O\). However,
rather than calculating \(k\sqrt{x}\) we calculate \(\sqrt{k^2 x}\), since
2019-03-17 14:40:57 +02:00
this way accuracy losses in taking the square root are much reduced.
Therefore this scaling operating is to be performed inside the root
2020-04-14 19:56:54 +03:00
function, not outside, and it scales by \(k^2\) not \(k\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit factor for a scaling correction for square roots</span><span class="named-paragraph-number">38.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-07-01 02:58:55 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP38_2"></a><b>&#167;38.2. </b>For cube roots,
2020-05-03 03:01:21 +03:00
\(\) {}^3\sqrt{s} = {}^3\sqrt{k_Xv} = {}^3\sqrt{k_X}{}^3\sqrt{v} = k_O{}^3\sqrt{v}\cdot
2020-04-14 19:56:54 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) = s_o\cdot
2020-05-03 03:01:21 +03:00
\left({{{}^3\sqrt{k_X}}\over{k_O}}\right) \(\)
2020-04-14 19:56:54 +03:00
and the overestimate is \(k = {}^3\sqrt{k_X}/k_O\). Scaling once again within
the rooting function, we scale by \(k^3\):
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Emit factor for a scaling correction for cube roots</span><span class="named-paragraph-number">38.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
2020-07-01 02:58:55 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">*</span><span class="identifier-syntax">k_O</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">k_X</span><span class="plain-syntax">) { </span><span class="identifier-syntax">Produce::val</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">, </span><span class="identifier-syntax">LITERAL_IVAL</span><span class="plain-syntax">, (</span><span class="identifier-syntax">inter_ti</span><span class="plain-syntax">) (</span><span class="identifier-syntax">k_X</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">/</span><span class="identifier-syntax">k_O</span><span class="plain-syntax">)); </span><span class="identifier-syntax">Produce::up</span><span class="plain-syntax">(</span><span class="identifier-syntax">Emit::tree</span><span class="plain-syntax">()); }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP38">&#167;38</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39"></a><b>&#167;39. Arithmetic on kinds. </b>We are finally able to provide our central routine, the one providing a service
2020-05-03 03:01:21 +03:00
for the rest of Inform. Given <span class="extract"><span class="extract-syntax">K1</span></span> and <span class="extract"><span class="extract-syntax">K2</span></span>, we return the kind resulting
from applying arithmetic operation <span class="extract"><span class="extract-syntax">op</span></span>, or <span class="extract"><span class="extract-syntax">NULL</span></span> if the operation cannot
meaningfully be applied. In the case where <span class="extract"><span class="extract-syntax">op</span></span> is a unary operation, <span class="extract"><span class="extract-syntax">K2</span></span>
has no significance and should be <span class="extract"><span class="extract-syntax">NULL</span></span>.
</p>
<p class="commentary">The kinds here are called operands, because they are what will be operated on.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></span>:<br/><a href="3-dmn.html#SP34">&#167;34</a>, <a href="3-dmn.html#SP35">&#167;35</a>, <a href="3-dmn.html#SP36">&#167;36</a>, <a href="3-dmn.html#SP37">&#167;37</a>, <a href="3-dmn.html#SP38">&#167;38</a>, <a href="3-dmn.html#SP40">&#167;40</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">K1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">K2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">operand1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand2</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">operand2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">op</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PLUS_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">MINUS_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">EQUALS_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">APPROXIMATION_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">)) {</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REMAINDER_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNARY_MINUS_OPERATION:</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">ROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">REALROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">2</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CUBEROOT_OPERATION:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">3</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">)</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">TIMES_OPERATION:</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIVIDE_OPERATION:</span>
<span class="plain-syntax"> </span><a href="3-dmn.html#SP23" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand1</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand2</span><span class="plain-syntax">, -1, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_1" class="named-paragraph-link"><span class="named-paragraph">Handle calculations entirely between dimensionless units more delicately</span><span class="named-paragraph-number">39.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_2" class="named-paragraph-link"><span class="named-paragraph">Handle the case of a dimensionless result</span><span class="named-paragraph-number">39.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_3" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_4" class="named-paragraph-link"><span class="named-paragraph">And otherwise create a kind as the intermediate result of a calculation</span><span class="named-paragraph-number">39.4</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="commentary firstcommentary"><a id="SP39_1"></a><b>&#167;39.1. </b>If <span class="extract"><span class="extract-syntax">result</span></span> is the empty unit sequence, we'll identify it as a number,
2019-03-17 14:40:57 +02:00
because number is the lowest type ID representing a dimensionless unit.
Usually that's good: for instance, it says that a frequency times a time
is a number, and not some more exotic dimensionless quantity like an angle.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">But it's not so good when the calculation is not really physical at all, but
2019-03-17 14:40:57 +02:00
purely mathematical, and all we are doing is working on dimensionless units.
2020-04-14 19:56:54 +03:00
For instance, if take an angle \(\theta\) and double it to \(2\theta\), we don't
want Inform to say the result is number &mdash; we want \(2\theta\) to be
2019-03-17 14:40:57 +02:00
another angle. So we make an exception.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle calculations entirely between dimensionless units more delicately</span><span class="named-paragraph-number">39.1</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">op</span><span class="plain-syntax"> == </span><span class="constant-syntax">REALROOT_OPERATION</span><span class="plain-syntax">) &amp;&amp; (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)))</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-kc.html#SP9" class="function-link"><span class="function-syntax">Kinds::Compare::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">, </span><span class="identifier-syntax">K2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K1</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">&#167;39</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39_2"></a><b>&#167;39.2. </b>It's also possible to get a dimensionless result by, for example, dividing
2019-03-17 14:40:57 +02:00
a mass by another mass, and we need to be careful to keep track of whether
we're using real or integer arithmetic: 1500.0m divided by 10.0m must be
150.0, not 150.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Handle the case of a dimensionless result</span><span class="named-paragraph-number">39.2</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_op_is_unary</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">op</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">)) ||</span>
<span class="plain-syntax"> (</span><a href="3-fv.html#SP3" class="function-link"><span class="function-syntax">Kinds::FloatingPoint::uses_floating_point</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_real_number</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">&#167;39</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39_3"></a><b>&#167;39.3. </b>If we've produced the right combination of fundamental units to make one of the
2019-03-17 14:40:57 +02:00
named units, then we return that as an atomic kind. For instance, maybe we
2020-05-03 03:01:21 +03:00
divided a velocity by a time, and now we find that we have ${\rm m}\cdot
{\rm s}^{-2}$, which turns out to have a name: acceleration.
2019-03-17 14:40:57 +02:00
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_BASE_KINDS</span><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP22" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">,</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">;</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">&#167;39</a>, <a href="3-dmn.html#SP40">&#167;40</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP39_4"></a><b>&#167;39.4. </b>Otherwise the <span class="extract"><span class="extract-syntax">result</span></span> is a unit sequence which doesn't have a name, so
2019-03-17 14:40:57 +02:00
we store it as an intermediate kind, representing a temporary value living
only for the duration of a calculation.
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">A last little wrinkle is: how we should scale this? For results like an
2019-03-17 14:40:57 +02:00
acceleration, something defined in the source text, we know how accurate the
author wants us to be. But these intermediate kinds are not defined, and we
don't know for sure what the author would want. It seems wise to set
2020-04-14 19:56:54 +03:00
\(k \geq k_X\) and \(k\geq k_Y\), so that we have at least as much detail as
2019-03-17 14:40:57 +02:00
the calculation would have had within each operand kind. So perhaps we should
2020-05-03 03:01:21 +03:00
put \(k = {\rm max}(k_X, k_Y)\). But in fact we will choose \(k\) = <span class="extract"><span class="extract-syntax">Kinds::Dimensions::lcm(k_X, k_Y)</span></span>,
2019-03-17 14:40:57 +02:00
the least common multiple, so that any subsequent divisions will cancel
correctly and we won't lose too much information through integer rounding.
2020-04-14 19:56:54 +03:00
(In practice this will probably either be the same as \({\rm max}(k_X, k_Y)\)
2020-05-03 03:01:21 +03:00
or will multiply by 6, since <span class="extract"><span class="extract-syntax">Kinds::Dimensions::lcm(60, 1000) == 6000</span></span> and so on.)
2019-03-17 14:40:57 +02:00
</p>
2020-05-03 03:01:21 +03:00
<p class="commentary">The same unit sequence can have different scalings each time it appears as
2020-04-14 19:56:54 +03:00
an intermediate calculation. We could get to \({\rm m}^2\cdot {\rm kg}\)
either as \({\rm m}\cdot{\rm kg}\) times \({\rm m}\), or as \({\rm m^2}\) times
\({\rm kg}\), or many other ways, and we'll get different scalings depending
2020-05-03 03:01:21 +03:00
on the route. This is why the <span class="extract"><span class="extract-syntax">unit_sequence</span></span> structure has a
<span class="extract"><span class="extract-syntax">scaling_factor</span></span> field; the choice of scale factor does not depend on
2019-03-17 14:40:57 +02:00
the physics but on the arithmetic method being used.
</p>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">And otherwise create a kind as the intermediate result of a calculation</span><span class="named-paragraph-number">39.4</span></span><span class="comment-syntax"> =</span>
2020-05-03 03:01:21 +03:00
</p>
2019-03-17 14:40:57 +02:00
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">.</span><span class="identifier-syntax">scaling_factor</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::lcm</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K1</span><span class="plain-syntax">), </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::scale_factor</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K2</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-knd.html#SP3_1" class="function-link"><span class="function-syntax">Kinds::intermediate_construction</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
2019-03-17 14:40:57 +02:00
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP39">&#167;39</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP40"></a><b>&#167;40. </b></p>
2020-05-03 03:01:21 +03:00
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="function-syntax">Kinds::Dimensions::to_rational_power</span><span class="plain-syntax">(</span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bad rational power"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP30" class="function-link"><span class="function-syntax">Kinds::Dimensions::dimensionless</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">kind</span><span class="plain-syntax"> *</span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><span class="identifier-syntax">K_number</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">op</span><span class="plain-syntax"> = </span><span class="constant-syntax">TIMES_OPERATION</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = -</span><span class="identifier-syntax">n</span><span class="plain-syntax">; </span><span class="identifier-syntax">op</span><span class="plain-syntax"> = </span><span class="constant-syntax">DIVIDE_OPERATION</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax"> = </span><a href="3-dmn.html#SP39" class="function-link"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">op</span><span class="plain-syntax">);</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">K</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unit_sequence</span><span class="plain-syntax"> *</span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP19" class="function-link"><span class="function-syntax">Kinds::Behaviour::get_dimensional_form</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">K</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="3-dmn.html#SP24" class="function-link"><span class="function-syntax">Kinds::Dimensions::root_unit_sequence</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">, </span><span class="identifier-syntax">m</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">result</span><span class="plain-syntax">) == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP39_3" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">39.3</span></a></span><span class="plain-syntax">;</span>
2020-05-03 03:01:21 +03:00
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
2019-03-17 14:40:57 +02:00
</pre>
2020-05-03 03:01:21 +03:00
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="2-dk.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-km.html">1</a></li><li class="progresschapter"><a href="2-knd.html">2</a></li><li class="progresscurrentchapter">3</li><li class="progresscurrent">dmn</li><li class="progresssection"><a href="3-fv.html">fv</a></li><li class="progresssection"><a href="3-sav.html">sav</a></li><li class="progresschapter"><a href="4-kf.html">4</a></li><li class="progressnext"><a href="3-fv.html">&#10095;</a></li></ul></div>
2020-05-03 03:01:21 +03:00
</nav><!--End of weave-->
2019-03-17 14:40:57 +02:00
2020-03-19 02:11:25 +02:00
</main>
2019-03-17 14:40:57 +02:00
</body>
</html>