Lispex 2.0 specification · not released · Tested product not run · Examples not run

<a id="lispex.page.v2.numbers"></a>

# Exact numbers

Calculate with exact integers, rational numbers, and decimals. Choose scale and rounding explicitly and keep numeric work within finite limits.

Canonical: /v2.0/en/docs/language/numbers

Document revision: 2.0-draft-1. Content locale: en. Translation: current.

- language: `lispex`
- languageVersion: `2.0`

<a id="lispex.section.v2.numbers.scope"></a>

## Scope

This chapter defines exact numeric values, division, scale, and rounding. It also describes the resource obligations of growing numeric values. [Source and normalization](/v2.0/en/docs/language/source) owns literal syntax. [Values and text](/v2.0/en/docs/language/values) owns scalar and structural equality.

<a id="lispex.section.v2.numbers.number-values"></a>

## Number values

An exact integer has no fractional part. An exact rational denotes a quotient of integers with a nonzero denominator. A reduced rational has a positive denominator and no common factor between its numerator and denominator.

An exact decimal is source notation for an exact integer or reduced rational. The spelling 0.1 denotes one tenth. A decimal point does not request an inexact number. Trailing decimal zeros do not create an observable scale on the numeric value.

Numeric values are immutable [scalars](/v2.0/en/docs/language/values#lispex.section.v2.values.datum). The notation used in these examples describes values and does not specify codec bytes or product output formatting.

<a id="lispex.rule.v2.numbers.exact-arithmetic"></a>

### Preserve exact numeric meaning

Integers, rational numbers, and decimal literals denote exact values. A successful arithmetic operation returns its exact mathematical result. It does not introduce binary floating point or perform implicit rounding.

**Why**

Rules can compare amounts and ratios without depending on a platform math library or a hidden precision setting. A decimal literal expresses the stated value exactly.

<a id="lispex.claim.v2.numbers.exact-arithmetic"></a>

Claim: `lispex.claim.v2.numbers.exact-arithmetic` · structural · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-calculation",
    "operands": "exact-values"
  },
  "result": {
    "kind": "exact-result",
    "implicitInexactConversion": false,
    "implicitRounding": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for integer, rational, and decimal arithmetic, cancellation, signs, mixed numeric forms, and resource boundaries."
  ]
}
```

<a id="lispex.example.v2.numbers.decimal-sum"></a>

### Add exact decimal values

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (= (+ 0.1 0.2) 3/10)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The comparison returns true because the exact sum of 0.1 and 0.2 is three tenths. Product invocation awaits its 2.0 adapter."
}
```

The Boolean expectation fixes the mathematical value without choosing a decimal result representation or displayed spelling.

<a id="lispex.rule.v2.numbers.reduced-rational"></a>

### Reduce rational values

A rational value is reduced to coprime numerator and denominator with a positive denominator. A negative sign belongs to the numerator. Equivalent fractions denote the same exact mathematical value.

**Why**

A reduced form gives each nonintegral fraction one mathematical description. It prevents unreduced source spellings from becoming different numeric values.

<a id="lispex.claim.v2.numbers.reduced-rational"></a>

Claim: `lispex.claim.v2.numbers.reduced-rational` · boundary · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "rational-value",
    "denominator": "nonzero"
  },
  "result": {
    "kind": "reduced-rational",
    "coprime": true,
    "denominatorSign": "positive",
    "signLocation": "numerator"
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for common factors, negative operands, zero, integral quotients, and numerator and denominator growth."
  ]
}
```

<a id="lispex.example.v2.numbers.rational-reduction"></a>

### Reduce a fraction and preserve its sign

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (denominator)
      (/ 6 denominator)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "integer",
        "value": "8"
      }
    },
    {
      "input": {
        "kind": "integer",
        "value": "-8"
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The two requests return the reduced rationals three quarters and negative three quarters. Both denominators are positive. Product invocation awaits its 2.0 adapter."
}
```

The numerator and denominator fields are documentation notation for the reduced values. They do not choose a serialized rational format.

<a id="lispex.rule.v2.numbers.numeric-comparison"></a>

### Compare exact mathematical values

Numeric equality and ordering compare exact mathematical values. A decimal spelling and a rational spelling for the same value compare numerically equal. Ordering must not round either operand through a host numeric format.

**Why**

Rules need stable comparisons near boundaries. Comparing exact values prevents an approximation from merging unequal amounts or separating equal ones.

