mcard-js 2.1.1 → 2.1.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.
Files changed (67) hide show
  1. package/README.md +118 -3
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/ptr/lambda/AlphaConversion.d.ts +42 -0
  7. package/dist/ptr/lambda/AlphaConversion.d.ts.map +1 -0
  8. package/dist/ptr/lambda/AlphaConversion.js +244 -0
  9. package/dist/ptr/lambda/AlphaConversion.js.map +1 -0
  10. package/dist/ptr/lambda/BetaReduction.d.ts +73 -0
  11. package/dist/ptr/lambda/BetaReduction.d.ts.map +1 -0
  12. package/dist/ptr/lambda/BetaReduction.js +322 -0
  13. package/dist/ptr/lambda/BetaReduction.js.map +1 -0
  14. package/dist/ptr/lambda/EtaConversion.d.ts +65 -0
  15. package/dist/ptr/lambda/EtaConversion.d.ts.map +1 -0
  16. package/dist/ptr/lambda/EtaConversion.js +228 -0
  17. package/dist/ptr/lambda/EtaConversion.js.map +1 -0
  18. package/dist/ptr/lambda/FreeVariables.d.ts +44 -0
  19. package/dist/ptr/lambda/FreeVariables.d.ts.map +1 -0
  20. package/dist/ptr/lambda/FreeVariables.js +207 -0
  21. package/dist/ptr/lambda/FreeVariables.js.map +1 -0
  22. package/dist/ptr/lambda/LambdaRuntime.d.ts +80 -0
  23. package/dist/ptr/lambda/LambdaRuntime.d.ts.map +1 -0
  24. package/dist/ptr/lambda/LambdaRuntime.js +417 -0
  25. package/dist/ptr/lambda/LambdaRuntime.js.map +1 -0
  26. package/dist/ptr/lambda/LambdaTerm.d.ts +95 -0
  27. package/dist/ptr/lambda/LambdaTerm.d.ts.map +1 -0
  28. package/dist/ptr/lambda/LambdaTerm.js +159 -0
  29. package/dist/ptr/lambda/LambdaTerm.js.map +1 -0
  30. package/dist/ptr/lambda/index.d.ts +24 -0
  31. package/dist/ptr/lambda/index.d.ts.map +1 -0
  32. package/dist/ptr/lambda/index.js +34 -0
  33. package/dist/ptr/lambda/index.js.map +1 -0
  34. package/dist/ptr/llm/Config.d.ts.map +1 -1
  35. package/dist/ptr/llm/Config.js +16 -0
  36. package/dist/ptr/llm/Config.js.map +1 -1
  37. package/dist/ptr/llm/LLMRuntime.d.ts.map +1 -1
  38. package/dist/ptr/llm/LLMRuntime.js +8 -0
  39. package/dist/ptr/llm/LLMRuntime.js.map +1 -1
  40. package/dist/ptr/llm/providers/MLCLLMProvider.d.ts +22 -0
  41. package/dist/ptr/llm/providers/MLCLLMProvider.d.ts.map +1 -0
  42. package/dist/ptr/llm/providers/MLCLLMProvider.js +155 -0
  43. package/dist/ptr/llm/providers/MLCLLMProvider.js.map +1 -0
  44. package/dist/ptr/llm/providers/WebLLMProvider.d.ts +22 -0
  45. package/dist/ptr/llm/providers/WebLLMProvider.d.ts.map +1 -0
  46. package/dist/ptr/llm/providers/WebLLMProvider.js +151 -0
  47. package/dist/ptr/llm/providers/WebLLMProvider.js.map +1 -0
  48. package/dist/ptr/node/CLMRunner.d.ts +33 -1
  49. package/dist/ptr/node/CLMRunner.d.ts.map +1 -1
  50. package/dist/ptr/node/CLMRunner.js +200 -1
  51. package/dist/ptr/node/CLMRunner.js.map +1 -1
  52. package/dist/ptr/node/NetworkConfig.d.ts +155 -0
  53. package/dist/ptr/node/NetworkConfig.d.ts.map +1 -0
  54. package/dist/ptr/node/NetworkConfig.js +8 -0
  55. package/dist/ptr/node/NetworkConfig.js.map +1 -0
  56. package/dist/ptr/node/NetworkRuntime.d.ts +115 -0
  57. package/dist/ptr/node/NetworkRuntime.d.ts.map +1 -0
  58. package/dist/ptr/node/NetworkRuntime.js +792 -0
  59. package/dist/ptr/node/NetworkRuntime.js.map +1 -0
  60. package/dist/ptr/node/Runtimes.d.ts +8 -1
  61. package/dist/ptr/node/Runtimes.d.ts.map +1 -1
  62. package/dist/ptr/node/Runtimes.js +18 -1
  63. package/dist/ptr/node/Runtimes.js.map +1 -1
  64. package/dist/storage/schema.d.ts.map +1 -1
  65. package/dist/storage/schema.js +5 -1
  66. package/dist/storage/schema.js.map +1 -1
  67. package/package.json +6 -2
