Books / Constructions / Chapter 2

Part I · Chapter 2

From Two Premises to a Conclusion

9 min read

Contents of Constructions

In the first chapter we recorded that water can donate a proton and asked about that same ability. The entry itself was enough for the answer. Now let us add a second piece of information and ask about a property that follows from the two together. To derive it, the model will also need a rule linking the two premises to a conclusion.

The textbook[^chapter-2-source] describes water in two roles: in one reaction it donates a proton, in another it accepts one. Let us record both abilities with the familiar relations:

assert donates_proton(entity_ref("urn:case:chem:h2o")) { id "k14-1"; origin case_input; }
assert accepts_proton(entity_ref("urn:case:chem:h2o")) { id "k14-2"; origin case_input; }

Both assertions concern the same object, urn:case:chem:h2o. The assertion names differ: k14-1 refers to donating a proton, k14-2 to accepting one. We speak of two abilities of one particle; we do not assert that it donates and accepts a proton simultaneously in a single reaction.

A particle capable of playing both roles is called amphiprotic. The vocabulary holds a separate relation for this property:

pub relation amphiprotic(s: Species) kind institutional {
    label ru unofficial "частица амфипротна: способна и отдать, и принять протон";
    label en unofficial "the species is amphiprotic";
}

The declaration has the familiar form: the name amphiprotic, one argument of type Species, captions in two languages. With this relation we can now ask whether water is amphiprotic. But neither of our two assertions answers it directly. To get an answer, we need a link between the known abilities and the new property.

First, put it in ordinary words: if a particle can donate a proton and can accept one, then it is amphiprotic. The two abilities serve as the conditions of the inference. The statements we reason from are called premises; the statement we reach is the conclusion.

In the same vocabulary file this link is recorded by a rule[^chapter-2-rule]:

@source(OS_14_1_AMPHIPROTIC)
pub rule AmphiproticDonatesAndAccepts strict {
    label ru unofficial "способная и отдать, и принять протон частица амфипротна (14.1)";
    label en unofficial "a species capable of either donating or accepting protons is amphiprotic (14.1)";
    for s: Species;
    when donates_proton(s) and accepts_proton(s);
    then amphiprotic(s);
}

The word rule declares a rule, and AmphiproticDonatesAndAccepts sets its name. By that name we will be able to recognize the rule in the explanation and check whether it was applied. The familiar label lines help read the entry, but the path from premises to conclusion is set by the for, when, and then lines. The historical English label says “either donating or accepting”, which is loose wording: the and in when requires both abilities.

for s: Species; introduces a variable s of type Species. In the relation declaration we already saw a place for an argument. The variable acts as a placeholder linking several assertions: in every place marked s, the same particle must appear. Substitute water, and the whole rule concerns water. Substitute ammonia, and it concerns ammonia.

when starts the condition. Between the two premises stands and: both are needed. If water can donate a proton and ammonia can accept one, that is not enough. You cannot collect two abilities from different particles and ascribe both to one of them.

One performer juggles on the ground, another rides a unicycle with empty hands. An impresario displays a poster ascribing both skills to a single performer.

then starts the conclusion. Here it is amphiprotic(s): the very particle for which both conditions hold is amphiprotic. The rule lets us derive a new assertion while keeping the link to the premises.

The mark strict means the rule is strict: when the condition holds, it yields the conclusion with no exception clause. That is a property of the rule in the model. By itself it does not certify that the information we recorded in the case is trustworthy. We will look at rules with exceptions later, in chapter 8.

Above the rule stands @source(OS_14_1_AMPHIPROTIC). It is a reference to the textbook’s fixed fragment, which the package names this way. The fragment first describes water’s two roles, then introduces the term “amphiprotic”. The formal entry expresses that link through two conditions. We will return to how source references are arranged in chapter 12; for now what matters is that the ground for recording the rule can be found and read.

The new relation has one more feature to explain: kind institutional instead of the familiar kind empirical. In this vocabulary the first two abilities describe empirical properties, while amphiproticity is presented as a property established by an accepted definition. Here the institutional mark does not mean belonging to an institution.