<a id="lispex.claim.v2.numbers.numeric-comparison"></a>

Claim: `lispex.claim.v2.numbers.numeric-comparison` · boundary · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-comparison",
    "operations": [
      "=",
      "<",
      "<=",
      ">",
      ">="
    ]
  },
  "result": {
    "kind": "mathematical-order",
    "implicitPrecisionLoss": false,
    "equivalentSpellingsNumericallyEqual": true
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for all comparison procedures, equal values with different spellings, close rationals, signs, and operand size limits."
  ]
}
```

<a id="lispex.example.v2.numbers.numeric-value-comparisons"></a>

### Compare ratios and decimal spellings

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (= 1.5 3/2)
            (= 0.30 3/10)
            (< 1/3 0.34)
            (= 1/3 0.33))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The comparisons return true, true, true, and false in order. One third is greater than 0.33 and less than 0.34. Product invocation awaits its 2.0 adapter."
}
```

The extra decimal zero does not change the numeric value. The scalar comparison case also checks that decimal source scale is not observable.

<a id="lispex.rule.v2.numbers.decimal-value"></a>

### Give decimal spellings exact numeric values

A decimal literal denotes an exact integer or reduced rational. Its source scale is not observable as numeric state. Mixed arithmetic uses these exact values. The scalar procedures eq? and eqv? compare their mathematical values across numeric spellings. A decimal scale needed for rounding must be supplied explicitly.

**Why**

One mathematical value should not acquire a hidden scale from its source spelling. Using integer and reduced-rational values keeps decimal notation exact while making a rounding policy a separate explicit choice.

Source scale is unobservable.

<a id="lispex.claim.v2.numbers.decimal-value"></a>

Claim: `lispex.claim.v2.numbers.decimal-value` · interaction · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "exact-decimal-use",
    "contexts": [
      "decimal-literal",
      "mixed-arithmetic",
      "scalar-equality"
    ]
  },
  "result": {
    "kind": "decimal-value-semantics",
    "valueDomain": [
      "integer",
      "reduced-rational"
    ],
    "sourceScaleObservable": false,
    "scalarEquality": "mathematical-value",
    "roundingScale": "explicit"
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for decimal spellings, integral decimals, mixed arithmetic, scalar comparisons, signed zero, and numeric resource boundaries."
  ]
}
```

<a id="lispex.example.v2.numbers.decimal-result-values"></a>

### Return the values denoted by decimal spellings

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (choose-sum)
      (if choose-sum
          (+ 0.1 0.2)
          1.00)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "boolean",
        "value": true
      }
    },
    {
      "input": {
        "kind": "boolean",
        "value": false
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The decimal sum returns the reduced rational three tenths. The literal 1.00 returns the exact integer one. Product invocation awaits its 2.0 adapter."
}
```

The two requests exercise nonintegral and integral decimal values. These value descriptions select mathematical kinds without freezing serialized codec tags or displayed spellings.

<a id="lispex.example.v2.numbers.scalar-number-spellings"></a>

### Compare numeric values across spellings

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (eq? 1 1.00)
            (eqv? 3/2 1.5)
            (eq? 0.30 3/10)
            (eqv? 1/3 0.33))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The scalar comparisons return true, true, true, and false. Decimal scale in source does not distinguish equal numeric values. Product invocation awaits its 2.0 adapter."
}
```

The last comparison stays false because one third and thirty-three hundredths are different exact values. No precision setting can make them equal.

See [Canonical codec bytes](/v2.0/en/docs/profiles#lispex.rule.v2.profiles.datum-byte-format), [Public rounding operations](/v2.0/en/docs/language/numbers#lispex.rule.v2.numbers.rounding-grid), [Concrete command forms](/v2.0/en/docs/tools/run#lispex.rule.v2.cli-and-diagnostics.command-forms).

<a id="lispex.rule.v2.numbers.exact-only"></a>

### Reject inexact numeric values

The language has no inexact numeric value kind. Inexact literals, floating point inputs, and requests for implicit inexact conversion must be rejected. A product cannot approximate a value and report a successful exact result.

**Why**

Keeping one exact numeric meaning removes host floating point behavior from rule outcomes. Rejection makes an unsupported numeric request visible.

<a id="lispex.claim.v2.numbers.exact-only"></a>

Claim: `lispex.claim.v2.numbers.exact-only` · boundary · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-admission",
    "requestedValue": "inexact"
  },
  "result": {
    "kind": "numeric-rejection",
    "inexactValueCreated": false,
    "silentApproximation": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for all inexact literal forms, NaN, infinities, host floating point inputs, and unsupported numeric conversions."
  ]
}
```

