@kortexya/reasoninglayer 1.28.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -18
- package/dist/index.cjs +176 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +349 -35
- package/dist/index.d.ts +349 -35
- package/dist/index.js +176 -18
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/config.ts
|
|
8
|
-
var SDK_VERSION = "
|
|
8
|
+
var SDK_VERSION = "2.0.0";
|
|
9
9
|
function resolveConfig(config) {
|
|
10
10
|
if (!config.baseUrl) {
|
|
11
11
|
throw new Error("ClientConfig.baseUrl is required");
|
|
@@ -1162,11 +1162,11 @@ var Sorts = class {
|
|
|
1162
1162
|
...params
|
|
1163
1163
|
});
|
|
1164
1164
|
/**
|
|
1165
|
-
* @description Per Definition IV.5 (Milanese & Pasi, IEEE TFS 2024 — CC-BY manuscript in reasoninglayer-sources/pdf_sources/), verbatim: ≺∼· ≝ ((≺∼ .− ∼) ⊍ ⪯)⊕ The combined chain preorder ≺∼ of Definition IV.1 with every DIRECTLY-similar pair deleted (`.−` zeroes the pair — it is not an arithmetic difference), the crisp order unioned back, and the result re-closed. A chain survives when its ENDPOINTS are not directly similar: slasher ⪯ horror ∼₀.₅ thriller keeps 0.5 while (horror, thriller) itself answers 0 — two similar sorts meet through their GLB instead (Fig. 4c: horror ⩏ thriller = slasher). The combined ≺∼ — where a direct ∼ edge IS a step; the coarse retrieval mode of Example V.4 — backs equivalence classes and term substitutability internally. (History: the differencing form here is ORIGINAL and faithful; #203 swapped in the combined semantics, and a 2026-08-23 pass re-documented that as correct from secondary sources. The accepted manuscript settled it the other way.)
|
|
1165
|
+
* @description Omitted, the answer is Def. IV.5 `≾̇` — the default because that is the relation the graded GLB and term substitutability are computed from. `granularity: "combined"` answers Def. IV.1 `≺∼`, where a similarity edge IS a step, so a directly-similar pair reads its similarity degree instead of the `0` the pair deletion gives it. A caller asking "how close are these two sorts" wants the second; a caller asking "does this sort substitute for that one" wants the first (#282). Per Definition IV.5 (Milanese & Pasi, IEEE TFS 2024 — CC-BY manuscript in reasoninglayer-sources/pdf_sources/), verbatim: ≺∼· ≝ ((≺∼ .− ∼) ⊍ ⪯)⊕ The combined chain preorder ≺∼ of Definition IV.1 with every DIRECTLY-similar pair deleted (`.−` zeroes the pair — it is not an arithmetic difference), the crisp order unioned back, and the result re-closed. A chain survives when its ENDPOINTS are not directly similar: slasher ⪯ horror ∼₀.₅ thriller keeps 0.5 while (horror, thriller) itself answers 0 — two similar sorts meet through their GLB instead (Fig. 4c: horror ⩏ thriller = slasher). The combined ≺∼ — where a direct ∼ edge IS a step; the coarse retrieval mode of Example V.4 — backs equivalence classes and term substitutability internally. (History: the differencing form here is ORIGINAL and faithful; #203 swapped in the combined semantics, and a 2026-08-23 pass re-documented that as correct from secondary sources. The accepted manuscript settled it the other way.)
|
|
1166
1166
|
*
|
|
1167
1167
|
* @tags sorts
|
|
1168
1168
|
* @name GetPreorderDegree
|
|
1169
|
-
* @summary Get preorder degree
|
|
1169
|
+
* @summary Get the preorder degree between two sorts, in either of the paper's two readings — `granularity` selects which, exactly as `GET /api/v1/sorts/quotient-order` does, and the answer echoes it back.
|
|
1170
1170
|
* @request POST:/api/v1/sorts/preorder-degree
|
|
1171
1171
|
*/
|
|
1172
1172
|
getPreorderDegree = (data, params = {}) => this.http.request({
|
|
@@ -1867,7 +1867,7 @@ var Inference = class {
|
|
|
1867
1867
|
...params
|
|
1868
1868
|
});
|
|
1869
1869
|
/**
|
|
1870
|
-
* @description # TRUE HOMOICONIC API Request contains a goal term and optional constraints. Response returns solutions with term-based substitutions. ## Temporal Reasoning Use constraints to filter by temporal relations: ```json { "goal": {"sort_name": "Employment", "features": {"valid_to": {"name": "?EndTime"}}}, "constraints": [{"type": "Guard", "left": "?EndTime", "op": "lt", "right": "1583020800000"}] } ``` ## Reading a solution `solutions[].proof.kind` says how the goal was established, and is always present: `proved` (a rule was applied — either it fired in this search, or the goal was a conclusion a forward chain had materialised and the engine recovered the rule from its recorded derivation, so `rule_term_id` and `rule_label` are filled), `fact` (a stored fact with no recorded derivation), `residuated` (an open-world leaf: unknown, never false), `unattributed` (a sound answer whose derivation the engine could not report). A client never has to infer this from the node's shape. A goal that carries `constraints` is a CONJUNCTION: its root node holds one subproof per clause and reports the strongest kind the clauses carry — `proved` when any clause was proved by a rule, else `fact`. `solutions[].substitution.bindings` carries one entry per query variable the engine resolved. A variable left unresolved is ABSENT; it is never bound to itself. # Authorization Requires X-Tenant-Id header. Traced: this is the path the zanzibar gateway hits for every permission check, so it is where an end-to-end trace either explains a slow request or does not. `skip_all` because the request body can be large and has no business in a span attribute.
|
|
1870
|
+
* @description # TRUE HOMOICONIC API Request contains a goal term and optional constraints. Response returns solutions with term-based substitutions. ## Temporal Reasoning Use constraints to filter by temporal relations: ```json { "goal": {"sort_name": "Employment", "features": {"valid_to": {"name": "?EndTime"}}}, "constraints": [{"type": "Guard", "left": "?EndTime", "op": "lt", "right": "1583020800000"}] } ``` ## Reading a solution `solutions[].proof.kind` says how the goal was established, and is always present: `proved` (a rule was applied — either it fired in this search, or the goal was a conclusion a forward chain had materialised and the engine recovered the rule from its recorded derivation, so `rule_term_id` and `rule_label` are filled), `fact` (a stored fact with no recorded derivation), `residuated` (an open-world leaf: unknown, never false), `unattributed` (a sound answer whose derivation the engine could not report). A client never has to infer this from the node's shape. A goal that carries `constraints` is a CONJUNCTION: its root node holds one subproof per clause and reports the strongest kind the clauses carry — `proved` when any clause was proved by a rule, else `fact`. `solutions[].substitution.bindings` carries one entry per query variable the engine resolved. A variable left unresolved is ABSENT; it is never bound to itself. ## Joining a proof to the thing it proves `proof.goal_term_id` is the TermId of the CONCLUSION the node proved. It joins to `POST /api/v1/query/by-sort` and `GET /api/v1/terms/{id}`, and two solutions of one goal share it only when they prove the same conclusion. It is ABSENT when there is no such id — a goal proved without a preceding `CHAIN` materialised no conclusion, and a derivation replayed from a persistent store cannot be attributed to one. A client falls back deliberately there rather than by accident. `proof.rule_head_term_id` names the rule's instantiated HEAD on a rule application, when it differs from the conclusion. ⛔ It is rule scaffolding: `GET /api/v1/terms/{id}` refuses it deliberately (#192). It is a grouping key, not a fetchable id. # Authorization Requires X-Tenant-Id header. Traced: this is the path the zanzibar gateway hits for every permission check, so it is where an end-to-end trace either explains a slow request or does not. `skip_all` because the request body can be large and has no business in a span attribute.
|
|
1871
1871
|
*
|
|
1872
1872
|
* @tags inference
|
|
1873
1873
|
* @name BackwardChain
|
|
@@ -13668,19 +13668,56 @@ function BulkSetSimilaritiesResponseFromApiToFront(dto) {
|
|
|
13668
13668
|
errors: dto.errors
|
|
13669
13669
|
};
|
|
13670
13670
|
}
|
|
13671
|
+
var SORT_PREORDER_GRANULARITIES = [
|
|
13672
|
+
"similarity_deleted",
|
|
13673
|
+
"combined"
|
|
13674
|
+
];
|
|
13675
|
+
function toSortPreorderGranularity(value) {
|
|
13676
|
+
const known = SORT_PREORDER_GRANULARITIES.find((candidate) => candidate === value);
|
|
13677
|
+
if (known === void 0) {
|
|
13678
|
+
throw new ValidationError(
|
|
13679
|
+
`Unknown preorder granularity "${value}" \u2014 expected ${SORT_PREORDER_GRANULARITIES.join(" or ")}.`
|
|
13680
|
+
);
|
|
13681
|
+
}
|
|
13682
|
+
return known;
|
|
13683
|
+
}
|
|
13671
13684
|
function GetPreorderDegreeRequestFromFrontToApi(model) {
|
|
13672
13685
|
return {
|
|
13673
13686
|
sort1_id: model.sort1Id,
|
|
13674
|
-
sort2_id: model.sort2Id
|
|
13687
|
+
sort2_id: model.sort2Id,
|
|
13688
|
+
granularity: model.granularity
|
|
13675
13689
|
};
|
|
13676
13690
|
}
|
|
13677
13691
|
function GetPreorderDegreeResponseFromApiToFront(dto) {
|
|
13678
13692
|
return {
|
|
13679
13693
|
sort1Id: dto.sort1_id,
|
|
13680
13694
|
sort2Id: dto.sort2_id,
|
|
13695
|
+
degree: dto.degree,
|
|
13696
|
+
granularity: toSortPreorderGranularity(dto.granularity)
|
|
13697
|
+
};
|
|
13698
|
+
}
|
|
13699
|
+
function QuotientClassFromApiToFront(dto) {
|
|
13700
|
+
return {
|
|
13701
|
+
sortIds: dto.sort_ids,
|
|
13702
|
+
size: dto.size,
|
|
13703
|
+
alpha: dto.alpha
|
|
13704
|
+
};
|
|
13705
|
+
}
|
|
13706
|
+
function QuotientOrderEdgeFromApiToFront(dto) {
|
|
13707
|
+
return {
|
|
13708
|
+
from: dto.from,
|
|
13709
|
+
to: dto.to,
|
|
13681
13710
|
degree: dto.degree
|
|
13682
13711
|
};
|
|
13683
13712
|
}
|
|
13713
|
+
function GetQuotientOrderResponseFromApiToFront(dto) {
|
|
13714
|
+
return {
|
|
13715
|
+
granularity: toSortPreorderGranularity(dto.granularity),
|
|
13716
|
+
classes: dto.classes.map(QuotientClassFromApiToFront),
|
|
13717
|
+
count: dto.count,
|
|
13718
|
+
orderEdges: dto.order_edges.map(QuotientOrderEdgeFromApiToFront)
|
|
13719
|
+
};
|
|
13720
|
+
}
|
|
13684
13721
|
function EquivalenceClassFromApiToFront(dto) {
|
|
13685
13722
|
return {
|
|
13686
13723
|
sortIds: dto.sort_ids,
|
|
@@ -14527,13 +14564,32 @@ var SortsClient = class {
|
|
|
14527
14564
|
/**
|
|
14528
14565
|
* Compute the preorder degree between two sorts.
|
|
14529
14566
|
*
|
|
14530
|
-
* @param request - Sort pair to compute preorder degree for
|
|
14531
|
-
*
|
|
14532
|
-
* @
|
|
14533
|
-
*
|
|
14534
|
-
* @
|
|
14535
|
-
*
|
|
14536
|
-
*
|
|
14567
|
+
* @param request - Sort pair to compute preorder degree for, and optionally
|
|
14568
|
+
* which of the two preorders to read it from.
|
|
14569
|
+
* @returns The preorder degree response including sort IDs, degree, and the
|
|
14570
|
+
* granularity the degree was read from.
|
|
14571
|
+
* @throws {@link ApiError} If the sorts do not exist, or if `granularity`
|
|
14572
|
+
* carries a spelling the engine does not accept.
|
|
14573
|
+
* @throws {@link ValidationError} If the engine answers a granularity this
|
|
14574
|
+
* SDK version does not know.
|
|
14575
|
+
*
|
|
14576
|
+
* @remarks
|
|
14577
|
+
* Per Definition IV.5 (Milanese and Pasi, IEEE TFS 2024), the dotted preorder
|
|
14578
|
+
* is `preorder_dot = ((combined_preorder .- similarity) union subsumption)^+`,
|
|
14579
|
+
* where `.-` DELETES each directly-similar pair — it is NOT an arithmetic
|
|
14580
|
+
* difference. So a directly-similar pair answers `0` under the default
|
|
14581
|
+
* granularity: two similar sorts meet through their GLB, not through each
|
|
14582
|
+
* other.
|
|
14583
|
+
*
|
|
14584
|
+
* `granularity` selects the reading, with the same two spellings
|
|
14585
|
+
* `GET /api/v1/sorts/quotient-order` uses:
|
|
14586
|
+
* - omitted or `similarity_deleted` — Definition IV.5, the default, and the
|
|
14587
|
+
* relation the graded GLB and term substitutability are computed from.
|
|
14588
|
+
* - `combined` — Definition IV.1, where a similarity edge IS a step, so a
|
|
14589
|
+
* directly-similar pair answers its similarity degree.
|
|
14590
|
+
*
|
|
14591
|
+
* The response always echoes the granularity back, so a `0.0` is never
|
|
14592
|
+
* ambiguous between "no path" and "the pair deletion zeroed it".
|
|
14537
14593
|
*
|
|
14538
14594
|
* Degree interpretation:
|
|
14539
14595
|
* - 1.0 = subsumption (sort1 <= sort2)
|
|
@@ -14544,17 +14600,78 @@ var SortsClient = class {
|
|
|
14544
14600
|
*
|
|
14545
14601
|
* @example
|
|
14546
14602
|
* ```typescript
|
|
14547
|
-
* const
|
|
14603
|
+
* const strict = await client.sorts.getPreorderDegree({
|
|
14548
14604
|
* sort1Id: 'uuid-1',
|
|
14549
14605
|
* sort2Id: 'uuid-2',
|
|
14550
14606
|
* });
|
|
14551
|
-
* console.log(
|
|
14607
|
+
* console.log(strict.degree, strict.granularity); // 0 'similarity_deleted'
|
|
14608
|
+
*
|
|
14609
|
+
* const coarse = await client.sorts.getPreorderDegree({
|
|
14610
|
+
* sort1Id: 'uuid-1',
|
|
14611
|
+
* sort2Id: 'uuid-2',
|
|
14612
|
+
* granularity: 'combined',
|
|
14613
|
+
* });
|
|
14614
|
+
* console.log(coarse.degree, coarse.granularity); // 0.5 'combined'
|
|
14552
14615
|
* ```
|
|
14553
14616
|
*/
|
|
14554
14617
|
async getPreorderDegree(request, requestOptions) {
|
|
14555
14618
|
const response = await this.sorts.getPreorderDegree(GetPreorderDegreeRequestFromFrontToApi(request), toRequestParams(requestOptions));
|
|
14556
14619
|
return GetPreorderDegreeResponseFromApiToFront(response.data);
|
|
14557
14620
|
}
|
|
14621
|
+
/**
|
|
14622
|
+
* Get the Definition IV.9 quotient order over the caller's own lattice.
|
|
14623
|
+
*
|
|
14624
|
+
* @param options - Which of the two fuzzy preorders to quotient. Omitted
|
|
14625
|
+
* means `combined`, the engine's default HERE.
|
|
14626
|
+
* @returns The equivalence classes with their degrees, and the fuzzy partial
|
|
14627
|
+
* order between them.
|
|
14628
|
+
* @throws {@link ApiError} 400 when `granularity` carries a spelling the
|
|
14629
|
+
* engine does not accept.
|
|
14630
|
+
* @throws {@link ValidationError} If the engine answers a granularity this
|
|
14631
|
+
* SDK version does not know.
|
|
14632
|
+
*
|
|
14633
|
+
* @remarks
|
|
14634
|
+
* This is the tenant-scoped companion of
|
|
14635
|
+
* {@link SortsClient.getEquivalenceClasses}: the classes, degrees and order
|
|
14636
|
+
* describe exactly the sorts the caller can see, where the older
|
|
14637
|
+
* equivalence-classes route computes process-wide and then filters. Prefer
|
|
14638
|
+
* this one.
|
|
14639
|
+
*
|
|
14640
|
+
* ⚠️ The default granularity here is `combined`, NOT the
|
|
14641
|
+
* `similarity_deleted` default of {@link SortsClient.getPreorderDegree}. The
|
|
14642
|
+
* two routes take the same two spellings and disagree on which is the
|
|
14643
|
+
* default, so state it when it matters. The response echoes it back either
|
|
14644
|
+
* way.
|
|
14645
|
+
*
|
|
14646
|
+
* `orderEdges` is SPARSE and indexes into `classes`: a pair with no edge has
|
|
14647
|
+
* degree `0`. The order is a partial order — antisymmetric, unlike either
|
|
14648
|
+
* preorder it is built from.
|
|
14649
|
+
*
|
|
14650
|
+
* Uses tagged serialization format.
|
|
14651
|
+
*
|
|
14652
|
+
* @example
|
|
14653
|
+
* ```typescript
|
|
14654
|
+
* const quotient = await client.sorts.getQuotientOrder({
|
|
14655
|
+
* granularity: 'similarity_deleted',
|
|
14656
|
+
* });
|
|
14657
|
+
*
|
|
14658
|
+
* for (const cls of quotient.classes) {
|
|
14659
|
+
* console.log(`class of ${cls.size} sorts, degree ${cls.alpha}`);
|
|
14660
|
+
* }
|
|
14661
|
+
* for (const edge of quotient.orderEdges) {
|
|
14662
|
+
* const lower = quotient.classes[edge.from];
|
|
14663
|
+
* const upper = quotient.classes[edge.to];
|
|
14664
|
+
* console.log(`${lower.sortIds} <= ${upper.sortIds} at ${edge.degree}`);
|
|
14665
|
+
* }
|
|
14666
|
+
* ```
|
|
14667
|
+
*/
|
|
14668
|
+
async getQuotientOrder(options, requestOptions) {
|
|
14669
|
+
const response = await this.sorts.getQuotientOrder(
|
|
14670
|
+
{ granularity: options?.granularity },
|
|
14671
|
+
toRequestParams(requestOptions)
|
|
14672
|
+
);
|
|
14673
|
+
return GetQuotientOrderResponseFromApiToFront(response.data);
|
|
14674
|
+
}
|
|
14558
14675
|
/**
|
|
14559
14676
|
* Get equivalence classes based on the combined preorder.
|
|
14560
14677
|
*
|
|
@@ -14562,8 +14679,16 @@ var SortsClient = class {
|
|
|
14562
14679
|
* @throws {@link ApiError} If the lattice cannot be computed.
|
|
14563
14680
|
*
|
|
14564
14681
|
* @remarks
|
|
14565
|
-
* Per Definition IV.9 (Milanese and Pasi 2024)
|
|
14566
|
-
* s1 ~ s2 iff
|
|
14682
|
+
* Per Definition IV.9 (Milanese and Pasi 2024), two sorts are equivalent when
|
|
14683
|
+
* each reaches the other: `s1 ~ s2` iff `preorder(s1, s2) > 0` AND
|
|
14684
|
+
* `preorder(s2, s1) > 0`. The preorder here is the COMBINED one, where a
|
|
14685
|
+
* similarity edge is itself a step — not the `similarity_deleted` default of
|
|
14686
|
+
* {@link SortsClient.getPreorderDegree}.
|
|
14687
|
+
*
|
|
14688
|
+
* ⚠️ This route computes PROCESS-WIDE and then filters, so its classes can
|
|
14689
|
+
* be shaped by sorts the caller cannot see. {@link SortsClient.getQuotientOrder}
|
|
14690
|
+
* computes on the tenant-visible hierarchy instead, returns the same classes
|
|
14691
|
+
* with their degrees, and adds the partial order between them. Prefer it.
|
|
14567
14692
|
*
|
|
14568
14693
|
* Uses tagged serialization format.
|
|
14569
14694
|
*
|
|
@@ -15870,6 +15995,7 @@ function ProofDtoFromApiToFront(dto) {
|
|
|
15870
15995
|
kind: dto.kind,
|
|
15871
15996
|
goalTermId: dto.goal_term_id,
|
|
15872
15997
|
ruleTermId: dto.rule_term_id,
|
|
15998
|
+
ruleHeadTermId: dto.rule_head_term_id,
|
|
15873
15999
|
goalDisplay: dto.goal_display,
|
|
15874
16000
|
ruleLabel: dto.rule_label,
|
|
15875
16001
|
substitution: HomoiconicSubstitutionDtoFromApiToFront(dto.substitution),
|
|
@@ -16749,6 +16875,14 @@ var InferenceClient = class {
|
|
|
16749
16875
|
*
|
|
16750
16876
|
* The `timeout_ms` field on the request is a wall-clock timeout for the search.
|
|
16751
16877
|
* When it fires, the backend returns whatever solutions have been found so far.
|
|
16878
|
+
*
|
|
16879
|
+
* To join a proof node to the thing it proves, read `proof.goalTermId` — the
|
|
16880
|
+
* conclusion's term ID, which `client.terms.getTerm()` and
|
|
16881
|
+
* `client.query.findBySort()` both answer for. It is OPTIONAL: a goal proved
|
|
16882
|
+
* without a preceding forward chain materialises no conclusion, so the node
|
|
16883
|
+
* carries no id and `proof.goalDisplay` renders it instead. Do not read
|
|
16884
|
+
* `proof.ruleHeadTermId` as a fetchable id — it names the rule's instantiated
|
|
16885
|
+
* head, which the term routes refuse.
|
|
16752
16886
|
*/
|
|
16753
16887
|
async backwardChain(request, requestOptions) {
|
|
16754
16888
|
const wireRequest = {
|
|
@@ -16852,13 +16986,37 @@ var InferenceClient = class {
|
|
|
16852
16986
|
/**
|
|
16853
16987
|
* Run negation-as-failure (NAF) proof search.
|
|
16854
16988
|
*
|
|
16855
|
-
* @param request - NAF prove request.
|
|
16989
|
+
* @param request - NAF prove request. Each literal's `term` takes a
|
|
16990
|
+
* {@link psi} term or a wire {@link TermInputDto}, like every other
|
|
16991
|
+
* term-carrying method.
|
|
16856
16992
|
* @returns NAF proof result.
|
|
16857
16993
|
*
|
|
16994
|
+
* @remarks
|
|
16995
|
+
* Uses the untagged (homoiconic) serialization format: a literal's features
|
|
16996
|
+
* are plain scalars and `"?Var"` strings.
|
|
16997
|
+
*
|
|
16998
|
+
* @example
|
|
16999
|
+
* ```typescript
|
|
17000
|
+
* const result = await client.inference.nafProve({
|
|
17001
|
+
* literals: [
|
|
17002
|
+
* { term: psi('employee', { name: '?Name' }) },
|
|
17003
|
+
* { term: psi('senior_engineer', { name: '?Name' }), negated: true },
|
|
17004
|
+
* ],
|
|
17005
|
+
* maxSolutions: 10,
|
|
17006
|
+
* });
|
|
17007
|
+
* ```
|
|
17008
|
+
*
|
|
16858
17009
|
* @see proveWithNegation — friendlier alias for this method.
|
|
16859
17010
|
*/
|
|
16860
17011
|
async nafProve(request, requestOptions) {
|
|
16861
|
-
const
|
|
17012
|
+
const wireRequest = {
|
|
17013
|
+
...request,
|
|
17014
|
+
literals: request.literals?.map((literal) => ({
|
|
17015
|
+
...literal,
|
|
17016
|
+
term: convertTermArg(literal.term)
|
|
17017
|
+
}))
|
|
17018
|
+
};
|
|
17019
|
+
const response = await this.api.nafProve(NafProveRequestFromFrontToApi(wireRequest), toRequestParams(requestOptions));
|
|
16862
17020
|
return NafProveResponseFromApiToFront(response.data);
|
|
16863
17021
|
}
|
|
16864
17022
|
/**
|