Skip to content

Variable: Value

@kortexya/reasoninglayer


@kortexya/reasoninglayer / Value

const Value: object

Defined in: src/builders/value.ts:73

Builder namespace for complex tagged ValueDto values that have no plain JS equivalent.

For simple types, pass plain JS values directly — the SDK auto-converts them:

  • "hello" → { type: "String", value: "hello" }
  • 42 → { type: "Integer", value: 42 }
  • 3.14 → { type: "Real", value: 3.14 }
  • true → { type: "Boolean", value: true }
  • null → { type: "Uninstantiated" }
  • [...] → { type: "List", value: [...] }

Use Value.* only for types that cannot be expressed as plain JS:

readonly bigInteger(value): BigIntegerValue

Create an arbitrary-precision integer.

string | bigint

The integer, as a bigint or its decimal string.

BigIntegerValue

A tagged BigIntegerValue: {"type": "BigInteger", "value": "170141183460469231731687303715884105727"}.

If a string is given that is not a decimal integer.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

The wire form is a string because JSON numbers are IEEE-754 doubles and lose precision above 2^53. Passing such a number as a plain JS number silently rounds it before the SDK ever sees it.

Value.bigInteger(2n ** 127n - 1n)
Value.bigInteger("170141183460469231731687303715884105727")

readonly choice(values): ChoiceValue

Create a disjunction of alternatives — {v1; v2; …}.

ValueDto[]

The alternatives.

ChoiceValue

A tagged ChoiceValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Unifies alternative-wise, so a choice narrows as information arrives rather than failing. Contrast Value.domain, which enumerates a finite domain for a solver to label.

Value.choice([{ type: "String", value: "draft" }, { type: "String", value: "sent" }])

readonly dateTime(value): DateTimeValue

Create an instant in time.

string | Date

An RFC 3339 / ISO 8601 timestamp, or a Date.

DateTimeValue

A tagged DateTimeValue: {"type": "DateTime", "value": "2026-01-15T10:30:00.000Z"}.

If a string is given that is not a parsable timestamp.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

A feature declared DateTime refuses a String, so this is not interchangeable with passing the timestamp as a plain string — a plain string becomes {"type":"String"} and the write is refused.

A Date is emitted in UTC with millisecond precision. A string is passed through as written, so an offset such as +01:00 is preserved; the engine compares instants, so it means the same moment either way.

Value.dateTime("2026-01-15T10:30:00Z")
Value.dateTime(new Date())

readonly domain(values): DomainValue

Create a finite domain of candidate values.

ValueDto[]

The candidates. The value is one of them.

DomainValue

A tagged DomainValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Unifies by intersection — meeting two domains keeps the values in both, and an empty intersection is ⊥. This is what a solver labels over; a Value.choice is a disjunction that narrows, and a plain array is one value that happens to be a list.

Value.domain([1, 2, 3].map((n) => ({ type: "Integer", value: n }) as const))

readonly externalRef(sourceId, externalId, options?): ExternalRefValue

Create a reference to an entity in another system.

string

External source identifier.

string

Entity id within that source.

Optional scalar path within the entity, and the sort expected after resolution.

string

string

ExternalRefValue

A tagged ExternalRefValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Unresolved by design: the engine holds the coordinates and resolves them through the source’s connector when a query needs the value.

Value.externalRef("crm", "acct-4711", { fieldPath: "billing.country" })

readonly fuzzyNumber(shape): FuzzyNumberValue

Create a fuzzy number defined by a membership function shape.

FuzzyShapeDto

The fuzzy membership function shape (use FuzzyShape builders).

FuzzyNumberValue

A tagged FuzzyNumberValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Note: The FuzzyShapeDto uses "kind" as its discriminator, NOT "type".

Value.fuzzyNumber(FuzzyShape.triangular(20, 22, 24))
// {"type": "FuzzyNumber", "value": {"shape": {"kind": "Triangular", "a": 20, "b": 22, "c": 24}}}

readonly fuzzyScalar(value, membership): FuzzyScalarValue

Create a fuzzy scalar with a value and membership degree.

number

The scalar value.

number

The membership degree (0.0 to 1.0).

FuzzyScalarValue

A tagged FuzzyScalarValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Value.fuzzyScalar(0.5, 0.8) // {"type": "FuzzyScalar", "value": {"value": 0.5, "membership": 0.8}}

readonly geometry(shape): GeometryValue

Create a geometric value.

GeometryDto

The shape, from the Geometry builder namespace.

GeometryValue

A tagged GeometryValue.

Serialization format: Tagged (ValueDto), whose inner shape is tagged by "kind" rather than "type".