But a relation-kind mark alone concludes nothing. In our scenario the abilities are reported by assertions with origin case_input, and amphiproticity is obtained by an explicitly recorded rule. To understand where a particular piece of information came from, look at those entries and the links between them, not only at kind.

Checking the conclusion

Take scenario 14 from the same check set[^chapter-2-tests] we worked with in the first chapter. Here it is shown in full; the file’s other scenarios and header are not included in the excerpt.

test "urn:query:openstax-chem-acids-14-book-water-both-roles-amphiprotic" {
    given {
        context {
            decision_time @2026-09-06T12:00:00Z;
            knowledge_time @2026-09-06T12:00:00Z;
            legal_time @2026-09-06;
            timezone "UTC";
        }
        assert donates_proton(entity_ref("urn:case:chem:h2o")) { id "k14-1"; origin case_input; }
        assert accepts_proton(entity_ref("urn:case:chem:h2o")) { id "k14-2"; origin case_input; }
    }
    evaluate truth(amphiprotic(entity_ref("urn:case:chem:h2o")));
    expect truth_status == TRUE_ONLY;
    expect evaluation_status == COMPUTED;
    expect applied(AmphiproticDonatesAndAccepts);
}

The scenario’s structure is as before. given sets the context and the input assertions, evaluate records the question, expect the expected results. The time fields are left as in the first chapter; at this stage we change only the information and the question.

Let us trace the path to the answer. The case holds both premises for water. The rule links them to amphiproticity. In this scenario there is a ground for such an assertion and no ground against it, so we expect TRUE_ONLY. As before, COMPUTED means the answer was computed.

The last line adds a new check: expect applied(AmphiproticDonatesAndAccepts);. It checks that an application of the named rule appears in the result’s supporting graph: the linked record of assertions and inferences behind the answer. That is a useful complement to checking the answer itself: now we also expect a particular line of reasoning. At the same time, applied does not assert that the rule was the only possible ground. The explanation will show which entries took part in its application.

From the reader companion directory you can repeat the first chapter’s command:

law engine test \
  corpus/laws/org/openstax/chemistry-acids/tests/openstax-chemistry-acids.lawtest \
  --program corpus/clir/openstax-chemistry-acids.lawir.json --imports \
  contexts/openstax-chemistry-acids.json

It will check the whole file. Among the results there will be a line:

test PASS: urn:query:openstax-chem-acids-14-book-water-both-roles-amphiprotic

This command uses the model shipped with the reader companion. The path after --program points to the prepared model used to compute the answers.

Where the answer came from

For a separate analysis, make a copy of the check file and save it in the reader companion directory under the name water.lawtest. Keep in it the three opening language, package, namespace lines and only the test block of scenario 14 shown above. The explanation command needs a single scenario so it is clear which answer to unpack. The companion’s question preparer supplies the pinned import context and asks the public compiler to prepare the case and question. It makes no decision about the answer; explain then computes and displays its grounds.

Run from the same root:

chapter2_explain=$(mktemp -d)
python3 reader_tools/prepare_question.py water.lawtest \
  --program corpus/clir/openstax-chemistry-acids.lawir.json --imports \
  contexts/openstax-chemistry-acids.json --out "$chapter2_explain"
law engine explain "$chapter2_explain"

The explain command shows what the answer rests on. Its output is below; the long rule-application identifier is shortened with an ellipsis.

