recursive-set 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Christian Strerath
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # RecursiveSet
2
+
3
+ > Mutable, recursive set implementation for TypeScript – inspired by Cantor's and ZFC set theory.
4
+
5
+ Supports arbitrary nesting, detects cycles (Foundation axiom), and includes all classic set operations (union, intersection, difference, powerset etc.).
6
+
7
+ [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
8
+ [![npm version](https://img.shields.io/npm/v/recursive-set.svg)](https://www.npmjs.com/package/recursive-set)
9
+
10
+ ---
11
+
12
+ ## Features
13
+
14
+ ✨ **Mutable, recursive sets** with arbitrary depth
15
+ 🔍 **Extensional equality** (two sets are equal iff their elements are equal)
16
+ 🛡️ **Cycle detection** (Foundation Axiom): prevents self-containing sets
17
+ 🧮 **Classic set operations**: union, intersection, difference, symmetric difference
18
+ 📐 **Power set and Cartesian product**
19
+ 🎯 **TypeScript generics**: works with strings, numbers, objects, states, even sets of sets
20
+ 🤖 **Ready for FSM**, mathematical, symbolic and practical use cases
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```
27
+
28
+ npm install recursive-set
29
+
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Quickstart
35
+
36
+ ```
37
+
38
+ import { RecursiveSet } from "recursive-set";
39
+
40
+ const q0 = "q0", q1 = "q1";
41
+ const eqClass = new RecursiveSet(q0, q1); // {q0, q1}
42
+ const classes = new RecursiveSet(eqClass);
43
+
44
+ classes.add(new RecursiveSet("q2", "q3")); // {{q0, q1}, {q2, q3}}
45
+
46
+ console.log(classes.toString()); // {{q0, q1}, {q2, q3}}
47
+
48
+ ```
49
+
50
+ ---
51
+
52
+ ## API Reference
53
+
54
+ ### Constructor
55
+
56
+ ```
57
+
58
+ new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
59
+
60
+ ```
61
+
62
+ ### Methods
63
+
64
+ **Mutation:**
65
+ - `add(element: T | RecursiveSet<T>): this` – Add element (chainable)
66
+ - `remove(element: T | RecursiveSet<T>): this` – Remove element (chainable)
67
+ - `clear(): this` – Remove all elements (chainable)
68
+
69
+ **Set Operations:**
70
+ - `union(other: RecursiveSet<T>): RecursiveSet<T>` – A ∪ B
71
+ - `intersection(other: RecursiveSet<T>): RecursiveSet<T>` – A ∩ B
72
+ - `difference(other: RecursiveSet<T>): RecursiveSet<T>` – A \ B
73
+ - `symmetricDifference(other: RecursiveSet<T>): RecursiveSet<T>` – A △ B
74
+
75
+ **Advanced Operations:**
76
+ - `powerset(): RecursiveSet<RecursiveSet<T>>` – 𝒫(A)
77
+ - `cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<RecursiveSet<T | U>>` – A × B
78
+
79
+ **Predicates:**
80
+ - `has(element: T | RecursiveSet<T>): boolean` – Check membership
81
+ - `isSubset(other: RecursiveSet<T>): boolean` – Check if ⊆
82
+ - `isSuperset(other: RecursiveSet<T>): boolean` – Check if ⊇
83
+ - `equals(other: RecursiveSet<T>): boolean` – Structural equality
84
+ - `isEmpty(): boolean` – Check if set is empty
85
+
86
+ **Properties:**
87
+ - `size: number` – Cardinality |A|
88
+ - `toString(): string` – Pretty print with ∅ and {}
89
+
90
+ ---
91
+
92
+ ## Examples
93
+
94
+ ### Basic Usage
95
+
96
+ ```
97
+
98
+ const s1 = new RecursiveSet(1, 2, 3);
99
+ const s2 = new RecursiveSet(2, 3, 4);
100
+
101
+ console.log(s1.union(s2)); // {1, 2, 3, 4}
102
+ console.log(s1.intersection(s2)); // {2, 3}
103
+ console.log(s1.difference(s2)); // {1}
104
+
105
+ ```
106
+
107
+ ### FSM Equivalence Classes
108
+
109
+ ```
110
+
111
+ const eq1 = new RecursiveSet("q0", "q1");
112
+ const eq2 = new RecursiveSet("q2", "q3");
113
+ const eqClasses = new RecursiveSet(eq1, eq2);
114
+
115
+ console.log(eqClasses.toString()); // {{q0, q1}, {q2, q3}}
116
+
117
+ ```
118
+
119
+ ### Power Set
120
+
121
+ ```
122
+
123
+ const set = new RecursiveSet(1, 2);
124
+ const power = set.powerset();
125
+
126
+ console.log(power.toString()); // {∅, {1}, {2}, {1, 2}}
127
+
128
+ ```
129
+
130
+ ### Foundation Axiom (Cycle Detection)
131
+
132
+ ```
133
+
134
+ const s = new RecursiveSet(1, 2);
135
+ try {
136
+ s.add(s); // ❌ Throws error
137
+ } catch (e) {
138
+ console.error(e.message); // "Foundation axiom violated..."
139
+ }
140
+
141
+ ```
142
+
143
+ ### Method Chaining
144
+
145
+ ```
146
+
147
+ const set = new RecursiveSet(1, 2)
148
+ .add(3)
149
+ .add(4)
150
+ .remove(1);
151
+
152
+ console.log(set); // {2, 3, 4}
153
+
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Use Cases
159
+
160
+ - **Finite State Machine (FSM) minimization**: Equivalence classes of states
161
+ - **Set theory algorithms**: Implement mathematical proofs and algorithms
162
+ - **Graph algorithms**: Represent node sets and partitions
163
+ - **Compiler design**: Symbol tables, scope analysis
164
+ - **Type systems**: Type inference and unification
165
+
166
+ ---
167
+
168
+ ## Development
169
+
170
+ ```
171
+
172
+
173
+ # Clone repository
174
+
175
+ git clone https://github.com/<USERNAME>/recursive-set.git
176
+ cd recursive-set
177
+
178
+ # Install dependencies
179
+
180
+ npm install
181
+
182
+ # Build
183
+
184
+ npm run build
185
+
186
+ # Run tests
187
+
188
+ npx tsx test.ts
189
+
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Contributing
195
+
196
+ Contributions are welcome! Please feel free to submit a Pull Request.
197
+
198
+ ---
199
+
200
+ ## License
201
+
202
+ MIT License
203
+ © 2025 Christian Strerath
204
+
205
+ See [LICENSE](LICENSE) for details.
206
+
207
+ ---
208
+
209
+ ## Acknowledgments
210
+
211
+ Inspired by:
212
+ - Cantor's set theory
213
+ - Zermelo-Fraenkel set theory with the Axiom of Choice (ZFC)
214
+ - Practical needs in FSM algorithms and formal language theory
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "recursive-set",
3
+ "version": "1.0.0",
4
+ "description": "Mutable recursive sets with ZFC axioms for TypeScript",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "watch": "tsc --watch",
17
+ "clean": "rm -rf dist",
18
+ "test": "tsx test.ts"
19
+ },
20
+ "keywords": [
21
+ "set-theory",
22
+ "zfc",
23
+ "cantor",
24
+ "recursive",
25
+ "data-structure",
26
+ "typescript",
27
+ "fsm",
28
+ "formal-languages"
29
+ ],
30
+ "author": "Christian Strerath",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/<USERNAME>/recursive-set.git"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/<USERNAME>/recursive-set/issues"
38
+ },
39
+ "homepage": "https://github.com/<USERNAME>/recursive-set#readme",
40
+ "devDependencies": {
41
+ "@types/node": "^20.0.0",
42
+ "tsx": "^4.20.6",
43
+ "typescript": "^5.6.0"
44
+ }
45
+ }
package/src/index.ts ADDED
@@ -0,0 +1,344 @@
1
+ /**
2
+ * @module recursive-set
3
+ * A mutable recursive set implementation enforcing Cantor's ZFC axioms
4
+ */
5
+
6
+ /**
7
+ * RecursiveSet: Mutable set with arbitrary nesting depth
8
+ *
9
+ * Enforced ZFC Axioms (as class invariants):
10
+ * - Extensionality: Sets with same elements are equal
11
+ * - Foundation (Regularity): No membership cycles allowed
12
+ * - Power Set: Can construct 𝒫(A) for any set A
13
+ * - Union: Can construct A ∪ B for any sets A, B
14
+ * - Pairing: Can construct {a, b} for any elements a, b
15
+ */
16
+ export class RecursiveSet<T = any> {
17
+ private _elements: Set<T | RecursiveSet<T>>;
18
+
19
+ constructor(...elements: Array<T | RecursiveSet<T>>) {
20
+ this._elements = new Set();
21
+ for (const el of elements) {
22
+ this._addElement(el);
23
+ }
24
+ this._checkInvariants();
25
+ }
26
+
27
+ /**
28
+ * Internal: Add element with cycle detection (Foundation axiom)
29
+ */
30
+ private _addElement(el: T | RecursiveSet<T>): void {
31
+ if (el instanceof RecursiveSet) {
32
+ if (this._wouldCreateCycle(el)) {
33
+ throw new Error(
34
+ "Foundation axiom violated: adding this element would create a membership cycle"
35
+ );
36
+ }
37
+ }
38
+ this._elements.add(el);
39
+ }
40
+
41
+ /**
42
+ * Check if adding element would violate Foundation axiom
43
+ */
44
+ private _wouldCreateCycle(element: RecursiveSet<T>): boolean {
45
+ const visited = new Set<RecursiveSet<any>>();
46
+ const toCheck: RecursiveSet<any>[] = [element];
47
+
48
+ while (toCheck.length > 0) {
49
+ const current = toCheck.pop()!;
50
+ if (current === this) {
51
+ return true;
52
+ }
53
+ if (visited.has(current)) {
54
+ continue;
55
+ }
56
+ visited.add(current);
57
+
58
+ for (const el of current._elements) {
59
+ if (el instanceof RecursiveSet) {
60
+ toCheck.push(el);
61
+ }
62
+ }
63
+ }
64
+ return false;
65
+ }
66
+
67
+ /**
68
+ * Verify class invariants (Design by Contract)
69
+ */
70
+ private _checkInvariants(): void {
71
+ // Extensionality: enforced by Set semantics
72
+ // Foundation: enforced by _wouldCreateCycle
73
+ // Well-definedness: enforced by TypeScript type system
74
+
75
+ // Additional runtime checks can be added here
76
+ if (process.env.NODE_ENV === 'development') {
77
+ // More expensive checks only in development
78
+ }
79
+ }
80
+
81
+ // === Mutable Operations ===
82
+
83
+ /**
84
+ * Add element to this set (Pairing axiom)
85
+ * @returns this for method chaining
86
+ */
87
+ add(element: T | RecursiveSet<T>): this {
88
+ this._addElement(element);
89
+ this._checkInvariants();
90
+ return this;
91
+ }
92
+
93
+ /**
94
+ * Remove element from this set
95
+ * @returns this for method chaining
96
+ */
97
+ remove(element: T | RecursiveSet<T>): this {
98
+ this._elements.delete(element);
99
+ return this;
100
+ }
101
+
102
+ /**
103
+ * Remove all elements
104
+ * @returns this for method chaining
105
+ */
106
+ clear(): this {
107
+ this._elements.clear();
108
+ return this;
109
+ }
110
+
111
+ // === Immutable Operations (return new sets) ===
112
+
113
+ /**
114
+ * Union of two sets (Union axiom)
115
+ * Returns A ∪ B
116
+ */
117
+ union(other: RecursiveSet<T>): RecursiveSet<T> {
118
+ const result = new RecursiveSet<T>();
119
+ result._elements = new Set([...this._elements, ...other._elements]);
120
+ return result;
121
+ }
122
+
123
+ /**
124
+ * Intersection of two sets
125
+ * Returns A ∩ B
126
+ */
127
+ intersection(other: RecursiveSet<T>): RecursiveSet<T> {
128
+ const result = new RecursiveSet<T>();
129
+ for (const el of this._elements) {
130
+ if (other.has(el)) {
131
+ result._elements.add(el);
132
+ }
133
+ }
134
+ return result;
135
+ }
136
+
137
+ /**
138
+ * Set difference
139
+ * Returns A \ B (elements in A but not in B)
140
+ */
141
+ difference(other: RecursiveSet<T>): RecursiveSet<T> {
142
+ const result = new RecursiveSet<T>();
143
+ for (const el of this._elements) {
144
+ if (!other.has(el)) {
145
+ result._elements.add(el);
146
+ }
147
+ }
148
+ return result;
149
+ }
150
+
151
+ /**
152
+ * Symmetric difference
153
+ * Returns A △ B (elements in either but not both)
154
+ */
155
+ symmetricDifference(other: RecursiveSet<T>): RecursiveSet<T> {
156
+ return this.union(other).difference(this.intersection(other));
157
+ }
158
+
159
+ /**
160
+ * Power set construction (Power Set axiom)
161
+ * Returns 𝒫(A) - set of all subsets
162
+ */
163
+ powerset(): RecursiveSet<RecursiveSet<T>> {
164
+ const elements = Array.from(this._elements);
165
+ const subsets: RecursiveSet<T>[] = [];
166
+
167
+ // Generate all 2^n subsets
168
+ const n = elements.length;
169
+ for (let i = 0; i < (1 << n); i++) {
170
+ const subset = new RecursiveSet<T>();
171
+ for (let j = 0; j < n; j++) {
172
+ if (i & (1 << j)) {
173
+ subset._elements.add(elements[j]);
174
+ }
175
+ }
176
+ subsets.push(subset);
177
+ }
178
+
179
+ return new RecursiveSet<RecursiveSet<T>>(...subsets);
180
+ }
181
+
182
+ /**
183
+ * Cartesian product
184
+ * Returns A × B as set of ordered pairs {{a}, {a,b}}
185
+ */
186
+ cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<RecursiveSet<T | U>> {
187
+ const pairs: RecursiveSet<T | U>[] = [];
188
+
189
+ for (const x of this._elements) {
190
+ for (const y of other._elements) {
191
+ // Kuratowski ordered pair: (x,y) := {{x}, {x,y}}
192
+ const pair = new RecursiveSet<T | U>(
193
+ new RecursiveSet<T | U>(x),
194
+ new RecursiveSet<T | U>(x, y)
195
+ );
196
+ pairs.push(pair);
197
+ }
198
+ }
199
+
200
+ return new RecursiveSet<RecursiveSet<T | U>>(...pairs);
201
+ }
202
+
203
+ // === Predicates ===
204
+
205
+ /**
206
+ * Check membership (∈)
207
+ */
208
+ has(element: T | RecursiveSet<T>): boolean {
209
+ return this._elements.has(element);
210
+ }
211
+
212
+ /**
213
+ * Check if subset (⊆)
214
+ */
215
+ isSubset(other: RecursiveSet<T>): boolean {
216
+ for (const el of this._elements) {
217
+ if (!other.has(el)) {
218
+ return false;
219
+ }
220
+ }
221
+ return true;
222
+ }
223
+
224
+ /**
225
+ * Check if superset (⊇)
226
+ */
227
+ isSuperset(other: RecursiveSet<T>): boolean {
228
+ return other.isSubset(this);
229
+ }
230
+
231
+ /**
232
+ * Check if proper subset (⊂)
233
+ */
234
+ isProperSubset(other: RecursiveSet<T>): boolean {
235
+ return this.isSubset(other) && !this.equals(other);
236
+ }
237
+
238
+ /**
239
+ * Check if empty set
240
+ */
241
+ isEmpty(): boolean {
242
+ return this._elements.size === 0;
243
+ }
244
+
245
+ // === Extensionality (Equality) ===
246
+
247
+ /**
248
+ * Structural equality (Extensionality axiom)
249
+ * Two sets are equal iff they have the same elements
250
+ */
251
+ equals(other: RecursiveSet<T>): boolean {
252
+ if (this._elements.size !== other._elements.size) {
253
+ return false;
254
+ }
255
+
256
+ for (const el of this._elements) {
257
+ if (el instanceof RecursiveSet) {
258
+ // Deep comparison for nested sets
259
+ let found = false;
260
+ for (const otherEl of other._elements) {
261
+ if (otherEl instanceof RecursiveSet && el.equals(otherEl)) {
262
+ found = true;
263
+ break;
264
+ }
265
+ }
266
+ if (!found) return false;
267
+ } else {
268
+ if (!other.has(el)) return false;
269
+ }
270
+ }
271
+ return true;
272
+ }
273
+
274
+ // === Utility ===
275
+
276
+ /**
277
+ * Cardinality |A|
278
+ */
279
+ get size(): number {
280
+ return this._elements.size;
281
+ }
282
+
283
+ /**
284
+ * Convert to native Set (shallow)
285
+ */
286
+ toSet(): Set<T | RecursiveSet<T>> {
287
+ return new Set(this._elements);
288
+ }
289
+
290
+ /**
291
+ * Iterate over elements
292
+ */
293
+ *[Symbol.iterator](): Iterator<T | RecursiveSet<T>> {
294
+ yield* this._elements;
295
+ }
296
+
297
+ /**
298
+ * Pretty print with mathematical notation
299
+ */
300
+ toString(): string {
301
+ if (this.isEmpty()) {
302
+ return "∅";
303
+ }
304
+
305
+ const elements = Array.from(this._elements).map(el => {
306
+ if (el instanceof RecursiveSet) {
307
+ return el.toString();
308
+ }
309
+ return String(el);
310
+ });
311
+
312
+ return `{${elements.join(", ")}}`;
313
+ }
314
+
315
+ /**
316
+ * For console.log
317
+ */
318
+ [Symbol.for('nodejs.util.inspect.custom')](): string {
319
+ return this.toString();
320
+ }
321
+ }
322
+
323
+ // === Helper Functions ===
324
+
325
+ /**
326
+ * Create empty set (Null Set axiom)
327
+ */
328
+ export function emptySet<T = any>(): RecursiveSet<T> {
329
+ return new RecursiveSet<T>();
330
+ }
331
+
332
+ /**
333
+ * Create singleton set
334
+ */
335
+ export function singleton<T>(element: T): RecursiveSet<T> {
336
+ return new RecursiveSet<T>(element);
337
+ }
338
+
339
+ /**
340
+ * Create set from iterable
341
+ */
342
+ export function fromIterable<T>(iterable: Iterable<T>): RecursiveSet<T> {
343
+ return new RecursiveSet<T>(...iterable);
344
+ }
package/test.ts ADDED
@@ -0,0 +1,115 @@
1
+ import { RecursiveSet } from './src/index.js';
2
+
3
+ console.log('=== RecursiveSet Test Suite ===\n');
4
+
5
+ // ============================================================================
6
+ // Test 1: Basic FSM State Sets
7
+ // ============================================================================
8
+ console.log('--- Test 1: Basic State Sets ---');
9
+ const q0 = "q0";
10
+ const q1 = "q1";
11
+ const q2 = "q2";
12
+ const q3 = "q3";
13
+
14
+ const eqClass1 = new RecursiveSet(q0, q1);
15
+ const eqClass2 = new RecursiveSet(q2, q3);
16
+ console.log(`Equivalence class 1: ${eqClass1}`);
17
+ console.log(`Equivalence class 2: ${eqClass2}`);
18
+ console.log();
19
+
20
+ // ============================================================================
21
+ // Test 2: Sets of Sets (Equivalence Classes)
22
+ // ============================================================================
23
+ console.log('--- Test 2: Sets of Sets ---');
24
+ const eqClasses = new RecursiveSet(eqClass1, eqClass2);
25
+ console.log(`Equivalence classes: ${eqClasses}`);
26
+ console.log();
27
+
28
+ // ============================================================================
29
+ // Test 3: Mutability - Adding Elements
30
+ // ============================================================================
31
+ console.log('--- Test 3: Mutability ---');
32
+ const eqClass3 = new RecursiveSet("q4");
33
+ eqClasses.add(eqClass3);
34
+ console.log(`After adding {q4}: ${eqClasses}`);
35
+ console.log();
36
+
37
+ // ============================================================================
38
+ // Test 4: Extensionality (Structural Equality)
39
+ // ============================================================================
40
+ console.log('--- Test 4: Extensionality Axiom ---');
41
+ const eqClass1_copy = new RecursiveSet("q0", "q1");
42
+ console.log(`eqClass1: ${eqClass1}`);
43
+ console.log(`eqClass1_copy: ${eqClass1_copy}`);
44
+ console.log(`Are they equal? ${eqClass1.equals(eqClass1_copy)}`);
45
+ console.log();
46
+
47
+ // ============================================================================
48
+ // Test 5: Empty Set Handling
49
+ // ============================================================================
50
+ console.log('--- Test 5: Empty Set ---');
51
+ const emptyClass = new RecursiveSet();
52
+ const eqClassesWithEmpty = new RecursiveSet(eqClass1, emptyClass);
53
+ console.log(`With empty class: ${eqClassesWithEmpty}`);
54
+ console.log();
55
+
56
+ // ============================================================================
57
+ // Test 6: Deep Nesting
58
+ // ============================================================================
59
+ console.log('--- Test 6: Deep Nesting ---');
60
+ const nested = new RecursiveSet(eqClasses, eqClassesWithEmpty);
61
+ console.log(`Nested structure: ${nested}`);
62
+ console.log();
63
+
64
+ // ============================================================================
65
+ // Test 7: Set Operations
66
+ // ============================================================================
67
+ console.log('--- Test 7: Set Operations ---');
68
+ const difference = eqClasses.difference(new RecursiveSet(eqClass2));
69
+ console.log(`eqClasses - {eqClass2} = ${difference}`);
70
+
71
+ const union = eqClass1.union(eqClass2);
72
+ console.log(`eqClass1 ∪ eqClass2 = ${union}`);
73
+
74
+ const intersection = new RecursiveSet(q0, q1, q2).intersection(new RecursiveSet(q1, q2, q3));
75
+ console.log(`{q0, q1, q2} ∩ {q1, q2, q3} = ${intersection}`);
76
+ console.log();
77
+
78
+ // ============================================================================
79
+ // Test 8: Power Set
80
+ // ============================================================================
81
+ console.log('--- Test 8: Power Set ---');
82
+ const small = new RecursiveSet(1, 2);
83
+ const power = small.powerset();
84
+ console.log(`𝒫({1, 2}) = ${power}`);
85
+ console.log();
86
+
87
+ // ============================================================================
88
+ // Test 9: Foundation Axiom (Cycle Detection)
89
+ // ============================================================================
90
+ console.log('--- Test 9: Foundation Axiom ---');
91
+ try {
92
+ const circular = new RecursiveSet(1, 2);
93
+ circular.add(circular);
94
+ console.log('❌ ERROR: Cycle should have been detected!');
95
+ } catch (e: any) {
96
+ console.log(`✓ Cycle detected: ${e.message}`);
97
+ }
98
+ console.log();
99
+
100
+ // ============================================================================
101
+ // Test 10: Subset Relations
102
+ // ============================================================================
103
+ console.log('--- Test 10: Subset Relations ---');
104
+ const setA = new RecursiveSet(1, 2, 3);
105
+ const setB = new RecursiveSet(1, 2);
106
+ console.log(`A = ${setA}`);
107
+ console.log(`B = ${setB}`);
108
+ console.log(`B ⊆ A? ${setB.isSubset(setA)}`);
109
+ console.log(`A ⊆ B? ${setA.isSubset(setB)}`);
110
+ console.log();
111
+
112
+ // ============================================================================
113
+ // Summary
114
+ // ============================================================================
115
+ console.log('=== All Tests Completed Successfully ✓ ===');
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022", /* Modern JavaScript */
4
+ "module": "ES2022", /* ESM modules */
5
+ "lib": ["ES2022"], /* Available APIs */
6
+ "outDir": "./dist", /* Compiled JS output directory */
7
+ "rootDir": "./src", /* TypeScript source files */
8
+ "declaration": true, /* Generate .d.ts type files */
9
+ "declarationMap": true, /* Source maps for types */
10
+ "sourceMap": true, /* Source maps for debugging */
11
+ "strict": true, /* Enable all strict checks */
12
+ "esModuleInterop": true, /* Better module compatibility */
13
+ "skipLibCheck": true, /* Faster compilation */
14
+ "forceConsistentCasingInFileNames": true,
15
+ "moduleResolution": "node" /* Node.js module resolution */
16
+ },
17
+ "include": ["src/**/*"], /* Files to compile */
18
+ "exclude": ["node_modules", "dist"] /* Files to ignore */
19
+ }