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.
- package/README.md +118 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/ptr/lambda/AlphaConversion.d.ts +42 -0
- package/dist/ptr/lambda/AlphaConversion.d.ts.map +1 -0
- package/dist/ptr/lambda/AlphaConversion.js +244 -0
- package/dist/ptr/lambda/AlphaConversion.js.map +1 -0
- package/dist/ptr/lambda/BetaReduction.d.ts +73 -0
- package/dist/ptr/lambda/BetaReduction.d.ts.map +1 -0
- package/dist/ptr/lambda/BetaReduction.js +322 -0
- package/dist/ptr/lambda/BetaReduction.js.map +1 -0
- package/dist/ptr/lambda/EtaConversion.d.ts +65 -0
- package/dist/ptr/lambda/EtaConversion.d.ts.map +1 -0
- package/dist/ptr/lambda/EtaConversion.js +228 -0
- package/dist/ptr/lambda/EtaConversion.js.map +1 -0
- package/dist/ptr/lambda/FreeVariables.d.ts +44 -0
- package/dist/ptr/lambda/FreeVariables.d.ts.map +1 -0
- package/dist/ptr/lambda/FreeVariables.js +207 -0
- package/dist/ptr/lambda/FreeVariables.js.map +1 -0
- package/dist/ptr/lambda/LambdaRuntime.d.ts +80 -0
- package/dist/ptr/lambda/LambdaRuntime.d.ts.map +1 -0
- package/dist/ptr/lambda/LambdaRuntime.js +417 -0
- package/dist/ptr/lambda/LambdaRuntime.js.map +1 -0
- package/dist/ptr/lambda/LambdaTerm.d.ts +95 -0
- package/dist/ptr/lambda/LambdaTerm.d.ts.map +1 -0
- package/dist/ptr/lambda/LambdaTerm.js +159 -0
- package/dist/ptr/lambda/LambdaTerm.js.map +1 -0
- package/dist/ptr/lambda/index.d.ts +24 -0
- package/dist/ptr/lambda/index.d.ts.map +1 -0
- package/dist/ptr/lambda/index.js +34 -0
- package/dist/ptr/lambda/index.js.map +1 -0
- package/dist/ptr/llm/Config.d.ts.map +1 -1
- package/dist/ptr/llm/Config.js +16 -0
- package/dist/ptr/llm/Config.js.map +1 -1
- package/dist/ptr/llm/LLMRuntime.d.ts.map +1 -1
- package/dist/ptr/llm/LLMRuntime.js +8 -0
- package/dist/ptr/llm/LLMRuntime.js.map +1 -1
- package/dist/ptr/llm/providers/MLCLLMProvider.d.ts +22 -0
- package/dist/ptr/llm/providers/MLCLLMProvider.d.ts.map +1 -0
- package/dist/ptr/llm/providers/MLCLLMProvider.js +155 -0
- package/dist/ptr/llm/providers/MLCLLMProvider.js.map +1 -0
- package/dist/ptr/llm/providers/WebLLMProvider.d.ts +22 -0
- package/dist/ptr/llm/providers/WebLLMProvider.d.ts.map +1 -0
- package/dist/ptr/llm/providers/WebLLMProvider.js +151 -0
- package/dist/ptr/llm/providers/WebLLMProvider.js.map +1 -0
- package/dist/ptr/node/CLMRunner.d.ts +33 -1
- package/dist/ptr/node/CLMRunner.d.ts.map +1 -1
- package/dist/ptr/node/CLMRunner.js +200 -1
- package/dist/ptr/node/CLMRunner.js.map +1 -1
- package/dist/ptr/node/NetworkConfig.d.ts +155 -0
- package/dist/ptr/node/NetworkConfig.d.ts.map +1 -0
- package/dist/ptr/node/NetworkConfig.js +8 -0
- package/dist/ptr/node/NetworkConfig.js.map +1 -0
- package/dist/ptr/node/NetworkRuntime.d.ts +115 -0
- package/dist/ptr/node/NetworkRuntime.d.ts.map +1 -0
- package/dist/ptr/node/NetworkRuntime.js +792 -0
- package/dist/ptr/node/NetworkRuntime.js.map +1 -0
- package/dist/ptr/node/Runtimes.d.ts +8 -1
- package/dist/ptr/node/Runtimes.d.ts.map +1 -1
- package/dist/ptr/node/Runtimes.js +18 -1
- package/dist/ptr/node/Runtimes.js.map +1 -1
- package/dist/storage/schema.d.ts.map +1 -1
- package/dist/storage/schema.js +5 -1
- package/dist/storage/schema.js.map +1 -1
- 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
|
|
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.
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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"}
|