@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/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 = "1.28.0";
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 ≾̇(s₁, s₂) between two sorts
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
- * @returns The preorder degree response including sort IDs and degree.
14532
- * @throws {@link ApiError} If the sorts do not exist.
14533
- *
14534
- * @remarks
14535
- * Per Definition IV.5 (Milanese and Pasi 2024), the combined preorder is:
14536
- * `preorder_dot = ((similarity - subsumption) union subsumption)^+`
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 result = await client.sorts.getPreorderDegree({
14603
+ * const strict = await client.sorts.getPreorderDegree({
14548
14604
  * sort1Id: 'uuid-1',
14549
14605
  * sort2Id: 'uuid-2',
14550
14606
  * });
14551
- * console.log(result.degree); // 0.72
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 preorder_dot(s1, s2) > 0 AND preorder_dot(s2, s1) > 0.
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 response = await this.api.nafProve(NafProveRequestFromFrontToApi(request), toRequestParams(requestOptions));
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
  /**