Books / Constructions / Chapter 15

Part V · Chapter 15

A Number With Its Unit

8 min read

Contents of Constructions

In Chapter 5 we compared the lengths of a triangle’s sides. For that example bare numbers were enough: every length came in one shared unit. Now imagine one person reporting a distance in metres and another in centimetres. Before comparing their numbers, check whether the entries denote the same length.

The entry 50 m has two parts: the number 50 and the unit metre. 5000 cm looks different but denotes the same length. But 50 s denotes time. Equal numbers alone do not establish equal quantities; different numbers alone do not establish different quantities.

This chapter follows one small calculation with units. It then changes the unit used for an input, supplies an incompatible unit, and compares a rule that converts explicitly with one that does not. Precision and rounding come separately at the end.

What the calculation receives

Take constant-force work from the supplied package calc.mechanics. With a force of 6 newtons and a displacement of 50 metres along the force, the work is 300 joules:

W = F · d
6 N · 50 m = 300 J

This formula has applicability conditions: the force stays constant, and the displacement points along it. Any other direction needs the angle taken into account. Our rule receives no angle and does not check that the force is constant[^chapter-15-model]. Whoever supplies the inputs must justify that this calculation fits the problem.

The package vocabulary accepts these inputs:

pub relation given_force_and_distance(c: Calculation, f: Quantity, d: Quantity) kind empirical {
    label en official "the constant force and the distance along which it acts";
    label ru unofficial "постоянная сила и путь, вдоль которого она действует";
}

For now we are reading the package’s declarations. The next chapter supplies the build commands needed to run this example.

c denotes the calculation, f the force, d the displacement. The last two arguments have type Quantity: a number together with a unit. The type is general; it does not require force for f or length for d. That dimension — the kind of physical quantity — is checked by the conversion operation inside the rule.

This allows writing 5000 cm instead of 50 m. But it also means that the relation’s declaration alone does not yet guarantee that what was passed into the force argument is indeed a force.

How the rule uses units

rule WorkOfConstantForce strict {
    label en official "W = Fd; newton times metre is the joule";
    label ru unofficial "W = Fd; ньютон на метр даёт джоуль";
    for c: Calculation;
    for f: Quantity;
    for d: Quantity;
    when given_force_and_distance(c, f, d);
    then work(c, quantity_of(unit_convert(magnitude(f), "N")
                             * unit_convert(magnitude(d), "m"), "J"));
}

The beginning is familiar: the rule reads the input relation and derives a new one. The computation sits in the argument of the work relation. Let us read it in order.

magnitude(f) supplies the numeric magnitude together with the unit information needed by the next operation. It does not leave only a bare number. Then unit_convert(..., "N") converts the force to newtons, and a second such operation converts the displacement to metres.

The resulting values are multiplied. Finally, quantity_of(..., "J") expresses the result in joules, checking that the unit agrees with the computed product. This is no license to stick an arbitrary label on an arbitrary number[^chapter-15-units].

The units.si package defines the relationships between units. In ordinary mathematical notation the newton is written as kg·m/s², and the joule as kg·m²/s². Multiplying by metres gives (kg·m/s²) · m = kg·m²/s²: the product of force and displacement has the dimension of work. The next chapter shows how to connect that package.

The full example

Below is a scenario from the mechanics check set. This runnable copy updates only the historical test-language header to 0.2 for the npm CLI. It can be saved as a separate .lawtest file:

language "law.core" version "0.2";
package calc.mechanics version "0.1.0";
namespace "urn:law:calc:mechanics";

test "urn:query:calc-mech-t04-work" {
    given {
        context { decision_time @2026-09-06T12:00:00Z; knowledge_time @2026-09-06T12:00:00Z; legal_time @2026-09-06; timezone "UTC"; }
        assert given_force_and_distance(entity_ref("urn:case:calc:m4"), 6 N, 50 m) { id "c4a"; origin case_input; }
    }
    evaluate truth(work(entity_ref("urn:case:calc:m4"), 300 J));
    expect truth_status == TRUE_ONLY;
    expect evaluation_status == COMPUTED;
    expect applied(WorkOfConstantForce);
}

The case reports force and displacement. The question checks whether 300 joules of work follow. The expectations demand, in order, a positive answer with no negative support, a completed computation, and the application of WorkOfConstantForce.

The arithmetic is checked independently: 6 · 50 = 300. The explanation shows the rule and the input assertion c4a on which it fired. That lets us link the numeric answer to the particular input quantities.

Change the unit, keep the quantity

In a copy of the scenario, replace 50 m with 5000 cm. Leave the expectations alone. The rule converts centimetres to metres, and the test passes again: the work is 300 J.

The conversion uses two different properties of a unit:

Characteristic What it lets us establish
Dimension Whether one unit can be converted into another at all
Scale How to recalculate the number in such a conversion