<a id="lispex.example.v2.numbers.inexact-literal-rejected"></a>

### Reject an explicit inexact literal

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      #i0.1))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "Preparation rejects the explicit inexact literal before the entry is evaluated. No inexact value or result datum is created. Product invocation awaits its 2.0 adapter."
}
```

This is a rejection example. Removing the inexact marker changes the source request to the exact decimal value. The concrete preparation code belongs to the diagnostic catalog.

<a id="lispex.section.v2.numbers.division"></a>

## Division

Exact division can produce a rational that has no finite decimal expansion. That value remains exact. A caller that needs a finite decimal scale must request an explicit rounding operation.

A zero divisor is a language domain failure. It does not produce infinity, an inexact value, or a successful result. [Conditions](/v2.0/en/docs/language/conditions) defines how a rule handles ordinary language failures.

<a id="lispex.rule.v2.numbers.exact-division"></a>

### Keep a quotient exact and reject zero divisors

Division by a nonzero exact number preserves the exact quotient. A quotient need not have a finite decimal expansion. Division by zero produces `domain.division-by-zero` and returns no result datum.

**Why**

A repeating decimal is still an exact rational. Keeping that value avoids a hidden precision choice. Zero division has a defined failure cause instead of an inexact special value.

<a id="lispex.claim.v2.numbers.exact-division"></a>

Claim: `lispex.claim.v2.numbers.exact-division` · boundary · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-division",
    "operation": "/"
  },
  "result": {
    "kind": "exact-quotient-or-domain-failure",
    "nonzeroDivisor": "exact-quotient",
    "zeroDivisor": "domain-failure",
    "infinityResult": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for zero divisors in every argument position, signs, large rational division, ordinary condition handling, and resource stops."
  ]
}
```

<a id="lispex.example.v2.numbers.division-cases"></a>