the species is amphiprotic(h2o): TRUE_ONLY
  rule_application  the species is amphiprotic(h2o)
    (urn:proof:apply:AmphiproticDonatesAndAccepts:f103e243…)
    assertion  the species donates a proton to another compound(h2o)
      (urn:proof:assert:urn:openstax:clir:chemistry-acids#k14-1)
    assertion  the species accepts a proton(h2o)
      (urn:proof:assert:urn:openstax:clir:chemistry-acids#k14-2)

This output uses the vocabulary’s English captions. The first line reports the answer about water’s amphiproticity. Below it sits a rule_application, the application of the rule named AmphiproticDonatesAndAccepts. Further below, indented further, are two assertions: the input assertions k14-1 and k14-2. Their names let us return to the particular entries in the case.

In the first chapter the answer rested on a single assertion. Now one more step has appeared between the input information and the answer. We can show not only the resulting property, but the rule that produced it, together with both premises.

When one piece of information is missing

Remove the entry about accepting a proton. In the check set, this case corresponds to scenario 15:

test "urn:query:openstax-chem-acids-15-book-water-one-role-no-conclusion" {
    given {
        context {
            decision_time @2026-09-06T12:00:00Z;
            knowledge_time @2026-09-06T12:00:00Z;
            legal_time @2026-09-06;
            timezone "UTC";
        }
        assert donates_proton(entity_ref("urn:case:chem:h2o")) { id "k15-1"; origin case_input; }
    }
    evaluate truth(amphiprotic(entity_ref("urn:case:chem:h2o")));
    expect truth_status == NEITHER;
    expect evaluation_status == COMPUTED;
}

Something is still known about water: it can donate a proton. But the question is about amphiproticity, and that conclusion needs both abilities. One premise is present, the other is not, so the rule under discussion does not apply. In this scenario there is no other ground for an answer for or against amphiproticity either. The result is NEITHER.

Compare with the first chapter. There we asked about ammonia, about which the case held no assertions at all. Now there is an entry about water, but it is not enough to answer the new question. Both cases produced NEITHER, though the input information differed.

The missing premise did not turn into a negative conclusion. To assert that water is not amphiprotic would take a ground against that property. Mere silence about accepting a proton is not enough for such a conclusion.

The direction of the rule

The entry when …; then …; sets a direction: from the conditions to the conclusion. The rule under discussion lets us conclude amphiproticity from the two abilities. It does not license the reverse move.

If only amphiprotic for water is recorded in the case, this rule will not derive the abilities to donate and accept protons by reasoning backwards. Although the definition connects all three properties, the formal entry expresses one particular transition. When reading a rule, distinguish what we understand from the definition from the conclusion recorded in the model.

That is why in our scenario it matters to keep exactly the two input abilities. If the property we seek is reported in advance, the answer can rest on that entry, and we will no longer test whether the two premises suffice to derive it by rule.

Try it yourself

For each exercise, take a fresh copy of water.lawtest with scenario 14. Run it with the test command, substituting the copy’s name for the full set’s path; the model after --program stays the same. First predict the result, then compare it with the one obtained.

  1. Swap the two assertions inside given. Will the answer and the rule’s application change? Check this without changing the expectations.
  2. Delete assertion k14-1, keeping only the ability to accept a proton. Keep the question and the expectations at first. Which two checks should find a mismatch? After running, explain why and correct the expectations for the new case.
  3. Keep both lines, but in assertion k14-2 replace urn:case:chem:h2o with urn:case:chem:nh3. Still ask about water’s amphiproticity. Are the two entries now enough for the conclusion? First check the old expectations, then write new ones and justify them through the variable s.

Check your predictions

In the first exercise both premises survive, and the check passes. In the second and third the answer is NEITHER: either one ability is missing, or the abilities belong to different objects. The old TRUE_ONLY and applied(AmphiproticDonatesAndAccepts) expectations fail. For the revised cases, replace the expected status with NEITHER and drop the expectation that this rule is applied; keep COMPUTED. Checks with such expectations will pass. We will learn how to express the absence of an application with a separate check later.

Now we can follow a short inference: find the two premises, make sure they concern one particle, and trace the transition to the conclusion. The next step is to work out what changes when an ability is not merely unmentioned but explicitly recorded as negated.

[^chapter-2-source]: OpenStax. Chemistry 2e, §14.1 “Brønsted–Lowry Acids and Bases”. Textbook: water’s two roles and amphiproticity. The fixed fragment OS_14_1_AMPHIPROTIC is in the sources file.

[^chapter-2-rule]: Complete vocabulary and the AmphiproticDonatesAndAccepts rule.

[^chapter-2-tests]: Complete check set, scenarios 14 and 15.

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

Constructions

Contents

You’re reading · Part I

Reading the First Model

Reading settings

Text size
Appearance

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