package/README.md CHANGED
@@ -13,7 +13,7 @@ Full-featured TypeScript implementation of MCard content-addressable storage, su
13
13
  - **UTF-8 Handles**: International support (文檔, مستند, ドキュメント, документ)
14
14
  - **Monadic API**: Maybe, Either, IO monads for functional composition
15
15
  - **PTR Runtime**: Polynomial Type Runtime with polyglot execution (JS, Python, Rust, C, WASM, Lean)
16
- - **LLM Integration**: Ollama provider for local LLM execution
16
+ - **LLM Integration**: Ollama, WebLLM (browser), and MLC-LLM providers
17
17
  - **Vector Search**: sqlite-vec extension for semantic similarity search
18
18
 
19
19
  ## Quick Start
@@ -303,6 +303,82 @@ npx tsx src/ptr/node/cli.ts status
303
303
  npx tsx src/ptr/node/cli.ts list
304
304
  ```
305
305
 
306
+ ### Lambda Calculus Runtime
307
+
308
+ The `LambdaRuntime` implements α-β-η conversions on MCard-stored Lambda terms:
309
+
310
+ ```typescript
311
+ import { Lambda, LambdaRuntime, CardCollection, SqliteNodeEngine } from 'mcard-js';
312
+
313
+ // Initialize
314
+ const engine = new SqliteNodeEngine(':memory:');
315
+ const collection = new CardCollection(engine);
316
+ const runtime = new LambdaRuntime(collection);
317
+
318
+ // Parse a Lambda expression - terms are stored as MCards!
319
+ const { termHash } = await runtime.execute('', { expression: '(\\x.x) y' }, { operation: 'parse' }, '');
320
+
321
+ // Normalize (apply β-reductions until normal form)
322
+ const result = await runtime.execute(termHash, {}, { operation: 'normalize' }, '');
323
+ console.log(result.prettyPrint); // "y"
324
+
325
+ // Or use the API directly:
326
+ const { parseLambdaExpression, normalize, alphaRename, betaReduce, etaReduce } = Lambda;
327
+
328
+ // Parse: (λx.λy.x) a b
329
+ const termHash2 = await parseLambdaExpression(collection, '(\\x.\\y.x) a b');
330
+
331
+ // Normalize to "a"
332
+ const normResult = await normalize(collection, termHash2, 'normal', 100).run();
333
+ console.log(normResult.right.normalForm); // Hash of normalized term
334
+ ```
335
+
336
+ **Key Features:**
337
+ - **α-conversion**: Rename bound variables (`alphaRename`, `alphaEquivalent`)
338
+ - **β-reduction**: Function application (`betaReduce`, `normalize`)
339
+ - **η-conversion**: Extensional equivalence (`etaReduce`, `etaExpand`)
340
+ - **Parser**: Simple Lambda syntax with `\x.M` or `λx.M`
341
+ - **MCard Storage**: Terms are hashes, enabling structural sharing and memoization
342
+
343
+ ### Multi-Runtime CLM Execution
344
+
345
+ The PTR supports executing CLMs across multiple runtimes with **consensus verification**:
346
+
347
+ ```typescript
348
+ import { CLMRunner, CLMLoader } from 'mcard-js/ptr/node';
349
+
350
+ const loader = new CLMLoader('.');
351
+ const runner = new CLMRunner('.');
352
+
353
+ // Load a multi-runtime CLM
354
+ const clm = loader.load('polyglot_comparison.yaml');
355
+
356
+ // Execute across all configured runtimes (Python, JS, Rust, C, WASM, Lean)
357
+ const result = await runner.executeMultiRuntime(clm, './chapters', { a: 5, b: 3 });
358
+
359
+ console.log(result.consensus); // true - all runtimes agree
360
+ console.log(result.consensusValue); // 8 - the agreed result
361
+ console.log(result.results); // Per-runtime results
362
+ ```
363
+
364
+ **CLI Usage:**
365
+ ```bash
366
+ # Run all CLMs across all chapters
367
+ npm run clm:all
368
+
369
+ # Run specific chapter
370
+ npm run clm:chapter chapter_01_arithmetic
371
+
372
+ # Run Lambda CLMs (specialized runner)
373
+ npm run clm:lambda
374
+ ```
375
+
376
+ **Features:**
377
+ - **Polyglot Consensus**: Verifies all runtimes produce identical results
378
+ - **Floating-Point Tolerance**: Handles precision differences with configurable tolerance (1e-9)
379
+ - **Graceful Fallback**: Unknown runtimes (R, Julia) are skipped, consensus among available runtimes
380
+ - **Legacy Format Support**: Handles both top-level `examples` and `balanced.examples`
381
+
306
382
  ## Content Detection
307
383
 
308
384
  The `ContentTypeInterpreter` module provides intelligent content type detection with parity to the Python implementation.
@@ -454,20 +530,59 @@ To run integration tests against a live Ollama instance:
454
530
  npx vitest tests/rag/Integration.test.ts
455
531
  ```