### Keep one third exact and reject division by zero

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (denominator)
      (/ 1 denominator)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "integer",
        "value": "3"
      }
    },
    {
      "input": {
        "kind": "integer",
        "value": "0"
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The first request returns the exact rational one third. The second produces a division-by-zero domain failure and no result datum. Product invocation awaits its 2.0 adapter."
}
```

The same prepared source receives two separate inputs. Neither request needs a decimal precision setting.

See [Diagnostic catalog and reports](/v2.0/en/docs/diagnostics#lispex.rule.v2.cli-and-diagnostics.diagnostics.catalog).

<a id="lispex.section.v2.numbers.scale-and-rounding"></a>

## Scale and rounding

A decimal scale specifies the place at which a value is rounded. Scale one uses tenths and scale two uses hundredths. Scale zero uses integers. Negative scales use decimal multiples. The exact numeric value does not preserve display scale.

Quantize receives its scale and mode explicitly. The named integer procedures fix their direction and scale zero. The [public catalog](/v2.0/en/docs/library#lispex.rule.v2.standard-library.procedure-catalog) lists their complete procedure contracts.

<a id="lispex.rule.v2.numbers.explicit-rounding"></a>

### Choose scale and rounding explicitly

An operation that rounds an exact number must identify its decimal scale and rounding mode in the program or input. Quantize takes both as arguments. The names floor, ceiling, and truncate identify fixed scale-zero policies. Ordinary exact arithmetic does not apply rounding implicitly. Host settings cannot choose the scale or mode.

**Why**

Different scales and rounding modes answer different questions about the same amount. Making the policy explicit lets the same rule reproduce that choice.

<a id="lispex.claim.v2.numbers.explicit-rounding"></a>

Claim: `lispex.claim.v2.numbers.explicit-rounding` · interaction · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-rounding",
    "input": "exact-number"
  },
  "result": {
    "kind": "explicit-rounding-policy",
    "scale": "program-or-input",
    "mode": "program-or-input",
    "hostSelectedPolicy": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for large signed scales, every rounding mode, ties, negative values, exact boundaries, and large coefficients."
  ]
}
```

<a id="lispex.example.v2.numbers.chosen-rounding-scales"></a>

### Choose tenths and hundredths in ordinary rule code

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define round-down
    (lambda (amount factor)
      (let loop ((units 0))
        (if (< amount (/ (+ units 1) factor))
            (/ units factor)
            (loop (+ units 1))))))

  (define rule
    (lambda (amount)
      (list (round-down amount 10)
            (round-down amount 100))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "rational",
        "numerator": "5",
        "denominator": "4"
      }
    }
  ],
  "roundingPolicy": {
    "domain": "nonnegative exact inputs",
    "mode": "toward negative infinity",
    "scales": [
      "one fractional decimal place",
      "two fractional decimal places"
    ]
  },
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "For the nonnegative input five quarters, rounding down to tenths returns six fifths. Rounding down to hundredths preserves five quarters. Product invocation awaits its 2.0 adapter."
}
```

This fixture implements downward rounding for nonnegative inputs with exact arithmetic. The factors ten and one hundred select the two scales explicitly. The public quantize procedure expresses the same policies with scale and mode arguments.

<a id="lispex.rule.v2.numbers.rounding-grid"></a>

### Round on an explicit decimal grid

The public rounding procedures use exact arithmetic. Every exact integer is an admitted scale. A scale has no host word bound. Finite evaluation limits govern the required work and storage.

| Procedure form | Argument domain | Result |
| --- | --- | --- |
| `(quantize x scale mode)` | Exact number, exact integer, and a listed mode symbol | Selected exact grid value |
| `(floor x)` | One exact number | Greatest integer no greater than the input |
| `(ceiling x)` | One exact number | Least integer no less than the input |
| `(truncate x)` | One exact number | Integer part toward zero |

Quantize requires all its arguments. The unary procedures fix scale zero and select the mode named by the procedure. They are separate procedures with the stated unary signatures.

| Name | Exact definition |
| --- | --- |
| `q` | `10^(-scale)` |
| `y` | `x / q` |
| `n` | Integer selected from `y` by the mode rule |
| Result | `n * q` |

Positive scales select decimal fractions. Negative scales select decimal multiples. An integral result is an integer. Other results are reduced rationals with positive denominators. Zero is the integer zero. The result retains neither display scale nor a zero sign.

**Why**

An integer scale describes the grid independently of host precision. Exact results preserve the adopted numeric value model. Named integer procedures express their fixed policy without a hidden default.

<a id="lispex.claim.v2.numbers.rounding-grid"></a>

Claim: `lispex.claim.v2.numbers.rounding-grid` · interaction · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "rounding-grid-call",
    "procedures": [
      "quantize",
      "floor",
      "ceiling",
      "truncate"
    ],
    "input": "exact-number",
    "scale": "any-exact-integer"
  },
  "result": {
    "kind": "canonical-exact-grid-result",
    "gridStep": "10^(-scale)",
    "integralResult": "integer",
    "fractionalResult": "reduced-rational",
    "retainedDisplayScale": false,
    "signedZero": false,
    "hostScaleBound": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for large signed scales, integral scale spellings, canonical result forms, and resource boundaries."
  ]
}
```

<a id="lispex.example.v2.numbers.quantize-scales"></a>

