docs← Back to article

Markdown for LLMs

Distinguish an unknown sum from zero

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# Distinguish an unknown sum from zero

## Intention

I want to derive a zero sum only when completeness of an empty journal is confirmed.

## Incorrect form and why it stays silent

Removing complete turns missing facts into an established zero. Removing the non-emptiness guard computes an empty sum:

```text title="Incorrect form"
when opened(j) and count(collect all a: Decimal where item(j, a)) == 0;
then total(j, 0.0);
```

## Correct form

```law
language "law.core" version "0.2";
package recipes.v.r05 version "0.1.0";
namespace "urn:recipe:v-negation:05";

entity Journal;
relation opened(j: Journal);
relation complete(j: Journal);
relation item(j: Journal, amount: Decimal);
relation total(j: Journal, amount: Decimal);
rule Sum strict {
    for j: Journal;
    when opened(j) and count(collect all a: Decimal where item(j, a)) >= 1;
    then total(j, sum(collect all a: Decimal where item(j, a)));
}
rule Zero strict {
    for j: Journal;
    when opened(j) and complete(j) and count(collect all a: Decimal where item(j, a)) == 0;
    then total(j, 0.0);
}
```

## Frozen execution scene

| Facts | Question | Answer |
|---|---|---|
| opened, no data | total(a, 0.0) | NEITHER |
| opened, complete | total(a, 0.0) | TRUE_ONLY |
| opened, item(a, 5.0) | total(a, 5.0) | TRUE_ONLY |
| no complete; completeness guard removed | total(a, 0.0) | TRUE_ONLY — model error |
| empty journal; sum guard removed | total(a, 0.0) | NEITHER, EMPTY_AGGREGATE |

```law
test "unknown sum stays unknown" {
    given {
        context {
            legal_time @2026-09-13;
            decision_time @2026-09-13T09:00:00+05:00;
            knowledge_time @2026-09-13T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert opened(entity_ref("urn:recipe:v-negation:05:a"));
    }
    evaluate truth(total(entity_ref("urn:recipe:v-negation:05:a"), 0.0));
    expect truth_status == NEITHER;

}
```

```law
test "completed journal fixes zero" {
    given {
        context {
            legal_time @2026-09-13;
            decision_time @2026-09-13T09:00:00+05:00;
            knowledge_time @2026-09-13T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert opened(entity_ref("urn:recipe:v-negation:05:a"));
        assert complete(entity_ref("urn:recipe:v-negation:05:a"));
    }
    evaluate truth(total(entity_ref("urn:recipe:v-negation:05:a"), 0.0));
    expect truth_status == TRUE_ONLY;

}
```

```law
test "present item fixes sum" {
    given {
        context {
            legal_time @2026-09-13;
            decision_time @2026-09-13T09:00:00+05:00;
            knowledge_time @2026-09-13T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert opened(entity_ref("urn:recipe:v-negation:05:a"));
        assert item(entity_ref("urn:recipe:v-negation:05:a"), 5.0);
    }
    evaluate truth(total(entity_ref("urn:recipe:v-negation:05:a"), 5.0));
    expect truth_status == TRUE_ONLY;

}
```

```law
test "dropped guard fabricates zero" {
    given {
        context {
            legal_time @2026-09-13;
            decision_time @2026-09-13T09:00:00+05:00;
            knowledge_time @2026-09-13T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert opened(entity_ref("urn:recipe:v-negation:05:a"));
    }
    evaluate truth(total(entity_ref("urn:recipe:v-negation:05:a"), 0.0));
    expect truth_status == TRUE_ONLY;

}
```

```law
test "empty sum errors distinctly" {
    given {
        context {
            legal_time @2026-09-13;
            decision_time @2026-09-13T09:00:00+05:00;
            knowledge_time @2026-09-13T09:00:00+05:00;
            timezone "Asia/Almaty";
        }
        assert opened(entity_ref("urn:recipe:v-negation:05:a"));
    }
    evaluate truth(total(entity_ref("urn:recipe:v-negation:05:a"), 0.0));
    expect truth_status == NEITHER;
    expect issue(EMPTY_AGGREGATE);
}
```

## Counterfactual

runs.without removes `complete(j) and ` or the non-emptiness guard. teaches drops the binding of j from Zero and requires E4101: counting an empty collection once does not replace the journal domain.

## Boundary

Absence of tuples by itself yields NEITHER, but not necessarily MISSING_INPUT. An empty sum has its own EMPTY_AGGREGATE; an unresolved comparison input is a different case.

## Pitfall

An empty sum gives EMPTY_AGGREGATE while count gives zero. In `calc.obligations` a separate journal-completeness flag does not let missing facts be taken as absence of obligations.