@dallaylaen/ski-interpreter 2.6.1 → 2.6.3

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/CHANGELOG.md CHANGED
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.6.3] - 2026-03-30
9
+
10
+ ### Added
11
+
12
+ - Quest cases now support `{ canonize: { max: number } }` option
13
+ to canonize terms before comparing.
14
+ This was added to cut off excessive `I(I(I(...)))`
15
+ in non-normalizable solutions.
16
+
17
+ ### Fixed
18
+
19
+ - Quests: Turing bird (wrong def) and Y combinator (was not accepting some valid solutions) fixed.
20
+ - Exposed more types supposed to be exposed all along.
21
+
22
+ ## [2.6.2] - 2026-03-29
23
+
24
+ ### Added
25
+
26
+ - (Re-)added { arity: number } to Alias constructor
27
+ (worked anyway but now it's official).
28
+ - More Alias tests.
29
+
30
+ ### Fixed
31
+
32
+ - Typos.
33
+
8
34
  ## [2.6.1] - 2026-03-29
9
35
 
10
36
  ### Fixed
package/README.md CHANGED
@@ -12,7 +12,7 @@ and can be used in Node.js or in the browser.
12
12
 
13
13
  A [playground](https://dallaylaen.github.io/ski-interpreter/)
14
14
  and a [quest page](https://dallaylaen.github.io/ski-interpreter/quest.html)
15
- containing interactive combinatory logic exercises of increasing difficulty are incuded.
15
+ containing interactive combinatory logic exercises of increasing difficulty are included.
16
16
 
17
17
  # Features:
18
18
 
@@ -74,7 +74,7 @@ This is consistent with combinator behavior under LO order.
74
74
 
75
75
  * [Quests](https://dallaylaen.github.io/ski-interpreter/quest.html)
76
76
 
77
- This page contains small combinatory logic exercises of increasing (hopefully) diffuculty.
77
+ This page contains small combinatory logic exercises of increasing (hopefully) difficulty.
78
78
  Each task requires the user to build a combinator with specific properties.
79
79
  New combinators are unlocked as the user progresses.
80
80
 
@@ -158,7 +158,7 @@ const iterator = expr.walk();
158
158
 
159
159
  // applying expressions
160
160
  const result = expr.run({max: 1000}, arg1, arg2, ...);
161
- // same sa
161
+ // same as
162
162
  expr.apply(arg1).apply(arg2).run();
163
163
  // or simply
164
164
  expr.apply(arg1, arg2).run();
@@ -281,7 +281,7 @@ const q = new Quest({
281
281
  q.check('CI'); // pass
282
282
  q.check('a->b->b a'); // ditto
283
283
  q.check('K'); // fail
284
- q.check('K(K(y x))') // nope! the variable scopes won't match
284
+ q.check('K(K(y x))') // nope! The variable scopes won't match
285
285
  ```
286
286
 
287
287
  See also [the quest guide](quest-intro.md) for more details on building your own quests or even interactive quest pages.
@@ -306,10 +306,10 @@ for building interactive quest pages from JSON-encoded quest data;
306
306
 
307
307
  # Prior art and inspiration
308
308
 
309
- * "To Mock The Mockingbird" by Raymond Smulian.
309
+ * "To Mock The Mockingbird" by Raymond Smullyan.
310
310
  * [combinator birds](https://www.angelfire.com/tx4/cus/combinator/birds.html) by [Chris Rathman](https://www.angelfire.com/tx4/cus/index.html)
311
311
  * [Fun with combinators](https://doisinkidney.com/posts/2020-10-17-ski.html) by [@oisdk](https://github.com/oisdk)
312
- * [Conbinatris](https://dirk.rave.org/combinatris/) by Dirk van Deun
312
+ * [Combinatris](https://dirk.rave.org/combinatris/) by Dirk van Deun
313
313
 
314
314
  # License and copyright
315
315
 
@@ -15628,14 +15628,6 @@ var Case = class {
15628
15628
  parse(src) {
15629
15629
  return new Subst(this.engine.parse(src, { env: this.env, scope: this }), this.input);
15630
15630
  }
15631
- /**
15632
- * @param {Expr} expr
15633
- * @return {CaseResult}
15634
- */
15635
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
15636
- check(..._expr) {
15637
- throw new Error("not implemented");
15638
- }
15639
15631
  };
15640
15632
  var ExprCase = class extends Case {
15641
15633
  /**
@@ -15644,6 +15636,7 @@ var ExprCase = class extends Case {
15644
15636
  * max?: number,
15645
15637
  * note?: string,
15646
15638
  * env?: {string: Expr},
15639
+ * canonize?: { max?: number, maxSize?: number, maxArgs?: number },
15647
15640
  * engine?: Parser
15648
15641
  * }} options
15649
15642
  * @param {[e1: string, e2: string]} terms
@@ -15652,6 +15645,7 @@ var ExprCase = class extends Case {
15652
15645
  if (terms.length !== 2)
15653
15646
  throw new Error("Case accepts exactly 2 strings");
15654
15647
  super(input, options);
15648
+ this.canonize = options.canonize;
15655
15649
  [this.e1, this.e2] = terms.map((s) => this.parse(s));
15656
15650
  }
15657
15651
  check(...args) {
@@ -15662,8 +15656,9 @@ var ExprCase = class extends Case {
15662
15656
  let reason = null;
15663
15657
  if (!r1.final || !r2.final)
15664
15658
  reason = "failed to reach normal form in " + this.max + " steps";
15665
- else
15666
- reason = r1.expr.diff(r2.expr);
15659
+ else {
15660
+ reason = this.canonize ? canonize(r1.expr, this.canonize).diff(canonize(r2.expr, this.canonize)) : r1.expr.diff(r2.expr);
15661
+ }
15667
15662
  return {
15668
15663
  pass: !reason,
15669
15664
  reason: reason ?? void 0,
@@ -15825,6 +15820,11 @@ function checkHtml(str) {
15825
15820
  }
15826
15821
  Quest.Group = Group;
15827
15822
  Quest.Case = Case;
15823
+ function canonize(term, options = {}) {
15824
+ return term.traverse({}, (e) => {
15825
+ return e.infer(options).expr;
15826
+ }) ?? term;
15827
+ }
15828
15828
 
15829
15829
  // src/extras.ts
15830
15830
  function search(seed, options, predicate) {