456
532
 
457
- ## Version 2.1.0 Release Notes (December 2025)
533
+ ## Version 2.1.2 Release Notes (December 2025)
458
534
  > Python Parity Update
459
535
 
460
536
  ### 🚀 New Features
537
+ * **Multi-Runtime Consensus**: Execute CLMs across Python, JS, Rust, C, WASM, Lean with automatic consensus verification.
538
+ * **Lambda Calculus Runtime**: Full α-β-η conversion engine in `src/ptr/lambda/` with parser and MCard-based term storage.
461
539
  * **GraphRAGEngine**: Full RAG orchestration in `src/rag/GraphRAGEngine.ts` matching Python's capabilities.
462
540
  * **Bulk Loader**: New `Loader` module for robust file ingestion with safety checks.
463
541
  * **LLM Monads**: `promptMonad` and `chatMonad` added to `LLMRuntime` for functional composition.
464
542
  * **Collection Search**: Enhanced `CardCollection` with search capabilities (content, hash, string).
543
+ * **CLM Test Runner**: New CLI (`npm run clm:all`) for running all CLMs with summary reporting.
544
+
545
+ ### 🌐 Network IO Enhancements
546
+ * **Retry with Backoff**: Configurable retry logic with `exponential`, `linear`, or `constant` backoff strategies.
547
+ ```typescript
548
+ config: {
549
+ url: 'https://api.example.com/data',
550
+ retry: {
551
+ max_attempts: 3,
552
+ backoff: 'exponential',
553
+ base_delay: 1000,
554
+ max_delay: 30000,
555
+ retry_on: [503, 429, 500] // Optional: custom status codes
556
+ }
557
+ }
558
+ ```
559
+ * **Response Caching**: Memory or MCard-persistent caching with TTL support.
560
+ ```typescript
561
+ config: {
562
+ url: 'https://api.example.com/cacheable',
563
+ cache: {
564
+ enabled: true,
565
+ ttl: 300, // seconds
566
+ storage: 'memory' // or 'mcard' for persistent
567
+ }
568
+ }
569
+ ```
570
+ * **Rate Limiting**: Token-bucket rate limiting per domain (10 req/sec default with burst of 20).
571
+ * **Bidirectional Sync**: New `both` and `bidirectional` modes for `mcard_sync` to push and pull in one operation.
572
+ ```typescript
573
+ config: {
574
+ url: 'http://remote:3000/sync',
575
+ mode: 'both' // pushes local cards, then pulls remote cards
576
+ }
577
+ ```
578
+
465
579
 
