Books / Constructions / Chapter 3
Part I · Chapter 3
Established, Refuted, Conflicting, Unknown
Contents of Constructions
In the last chapter we removed one piece of information about
water. The remaining data was not enough for the conclusion
about amphiproticity, and the result was NEITHER. But deleting the
message “water can accept a proton” and recording “water cannot
accept a proton” are different actions. In the first case the
information is gone; in the second, a counter-assertion appears.
Let us examine that difference using the familiar question: can water donate a proton? Set the amphiproticity conclusion aside for now and look at the input assertions themselves. That will show what changes when one entry is added or removed.
Two questions instead of one
For an answer, two sides must be checked independently: whether there is a ground for the assertion and whether there is a ground against it. That yields four combinations[^chapter-3-support]:
| Ground for | Ground against | How to read the answer |
|---|---|---|
| present | absent | assertion established |
| absent | present | assertion refuted |
| present | present | grounds conflict with each other |
| absent | absent | assertion neither established nor refuted |
The language uses the statuses TRUE_ONLY, FALSE_ONLY, BOTH,
and NEITHER. Two states are already familiar: in the first
chapter the positive entry about water gave TRUE_ONLY, and the
question about ammonia, about which nothing was reported, gave
NEITHER.
The words “established” and “refuted” here refer to the grounds in the case and model under discussion. They do not certify that the input information is true. The word “unknown” does not mean that no answer can ever be found: the grounds available here support neither side.
How to record a negation
A positive assertion began with assert donates_proton(…). For
a negative one, add not before the relation name. In scenario
16[^chapter-3-tests] it looks like this:
test "urn:query:openstax-chem-acids-16-book-water-donation-refuted" {
given {
context {
decision_time @2026-09-06T12:00:00Z;
knowledge_time @2026-09-06T12:00:00Z;
legal_time @2026-09-06;
timezone "UTC";
}
assert not donates_proton(entity_ref("urn:case:chem:h2o")) { id "k16-1"; origin case_input; }
}
evaluate truth(donates_proton(entity_ref("urn:case:chem:h2o")));
expect truth_status == FALSE_ONLY;
expect evaluation_status == COMPUTED;
}
The new line reads: “Recorded: water cannot donate a proton.” The
question stayed positive: evaluate truth(donates_proton(…)). We
ask about the ability to donate a proton, while the only assertion
is directed against it. Hence the answer FALSE_ONLY.
This is a deliberately altered teaching example. Earlier we recorded water’s ability to donate a proton following the textbook’s description; now we check how the language handles the opposite message. The resulting answer shows what follows from the entered information, not a new discovery about water’s properties.
The test block is shown in full. As before, it belongs to the
shared file with the language, package, namespace header. The
context, the question, and the COMPUTED expectation are arranged
as in the previous chapters. New here are only the explicit negation
and its matching answer status.
What conflict produces
Now keep the positive entry and add the negative one. In scenario 17 both concern one ability of the same water:
test "urn:query:openstax-chem-acids-17-book-water-donation-both" {
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 "k17-yes"; origin case_input; }
assert not donates_proton(entity_ref("urn:case:chem:h2o")) { id "k17-no"; origin case_input; }
}
evaluate truth(donates_proton(entity_ref("urn:case:chem:h2o")));
expect truth_status == BOTH;
expect evaluation_status == COMPUTED;
}
Assertion k17-yes gives a ground for water donating a proton,
and k17-no gives a ground against it. Neither entry has vanished. Hence the answer BOTH: the
case holds grounds on both sides.
The scenarios can be checked with the familiar command from the reader companion directory:
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
For scenario 17 it will print:
test PASS: urn:query:openstax-chem-acids-17-book-water-donation-both
Author’s paraphrase of the engine output above: the check of
scenario 17 passed — the obtained conflict matched the expected
BOTH status.
The evaluation_status == COMPUTED expectation held as well:
the BOTH answer could be computed. Conflicting information
and a failed query run are different things.
Let us look at the explanation. Make a copy of the check file,
water-both.lawtest, in the reader companion directory. Keep in it the three
header lines and only the scenario 17 block, as we did with
scenario 14 in the last chapter. Run:
chapter3_explain=$(mktemp -d)
python3 reader_tools/prepare_question.py water-both.lawtest \
--program corpus/clir/openstax-chemistry-acids.lawir.json --imports \
contexts/openstax-chemistry-acids.json --out "$chapter3_explain"
law engine explain "$chapter3_explain"
Both grounds are visible in the explanation:
the species donates a proton to another compound(h2o): BOTH
assertion ¬ the species donates a proton to another compound(h2o)
(urn:proof:assert:urn:openstax:clir:chemistry-acids#k17-no)
assertion the species donates a proton to another compound(h2o)
(urn:proof:assert:urn:openstax:clir:chemistry-acids#k17-yes)
Author’s paraphrase of the engine output above: the question of
whether water donates a proton is answered BOTH — the negating
entry k17-no and the affirming entry k17-yes each support their
own side, with no rules applied.
The sign ¬ before a caption denotes negation. Next to each of the
two entries appears its identifier: we can go back to the assertion
for and the assertion against. In this case the answer rests
directly on them, with no rules applied.
Swapping those two lines inside given leaves the answer BOTH.
A line’s later position does not give it greater weight and does not
cancel the other entry. To resolve the conflict, the grounds of the
messages themselves must be investigated. We will see in chapter 11
how to present sources of information and their authors.
BOTH does not mean “fifty percent probability”. The four states
report what grounds exist, not a degree of confidence. In this
scenario neither vote-counting nor picking the more convincing
entry is specified.
When nothing is said about the ability
In scenario 18 only water’s other ability is reported:
assert accepts_proton(entity_ref("urn:case:chem:h2o")) { id "k18-1"; origin case_input; }
While the question and the expectation concern donating a proton:
evaluate truth(donates_proton(entity_ref("urn:case:chem:h2o")));
expect truth_status == NEITHER;
These are two excerpts from the scenario: the input assertion and
the lines with the question and the expected answer. The complete
block lives in the same check set. It holds neither a positive nor
a negative entry about donating a proton. In this model, donating
does not follow from accepting a proton either. Hence the answer
NEITHER.

Now compare all four cases for the same question:
| Entries about water donating a proton | Scenario | Answer |
|---|---|---|
| only positive | 12, chapter 1 | TRUE_ONLY |
| only negative | 16 | FALSE_ONLY |
| both | 17 | BOTH |
| neither | 18 | NEITHER |
The last two lines are especially easy to mix up. When entries
disagree, they cannot be treated as absent. When there are no
entries, the assertion cannot be treated as refuted. An explicit
not reports a negation; the mere absence of information creates
no such entry. Separate conditions on the completeness of
information will appear in chapter 7.
A negative conclusion by rule
Return to amphiproticity. In the last chapter we obtained that property from two abilities. Now take a different case: the ability to donate a proton is established, while the ability to accept one is refuted. For a conclusion about amphiproticity the vocabulary has a separate rule[^chapter-3-rule]:
@source(OS_14_1_AMPHIPROTIC)
pub rule NotAmphiproticWithoutAcceptance strict {
label ru unofficial "отдающая протон частица с опровергнутой акцепторностью не амфипротна (14.1)";
label en unofficial "a proton donor whose acceptance is refuted is not amphiprotic (14.1)";
for s: Species;
when donates_proton(s) and refuted(accepts_proton(s));
then not amphiprotic(s);
}
It can be read as: “If a particle can donate a proton, while its
ability to accept a proton is refuted, then the particle is not
amphiprotic.” The variable s still binds both premises and the
conclusion to one particle.
The condition introduces the expression
refuted(accepts_proton(s)). It checks that accepting a proton
has exactly the FALSE_ONLY status: a ground against it is
present and no ground for it is present. It fails for NEITHER,
where no ground against it is present. It also fails for BOTH,
where a ground for it is present as well as a ground against it.
Two actions matter here. assert not in a case adds a negative
assertion. refuted(…) in a rule checks the state of an assertion
given the available grounds. Those grounds may be input or derived;
the check does not reduce to finding a line with assert not.
The conclusion reads then not amphiprotic(s). This is a negative
conclusion: applying the rule yields a ground against
amphiproticity. Let us check it on scenario 19:
test "urn:query:openstax-chem-acids-19-book-water-acceptance-refuted-not-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 "k19-1"; origin case_input; }
assert not accepts_proton(entity_ref("urn:case:chem:h2o")) { id "k19-2"; origin case_input; }
}
evaluate truth(amphiprotic(entity_ref("urn:case:chem:h2o")));
expect truth_status == FALSE_ONLY;
expect evaluation_status == COMPUTED;
expect applied(NotAmphiproticWithoutAcceptance);
}
Here donating a proton has the status TRUE_ONLY, accepting —
FALSE_ONLY. Both premises of the negative rule hold. The positive
rule from the last chapter does not apply: the ability to accept
a proton is not established. As a result, there is a ground against
amphiproticity and none for it. The answer is FALSE_ONLY, and the
applied expectation confirms the application of
NotAmphiproticWithoutAcceptance.
This differs from scenario 15 in the last chapter. There nothing
was said about accepting a proton, and the answer about
amphiproticity came out NEITHER. Here a negative piece of
information appeared, which the rule builds on. A missing premise
and a refuted premise give different results.
When a disputed premise stops the conclusion
One case remains to test our understanding of refuted.
Suppose the ability to donate a proton is established, while
accepting a proton has entries both for and against. Accepting
a proton gets BOTH. How will that affect amphiproticity?
In the positive rule, accepts_proton(s) is an ordinary positive
premise, rather than an explicit status check. It requires TRUE_ONLY.
A ground for accepting a proton is not enough when a ground against it
is also present. So the positive rule does not apply. The negative rule does
not apply either: its refuted condition requires FALSE_ONLY,
not BOTH.
In this case there are no other grounds either for or against
amphiproticity, so the result is NEITHER. Scenario 22 records
this case. In every row below, donating a proton remains established;
only the status of accepting a proton changes:
| State of accepting a proton | Answer about amphiproticity |
|---|---|
TRUE_ONLY |
TRUE_ONLY |
FALSE_ONLY |
FALSE_ONLY |
NEITHER |
NEITHER |
BOTH |
NEITHER |
The table concerns these rules and this input information. A conflict in one ability need not become a conflict in the derived property. To predict the result, read the conditions of the rules being applied.
Try it yourself
For single-scenario work use a copy with the three header lines, as
when running the explanation. In the test command, replace the
shared set’s path with your copy’s name; the path after --program
stays the same. Before each change, predict the answer.
- In a copy of scenario 17, swap the two entries. Check the result
and the explanation. Then make three fresh copies: in one keep
only the positive entry, in another keep only the negative one,
and in the third delete both. Do not change the question or the
context. For each fresh copy, first run the check with the old
BOTHexpectation and note the mismatch; then replace it with the expectation you can justify from the entries that remain. - In a copy of scenario 19, delete the negative entry
k19-2. Why do the old status and rule-application expectations no longer hold? Explain the result through both premises, then fix the expectations. - In a fresh copy of scenario 19, keep both input entries and add
a positive entry about water accepting a proton. Give it a new
name,
k19-3. Still ask about amphiproticity. First check the old expectations, then correct them, explaining separately why each of the two rules under discussion does not apply.
Check your predictions
In the first exercise the swap keeps BOTH. Deleting the entries
one by one gives TRUE_ONLY, FALSE_ONLY, and NEITHER. In the
second and third exercises the answer about amphiproticity is
NEITHER, but the reasons differ: information about accepting
a proton is either missing or conflicting. In both cases replace the
FALSE_ONLY expectation with NEITHER and drop the expectation
that the negative rule is applied. Keep COMPUTED. Checks with the
new expectations will pass.
We have learned to tell apart a missing ground, a refutation, and a conflict. But the same answer state does not yet say how exactly it came about. In the next chapter we will examine the explanation in more detail: walk from the answer back to the input information and the rule’s source, then find out why an expected conclusion was not reached.
[^chapter-3-support]: Arxo specification, §§61–66: independent grounds, explicit negation, status checks, and rule conditions.
[^chapter-3-tests]: Complete check set: scenarios 16–19 and 22 discussed in this chapter.
[^chapter-3-rule]: The NotAmphiproticWithoutAcceptance rule in the complete vocabulary. The refuted check is defined in §65 of the specification; the ordinary positive premise in §66.
Contents · PDF · EPUB · Original text under CC BY 4.0 · Source-material terms