Metre and centimetre share the dimension of length. A centimetre is 1/100 of a metre. Seconds cannot be converted into metres: their dimensions differ.

An elephant and a tiny mouse cover one distance between flags, leaving large and small footprints.

Another mechanics scenario starts with an initial velocity of 36 km_per_h, zero acceleration, and an elapsed time of 1 h. It asks for the final velocity of 10 m_per_s. With zero acceleration the velocity stays the same; its written form changes in both number and unit: 36 · 1000 / 3600 = 10. The rule explicitly converts velocity, acceleration, and time to consistent units.

When the number is right but the unit is wrong

Replace 6 N with 6 J in the work example. The number stays the same, but energy goes in instead of force. Conversion to newtons is impossible. The query yields NEITHER with the status RUNTIME_ERROR; the reason is UNIT_DIMENSION_MISMATCH.

That result does not mean “the work is not 300 joules”. The computation never completed: the input dimension does not fit. What needs fixing is the force input, not the expected numeric answer.

The OpenStax measurement model provides a contrast: a rule that compares quantities without first converting them. It checks a claimed product of quantities. Here is the rule’s condition:

    when claimed_product(e, first, second, claimed)
        and magnitude(first) * magnitude(second) == magnitude(claimed);

This is an excerpt from ClaimedProductMatches[^chapter-15-comparison]. Here e identifies the equation being checked; first and second are the factors, and claimed is the proposed result. The rule multiplies the first two quantities and compares the result with the third. There is no explicit conversion before the comparison here.

Factors Claimed result Check outcome
2 m_per_s and 3 s 6 m TRUE_ONLY, COMPUTED
The same 6 s NEITHER, RUNTIME_ERROR
The same 0.006 km NEITHER, RUNTIME_ERROR

In the last two cases the reason is UNIT_MISMATCH: the comparison needs identical units. But the two errors mean different things. Metres and seconds clash in dimension. Metres and kilometres agree in dimension, but the scale needs recalculating before comparing. 0.006 km still equals 6 m physically; this particular rule just skips the needed conversion.

So a quantity can be convertible, yet a particular rule may still not convert it. Those are different things. The work rule writes unit_convert explicitly. The product-check rule leaves it out.

Precision and rounding

An exact calculation does not make the initial measurement exact. If a length carries a measurement error, multiplying by force does not remove it. Our simple case records no measurement errors; the answer does not establish that the measurements were error-free.

For arithmetic the language distinguishes decimal numbers from exact fractions. For example, another mechanics scenario divides the work 200 J by the heat quantity 500 J and obtains the dimensionless ratio 2/5. The fraction needs no prior replacement by an approximation.

The model can also round when the problem requires it. In .law you write rounding explicitly. For example, the following expression rounds a decimal value to two decimal places under HALF_UP:

round(1.235, 2, "HALF_UP")

This is a bare expression, not a complete model file. Its result is 1.24. The arguments give the number of places and how to handle the midpoint. The rounded value is then used in the rest of the calculation.

Shortening a number for display is different. Showing fewer places alone must not change the value the rules use. An exact result, an explicitly rounded result, and its display must be kept apart.

Check the example’s boundaries

The next chapter gives the build commands for this scenario and its dependency. Prepare the changes in tasks 1 and 2 now, then run them there using a copy of the full example. Task 3 can be reasoned through from the table:

  1. Replace metres with centimetres, keeping the length. Explain why the 300 J expectation stays the same.
  2. Pass joules instead of newtons. Check not only NEITHER but also RUNTIME_ERROR with the reason UNIT_DIMENSION_MISMATCH. The old rule-application expectation must be removed: the rule could not produce a result.
  3. Compare the two failures from the product table. For which of them is an explicit unit conversion enough, and for which must the input data itself be fixed?

Now the number carries a unit, the conversion lives in a rule, and the formula carries applicability conditions. For someone else to repeat this calculation, they need the same formulas and the same unit definitions. The next chapter shows how to hand over both together.

[^chapter-15-model]: The WorkOfConstantForce rule takes only force and displacement; its conditions include neither an angle nor a check that the force is constant. Scenario 04 checks the conclusion for the given inputs. [^chapter-15-units]: §49.1 of the Arxo specification describes Magnitude, explicit conversion, and the check of the result’s unit; the unit definitions live in the SI registry. Operations use the unit information together with the number. [^chapter-15-comparison]: The product-check rule and scenarios 02a–c. In both comparison failures the full document reports UNIT_MISMATCH and RUNTIME_ERROR; when converting J to N the reason is different — UNIT_DIMENSION_MISMATCH.

Contents · PDF · EPUB · Original text under CC BY 4.0 · Source-material terms

Constructions

Contents

You’re reading · Part V

Assemble and Hand Over

Reading settings

Text size
Appearance

Preferences and your reading place are saved only in this browser.