466
580
  ### 🛠️ Polyglot Runtime Fixes
467
- * **ESM Compatibility**: Fixed `ReferenceError: require is not defined` in `SqliteNodeEngine`.
581
+ * **ESM Compatibility**: Fixed `ReferenceError: require is not defined` in `SqliteNodeEngine` and `schema.ts`.
468
582
  * **Double-Encoding Fix**: Resolved input context double-JSON-encoding.
469
583
  * **Loader Context Injection**: Fixed `CLMRunner` context passing.
470
584
  * **CLM Example Iteration**: Updated `CLMLoader` for better example handling.
585
+ * **Floating-Point Tolerance**: Added configurable tolerance for numeric consensus (1e-9).
471
586
 
472
587
  ### Previous Fixes (2.0.0)
473
588
  ### SQLite Foreign Key Constraint Fix
package/dist/index.d.ts CHANGED
@@ -23,4 +23,6 @@ import * as Loader from './util/Loader';
23
23
  export { FileIO, Loader };
24
24
  export { LLMRuntime, promptMonad, chatMonad } from './ptr/llm/LLMRuntime';
25
25
  export { LLMConfig } from './ptr/llm/Config';
26
+ export * as Lambda from './ptr/lambda';
27
+ export { LambdaRuntime } from './ptr/lambda/LambdaRuntime';
26
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,cAAc,oBAAoB,CAAC;AAInC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,cAAc,oBAAoB,CAAC;AAInC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -31,4 +31,7 @@ export { FileIO, Loader };
31
31
  // LLM
32
32
  export { LLMRuntime, promptMonad, chatMonad } from './ptr/llm/LLMRuntime';
33
33
  export { LLMConfig } from './ptr/llm/Config';
