mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
1177 lines
196 KiB
HTML
1177 lines
196 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Dimensions</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<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">
|
|
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
|
|
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
|
|
|
|
<script src="../docs-assets/Bigfoot.js"></script>
|
|
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<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>
|
|
|
|
<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">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Inform.png" height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../compiler.html">compiler tools</a></li>
|
|
<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>
|
|
</ul><h2>Compiler Webs</h2><ul>
|
|
<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>
|
|
</ul><h2>Inbuild Modules</h2><ul>
|
|
<li><a href="../supervisor-module/index.html">supervisor</a></li>
|
|
</ul><h2>Inform7 Modules</h2><ul>
|
|
<li><a href="../core-module/index.html">core</a></li>
|
|
<li><a href="../assertions-module/index.html">assertions</a></li>
|
|
<li><a href="../values-module/index.html">values</a></li>
|
|
<li><a href="../knowledge-module/index.html">knowledge</a></li>
|
|
<li><a href="../imperative-module/index.html">imperative</a></li>
|
|
<li><a href="../runtime-module/index.html">runtime</a></li>
|
|
<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>
|
|
</ul><h2>Inter Modules</h2><ul>
|
|
<li><a href="../bytecode-module/index.html">bytecode</a></li>
|
|
<li><a href="../building-module/index.html">building</a></li>
|
|
<li><a href="../codegen-module/index.html">codegen</a></li>
|
|
</ul><h2>Services</h2><ul>
|
|
<li><a href="../arch-module/index.html">arch</a></li>
|
|
<li><a href="../calculus-module/index.html">calculus</a></li>
|
|
<li><a href="../html-module/index.html">html</a></li>
|
|
<li><a href="../inflections-module/index.html">inflections</a></li>
|
|
<li><a href="index.html"><span class="selectedlink">kinds</span></a></li>
|
|
<li><a href="../linguistics-module/index.html">linguistics</a></li>
|
|
<li><a href="../problems-module/index.html">problems</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="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--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>
|
|
<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>
|
|
|
|
<ul class="toc"><li><a href="3-dmn.html#SP11">§11. Prior kinds</a></li><li><a href="3-dmn.html#SP12">§12. Multiplication lists</a></li><li><a href="3-dmn.html#SP16">§16. Unary operations</a></li><li><a href="3-dmn.html#SP17">§17. Euclid's algorithm</a></li><li><a href="3-dmn.html#SP19">§19. Unit sequences</a></li><li><a href="3-dmn.html#SP28">§28. Performing derivations</a></li><li><a href="3-dmn.html#SP29">§29. Classifying the units</a></li><li><a href="3-dmn.html#SP30">§30. Logging</a></li><li><a href="3-dmn.html#SP31">§31. Arithmetic on kinds</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. </b>We sort quasinumerical kinds<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> into three: fundamental units, derived units
|
|
with dimensions, and dimensionless units. In the default setup provided by
|
|
a work of IF generated by Inform, there is one fundamental unit ("time"),
|
|
there are two dimensionless units ("number" and "real number") and no derived
|
|
units. Dimension checking does very little in this minimal environment, though
|
|
it will, for example, forbid an attempt to multiply 10 PM by 9:15 AM, or
|
|
indeed to multiply kinds which aren't numberical at all, such as a text by a
|
|
sound effect.<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>
|
|
</p>
|
|
|
|
<p class="commentary">Further fundamental units are created every time source text like this is read:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Mass is a kind of value. 1kg specifies a mass.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Mass will then be considered fundamental until the source text says otherwise.
|
|
It would no doubt be cool to decide what is fundamental and what is derived by
|
|
applying Buckingham's \(\pi\)-theorem to all the equations we need to use, but
|
|
this is a tricky technique and does not always produce the "natural" results
|
|
which people expect. So Inform requires the writer to specify explicitly
|
|
how units combine. When it reads, for example,
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>A mass times an acceleration specifies a force.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Inform chooses one of the three units — say, force — and derives that from
|
|
the others.
|
|
</p>
|
|
|
|
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> Basically, any kind on which arithmetic can be done. To test this, call
|
|
<a href="2-uk.html#SP17" class="internal">Kinds::Behaviour::is_quasinumerical</a>.
|
|
<a href="#fnref:1" title="return to text"> ↩</a></p></li><li class="footnote" id="fn:2"><p class="inwebfootnote"><sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> Occasionally we have thought about allowing text to be duplicated by
|
|
multiplication — 2 times "zig" would be "zigzig", and maybe similarly for
|
|
lists — but it always seemed more likely to be used by mistake than intentionally.
|
|
<a href="#fnref:2" title="return to text"> ↩</a></p></li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>Multiplication rules are stored in a linked list associated with the left
|
|
operand; so that the rule \(A\) times \(B\) specifies \(C\) causes \((B, C)\) to be
|
|
stored in the list of <span class="extract"><span class="extract-syntax">multiplications</span></span> belonging to \(A\).
|
|
</p>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure dimensional_rules is private to this section.</li><li>The structure dimensional_rule is accessed in 2/tlok and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>The derivation process can be seen in action by feeding Inform
|
|
definitions of the SI units (see the test case <span class="extract"><span class="extract-syntax">SIUnits-G</span></span>) and looking at
|
|
the output of:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Test dimensions (internal) with --.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">(The dash is meaningless — this is a test with no input.) In the output, we
|
|
see that
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<p class="commentary">...and so on. Those expressions on the right hand sides are "derived units",
|
|
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 — imagine going into a cycle shop and asking for a
|
|
\(5 {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-3}\cdot{\rm A}^{-1}\) battery.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>A "dimensionless" quantity is one which is just a number, and is not a
|
|
physical measurement as such. In an equation like
|
|
$$ K = {{mv^2}\over{2}} $$
|
|
the 2 is clearly dimensionless, but other possibilities also exist. The
|
|
arc length of part of a circle at radius \(r\) drawn out to angle \(\theta\)
|
|
(if measured in radians) is given by:
|
|
$$ A = \theta r $$
|
|
Here \(A\) and \(r\) are both lengths, so the angle \(\theta\) must be dimensionless.
|
|
But clearly it's not quite conceptually the same thing as an ordinary number.
|
|
Inform deduces dimensionlessness from multiplication laws like so:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Angle is a kind of value. 1 rad specifies an angle. Length times angle specifies a length.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">Inform is not quite so careful about distinguishing dimensionless quantities
|
|
as some physicists might be. The official SI units distinguish angle, measured
|
|
in radians, and solid angle, in steradians, writing them as having units
|
|
\({\rm m}\cdot{\rm m}^{-1}\) and \({\rm m}^2\cdot{\rm m}^{-2}\) respectively —
|
|
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>
|
|
|
|
<p class="commentary">then Inform treats angle and solid angle as having the same multiplicative
|
|
properties — but it still allows variables to have either one as a kind of
|
|
value, and prints them differently.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. </b>In the process of calculations, we often need to create other and nameless
|
|
units as partial answers of calculations. Consider the kinetic energy equation
|
|
$$ K = {{mv^2}\over{2}} $$
|
|
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>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> (length)2.(elapsed time)-2</span>
|
|
</pre>
|
|
<p class="commentary">but that's a unit which isn't useful for much, and doesn't have any everyday
|
|
name. Inform creates what are called "intermediate kinds" like this in
|
|
order to be able to represent the kinds of intermediate values which turn
|
|
up in calculation. They use the special <span class="extract"><span class="extract-syntax">CON_INTERMEDIATE</span></span> construction, they
|
|
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" class="paragraph-anchor"></a><b>§6. </b>Expressions like \({\rm m}^2\cdot{\rm kg}\) are stored inside Inform as
|
|
sequences of ordered pairs in the form
|
|
$$ ((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 < B_2 < ... < B_k\). For instance, energy would be
|
|
$$ (({\rm length}, 2), ({\rm mass}, 1), ({\rm elapsed~time}, -2)). $$
|
|
</p>
|
|
|
|
<p class="commentary">Every physically different derived unit has a unique and distinct sequence.
|
|
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:
|
|
$$ {\rm J}\cdot {\rm K}^{-1}\cdot {\rm kg}^{-1} \quad = \quad {\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1} $$
|
|
But this is because the Joule is a derived unit. Substituting
|
|
\({\rm J} = {\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\)
|
|
to get back to fundamental units shows that both sides would be computed as the
|
|
same unit sequence.
|
|
</p>
|
|
|
|
<p class="commentary">The case \(k=0\), the empty sequence, is not only legal but important: it is
|
|
the derivation for a dimensionless unit. (As discussed above, Inform doesn't
|
|
see different dimensionless units as being physically different.)
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure unit_pair is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>The following is a hard limit, but really not a problematic one. The
|
|
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
|
|
(\({\rm kg}\cdot{\rm m}^2\cdot{\rm s}^{-2}\cdot{\rm K}^{-1}\cdot{\rm mol}^{-1}\),
|
|
if you're taking notes).
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure unit_sequence is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>Manipulating units like \({\rm m}^2\cdot{\rm kg}\cdot{\rm s}^{-2}\) looks
|
|
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
|
|
we have a commutative ring \(R\) of underlying numbers, and extend by a pair of
|
|
formal variables \(U_i\) and \(U_i^{-1}\) for each new kind, then quotient by the
|
|
ideal generated by \(U_jU_j^{-1}\) and also by all of the derivations we know of.
|
|
Thus Inform calculates in the ring:
|
|
$$ 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). $$
|
|
It does that in practice by eliminating all of the \(U_i\) and \(U_i^{-1}\)
|
|
which are derived, so that it's left with just
|
|
$$ 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}). $$
|
|
</p>
|
|
|
|
<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}]/ ({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1, {\rm J}{\rm J}^{-1} = 1, {\rm s}{\rm W} = {\rm J}) $$
|
|
which by substituting all occurrences of J can be reduced to:
|
|
$$ I = R[{\rm s}, {\rm s}^{-1}, {\rm W}, {\rm W}^{-1}]/ ({\rm s}{\rm s}^{-1} = 1, {\rm W}{\rm W}^{-1}=1). $$
|
|
Of course there are other ways to calculate \(I\) — we could have
|
|
eliminated any of the three units and kept the other two.
|
|
</p>
|
|
|
|
<p class="commentary">If the derivations were ever more complex than \(AB=C\), we might have to
|
|
use some elegant algorithms for calculating Gröbner bases in order to
|
|
determine \(I\). But Inform's syntax is such that the writer of the source
|
|
text gives us the simplest possible description of the ideal, so no such
|
|
fun occurs.
|
|
</p>
|
|
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. </b>But enough abstraction: time for some arithmetic. Inform performs
|
|
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 Basic Inform extension.
|
|
</p>
|
|
|
|
<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 — 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 — 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 — 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 — 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 — 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 — used only in equations</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>The following is associated with "total...", as in "the total weight
|
|
of things on the table", but for dimensional purposes we ignore it.
|
|
</p>
|
|
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. Prior kinds. </b>It turns out to be convenient to have a definition ordering of fundamental kinds,
|
|
which is completely unlike the \(\leq\) relation; it just places them in
|
|
order of creation.
|
|
</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::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#SP21_4">§21.4</a>, <a href="3-dmn.html#SP28_1">§28.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>
|
|
<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#SP11" 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">)-></span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax"> <</span>
|
|
<span class="plain-syntax"> </span><a href="2-knd.html#SP11" 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">)-></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>
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. Multiplication lists. </b>The linked lists of multiplication rules begin empty for every kind:
|
|
</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::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="4-kc2.html#SP9_1">§9.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>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. </b>And this adds a new one to the relevant list:
|
|
</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#SP15">§15</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>
|
|
<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#SP18" 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">-></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">-></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">-></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><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<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">-></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">-></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>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">dimr_new</span><span class="plain-syntax">-></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>
|
|
<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">-></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">-></span><span class="element-syntax">next</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dimrs</span><span class="plain-syntax">-></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">-></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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. </b>The following loop-header macro iterates through the possible triples
|
|
\((L, R, O)\) of multiplication rules \(L\times R = O\).
|
|
</p>
|
|
|
|
<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#SP18" 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">-></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">-></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">-></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">-></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">-></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">-></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">-></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">-></span><span class="element-syntax">outcome</span><span class="plain-syntax">):0)</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. </b>And this is where the user asks for a multiplication to come out in a
|
|
particular way:
|
|
</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::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#SP13" 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#SP13" 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#SP13" 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><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<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#SP17" 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#SP17" 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#SP17" 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><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<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#SP13" 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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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">)) && (</span><a href="2-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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">)) && (</span><a href="2-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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#SP28" 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>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. Unary operations. </b>All we need to know is which ones are unary, in fact, and:
|
|
</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#SP31">§31</a>, <a href="3-dmn.html#SP31_2">§31.2</a>, <a href="3-dmn.html#SP31_3">§31.3</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>
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>§17. Euclid's algorithm. </b>In my entire life, I believe this is the only time I have ever actually
|
|
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. It typically takes a shade under \(\log n\) steps,
|
|
which is nicely quick. But I don't look at the code and immediately see this, myself.
|
|
</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::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#SP18">§18</a><br/>Scaled Arithmetic Values - <a href="3-sav.html#SP13_2_2">§13.2.2</a>, <a href="3-sav.html#SP25_1_2">§25.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>
|
|
<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"><1) || (</span><span class="identifier-syntax">n</span><span class="plain-syntax"><1)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"applied 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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>§18. </b>The sequence of operation here is to reduce the risk of integer overflows
|
|
when multiplying <span class="extract"><span class="extract-syntax">m</span></span> by <span class="extract"><span class="extract-syntax">n</span></span>.
|
|
</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::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#SP31_4">§31.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#SP17" 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>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>§19. Unit sequences. </b>Given a fundamental type \(B\), convert it to a unit sequence: \(B = B^1\), so we
|
|
get a sequence with a single pair: \(((B, 1))\). Uniquely, <span class="extract"><span class="extract-syntax">number</span></span> is born
|
|
derived and dimensionless, though, so that comes out as the empty sequence.
|
|
</p>
|
|
|
|
<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="4-kc2.html#SP9_1">§9.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>
|
|
<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="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">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 compilers</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="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">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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>§20. </b>As noted above, two units represent dimensionally equivalent physical
|
|
quantities if and only if they are identical, which makes comparison easy:
|
|
</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::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#SP28_4">§28.4</a>, <a href="3-dmn.html#SP31_1">§31.1</a>, <a href="3-dmn.html#SP23_1">§23.1</a><br/>Kinds - <a href="2-knd.html#SP24">§24</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>
|
|
<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">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax"> != </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-></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>
|
|
<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"><ik1-></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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-></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="plain-syntax"> </span><span class="identifier-syntax">ik2</span><span class="plain-syntax">-></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>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">ik1</span><span class="plain-syntax">-></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">-></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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>§21. </b>We now have three fundamental operations we can perform on unit sequences.
|
|
First, we can multiply them: that is, we store in <span class="extract"><span class="extract-syntax">result</span></span> the unit
|
|
sequence representing \(X_1^{s_1}X_2^{s_2}\), where \(X_1\) and \(X_2\) are
|
|
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>.
|
|
</p>
|
|
|
|
<p class="commentary">So the case \(s_1 = s_2 = 1\) represents multiplying \(X_1\) by \(X_2\), while
|
|
\(s_1 = 1, s_2 = -1\) represents dividing \(X_1\) by \(X_2\). But we can also
|
|
raise to higher powers.
|
|
</p>
|
|
|
|
<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}} \(\)
|
|
where \(T_{11} < T_{12} < ... < T_{1n}\) and \(T_{21}<T_{22}<...<T_{2m}\). We
|
|
can therefore merge the two in a single pass.
|
|
</p>
|
|
|
|
<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
|
|
read positions in each sequence, while we are currently looking at the
|
|
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
|
|
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
|
|
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
|
|
out in numerical order.
|
|
</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::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#SP24_2">§24.2</a>, <a href="3-dmn.html#SP28_2">§28.2</a>, <a href="3-dmn.html#SP28_4">§28.4</a>, <a href="3-dmn.html#SP31_1">§31.1</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="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><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">-></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#SP21_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">21.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#SP21_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">21.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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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>
|
|
<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#SP21_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">21.3</span></a></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="named-paragraph-container code-font"><a href="3-dmn.html#SP21_4" class="named-paragraph-link"><span class="named-paragraph">Different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">21.4</span></a></span><span class="plain-syntax">;</span>
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP21_1" class="paragraph-anchor"></a><b>§21.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">21.1</span></span><span class="comment-syntax"> =</span>
|
|
</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">t1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">us1</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">i1</span><span class="plain-syntax"> < </span><span class="identifier-syntax">us1</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP21">§21</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP21_2" class="paragraph-anchor"></a><b>§21.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">21.2</span></span><span class="comment-syntax"> =</span>
|
|
</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">us2</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">i2</span><span class="plain-syntax"> < </span><span class="identifier-syntax">us2</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP21">§21</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP21_3" class="paragraph-anchor"></a><b>§21.3. </b>So here the head of one sequence is \(T^{p_1}\) and the head of the other
|
|
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
|
|
cancelled out, that is, where \(p_1s_1+p_2s_2\) = 0.
|
|
</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">21.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<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">-></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#SP21_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">21.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP21">§21</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP21_4" class="paragraph-anchor"></a><b>§21.4. </b>Otherwise we copy. By copying the numerically lower term, we can be sure
|
|
that it will never occur again in either sequence. So we can copy it straight
|
|
into the results.
|
|
</p>
|
|
|
|
<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
|
|
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
|
|
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">Different fundamental units, so copy the numerically lower one into the result</span><span class="named-paragraph-number">21.4</span></span><span class="comment-syntax"> =</span>
|
|
</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">) && (</span><a href="3-dmn.html#SP11" 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>
|
|
<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="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#SP21_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">21.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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">) && (</span><a href="3-dmn.html#SP11" 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>
|
|
<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="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#SP21_3_1" class="named-paragraph-link"><span class="named-paragraph">Trip a unit sequence overflow</span><span class="named-paragraph-number">21.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">result</span><span class="plain-syntax">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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">-></span><span class="element-syntax">unit_pairs</span><span class="plain-syntax">[</span><span class="identifier-syntax">result</span><span class="plain-syntax">-></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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP21">§21</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP21_3_1" class="paragraph-anchor"></a><b>§21.3.1. </b>For reasons explained above, this is really never going to happen by
|
|
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">21.3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<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><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP21_3">§21.3</a>, <a href="3-dmn.html#SP21_4">§21.4</a> (twice).</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>§22. </b>The second operation is taking roots.
|
|
</p>
|
|
|
|
<p class="commentary">Surprisingly, perhaps, it's much easier to compute \(\sqrt{X}\) or
|
|
\(^{3}\sqrt{X}\) for any unit \(X\) — it's just that it can't always be done.
|
|
Inform does not permit non-integer powers of units, so for instance
|
|
\(\sqrt{{\rm time}}\) does not exist, whereas \(\sqrt{{\rm length}^2\cdot{\rm mass}^{-2}}\)
|
|
does. Square roots exist if each power in the sequence is even, cube roots
|
|
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#SP23">§23</a>, <a href="3-dmn.html#SP31_1">§31.1</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>
|
|
<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">for</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">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><result-></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><span class="identifier-syntax">result</span><span class="plain-syntax">-></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">-></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">-></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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>§23. </b>More generally, we can raise a unit sequence to the rational power \(n/m\),
|
|
though subject to the same stipulations:
|
|
</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::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"> < </span><span class="constant-syntax">1</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="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#SP29" 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>
|
|
<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"> < </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"> > </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#SP31" 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>
|
|
<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#SP17" 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#SP22" 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">, &</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#SP23_1" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</span><span class="named-paragraph-number">23.1</span></a></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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>§24. </b>The final operation on unit sequences is substitution. Given a fundamental type
|
|
\(B\), we substitute \(B = K_D\) into an existing unit sequence \(K_E\). (This is
|
|
used when \(B\) is becoming a derived type — once we discover that \(B=K_D\),
|
|
we are no longer allowed to keep \(B\) in any unit sequence.)
|
|
</p>
|
|
|
|
<p class="commentary">We simply search for \(B^p\), and if we find it, we remove it and then
|
|
multiply by \(K_D^p\).
|
|
</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::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#SP28_3">§28.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="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>
|
|
<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>
|
|
<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"><existing-></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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></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>
|
|
<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">-></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#SP24_1" class="named-paragraph-link"><span class="named-paragraph">Remove the B term from the existing sequence</span><span class="named-paragraph-number">24.1</span></a></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">found</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="3-dmn.html#SP24_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">24.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP24_1" class="paragraph-anchor"></a><b>§24.1. </b>We shuffle the remaining terms in the sequence down by one, overwriting B:
|
|
</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">24.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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"><existing-></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>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-></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">-></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">-></span><span class="element-syntax">no_unit_pairs</span><span class="plain-syntax">--;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP24">§24</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP24_2" class="paragraph-anchor"></a><b>§24.2. </b>We now multiply by \(K_D^p\).
|
|
</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">24.2</span></span><span class="comment-syntax"> =</span>
|
|
</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">result</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP21" 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">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP24">§24</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>§25. </b>For reasons which will be explained in <a href="3-sav.html" class="internal">Scaled Arithmetic Values</a>, a unit
|
|
sequence also has a scale factor associated with it:
|
|
</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::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#SP17">§17</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">-></span><span class="element-syntax">scaling_factor</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>§26. </b>That just leaves, as usual, indexing...
|
|
</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/>Describing Kinds - <a href="2-dk.html#SP24_1">§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>
|
|
<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">-></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"><deriv-></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">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">-></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">-></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">>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">CODEGEN_MODULE</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ChartElement::old_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>
|
|
<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">"<sup>%d</sup>"</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">>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"> < </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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>§27. </b>...and logging.
|
|
</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::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">§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">"<null-us>"</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">-></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"><deriv-></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">>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">-></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">-></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">-></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="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>§28. Performing derivations. </b>The following is called when the user specifies that \(L\) times \(R\) specifies
|
|
an \(O\). Any of the three might be either a fundamental unit (so far) or a
|
|
derived unit (already).
|
|
</p>
|
|
|
|
<p class="commentary">If two or more are fundamental units, we have a choice. That is, suppose we have
|
|
created three kinds already: mass, acceleration, force. Then we read:
|
|
</p>
|
|
|
|
<blockquote>
|
|
<p>Mass times acceleration specifies a force.</p>
|
|
</blockquote>
|
|
|
|
<p class="commentary">We could make this true in any of three ways: keep M and A as fundamental units
|
|
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>
|
|
|
|
<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#SP15">§15</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>
|
|
<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#SP28_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">28.1</span></a></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">newest_term</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">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#SP28_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">28.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#SP28_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">28.3</span></a></span><span class="plain-syntax">;</span>
|
|
<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#SP28_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">28.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP28_1" class="paragraph-anchor"></a><b>§28.1. </b>Data type IDs are allocated in creation order, so "newest" means largest ID.
|
|
</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">28.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<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"><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#SP11" 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">])) && (</span><a href="2-uk.html#SP17" 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>
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP28">§28</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP28_2" class="paragraph-anchor"></a><b>§28.2. </b>We need to ensure that the user's multiplication rule is henceforth true,
|
|
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">28.2</span></span><span class="comment-syntax"> =</span>
|
|
</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 L is newest and we derive L = O/R</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP17" 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#SP17" 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 R is newest and we derive R = O/L</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP17" 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#SP17" 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 O is newest and we derive O = LR</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">kx</span><span class="plain-syntax"> = </span><a href="2-uk.html#SP17" 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#SP17" 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#SP17" 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#SP21" 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">, &</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
<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#SP17" 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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP28">§28</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP28_3" class="paragraph-anchor"></a><b>§28.3. </b>Later in Inform's run, when we start compiling code, many more unit sequences
|
|
will exist on a temporary basis — as part of the kinds for intermediate results
|
|
in calculations — 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">28.3</span></span><span class="comment-syntax"> =</span>
|
|
</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">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#SP17" 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#SP17" 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#SP24" 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>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP28">§28</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP28_4" class="paragraph-anchor"></a><b>§28.4. </b>If we have \(AB = C\) but all three of \(A\), \(B\), \(C\) are already derived,
|
|
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 — because it's already true that
|
|
\(AB = C\) — or contradictory — because we know \(AB\neq C\). We silently
|
|
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">28.4</span></span><span class="comment-syntax"> =</span>
|
|
</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">product</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP21" class="function-link"><span class="function-syntax">Kinds::Dimensions::multiply_unit_sequences</span></a><span class="plain-syntax">(</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP17" 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#SP17" 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">, &</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#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">product</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="2-uk.html#SP17" 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><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP28">§28</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>§29. Classifying the units. </b>Some of the derived units are dimensionless, others not. <span class="extract"><span class="extract-syntax">number</span></span> and
|
|
<span class="extract"><span class="extract-syntax">real number</span></span> are always dimensionless, and any unit whose derivation is the
|
|
empty unit sequence must be dimensionless.
|
|
</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::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#SP23">§23</a>, <a href="3-dmn.html#SP30">§30</a>, <a href="3-dmn.html#SP31_2">§31.2</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>
|
|
<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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-uk.html#SP17" 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#SP29" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP17" 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">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#SP31_3">§31.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">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">us</span><span class="plain-syntax">-></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>
|
|
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Kinds::Dimensions::kind_is_derived</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::kind_is_derived</span></span>:<br/><a href="3-dmn.html#SP30">§30</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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-knd.html#SP12" 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>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="2-uk.html#SP17" 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="plain-syntax"> (</span><a href="2-uk.html#SP17" 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">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP29" 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>
|
|
<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>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>§30. Logging. </b>This is used by the internal "dimensions" test of Inform:
|
|
</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::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#SP29" 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">++ > </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>
|
|
<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#SP29" 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">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="3-dmn.html#SP29" 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">) &&</span>
|
|
<span class="plain-syntax"> (</span><a href="2-uk.html#SP17" 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">++ > </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>
|
|
<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#SP29" 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><a href="2-knd.html#SP12" 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>
|
|
<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#SP17" 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>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>§31. Arithmetic on kinds. </b>We are finally able to provide our central routine, the one providing a service
|
|
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>
|
|
|
|
<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('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Kinds::Dimensions::arithmetic_on_kinds</span></span>:<br/><a href="3-dmn.html#SP23">§23</a><br/>Scaled Arithmetic Values - <a href="3-sav.html#SP2">§2</a>, <a href="3-sav.html#SP3">§3</a>, <a href="3-sav.html#SP4">§4</a>, <a href="3-sav.html#SP5">§5</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>
|
|
<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#SP16" 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">) && (</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>
|
|
|
|
<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#SP17" 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#SP17" 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#SP16" 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">) && (</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>
|
|
|
|
<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="named-paragraph-container code-font"><a href="3-dmn.html#SP31_1" class="named-paragraph-link"><span class="named-paragraph">Calculate the result unit sequence, or return null if this is impossible</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">Handle calculations entirely between dimensionless units more delicately</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">Promote dimensionless numbers to real if necessary</span><span class="named-paragraph-number">31.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#SP23_1" class="named-paragraph-link"><span class="named-paragraph">Identify the result as a known kind, if possible</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#SP31_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">31.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP31_1" class="paragraph-anchor"></a><b>§31.1. </b>Some operations — like addition — cannot be performed on mixed dimensions,
|
|
and roots can only be taken where fractional powers are avoided, so we sometimes
|
|
have to give up here and return <span class="extract"><span class="extract-syntax">NULL</span></span>. Otherwise, though, the functions above
|
|
make it possible to work out the correct unit sequence.
|
|
</p>
|
|
|
|
<p class="commentary">It's an interesting question what the result of a remainder should be, in
|
|
dimensional terms. Clearly the remainder after dividing 90kg by 20 is 10kg.
|
|
Inform says the remainder after dividing 90kg by 20kg is also 10kg. There's
|
|
an argument that it ought to be 10, but if \(n = qm + r\) then the remainder \(r\)
|
|
must have the dimensions of \(n\) (here 90kg) and also of \(qm\) (here 4 times 20kg),
|
|
so it has to be a weight, not a dimensionless number.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Calculate the result unit sequence, or return null if this is impossible</span><span class="named-paragraph-number">31.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<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#SP20" 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>
|
|
<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>
|
|
<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#SP22" 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">, &</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="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#SP22" 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">, &</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="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#SP22" 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">, &</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="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#SP21" 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">, &</span><span class="identifier-syntax">result</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">DIVIDE_OPERATION:</span>
|
|
<span class="plain-syntax"> </span><a href="3-dmn.html#SP21" 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, &</span><span class="identifier-syntax">result</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="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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_2" class="paragraph-anchor"></a><b>§31.2. </b>If <span class="extract"><span class="extract-syntax">result</span></span> is the empty unit sequence, we'll identify it as a number,
|
|
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>
|
|
|
|
<p class="commentary">But it's not so good when the calculation is not really physical at all, but
|
|
purely mathematical, and all we are doing is working on dimensionless units.
|
|
For instance, if take an angle \(\theta\) and double it to \(2\theta\), we don't
|
|
want Inform to say the result is number — we want \(2\theta\) to be
|
|
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">31.2</span></span><span class="comment-syntax"> =</span>
|
|
</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="3-dmn.html#SP16" 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">) && (</span><a href="2-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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="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#SP29" 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>
|
|
<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#SP29" 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="plain-syntax"> (</span><a href="3-dmn.html#SP29" 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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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-knd.html#SP24" class="function-link"><span class="function-syntax">Kinds::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>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_3" class="paragraph-anchor"></a><b>§31.3. </b>It's also possible to get a dimensionless result by, for example, dividing
|
|
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">Promote dimensionless numbers to real if necessary</span><span class="named-paragraph-number">31.3</span></span><span class="comment-syntax"> =</span>
|
|
</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="3-dmn.html#SP29" class="function-link"><span class="function-syntax">Kinds::Dimensions::us_dimensionless</span></a><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><a href="3-dmn.html#SP16" 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#SP2" 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>
|
|
<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#SP2" 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#SP2" 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>
|
|
<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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP23_1" class="paragraph-anchor"></a><b>§23.1. </b>If we've produced the right combination of fundamental units to make one of the
|
|
named units, then we return that as an atomic kind. For instance, maybe we
|
|
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.
|
|
</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">23.1</span></span><span class="comment-syntax"> =</span>
|
|
</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">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#SP20" class="function-link"><span class="function-syntax">Kinds::Dimensions::compare_unit_sequences</span></a><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#SP17" 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>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP23">§23</a>, <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP31_4" class="paragraph-anchor"></a><b>§31.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
|
|
we store it as an intermediate kind, representing a temporary value living
|
|
only for the duration of a calculation.
|
|
</p>
|
|
|
|
<p class="commentary">A last little wrinkle is: how we should scale this? For results like an
|
|
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
|
|
\(k \geq k_X\) and \(k\geq k_Y\), so that we have at least as much detail as
|
|
the calculation would have had within each operand kind. So perhaps we should
|
|
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>,
|
|
the least common multiple, so that any subsequent divisions will cancel
|
|
correctly and we won't lose too much information through integer rounding.
|
|
(In practice this will probably either be the same as \({\rm max}(k_X, k_Y)\)
|
|
or will multiply by 6, since <span class="extract"><span class="extract-syntax">Kinds::Dimensions::lcm(60, 1000) == 6000</span></span> and so on.)
|
|
</p>
|
|
|
|
<p class="commentary">The same unit sequence can have different scalings each time it appears as
|
|
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
|
|
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
|
|
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">31.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<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#SP18" class="function-link"><span class="function-syntax">Kinds::Dimensions::lcm</span></a><span class="plain-syntax">(</span><a href="2-uk.html#SP17" 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#SP17" 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#SP6_1" class="function-link"><span class="function-syntax">Kinds::intermediate_construction</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">result</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="3-dmn.html#SP31">§31</a>.</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="2-uk.html">❮</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-abgtn.html">4</a></li><li class="progressnext"><a href="3-fv.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|