### Use positive and negative decimal scales

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (quantize 149/100 1 'floor)
            (quantize 149/100 2 'exact)
            (quantize 1250 -2 'half-even)
            (quantize 1350 -2 'half-even)
            (quantize -1250 -2 'half-even)
            (quantize -1350 -2 'half-even)
            (quantize -149 -1 'floor)
            (quantize -149 -1 'ceiling)
            (quantize 3 2 'exact))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The results preserve the exact decimal grid for tenths, hundredths, tens, and hundreds. Integral results use integer values. Product invocation awaits its 2.0 adapter."
}
```

Negative scales round to decimal multiples. Half-even uses parity after scaling. The final value three has no stored display scale.

<a id="lispex.example.v2.numbers.integer-rounding-procedures"></a>

### Use the named integer rounding procedures

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (floor 7/4)
            (ceiling 7/4)
            (truncate 7/4)
            (floor -7/4)
            (ceiling -7/4)
            (truncate -7/4)
            (floor 2)
            (ceiling 0)
            (truncate 0))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The named procedures return exact integers using their fixed scale-zero direction. Product invocation awaits its 2.0 adapter."
}
```

The procedure name supplies the policy. Each unary result equals quantize at scale zero with the corresponding explicit mode.

<a id="lispex.rule.v2.numbers.rounding-modes"></a>

### Select a rounding mode and resolve every tie

Mode symbols match the exact spellings below. Case folding and symbol aliases do not apply. An integral scaled value selects itself in every mode.

| Name | Definition for a nonintegral scaled value |
| --- | --- |
| `a` | Greatest integer less than `y` |
| `b` | `a + 1` |
| `t` | `y - a` |
| Nearest without a tie | Select `a` when `t < 1/2` and `b` when `t > 1/2` |

| Mode symbol | Selected integer | Tie at `t = 1/2` |
| --- | --- | --- |
| `floor` | `a` | `a` |
| `ceiling` | `b` | `b` |
| `truncate` | `a` for positive `y` and `b` for negative `y` | Same sign rule |
| `away-from-zero` | `b` for positive `y` and `a` for negative `y` | Same sign rule |
| `half-even` | Nearest without a tie | The even integer among `a` and `b` |
| `half-away-from-zero` | Nearest without a tie | `b` for positive `y` and `a` for negative `y` |
| `half-toward-zero` | Nearest without a tie | `a` for positive `y` and `b` for negative `y` |
| `exact` | `domain.numeric` with `rounding-required` | `domain.numeric` with `rounding-required` |

Distance and tie tests use exact arithmetic. The exact mode succeeds only when the input already lies on the grid. A host rounding mode, locale, or numeric library cannot change this selection.

**Why**

Directed modes serve explicit lower and upper bounds. Nearest modes state their tie policy for both signs. The exact mode lets a rule require lossless quantization.

<a id="lispex.claim.v2.numbers.rounding-modes"></a>

Claim: `lispex.claim.v2.numbers.rounding-modes` · interaction · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "rounding-mode-selection",
    "input": "exact-scaled-number",
    "modes": [
      "floor",
      "ceiling",
      "truncate",
      "away-from-zero",
      "half-even",
      "half-away-from-zero",
      "half-toward-zero",
      "exact"
    ]
  },
  "result": {
    "kind": "exact-integer-selection",
    "integralInput": "unchanged",
    "nearestDistance": "exact",
    "ties": {
      "half-even": "even-integer",
      "half-away-from-zero": "greater-magnitude",
      "half-toward-zero": "lesser-magnitude"
    },
    "exactOffGrid": "rounding-required",
    "hostSelectedPolicy": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for every mode, both signs, ties at each grid scale, exact grid points, and large numerators and denominators."
  ]
}
```

<a id="lispex.example.v2.numbers.directed-rounding-signs"></a>

### Apply every directed mode to both signs

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (quantize 7/4 0 'floor)
            (quantize 7/4 0 'ceiling)
            (quantize 7/4 0 'truncate)
            (quantize 7/4 0 'away-from-zero)
            (quantize -7/4 0 'floor)
            (quantize -7/4 0 'ceiling)
            (quantize -7/4 0 'truncate)
            (quantize -7/4 0 'away-from-zero))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "Positive inputs produce one, two, one, and two. Negative inputs produce minus two, minus one, minus one, and minus two. Product invocation awaits its 2.0 adapter."
}
```

The same explicit mode applies to each sign. Directed modes do not inspect a host rounding setting.

<a id="lispex.example.v2.numbers.rounding-ties"></a>

### Resolve nearest ties and normalize zero

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (quantize 1/2 0 'half-even)
            (quantize 1/2 0 'half-away-from-zero)
            (quantize 1/2 0 'half-toward-zero)
            (quantize -1/2 0 'half-even)
            (quantize -1/2 0 'half-away-from-zero)
            (quantize -1/2 0 'half-toward-zero)
            (quantize 3/2 0 'half-even)
            (quantize 3/2 0 'half-away-from-zero)
            (quantize 3/2 0 'half-toward-zero)
            (quantize -3/2 0 'half-even)
            (quantize -3/2 0 'half-away-from-zero)
            (quantize -3/2 0 'half-toward-zero)
            (quantize 5/4 1 'half-even)
            (quantize 5/4 1 'half-away-from-zero)
            (quantize -5/4 1 'half-toward-zero))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "Each tie follows its named policy for both signs. Every result at zero is the same integer zero. Product invocation awaits its 2.0 adapter."
}
```

The first twelve values cover both neighboring parities. The final three ties use a fractional decimal grid.

<a id="lispex.example.v2.numbers.nearest-rounding-nonties"></a>

### Choose the closest grid point away from ties

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (list (quantize 7/5 0 'half-even)
            (quantize 7/5 0 'half-away-from-zero)
            (quantize 7/5 0 'half-toward-zero)
            (quantize -7/5 0 'half-even)
            (quantize -7/5 0 'half-away-from-zero)
            (quantize -7/5 0 'half-toward-zero)
            (quantize 8/5 0 'half-even)
            (quantize 8/5 0 'half-away-from-zero)
            (quantize 8/5 0 'half-toward-zero)
            (quantize -8/5 0 'half-even)
            (quantize -8/5 0 'half-away-from-zero)
            (quantize -8/5 0 'half-toward-zero))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "All nearest modes choose the same closest integer when the scaled distance is not a tie. Product invocation awaits its 2.0 adapter."
}
```

The cases cover both sides of a half and both signs. The three nearest modes differ only at exact ties.

<a id="lispex.example.v2.numbers.quantize-exact-grid"></a>

### Require a value already on the selected grid

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (quantize (car input) (car (cdr input)) 'exact)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "rational",
            "numerator": "5",
            "denominator": "4"
          },
          {
            "kind": "integer",
            "value": "2"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "rational",
            "numerator": "5",
            "denominator": "4"
          },
          {
            "kind": "integer",
            "value": "1"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1000"
          },
          {
            "kind": "integer",
            "value": "-3"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "-1"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "integer",
            "value": "3"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "integer",
            "value": "-3"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "2"
          },
          {
            "kind": "integer",
            "value": "2"
          }
        ]
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The exact mode preserves grid values and rejects both off-grid requests with a rounding-required domain failure. Product invocation awaits its 2.0 adapter."
}
```

Lossless quantization preserves mathematical values. An exact integer result stays an integer even at a positive scale.

<a id="lispex.rule.v2.numbers.rounding-checks"></a>

### Check rounding arguments before numeric work

Operator and operand evaluation follows the [call order](/v2.0/en/docs/language/procedures). An operand failure ends that evaluation before procedure checks. After operand evaluation, check arity before checking argument domains. Quantize checks the number, scale, and mode in that order. Unary rounding checks its single exact number.

| Check | Failure |
| --- | --- |
| Quantize receives exactly three arguments | `runtime.arity` |
| A unary rounding procedure receives exactly one argument | `runtime.arity` |
| The number is exact numeric data | `domain.type` with expected type `number` |
| The scale is an exact integer | `domain.type` with expected type `integer` |
| The mode is one listed symbol | `domain.type` for a non-symbol. `domain.numeric` with `invalid-rounding-mode` for an unlisted symbol |
| The exact mode input lies on the grid | `domain.numeric` with `rounding-required` |

After arity succeeds, the operation follows the event order below. Argument checks repeat in argument order. Unary procedures have no synthetic scale or mode argument checks.

| Event | Work governed by the event |
| --- | --- |
| `argument-check` | Validate the current argument domain |
| `decimal-scale` | Form the exact grid step from the scale |
| `exact-divide` | Form the scaled value and adjacent integer candidates |
| `rounding-select` | Select an integer or report rounding-required |
| `rational-reduce` | Form and reduce the exact result |
| `datum-allocate` | Reserve and create the result datum |

Each event applies [reservation before effect](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.reserve-before-effect). It uses the [fixed resource axis order](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.atomic-axis-order). The first domain failure or refused reservation ends the call. Later events do not run. A refusal returns no rounded substitute or partial datum. Successful grid points and zero still follow the declared event stages. Optimization preserves their semantic charges and first failure.

These names identify operation families. The [resource event catalog](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.event-catalog) defines their reservation points and canonical sites.
The selected resource model supplies their requirement vectors. [Resource coefficients and limits](/v2.0/en/docs/language/resources#lispex.pending.v2.resources.model-numbers) remain under the cost model freeze decision.

**Why**

Validation order fixes which invalid argument a program observes. Reserving numeric work before its effect keeps enormous scales within finite execution. A failed call cannot silently replace the requested policy with an approximation.

<a id="lispex.claim.v2.numbers.rounding-checks"></a>

Claim: `lispex.claim.v2.numbers.rounding-checks` · interaction · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "rounding-check-sequence",
    "procedures": [
      "quantize",
      "floor",
      "ceiling",
      "truncate"
    ]
  },
  "result": {
    "kind": "ordered-rounding-events",
    "afterOperandEvaluation": {
      "quantize": [
        "arity",
        "number-domain",
        "scale-domain",
        "mode-domain"
      ],
      "unary": [
        "arity",
        "number-domain"
      ]
    },
    "events": [
      "argument-check",
      "decimal-scale",
      "exact-divide",
      "rounding-select",
      "rational-reduce",
      "datum-allocate"
    ],
    "exactFailureStage": "rounding-select",
    "reservationBeforeEffect": true,
    "partialResult": false,
    "approximationFallback": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for each invalid argument, arity, every event boundary, all resource axes, and optimization parity."
  ]
}
```

<a id="lispex.example.v2.numbers.quantize-validation-order"></a>

### Reject invalid rounding calls in the declared order

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (arguments)
      (apply quantize arguments)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "string",
            "value": "bad"
          },
          {
            "kind": "integer",
            "value": "0"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "symbol",
            "value": "half-even"
          },
          {
            "kind": "integer",
            "value": "9"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "string",
            "value": "bad"
          },
          {
            "kind": "rational",
            "numerator": "1",
            "denominator": "2"
          },
          {
            "kind": "string",
            "value": "bad"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "rational",
            "numerator": "1",
            "denominator": "2"
          },
          {
            "kind": "string",
            "value": "bad"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "string",
            "value": "half-even"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "symbol",
            "value": "HALF-EVEN"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "symbol",
            "value": "unknown"
          }
        ]
      }
    },
    {
      "input": {
        "kind": "list",
        "items": [
          {
            "kind": "integer",
            "value": "1"
          },
          {
            "kind": "integer",
            "value": "0"
          },
          {
            "kind": "symbol",
            "value": "half-even"
          }
        ]
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "Arity failures precede domain checks. The number, scale, and mode checks then select the first invalid argument. Product invocation awaits its 2.0 adapter."
}
```

Mode strings and differently cased symbols are invalid. Numeric calculation begins only after every argument check succeeds.

<a id="lispex.example.v2.numbers.rounding-operand-before-arity"></a>

### Observe an operand failure before rounding arity

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (quantize (car '()) 0)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The car operand fails before the missing mode can produce a quantize arity failure. Product invocation awaits its 2.0 adapter."
}
```

This case applies the existing operator and operand evaluation order to the new procedure.

<a id="lispex.example.v2.numbers.rounding-resource-stop"></a>

### Reserve rounding work before selecting a result

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (quantize 1/3 2 'exact)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values that admit the preceding events and refuse work at rounding-select"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "resourceBoundary": {
    "event": "rounding-select",
    "axis": "work",
    "earlierReservations": "succeed",
    "selectedReservation": "insufficient remaining capacity"
  },
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The declared rounding-select reservation fails before the exact mode can report rounding-required. Product invocation awaits its 2.0 adapter."
}
```

The request names a symbolic resource boundary. Numeric tariff coefficients and finite limit values remain with the resource model.

<a id="lispex.section.v2.numbers.numeric-size"></a>

## Numeric size

Exactness does not promise unlimited computation. Operand sizes, intermediate products, rational reduction, division, comparison, and encoding all require bounded work. The [resource contract](/v2.0/en/docs/language/resources) governs logical allocation and reservations.

Host integer width is not a numeric rule. A product must either support an admitted exact calculation under its fixed semantic limits or report the specified failure. It cannot wrap a value, saturate it, or substitute a rounded approximation.

<a id="lispex.rule.v2.numbers.bounded-arithmetic"></a>

### Bound numeric work without changing its meaning

Exact numeric operations apply [work limits](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.work-units), [logical allocation](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.logical-allocation), and the [terminal-failure rule](/v2.0/en/docs/language/conditions#lispex.rule.v2.conditions.terminal-boundary). Numeric growth and intermediate values contribute their declared events. A failed numeric operation returns no wrapped, truncated, or rounded result. Host word size cannot change an admitted calculation.

**Why**

Exact arithmetic can grow beyond the size of its source literals. Charging that growth preserves finite execution while keeping numeric meaning independent of machine word width.

<a id="lispex.claim.v2.numbers.bounded-arithmetic"></a>

Claim: `lispex.claim.v2.numbers.bounded-arithmetic` · boundary · coverage partial · verification not-run

- language: `lispex`
- languageVersion: `2.0`

```json
{
  "predicate": {
    "kind": "numeric-resource-use",
    "sizes": [
      "operands",
      "intermediate-values",
      "results",
      "encoding"
    ]
  },
  "result": {
    "kind": "bounded-exact-arithmetic",
    "wordSizeSelectsMeaning": false,
    "limitFailure": "terminal-resource-stop",
    "approximationFallback": false
  },
  "pendingCases": [
    "Native, npm, and WASM products require cases across every supported engine and architecture for operand bit growth, multiplication, reduction, division, comparison, encoding reservations, simultaneous limits, and supported architectures."
  ]
}
```

<a id="lispex.example.v2.numbers.beyond-machine-word"></a>

### Calculate beyond a 64-bit unsigned range

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (+ 18446744073709551615 1)))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "finite values sufficient for the stated finite calculation"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "With sufficient finite limits, the result is the exact integer 18446744073709551616. Product invocation awaits its 2.0 adapter."
}
```

The operand is a test value, not a language limit. A machine word boundary cannot change the sum or select a different failure on an admitted product.

<a id="lispex.example.v2.numbers.growing-exact-calculation"></a>

### Stop an unending calculation with numeric growth

Mode: illustrative. Stage: semantic-request. Verification: not-run.

- language: `lispex`
- languageVersion: `2.0`

File: `source.scm`

```lispex
(module main
  (import)
  (export rule)
  (entry rule)
  (define rule
    (lambda (input)
      (let loop ((number 2))
        (loop (* number number)))))
)
```

File: `request.json`

```lispex
{
  "notation": "documentation-request",
  "source": "source.scm",
  "semantics": {
    "language": "Lispex 2.0",
    "standardLibrary": "one fixed library identity",
    "unicode": "one fixed Unicode semantics version",
    "resourceModel": "one fixed finite resource model"
  },
  "limits": {
    "prepare": "finite values sufficient to prepare this source",
    "evaluate": "fixed finite work and logical allocation values"
  },
  "requests": [
    {
      "input": {
        "kind": "list",
        "items": []
      }
    }
  ],
  "rootModule": "main",
  "moduleSources": [
    {
      "name": "main",
      "source": "source.scm"
    }
  ]
}
```

Fixture inputs and environment:

```json
{
  "entry": "source.scm",
  "argv": [],
  "stdin": "",
  "cwd": ".",
  "environment": [],
  "wrapper": null,
  "packageRef": null,
  "lockRef": null,
  "generatedBindingRefs": {
    "knowledgeState": "not-applicable",
    "values": []
  }
}
```

#### Expected result

```json
{
  "status": "unspecified",
  "reason": "The finite resource contract stops the growing calculation and returns control. No partial value or approximate substitute is returned. Product invocation awaits its 2.0 adapter."
}
```

The square grows on every iteration. The final resource model determines the first exhausted axis and site for each fixed set of finite limits. Those details require the model to be frozen and do not imply a product pass.

See [Resource model numbers](/v2.0/en/docs/language/resources#lispex.pending.v2.resources.model-numbers).

<a id="lispex.section.v2.numbers.related"></a>

## Related chapters

[Source and normalization](/v2.0/en/docs/language/source)

[Values and text](/v2.0/en/docs/language/values)

[Resources](/v2.0/en/docs/language/resources)

[Standard library](/v2.0/en/docs/library)

<a id="lispex.pending.v2.resources.model-numbers"></a>

### Pending · Resource model numbers

The 2.0 tariff coefficients, logical allocation units, bit-size accounting, detailed frame accounting, finite defaults, representation limits, and physical memory envelopes remain open. This includes preparation, calls, values, exact arithmetic, equality, text, record conversion, and canonical encoding.

Profile host budget coefficients and defaults remain separate from language preparation and evaluation budgets. Trace capacity, reservation sizes, and host memory requirements retain their separate reporting scope. Each budget retains its own identity and accounting boundary.

Implementation and attack tests must support these choices. [Resource event declarations](/v2.0/en/docs/language/resources#lispex.rule.v2.resources.event-catalog) and [native kernel membership](/v2.0/en/docs/library#lispex.pending.v2.standard-library.kernel-and-cost-model) remain separate contracts.

<a id="lispex.pending.v2.standard-library.kernel-and-cost-model"></a>

### Pending · Native kernel membership

The final native kernel list and count remain open. Implementation and product attack tests must support these choices. [Tariff coefficients, allocation units, finite defaults, and physical envelopes](/v2.0/en/docs/language/resources#lispex.pending.v2.resources.model-numbers) are tracked once with the resource numbers.

## Related

[Source and normalization](/v2.0/en/docs/language/source)

[Values and text](/v2.0/en/docs/language/values)

[Resources](/v2.0/en/docs/language/resources)

[Standard library](/v2.0/en/docs/library)