Value.geometry(Geometry.boundingBox(10, 20, 100, 50))

readonly measurement(value, unit): MeasurementValue

Create a dimensioned quantity.

number

The magnitude.

MeasurementUnitDto

The unit it is measured in.

MeasurementValue

A tagged MeasurementValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

The engine converts between units of the same dimension before comparing, so 100 Centimeters equals 1 Meters. A bare Real carries no unit and is not comparable to a measurement at all.

Value.measurement(1.8, "Meters")

readonly psiTerm(sortId, features?): PsiTermValue

Create a nested Psi-term carried as a feature value.

string

Sort of the nested term (UUID).

Record<string, ValueDto>

Named features of the nested term, already tagged.

PsiTermValue

A tagged PsiTermValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

The nested term is structural — it is not stored separately and has no id of its own, so nothing can reference it later. Use Value.reference to point at a term that IS stored.

features is already in tagged form. To build it from plain JS values, pass them through toTaggedFeatures.

Value.psiTerm(addressSortId, toTaggedFeatures({ city: "Cairo", postcode: 11511 }))

readonly reference(target): ReferenceValue

Create a reference to another stored term — by its UUID, or by the @key values that name it.

string | ReferenceDesignator

The referenced term’s UUID, or a ReferenceDesignator naming it through the @key features of its sort.

ReferenceValue

A tagged ReferenceValue: {"type": "Reference", "value": "uuid"} for the id form, {"type":"Reference","value":{"sort_name":…,"features":…}} for the designator form.

ValidationError when the designator carries an empty sortName, or names no feature — the engine refuses both, so the builder refuses them before the round trip.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries and fuzzy operations. The homoiconic inference endpoints take the untagged format and have no designator form.

The two forms differ in what they can be used for:

  • The UUID form is what a read answers, and the only form that can point at a term whose sort declares no @key.
  • The designator form is WRITE-side only. It RESOLVES to a term that already exists and never mints one: measured on 2026-09-18, writing a payment whose invoice feature was Value.reference({ sortName: 'invoice', features: { number: { type: 'String', value: 'INV-1' } } }) stored {"type":"Reference","value":"4641cbcb-…"} — the id of the single existing invoice — and the invoice extent still held exactly one term. A designator matching nothing is refused 422 no term of sort 'invoice' carries @key 'number' = "INV-NOPE"; a reference designator names an existing term, it never creates one. The same refusal arrives from POST /api/v1/terms/bulk as a BulkRefusedError naming the entry index.

The designator’s features keys are OSF feature names — user data, not schema — and survive the request bridge verbatim, so a feature declared invoiceNumber must be spelled invoiceNumber here. Sending the snake_cased spelling is refused: 422 feature 'invoice_number' of sort 'invoice' is not a @key feature; a designator addresses a term only through its @key.

// By id:
Value.reference("550e8400-e29b-41d4-a716-446655440000")
// By @key, when the caller has the business key and not the UUID:
Value.reference({
sortName: 'invoice',
features: { number: { type: 'String', value: 'INV-1' } },
})

readonly set(lower, upper, sortConstraint?): SetValue

Create a set value with lower and upper bounds and an optional sort constraint.

string[]

Lower bound — definite members (term UUIDs).

string[]

Upper bound — possible members (term UUIDs).

string

Optional sort constraint for set members.

SetValue

A tagged SetValue.

Serialization format: Tagged (ValueDto). Use with term CRUD, queries, fuzzy operations.

Represents partial information about set membership using Smyth powerdomain semantics.

Value.set(["uuid1"], ["uuid1", "uuid2", "uuid3"], "person_sort_id")

readonly sortId(id): SortIdValue

Create a reference to a sort by UUID.

string

The UUID of the sort.

SortIdValue

A tagged SortIdValue: {"type": "SortId", "value": "uuid"}.

Used by homoiconic meta-constraints — primarily Constraint.typeOf(...) — whose feature targets a sort as a first-class value. The chainer dispatches this directly via Value::SortId.

Value.sortId("550e8400-e29b-41d4-a716-446655440000")
// { type: 'SortId', value: '550e8400-e29b-41d4-a716-446655440000' }

Serialization format: Tagged (ValueDto).

import { Value, FuzzyShape } from '@kortexya/reasoninglayer';
// Plain values (no builder needed):
const features = { name: "Alice", age: 30, active: true };
// Complex types (require Value.*):
const ref = Value.reference("term-uuid");
const fuzzy = Value.fuzzyNumber(FuzzyShape.triangular(20, 22, 24));
const membership = Value.fuzzyScalar(0.5, 0.8);
const group = Value.set(["uuid1"], ["uuid1", "uuid2"]);