Creating Sorts
Sorts are the type system of the Reasoning Layer. They form a lattice with multiple inheritance, feature declarations, and inter-feature constraints. Every Psi-term (data instance) belongs to a sort.
Creating a single sort
Use client.sorts.createSort() to create a sort. The method accepts a CreateSortRequest and returns the created SortDto.
import { ReasoningLayerClient } from '@kortexya/reasoninglayer';
const client = new ReasoningLayerClient({ baseUrl: 'https://platform.ovh.reasoninglayer.ai', tenantId: 'my-tenant-uuid', auth: { mode: 'cookie' },});
const person = await client.sorts.createSort({ name: 'person', description: 'A human being',});
console.log(person.id); // UUID assigned by the serverconsole.log(person.name); // "person"Using the SortBuilder
The SortBuilder provides a fluent API for constructing complex sort definitions with features, parents, and constraints.
import { SortBuilder } from '@kortexya/reasoninglayer';
const request = SortBuilder.create('employee') .parent(personSortId) .feature({ name: 'salary', required: true, constraint: { type: 'IntegerRange', value: { min: 0, max: 10_000_000 } }, }) .feature({ name: 'department', required: true, expectedSort: 'department', }) .feature({ name: 'email', required: false, constraint: { type: 'StringPattern', value: '^[^@]+@[^@]+$' }, }) .boundConstraint({ constraintType: 'upper', target: 'endDate', sourcePath: 'company.dissolutionDate', }) .description('An employee at a company') .build();
const employee = await client.sorts.createSort(request);Deterministic UUIDs
You can assign a specific UUID to a sort, which is useful for homoiconic cross-references between sorts, rules, and facts.
const request = SortBuilder.create('sensor_reading') .withId('550e8400-e29b-41d4-a716-446655440000') .feature({ name: 'value', required: true }) .build();Multiple inheritance
Sorts support multiple parents. Call .parent() multiple times or use .parents() with an array.
const request = SortBuilder.create('teaching_assistant') .parent(studentSortId) .parent(staffSortId) .feature({ name: 'courses_assisting', required: true }) .build();
// Equivalent:const request2 = SortBuilder.create('teaching_assistant') .parents([studentSortId, staffSortId]) .feature({ name: 'courses_assisting', required: true }) .build();Bulk creation with name-based parents
When defining an entire hierarchy at once, use bulkCreateSorts. Unlike createSort, parent references use sort names (not UUIDs), which are resolved server-side.
const result = await client.sorts.bulkCreateSorts({ sorts: [ { name: 'animal', description: 'Base animal sort' }, { name: 'mammal', parents: ['animal'] }, { name: 'bird', parents: ['animal'] }, { name: 'bat', parents: ['mammal'], description: 'A flying mammal' }, { name: 'penguin', parents: ['bird'], features: [ { name: 'colony_size', required: false }, ], }, ],});
console.log(result.createdCount); // 5console.log(result.sortIds); // { animal: "uuid1", mammal: "uuid2", ... }
// Check for partial failuresif (result.errors && result.errors.length > 0) { for (const err of result.errors) { console.error(`Failed to create ${err.name}: ${err.error}`); }}GLB and LUB computation
The Greatest Lower Bound (GLB) is the most specific common sort of two sorts. The Least Upper Bound (LUB) is the most general common supersort.
// Compute GLBconst glb = await client.sorts.computeGlb({ sort1Id: employeeSortId, sort2Id: customerSortId,});
if (glb.glb) { console.log(`GLB sort: ${glb.glb}`);} else { console.log('No common lower bound exists');}
// Compute LUBconst lub = await client.sorts.computeLub({ sort1Id: employeeSortId, sort2Id: customerSortId,});
if (lub.lub) { console.log(`LUB sort: ${lub.lub}`);}Decoding a GLB as a type disjunction
When the GLB does not correspond to a single named sort, decodeGlb returns a human-readable disjunction.
const decoded = await client.sorts.decodeGlb({ sort1Id: sortA, sort2Id: sortB,});
console.log(decoded.formatted); // "int | real"console.log(decoded.isBottom); // falseconsole.log(decoded.sortNames); // ["int", "real"]console.log(decoded.sortIds); // ["uuid1", "uuid2"]Convenience aliases
You can also use convenience aliases with simpler positional arguments:
const glb = await client.sorts.findCommonSubtype(employeeSortId, customerSortId);const lub = await client.sorts.findCommonSupertype(employeeSortId, customerSortId);const decoded = await client.sorts.explainCommonSubtype(sortA, sortB);Sort comparison
Compare two sorts using one of six comparison operators.
// Check if employee is a subtype of personconst result = await client.sorts.compareSorts({ operator: 'isa_le', sortA: 'employee', sortB: 'person',});
console.log(result.result); // trueAvailable operators:
| Operator | Meaning |
|---|---|
isa_le | A is a subtype of or equal to B |
isa_lt | A is a strict subtype of B |
isa_ge | A is a supertype of or equal to B |
isa_gt | A is a strict supertype of B |
isa_eq | A and B are the same sort |
isa_cmp | General comparison (returns comparison result) |
There is also a convenience method for subtype checking:
const isSub = await client.sorts.isSubtype(employeeSortId, personSortId);console.log(isSub); // trueSort similarity
Set and retrieve fuzzy similarity between two sorts. Similarity is a symmetric value from 0.0 to 1.0.
// Set similarity between two sortsawait client.sorts.setSortSimilarity({ sort1Id: catSortId, sort2Id: dogSortId, degree: 0.7,});
// Retrieve similarityconst sim = await client.sorts.getSortSimilarity({ sort1Id: catSortId, sort2Id: dogSortId,});
console.log(sim.degree); // 0.7Navigating the hierarchy
// Direct childrenconst children = await client.sorts.getChildren(animalSortId);
// Direct parentsconst parents = await client.sorts.getParents(mammalSortId);
// All ancestors (transitive)const ancestors = await client.sorts.getAncestors(batSortId);
// All descendants (transitive)const descendants = await client.sorts.getDescendants(animalSortId);
// Compatible sortsconst compatible = await client.sorts.getCompatible(mammalSortId);Listing and deleting sorts
// List all sorts in the tenantconst allSorts = await client.sorts.listSorts();
// Delete a sortawait client.sorts.deleteSort(sortId);