34
+ // Lambda Calculus Runtime (α-β-η conversions)
35
+ export * as Lambda from './ptr/lambda';
36
+ export { LambdaRuntime } from './ptr/lambda/LambdaRuntime';
34
37
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,2CAA2C;AAE3C,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAIzE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO;AACP,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,SAAS;AACT,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,gCAAgC;AAChC,OAAO,EAAE,YAAY,EAAmC,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,cAAc,oBAAoB,CAAC;AAEnC,QAAQ;AACR,0DAA0D;AAC1D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE1B,MAAM;AACN,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,2CAA2C;AAE3C,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAIzE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO;AACP,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,SAAS;AACT,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,gCAAgC;AAChC,OAAO,EAAE,YAAY,EAAmC,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,cAAc,oBAAoB,CAAC;AAEnC,QAAQ;AACR,0DAA0D;AAC1D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE1B,MAAM;AACN,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,8CAA8C;AAC9C,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Alpha Conversion (α-conversion)
3
+ *
4
+ * Renames bound variables in Lambda terms while preserving meaning.
5
+ *
6
+ * Rule: λx.M ≡α λy.M[x:=y] (where y is fresh)
7
+ *
8
+ * Alpha conversion is the basis of variable renaming and is essential
9
+ * for avoiding variable capture during beta reduction.
10
+ *
11
+ * @module mcard-js/ptr/lambda/AlphaConversion
12
+ */
13
+ import { CardCollection } from '../../model/CardCollection';
14
+ import { IO } from '../../monads/IO';
15
+ import { Either } from '../../monads/Either';
16
+ /**
17
+ * Alpha-rename: Rename the bound variable of an abstraction
18
+ *
19
+ * λx.M → λy.M[x:=y]
20
+ *
21
+ * @param collection - Card collection for term storage
22
+ * @param absHash - Hash of the abstraction term
23
+ * @param newParam - New name for the bound variable
24
+ * @returns IO<Either<error, newHash>>
25
+ */
26
+ export declare function alphaRename(collection: CardCollection, absHash: string, newParam: string): IO<Either<string, string>>;
27
+ /**
28
+ * Check if two terms are alpha-equivalent
29
+ *
30
+ * Two terms are α-equivalent if they differ only in the names of bound variables.
31
+ *
32
+ * Note: If hashes are equal, terms are definitionally identical (stronger than α-equiv).
33
+ */
34
+ export declare function alphaEquivalent(collection: CardCollection, hash1: string, hash2: string): IO<Either<string, boolean>>;
35
+ /**
36
+ * Alpha-normalize a term using canonical variable names
37
+ *
38
+ * All bound variables are renamed to a₀, a₁, a₂... based on binding depth.
39
+ * This produces a canonical representative of the α-equivalence class.
40
+ */
41
+ export declare function alphaNormalize(collection: CardCollection, termHash: string): IO<Either<string, string>>;
42
+ //# sourceMappingURL=AlphaConversion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlphaConversion.d.ts","sourceRoot":"","sources":["../../../src/ptr/lambda/AlphaConversion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAa5D,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAM7C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACvB,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwC5B;AA+DD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC3B,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACd,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgB7B;AA6ED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQ5B"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Alpha Conversion (α-conversion)
3
+ *
4
+ * Renames bound variables in Lambda terms while preserving meaning.
5
+ *
6
+ * Rule: λx.M ≡α λy.M[x:=y] (where y is fresh)
7
+ *
8
+ * Alpha conversion is the basis of variable renaming and is essential
9
+ * for avoiding variable capture during beta reduction.
10
+ *
11
+ * @module mcard-js/ptr/lambda/AlphaConversion
12
+ */
13
+ import { loadTerm, storeTerm, mkVar, mkAbs, mkApp, isAbs } from './LambdaTerm';
14
+ import { freeVariables } from './FreeVariables';
15
+ import { IO } from '../../monads/IO';
16
+ import { Either } from '../../monads/Either';
17
+ // ─────────────────────────────────────────────────────────────────────────────
18
+ // Alpha Conversion
19
+ // ─────────────────────────────────────────────────────────────────────────────
20
+ /**
21
+ * Alpha-rename: Rename the bound variable of an abstraction
22
+ *
23
+ * λx.M → λy.M[x:=y]
24
+ *
25
+ * @param collection - Card collection for term storage
26
+ * @param absHash - Hash of the abstraction term
27
+ * @param newParam - New name for the bound variable
28
+ * @returns IO<Either<error, newHash>>
29
+ */
30
+ export function alphaRename(collection, absHash, newParam) {
31
+ return IO.of(async () => {
32
+ const term = await loadTerm(collection, absHash);
33
+ if (!term) {
34
+ return Either.left(`Term not found: ${absHash}`);
35
+ }
36
+ if (!isAbs(term)) {
37
+ return Either.left(`Alpha conversion only applies to abstractions, got ${term.tag}`);
38
+ }
39
+ // If same name, no change needed
40
+ if (term.param === newParam) {
41
+ return Either.right(absHash);
42
+ }
43
+ // Check that new name doesn't capture free variables in body
44
+ const bodyFV = await freeVariables(collection, term.body).run();
45
+ if (bodyFV.isJust && bodyFV.value.has(newParam)) {
46
+ return Either.left(`Cannot α-rename to '${newParam}': would capture free variable in body`);
47
+ }
48
+ // Substitute old param with new param in body
49
+ const newBodyHash = await substituteVar(collection, term.body, term.param, newParam);
50
+ // Create new abstraction
51
+ const newAbs = mkAbs(newParam, newBodyHash);
52
+ const resultHash = await storeTerm(collection, newAbs);
53
+ return Either.right(resultHash);
54
+ });
55
+ }
56
+ /**
57
+ * Substitute a variable with another variable name throughout a term
58
+ *
59
+ * M[x:=y] - replaces all free occurrences of x with y
60
+ */
61
+ async function substituteVar(collection, termHash, oldVar, newVar) {
62
+ const term = await loadTerm(collection, termHash);
63
+ if (!term) {
64
+ throw new Error(`Term not found: ${termHash}`);
65
+ }
66
+ switch (term.tag) {
67
+ case 'Var':
68
+ if (term.name === oldVar) {
69
+ // Replace with new variable
70
+ const newTerm = mkVar(newVar);
71
+ return storeTerm(collection, newTerm);
72
+ }
73
+ // Different variable, unchanged
74
+ return termHash;
75
+ case 'Abs':
76
+ if (term.param === oldVar) {
77
+ // Bound variable shadows, stop substitution
78
+ return termHash;
79
+ }
80
+ // Recurse into body
81
+ const newBody = await substituteVar(collection, term.body, oldVar, newVar);
82
+ if (newBody === term.body) {
83
+ // No change
84
+ return termHash;
85
+ }
86
+ const newAbs = mkAbs(term.param, newBody);
87
+ return storeTerm(collection, newAbs);
88
+ case 'App':
89
+ const newFunc = await substituteVar(collection, term.func, oldVar, newVar);
90
+ const newArg = await substituteVar(collection, term.arg, oldVar, newVar);
91
+ if (newFunc === term.func && newArg === term.arg) {
92
+ // No change
93
+ return termHash;
94
+ }
95
+ const newApp = mkApp(newFunc, newArg);
96
+ return storeTerm(collection, newApp);
97
+ }
98
+ }
99
+ // ─────────────────────────────────────────────────────────────────────────────
100
+ // Alpha Equivalence
101
+ // ─────────────────────────────────────────────────────────────────────────────
102
+ /**
103
+ * Check if two terms are alpha-equivalent
104
+ *
105
+ * Two terms are α-equivalent if they differ only in the names of bound variables.
106
+ *
107
+ * Note: If hashes are equal, terms are definitionally identical (stronger than α-equiv).
108
+ */
109
+ export function alphaEquivalent(collection, hash1, hash2) {
110
+ return IO.of(async () => {
111
+ // Same hash = identical terms
112
+ if (hash1 === hash2) {
113
+ return Either.right(true);
114
+ }
115
+ const term1 = await loadTerm(collection, hash1);
116
+ const term2 = await loadTerm(collection, hash2);
117
+ if (!term1)
118
+ return Either.left(`Term not found: ${hash1}`);
119
+ if (!term2)
120
+ return Either.left(`Term not found: ${hash2}`);
121
+ const equiv = await checkAlphaEquiv(collection, term1, term2, new Map(), new Map());
122
+ return Either.right(equiv);
123
+ });
124
+ }
125
+ /**
126
+ * Internal alpha-equivalence check with variable renaming maps
127
+ */
128
+ async function checkAlphaEquiv(collection, term1, term2, rename1, // Maps var name in term1 to de Bruijn index
129
+ rename2 // Maps var name in term2 to de Bruijn index
130
+ ) {
131
+ if (term1.tag !== term2.tag) {
132
+ return false;
133
+ }
134
+ switch (term1.tag) {
135
+ case 'Var': {
136
+ const t2 = term2;
137
+ const idx1 = rename1.get(term1.name);
138
+ const idx2 = rename2.get(t2.name);
139
+ if (idx1 !== undefined && idx2 !== undefined) {
140
+ // Both are bound variables - compare by binding depth
141
+ return idx1 === idx2;
142
+ }
143
+ if (idx1 === undefined && idx2 === undefined) {
144
+ // Both are free variables - compare by name
145
+ return term1.name === t2.name;
146
+ }
147
+ // One bound, one free - not equivalent
148
+ return false;
149
+ }
150
+ case 'Abs': {
151
+ const t2 = term2;
152
+ // Extend renaming maps with new binding
153
+ const depth = rename1.size;
154
+ const newRename1 = new Map(rename1);
155
+ const newRename2 = new Map(rename2);
156
+ newRename1.set(term1.param, depth);
157
+ newRename2.set(t2.param, depth);
158
+ // Load and compare bodies
159
+ const body1 = await loadTerm(collection, term1.body);
160
+ const body2 = await loadTerm(collection, t2.body);
161
+ if (!body1 || !body2)
162
+ return false;
163
+ return checkAlphaEquiv(collection, body1, body2, newRename1, newRename2);
164
+ }
165
+ case 'App': {
166
+ const t2 = term2;
167
+ const func1 = await loadTerm(collection, term1.func);
168
+ const func2 = await loadTerm(collection, t2.func);
169
+ const arg1 = await loadTerm(collection, term1.arg);
170
+ const arg2 = await loadTerm(collection, t2.arg);
171
+ if (!func1 || !func2 || !arg1 || !arg2)
172
+ return false;
173
+ const funcEquiv = await checkAlphaEquiv(collection, func1, func2, rename1, rename2);
174
+ if (!funcEquiv)
175
+ return false;
176
+ return checkAlphaEquiv(collection, arg1, arg2, rename1, rename2);
177
+ }
178
+ }
179
+ }
180
+ // ─────────────────────────────────────────────────────────────────────────────
181
+ // Alpha Normalization (De Bruijn-like canonical form)
182
+ // ─────────────────────────────────────────────────────────────────────────────
183
+ /**
184
+ * Alpha-normalize a term using canonical variable names
185
+ *
186
+ * All bound variables are renamed to a₀, a₁, a₂... based on binding depth.
187
+ * This produces a canonical representative of the α-equivalence class.
188
+ */
189
+ export function alphaNormalize(collection, termHash) {
190
+ return IO.of(async () => {
191
+ const result = await normalizeWithDepth(collection, termHash, new Map(), 0);
192
+ if (result === null) {
193
+ return Either.left(`Term not found: ${termHash}`);
194
+ }
195
+ return Either.right(result);
196
+ });
197
+ }
198
+ /**
199
+ * Internal normalization with depth tracking
200
+ */
201
+ async function normalizeWithDepth(collection, termHash, bindings, // original name -> canonical name
202
+ depth) {
203
+ const term = await loadTerm(collection, termHash);
204
+ if (!term)
205
+ return null;
206
+ switch (term.tag) {
207
+ case 'Var': {
208
+ const canonicalName = bindings.get(term.name);
209
+ if (canonicalName) {
210
+ // Bound variable - use canonical name
211
+ const newVar = mkVar(canonicalName);
212
+ return storeTerm(collection, newVar);
213
+ }
214
+ // Free variable - keep original name
215
+ return termHash;
216
+ }
217
+ case 'Abs': {
218
+ // Generate canonical name for this binding depth
219
+ const canonicalName = `a${depth}`;
220
+ // Extend bindings
221
+ const newBindings = new Map(bindings);
222
+ newBindings.set(term.param, canonicalName);
223
+ // Normalize body
224
+ const newBody = await normalizeWithDepth(collection, term.body, newBindings, depth + 1);
225
+ if (newBody === null)
226
+ return null;
227
+ const newAbs = mkAbs(canonicalName, newBody);
228
+ return storeTerm(collection, newAbs);
229
+ }
230
+ case 'App': {
231
+ const newFunc = await normalizeWithDepth(collection, term.func, bindings, depth);
232
+ const newArg = await normalizeWithDepth(collection, term.arg, bindings, depth);
233
+ if (newFunc === null || newArg === null)
234
+ return null;
235
+ // If unchanged, return original
236
+ if (newFunc === term.func && newArg === term.arg) {
237
+ return termHash;
238
+ }
239
+ const newApp = mkApp(newFunc, newArg);
240
+ return storeTerm(collection, newApp);
241
+ }
242
+ }
243
+ }
244
+ //# sourceMappingURL=AlphaConversion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlphaConversion.js","sourceRoot":"","sources":["../../../src/ptr/lambda/AlphaConversion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Beta Reduction (β-reduction)
3
+ *
4
+ * The computational heart of Lambda Calculus - function application.
5
+ *
6
+ * Rule: (λx.M) N →β M[x:=N]
7
+ *
8
+ * A term of the form (λx.M) N is called a "beta-redex" (reducible expression).
9
+ * Beta reduction substitutes the argument N for all free occurrences of x in M.
10
+ *
11
+ * IMPORTANT: Must handle capture avoidance - if N contains free variables
12
+ * that would become bound in M, we must α-rename first.
13
+ *
14
+ * @module mcard-js/ptr/lambda/BetaReduction
15
+ */
16
+ import { CardCollection } from '../../model/CardCollection';
17
+ import { IO } from '../../monads/IO';
18
+ import { Either } from '../../monads/Either';
19
+ import { Maybe } from '../../monads/Maybe';
20
+ /**
21
+ * Check if a term is a beta-redex: (λx.M) N
22
+ */
23
+ export declare function isRedex(collection: CardCollection, termHash: string): IO<boolean>;
24
+ /**
25
+ * Find the leftmost-outermost redex (normal order reduction)
26
+ * Returns Maybe<hash of redex>
27
+ */
28
+ export declare function findLeftmostRedex(collection: CardCollection, termHash: string): IO<Maybe<string>>;
29
+ /**
30
+ * Find the leftmost-innermost redex (applicative order reduction)
31
+ */
32
+ export declare function findInnermostRedex(collection: CardCollection, termHash: string): IO<Maybe<string>>;
33
+ /**
34
+ * Perform a single beta reduction step on a redex
35
+ *
36
+ * (λx.M) N →β M[x:=N]
37
+ *
38
+ * @param collection - Card collection
39
+ * @param redexHash - Hash of the application term (λx.M) N
40
+ * @returns Either<error, resultHash>
41
+ */
42
+ export declare function betaReduce(collection: CardCollection, redexHash: string): IO<Either<string, string>>;
43
+ export type ReductionStrategy = 'normal' | 'applicative' | 'lazy';
44
+ /**
45
+ * Perform one reduction step using the specified strategy
46
+ */
47
+ export declare function reduceStep(collection: CardCollection, termHash: string, strategy?: ReductionStrategy): IO<Maybe<string>>;
48
+ export interface NormalizationResult {
49
+ normalForm: string;
50
+ steps: number;
51
+ reductionPath: string[];
52
+ }
53
+ /**
54
+ * Normalize a term to its normal form (no more redexes)
55
+ *
56
+ * @param collection - Card collection
57
+ * @param termHash - Starting term
58
+ * @param strategy - Reduction strategy
59
+ * @param maxSteps - Maximum reduction steps (prevent infinite loops)
60
+ * @returns Either<error, NormalizationResult>
61
+ */
62
+ export declare function normalize(collection: CardCollection, termHash: string, strategy?: ReductionStrategy, maxSteps?: number): IO<Either<string, NormalizationResult>>;
63
+ /**
64
+ * Check if a term is in normal form (has no redexes)
65
+ */
66
+ export declare function isNormalForm(collection: CardCollection, termHash: string): IO<boolean>;
67
+ /**
68
+ * Check if a term has a normal form (is normalizing)
69
+ *
70
+ * Note: This is undecidable in general, so we use a bounded check
71
+ */
72
+ export declare function hasNormalForm(collection: CardCollection, termHash: string, maxSteps?: number): IO<boolean>;
73
+ //# sourceMappingURL=BetaReduction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BetaReduction.d.ts","sourceRoot":"","sources":["../../../src/ptr/lambda/BetaReduction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAgB5D,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAM3C;;GAEG;AACH,wBAAgB,OAAO,CACnB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,OAAO,CAAC,CAQb;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAInB;AAmCD;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAInB;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACtB,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,MAAM,GAClB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkC5B;AA+GD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;AAElE;;GAEG;AACH,wBAAgB,UAAU,CACtB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,iBAA4B,GACvC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CA8CnB;AA8DD,MAAM,WAAW,mBAAmB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACrB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,iBAA4B,EACtC,QAAQ,GAAE,MAAa,GACxB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CA2BzC;AAED;;GAEG;AACH,wBAAgB,YAAY,CACxB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACjB,EAAE,CAAC,OAAO,CAAC,CAEb;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CACzB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAa,GACxB,EAAE,CAAC,OAAO,CAAC,CAGb"}