recursive-set 2.2.0 → 3.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/README.md +87 -73
- package/dist/cjs/index.js +134 -100
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +30 -6
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +132 -99
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# RecursiveSet
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> High-performance, mutable set implementation for TypeScript – modeled after ZFC set theory.
|
|
4
4
|
|
|
5
|
-
Supports
|
|
5
|
+
Supports recursive nesting, strict structural equality, and includes all classic set operations (union, intersection, difference, powerset, cartesian product). **Designed for Theoretical Computer Science, Graphs, and FSMs.**
|
|
6
6
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[](https://www.npmjs.com/package/recursive-set)
|
|
@@ -11,50 +11,56 @@ Supports arbitrary nesting, detects cycles (Foundation axiom), and includes all
|
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
-
**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**
|
|
18
|
-
**
|
|
19
|
-
**
|
|
20
|
-
**TypeScript generics**: works with strings, numbers, objects, states, even sets of sets
|
|
21
|
-
**Ready for FSM**, mathematical, symbolic and practical use cases
|
|
14
|
+
* **Strict Value Equality:** Mathematical sets behave mathematically. `{a, b}` is equal to `{b, a}`.
|
|
15
|
+
* **Tuples First:** Includes a strongly typed `Tuple` class for ordered pairs (e.g., edges, transitions), solving JS Array reference pitfalls.
|
|
16
|
+
* **Homogeneous by Default:** Generic typing (`RecursiveSet<T>`) enforces clean data structures.
|
|
17
|
+
* **Recursive:** Sets can contain sets (of sets...). Ideal for Power Sets and Von Neumann Ordinals.
|
|
18
|
+
* **Copy-on-Write:** **O(1) cloning** via structural sharing (powered by persistent Red-Black Trees).
|
|
19
|
+
* **Lean \& Mean:** No implicit overhead. Cycle checking is left to the user to allow maximum performance.
|
|
22
20
|
|
|
23
21
|
---
|
|
24
22
|
|
|
25
23
|
## Implementation Details
|
|
26
24
|
|
|
27
|
-
This library enforces
|
|
25
|
+
This library enforces **Strict ZFC Semantics**, differing from native JavaScript `Set`:
|
|
28
26
|
|
|
29
|
-
- **Extensionality:** Two sets are
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- **Performance:**
|
|
35
|
-
-
|
|
36
|
-
-
|
|
27
|
+
- **Extensionality:** Two sets are equal if they contain the same elements.
|
|
28
|
+
- `new RecursiveSet(new RecursiveSet(1)).equals(new RecursiveSet(new RecursiveSet(1)))` is `true`.
|
|
29
|
+
- **No Hidden References:** Plain JavaScript Arrays and Objects are **rejected** to prevent reference-equality confusion.
|
|
30
|
+
- Use `Tuple` for ordered sequences.
|
|
31
|
+
- Use `RecursiveSet` for collections.
|
|
32
|
+
- **Performance:** Powered by **Functional Red-Black Trees**.
|
|
33
|
+
- Insertion/Lookup: **O(log n)**.
|
|
34
|
+
- Cloning: **O(1)**.
|
|
37
35
|
|
|
38
36
|
---
|
|
39
37
|
|
|
40
38
|
## Installation
|
|
41
39
|
|
|
42
|
-
```
|
|
40
|
+
```bash
|
|
43
41
|
npm install recursive-set
|
|
44
42
|
```
|
|
45
43
|
|
|
46
44
|
---
|
|
47
45
|
## Quickstart
|
|
48
|
-
```
|
|
49
|
-
import { RecursiveSet } from "recursive-set";
|
|
46
|
+
```typescript
|
|
47
|
+
import { RecursiveSet, Tuple } from "recursive-set";
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
49
|
+
// 1. Sets of primitives
|
|
50
|
+
const states = new RecursiveSet<string>();
|
|
51
|
+
states.add("q0").add("q1");
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
// 2. Sets of Sets (Partitioning)
|
|
54
|
+
const partition = new RecursiveSet<RecursiveSet<string>>();
|
|
55
|
+
partition.add(states); // {{q0, q1}}
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// 3. Tuples (Ordered Pairs / Edges)
|
|
58
|
+
const edge = new Tuple("q0", "q1"); // (q0, q1)
|
|
59
|
+
const transitions = new RecursiveSet<Tuple<[string, string]>>();
|
|
60
|
+
transitions.add(edge);
|
|
61
|
+
|
|
62
|
+
console.log(partition.toString()); // {{q0, q1}}
|
|
63
|
+
console.log(transitions.toString()); // {(q0, q1)}
|
|
58
64
|
```
|
|
59
65
|
|
|
60
66
|
---
|
|
@@ -63,16 +69,17 @@ console.log(classes.toString()); // {{q0, q1}, {q2, q3}}
|
|
|
63
69
|
|
|
64
70
|
### Constructor
|
|
65
71
|
|
|
66
|
-
```
|
|
72
|
+
```typescript
|
|
73
|
+
// T must be explicit or inferred. No default 'unknown'.
|
|
67
74
|
new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
68
75
|
```
|
|
69
76
|
|
|
70
77
|
### Methods
|
|
71
78
|
|
|
72
79
|
**Mutation:**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
* `add(element: T | RecursiveSet<T>): this` – Add element. **Throws on NaN or plain Object/Array.**
|
|
81
|
+
* `remove(element: T | RecursiveSet<T>): this` – Remove element.
|
|
82
|
+
* `clear(): this` – Remove all elements.
|
|
76
83
|
|
|
77
84
|
**Snapshot:**
|
|
78
85
|
- `clone(): RecursiveSet<T>` – Creates a shallow copy in **O(1)** time (Copy-on-Write).
|
|
@@ -85,7 +92,7 @@ new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
|
85
92
|
|
|
86
93
|
**Advanced Operations:**
|
|
87
94
|
- `powerset(): RecursiveSet<RecursiveSet<T>>` – 𝒫(A)
|
|
88
|
-
- `cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<
|
|
95
|
+
- `cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<Tuple<[T, U]>>` – A × B (Returns Tuples!)
|
|
89
96
|
|
|
90
97
|
**Predicates:**
|
|
91
98
|
- `has(element: T | RecursiveSet<T>): boolean` – Check membership
|
|
@@ -98,13 +105,23 @@ new RecursiveSet<T>(...elements: Array<T | RecursiveSet<T>>)
|
|
|
98
105
|
- `size: number` – Cardinality |A|
|
|
99
106
|
- `toString(): string` – Pretty print with ∅ and {}
|
|
100
107
|
|
|
108
|
+
### Tuple Class
|
|
109
|
+
|
|
110
|
+
Helper for structural value equality of sequences.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const t1 = new Tuple(1, 2);
|
|
114
|
+
const t2 = new Tuple(1, 2);
|
|
115
|
+
// In JS: [1,2] !== [1,2]
|
|
116
|
+
// In RecursiveSet: t1 equals t2 (Structural Equality)
|
|
117
|
+
```
|
|
101
118
|
---
|
|
102
119
|
|
|
103
120
|
## Examples
|
|
104
121
|
|
|
105
122
|
### Basic Usage
|
|
106
123
|
|
|
107
|
-
```
|
|
124
|
+
```typescript
|
|
108
125
|
const s1 = new RecursiveSet(1, 2, 3);
|
|
109
126
|
const s2 = new RecursiveSet(2, 3, 4);
|
|
110
127
|
|
|
@@ -115,7 +132,7 @@ console.log(s1.difference(s2)); // {1}
|
|
|
115
132
|
|
|
116
133
|
### Backtracking with O(1) Clone
|
|
117
134
|
|
|
118
|
-
```
|
|
135
|
+
```typescript
|
|
119
136
|
const state = new RecursiveSet("init");
|
|
120
137
|
// ... perform some operations ...
|
|
121
138
|
|
|
@@ -129,67 +146,65 @@ state.add("newState");
|
|
|
129
146
|
|
|
130
147
|
### Power Set
|
|
131
148
|
|
|
132
|
-
```
|
|
149
|
+
```typescript
|
|
133
150
|
const set = new RecursiveSet(1, 2);
|
|
134
151
|
const power = set.powerset();
|
|
135
152
|
|
|
136
153
|
console.log(power.toString()); // {∅, {1}, {2}, {1, 2}}
|
|
137
154
|
```
|
|
138
155
|
|
|
139
|
-
###
|
|
156
|
+
### Cartesian Product \& Tuples
|
|
140
157
|
|
|
141
|
-
```
|
|
142
|
-
const
|
|
158
|
+
```typescript
|
|
159
|
+
const A = new RecursiveSet(1, 2);
|
|
160
|
+
const B = new RecursiveSet("x", "y");
|
|
143
161
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
s.add(s);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
console.error(e.message); // "Foundation axiom violated..."
|
|
149
|
-
}
|
|
162
|
+
// A × B = {(1, x), (1, y), (2, x), (2, y)}
|
|
163
|
+
const product = A.cartesianProduct(B);
|
|
150
164
|
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
} catch (e) {
|
|
155
|
-
console.error(e.message); // "NaN is not supported..."
|
|
165
|
+
// Result contains strongly typed Tuples
|
|
166
|
+
for (const tuple of product) {
|
|
167
|
+
console.log(tuple.get(0), tuple.get(1)); // 1 "x"
|
|
156
168
|
}
|
|
157
169
|
```
|
|
158
170
|
|
|
159
|
-
---
|
|
160
171
|
|
|
161
|
-
|
|
172
|
+
### Strictness (Breaking Changes in V3)
|
|
162
173
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **Graph algorithms**: Represent node sets and partitions
|
|
166
|
-
- **Compiler design**: Symbol tables, scope analysis
|
|
167
|
-
- **Type systems**: Type inference and unification
|
|
174
|
+
```typescript
|
|
175
|
+
const s = new RecursiveSet<number>();
|
|
168
176
|
|
|
169
|
-
|
|
177
|
+
// ❌ Error: Plain Arrays not supported (Reference Ambiguity)
|
|
178
|
+
// s.add([1, 2]);
|
|
170
179
|
|
|
171
|
-
|
|
180
|
+
// ✅ Correct: Use Tuple
|
|
181
|
+
s.add(new Tuple(1, 2));
|
|
172
182
|
|
|
183
|
+
// ❌ Error: NaN is not supported
|
|
184
|
+
// s.add(NaN);
|
|
173
185
|
```
|
|
174
|
-
# Clone repository
|
|
175
|
-
git clone https://github.com/cstrerath/recursive-set.git
|
|
176
|
-
cd recursive-set
|
|
177
186
|
|
|
178
|
-
# Install dependencies
|
|
179
|
-
npm install
|
|
180
187
|
|
|
181
|
-
|
|
182
|
-
npm run build
|
|
188
|
+
---
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
190
|
+
## Use Cases
|
|
191
|
+
|
|
192
|
+
* **Finite State Machine (FSM):** States as Sets, Transitions as Tuples.
|
|
193
|
+
* **Graph Theory:** Edges as Tuples `(u, v)`, Nodes as Sets.
|
|
194
|
+
* **Formal Languages:** Alphabets, Grammars, Power Sets.
|
|
187
195
|
|
|
188
196
|
---
|
|
189
197
|
|
|
190
198
|
## Contributing
|
|
191
199
|
|
|
192
|
-
Contributions are welcome!
|
|
200
|
+
Contributions are welcome!
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git clone https://github.com/cstrerath/recursive-set.git
|
|
204
|
+
npm install
|
|
205
|
+
npm run build
|
|
206
|
+
npx tsx test.ts
|
|
207
|
+
```
|
|
193
208
|
|
|
194
209
|
---
|
|
195
210
|
|
|
@@ -205,7 +220,6 @@ See [LICENSE](LICENSE) for details.
|
|
|
205
220
|
## Acknowledgments
|
|
206
221
|
|
|
207
222
|
Inspired by:
|
|
208
|
-
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- Powered by [functional-red-black-tree](https://github.com/mikolalysenko/functional-red-black-tree) for O(log n) persistence
|
|
223
|
+
* Zermelo-Fraenkel set theory (ZFC)
|
|
224
|
+
* Formal Language Theory requirements
|
|
225
|
+
* Powered by [functional-red-black-tree](https://github.com/mikolalysenko/functional-red-black-tree)
|
package/dist/cjs/index.js
CHANGED
|
@@ -3,64 +3,115 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RecursiveSet = void 0;
|
|
6
|
+
exports.RecursiveSet = exports.Tuple = void 0;
|
|
7
7
|
exports.emptySet = emptySet;
|
|
8
8
|
exports.singleton = singleton;
|
|
9
9
|
exports.fromIterable = fromIterable;
|
|
10
10
|
const functional_red_black_tree_1 = __importDefault(require("functional-red-black-tree"));
|
|
11
11
|
/**
|
|
12
12
|
* @module recursive-set
|
|
13
|
-
* A mutable recursive set implementation
|
|
14
|
-
* Powered by Red-Black Trees for O(log n) operations
|
|
13
|
+
* A mutable recursive set implementation.
|
|
14
|
+
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
15
15
|
*/
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
18
|
+
* Immutable by design.
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
class Tuple {
|
|
21
|
+
values;
|
|
22
|
+
constructor(...values) {
|
|
23
|
+
this.values = values;
|
|
24
|
+
}
|
|
25
|
+
get length() {
|
|
26
|
+
return this.values.length;
|
|
27
|
+
}
|
|
28
|
+
get(index) {
|
|
29
|
+
return this.values[index];
|
|
30
|
+
}
|
|
31
|
+
*[Symbol.iterator]() {
|
|
32
|
+
for (const val of this.values) {
|
|
33
|
+
yield val;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
toString() {
|
|
37
|
+
return `(${this.values.map(v => String(v)).join(', ')})`;
|
|
38
|
+
}
|
|
39
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
40
|
+
return this.toString();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.Tuple = Tuple;
|
|
44
|
+
class RecursiveSet {
|
|
45
|
+
_tree;
|
|
46
|
+
/**
|
|
47
|
+
* Static comparator for Red-Black Tree ordering.
|
|
48
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
49
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
50
|
+
*/
|
|
51
|
+
static compare(a, b) {
|
|
52
|
+
if (a === b)
|
|
53
|
+
return 0;
|
|
54
|
+
const isSetA = a instanceof RecursiveSet;
|
|
55
|
+
const isSetB = b instanceof RecursiveSet;
|
|
56
|
+
const isTupA = a instanceof Tuple;
|
|
57
|
+
const isTupB = b instanceof Tuple;
|
|
58
|
+
// Sort Order: Primitives (0) < Tuples (1) < Sets (2)
|
|
59
|
+
const getTypeScore = (isSet, isTup) => {
|
|
60
|
+
if (isSet)
|
|
61
|
+
return 2;
|
|
62
|
+
if (isTup)
|
|
63
|
+
return 1;
|
|
64
|
+
return 0;
|
|
65
|
+
};
|
|
66
|
+
const scoreA = getTypeScore(isSetA, isTupA);
|
|
67
|
+
const scoreB = getTypeScore(isSetB, isTupB);
|
|
68
|
+
if (scoreA !== scoreB)
|
|
69
|
+
return scoreA < scoreB ? -1 : 1;
|
|
70
|
+
// 1. Sets
|
|
71
|
+
if (isSetA && isSetB) {
|
|
72
|
+
const setA = a;
|
|
73
|
+
const setB = b;
|
|
74
|
+
if (setA.size !== setB.size)
|
|
75
|
+
return setA.size < setB.size ? -1 : 1;
|
|
76
|
+
let iterA = setA._tree.begin;
|
|
77
|
+
let iterB = setB._tree.begin;
|
|
78
|
+
while (iterA.valid && iterB.valid) {
|
|
79
|
+
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
80
|
+
if (cmp !== 0)
|
|
81
|
+
return cmp;
|
|
82
|
+
iterA.next();
|
|
83
|
+
iterB.next();
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
// 2. Tuples
|
|
88
|
+
if (isTupA && isTupB) {
|
|
89
|
+
const tupA = a;
|
|
90
|
+
const tupB = b;
|
|
91
|
+
if (tupA.length !== tupB.length)
|
|
92
|
+
return tupA.length < tupB.length ? -1 : 1;
|
|
93
|
+
for (let i = 0; i < tupA.length; i++) {
|
|
94
|
+
const cmp = RecursiveSet.compare(tupA.get(i), tupB.get(i));
|
|
95
|
+
if (cmp !== 0)
|
|
96
|
+
return cmp;
|
|
97
|
+
}
|
|
98
|
+
return 0;
|
|
33
99
|
}
|
|
100
|
+
// 3. Primitives (guaranteed by add() validation)
|
|
101
|
+
const tA = typeof a;
|
|
102
|
+
const tB = typeof b;
|
|
103
|
+
if (tA !== tB)
|
|
104
|
+
return tA > tB ? 1 : -1;
|
|
105
|
+
// @ts-ignore
|
|
34
106
|
if (a < b)
|
|
35
107
|
return -1;
|
|
108
|
+
// @ts-ignore
|
|
36
109
|
if (a > b)
|
|
37
110
|
return 1;
|
|
38
111
|
return 0;
|
|
39
112
|
}
|
|
40
|
-
// 4. Recursive Sets
|
|
41
|
-
const sizeA = a.size;
|
|
42
|
-
const sizeB = b.size;
|
|
43
|
-
if (sizeA !== sizeB)
|
|
44
|
-
return sizeA < sizeB ? -1 : 1;
|
|
45
|
-
// Lexicographical comparison
|
|
46
|
-
const itA = a[Symbol.iterator]();
|
|
47
|
-
const itB = b[Symbol.iterator]();
|
|
48
|
-
let nextA = itA.next();
|
|
49
|
-
let nextB = itB.next();
|
|
50
|
-
while (!nextA.done) {
|
|
51
|
-
const cmp = compare(nextA.value, nextB.value);
|
|
52
|
-
if (cmp !== 0)
|
|
53
|
-
return cmp;
|
|
54
|
-
nextA = itA.next();
|
|
55
|
-
nextB = itB.next();
|
|
56
|
-
}
|
|
57
|
-
return 0;
|
|
58
|
-
}
|
|
59
|
-
class RecursiveSet {
|
|
60
|
-
// Red-Black Tree (immutable structure, we replace on mutation)
|
|
61
|
-
_tree; // Type from functional-red-black-tree
|
|
62
113
|
constructor(...elements) {
|
|
63
|
-
this._tree = (0, functional_red_black_tree_1.default)(compare);
|
|
114
|
+
this._tree = (0, functional_red_black_tree_1.default)(RecursiveSet.compare);
|
|
64
115
|
for (const el of elements) {
|
|
65
116
|
this.add(el);
|
|
66
117
|
}
|
|
@@ -68,35 +119,28 @@ class RecursiveSet {
|
|
|
68
119
|
// === Copy-on-Write Support ===
|
|
69
120
|
/**
|
|
70
121
|
* Creates a shallow copy of the set in O(1) time.
|
|
71
|
-
* Due to the immutable nature of the underlying tree,
|
|
72
|
-
* this is extremely efficient (structural sharing).
|
|
73
122
|
*/
|
|
74
123
|
clone() {
|
|
75
124
|
const clone = new RecursiveSet();
|
|
76
|
-
// We replace the empty tree directly with the reference to the current tree.
|
|
77
|
-
// Since the tree is persistent/immutable, this is safe and instant.
|
|
78
125
|
clone._tree = this._tree;
|
|
79
126
|
return clone;
|
|
80
127
|
}
|
|
81
128
|
// === Mutable Operations ===
|
|
82
129
|
add(element) {
|
|
83
|
-
//
|
|
130
|
+
// Validation
|
|
84
131
|
if (typeof element === "number" && Number.isNaN(element)) {
|
|
85
|
-
throw new Error("NaN is not supported
|
|
132
|
+
throw new Error("NaN is not supported");
|
|
86
133
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// 2. Cycle Check (Foundation Axiom)
|
|
94
|
-
if (element instanceof RecursiveSet) {
|
|
95
|
-
if (this._wouldCreateCycle(element)) {
|
|
96
|
-
throw new Error("Foundation axiom violated: membership cycle detected");
|
|
97
|
-
}
|
|
134
|
+
const isSet = element instanceof RecursiveSet;
|
|
135
|
+
const isTup = element instanceof Tuple;
|
|
136
|
+
const isObject = element !== null && typeof element === 'object' && !isSet && !isTup;
|
|
137
|
+
if (isObject) {
|
|
138
|
+
throw new Error("Plain Objects and Arrays are not supported. " +
|
|
139
|
+
"Use Tuple for sequences or RecursiveSet for nested structures.");
|
|
98
140
|
}
|
|
99
|
-
//
|
|
141
|
+
// Idempotency
|
|
142
|
+
if (this.has(element))
|
|
143
|
+
return this;
|
|
100
144
|
this._tree = this._tree.insert(element, true);
|
|
101
145
|
return this;
|
|
102
146
|
}
|
|
@@ -105,22 +149,21 @@ class RecursiveSet {
|
|
|
105
149
|
return this;
|
|
106
150
|
}
|
|
107
151
|
clear() {
|
|
108
|
-
this._tree = (0, functional_red_black_tree_1.default)(compare);
|
|
152
|
+
this._tree = (0, functional_red_black_tree_1.default)(RecursiveSet.compare);
|
|
109
153
|
return this;
|
|
110
154
|
}
|
|
111
|
-
// ===
|
|
155
|
+
// === Set Operations ===
|
|
112
156
|
union(other) {
|
|
113
|
-
const result =
|
|
114
|
-
for (const el of this)
|
|
115
|
-
result.add(el);
|
|
157
|
+
const result = this.clone();
|
|
116
158
|
for (const el of other)
|
|
117
159
|
result.add(el);
|
|
118
160
|
return result;
|
|
119
161
|
}
|
|
120
162
|
intersection(other) {
|
|
121
163
|
const result = new RecursiveSet();
|
|
122
|
-
|
|
123
|
-
|
|
164
|
+
const [smaller, larger] = this.size < other.size ? [this, other] : [other, this];
|
|
165
|
+
for (const el of smaller) {
|
|
166
|
+
if (larger.has(el)) {
|
|
124
167
|
result.add(el);
|
|
125
168
|
}
|
|
126
169
|
}
|
|
@@ -136,13 +179,15 @@ class RecursiveSet {
|
|
|
136
179
|
return result;
|
|
137
180
|
}
|
|
138
181
|
symmetricDifference(other) {
|
|
139
|
-
return this.
|
|
182
|
+
return this.difference(other).union(other.difference(this));
|
|
140
183
|
}
|
|
141
184
|
powerset() {
|
|
185
|
+
const n = this.size;
|
|
186
|
+
if (n > 30)
|
|
187
|
+
throw new Error("Powerset size exceeds 32-bit integer limit");
|
|
142
188
|
const elements = [];
|
|
143
|
-
this._tree.forEach((key) => { elements.push(key);
|
|
189
|
+
this._tree.forEach((key) => { elements.push(key); });
|
|
144
190
|
const subsets = [];
|
|
145
|
-
const n = elements.length;
|
|
146
191
|
for (let i = 0; i < (1 << n); i++) {
|
|
147
192
|
const subset = new RecursiveSet();
|
|
148
193
|
for (let j = 0; j < n; j++) {
|
|
@@ -154,23 +199,26 @@ class RecursiveSet {
|
|
|
154
199
|
}
|
|
155
200
|
return new RecursiveSet(...subsets);
|
|
156
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
204
|
+
* Uses the Tuple class to ensure structural equality.
|
|
205
|
+
*/
|
|
157
206
|
cartesianProduct(other) {
|
|
158
|
-
const
|
|
207
|
+
const result = new RecursiveSet();
|
|
159
208
|
for (const x of this) {
|
|
160
209
|
for (const y of other) {
|
|
161
|
-
|
|
162
|
-
const valY = y;
|
|
163
|
-
const pair = new RecursiveSet(new RecursiveSet(valX), new RecursiveSet(valX, valY));
|
|
164
|
-
pairs.push(pair);
|
|
210
|
+
result.add(new Tuple(x, y));
|
|
165
211
|
}
|
|
166
212
|
}
|
|
167
|
-
return
|
|
213
|
+
return result;
|
|
168
214
|
}
|
|
169
215
|
// === Predicates ===
|
|
170
216
|
has(element) {
|
|
171
217
|
return this._tree.get(element) !== undefined;
|
|
172
218
|
}
|
|
173
219
|
isSubset(other) {
|
|
220
|
+
if (this.size > other.size)
|
|
221
|
+
return false;
|
|
174
222
|
for (const el of this) {
|
|
175
223
|
if (!other.has(el))
|
|
176
224
|
return false;
|
|
@@ -187,26 +235,7 @@ class RecursiveSet {
|
|
|
187
235
|
return this.size === 0;
|
|
188
236
|
}
|
|
189
237
|
equals(other) {
|
|
190
|
-
return compare(this, other) === 0;
|
|
191
|
-
}
|
|
192
|
-
// === Internals ===
|
|
193
|
-
_wouldCreateCycle(element) {
|
|
194
|
-
const visited = new Set();
|
|
195
|
-
const stack = [element];
|
|
196
|
-
while (stack.length > 0) {
|
|
197
|
-
const current = stack.pop();
|
|
198
|
-
if (current === this)
|
|
199
|
-
return true;
|
|
200
|
-
if (visited.has(current))
|
|
201
|
-
continue;
|
|
202
|
-
visited.add(current);
|
|
203
|
-
for (const child of current) {
|
|
204
|
-
if (child instanceof RecursiveSet) {
|
|
205
|
-
stack.push(child);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return false;
|
|
238
|
+
return RecursiveSet.compare(this, other) === 0;
|
|
210
239
|
}
|
|
211
240
|
// === Utility ===
|
|
212
241
|
get size() {
|
|
@@ -214,13 +243,16 @@ class RecursiveSet {
|
|
|
214
243
|
}
|
|
215
244
|
toSet() {
|
|
216
245
|
const result = new Set();
|
|
217
|
-
this._tree.forEach((key) => { result.add(key);
|
|
246
|
+
this._tree.forEach((key) => { result.add(key); });
|
|
218
247
|
return result;
|
|
219
248
|
}
|
|
249
|
+
// Lazy Iterator
|
|
220
250
|
*[Symbol.iterator]() {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
251
|
+
let iter = this._tree.begin;
|
|
252
|
+
while (iter.valid) {
|
|
253
|
+
yield iter.key;
|
|
254
|
+
iter.next();
|
|
255
|
+
}
|
|
224
256
|
}
|
|
225
257
|
toString() {
|
|
226
258
|
if (this.isEmpty())
|
|
@@ -230,10 +262,12 @@ class RecursiveSet {
|
|
|
230
262
|
if (key instanceof RecursiveSet) {
|
|
231
263
|
elements.push(key.toString());
|
|
232
264
|
}
|
|
265
|
+
else if (key instanceof Tuple) {
|
|
266
|
+
elements.push(key.toString());
|
|
267
|
+
}
|
|
233
268
|
else {
|
|
234
269
|
elements.push(String(key));
|
|
235
270
|
}
|
|
236
|
-
return undefined;
|
|
237
271
|
});
|
|
238
272
|
return `{${elements.join(", ")}}`;
|
|
239
273
|
}
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,10 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module recursive-set
|
|
3
|
+
* A mutable recursive set implementation.
|
|
4
|
+
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
8
|
+
* Immutable by design.
|
|
9
|
+
*/
|
|
10
|
+
export declare class Tuple<T extends unknown[]> {
|
|
11
|
+
readonly values: T;
|
|
12
|
+
constructor(...values: T);
|
|
13
|
+
get length(): number;
|
|
14
|
+
get<K extends keyof T>(index: K): T[K];
|
|
15
|
+
[Symbol.iterator](): Iterator<T[number]>;
|
|
16
|
+
toString(): string;
|
|
17
|
+
}
|
|
18
|
+
export declare class RecursiveSet<T> {
|
|
2
19
|
private _tree;
|
|
20
|
+
/**
|
|
21
|
+
* Static comparator for Red-Black Tree ordering.
|
|
22
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
23
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
24
|
+
*/
|
|
25
|
+
static compare(a: unknown, b: unknown): number;
|
|
3
26
|
constructor(...elements: Array<T | RecursiveSet<T>>);
|
|
4
27
|
/**
|
|
5
28
|
* Creates a shallow copy of the set in O(1) time.
|
|
6
|
-
* Due to the immutable nature of the underlying tree,
|
|
7
|
-
* this is extremely efficient (structural sharing).
|
|
8
29
|
*/
|
|
9
30
|
clone(): RecursiveSet<T>;
|
|
10
31
|
add(element: T | RecursiveSet<T>): this;
|
|
@@ -15,20 +36,23 @@ export declare class RecursiveSet<T = any> {
|
|
|
15
36
|
difference(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
16
37
|
symmetricDifference(other: RecursiveSet<T>): RecursiveSet<T>;
|
|
17
38
|
powerset(): RecursiveSet<RecursiveSet<T>>;
|
|
18
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
41
|
+
* Uses the Tuple class to ensure structural equality.
|
|
42
|
+
*/
|
|
43
|
+
cartesianProduct<U>(other: RecursiveSet<U>): RecursiveSet<Tuple<[T | RecursiveSet<T>, U | RecursiveSet<U>]>>;
|
|
19
44
|
has(element: T | RecursiveSet<T>): boolean;
|
|
20
45
|
isSubset(other: RecursiveSet<T>): boolean;
|
|
21
46
|
isSuperset(other: RecursiveSet<T>): boolean;
|
|
22
47
|
isProperSubset(other: RecursiveSet<T>): boolean;
|
|
23
48
|
isEmpty(): boolean;
|
|
24
49
|
equals(other: RecursiveSet<T>): boolean;
|
|
25
|
-
private _wouldCreateCycle;
|
|
26
50
|
get size(): number;
|
|
27
51
|
toSet(): Set<T | RecursiveSet<T>>;
|
|
28
52
|
[Symbol.iterator](): Iterator<T | RecursiveSet<T>>;
|
|
29
53
|
toString(): string;
|
|
30
54
|
}
|
|
31
|
-
export declare function emptySet<T
|
|
55
|
+
export declare function emptySet<T>(): RecursiveSet<T>;
|
|
32
56
|
export declare function singleton<T>(element: T): RecursiveSet<T>;
|
|
33
57
|
export declare function fromIterable<T>(iterable: Iterable<T>): RecursiveSet<T>;
|
|
34
58
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,57 +1,107 @@
|
|
|
1
1
|
import createTree from 'functional-red-black-tree';
|
|
2
2
|
/**
|
|
3
3
|
* @module recursive-set
|
|
4
|
-
* A mutable recursive set implementation
|
|
5
|
-
* Powered by Red-Black Trees for O(log n) operations
|
|
4
|
+
* A mutable recursive set implementation.
|
|
5
|
+
* Powered by functional Red-Black Trees for O(log n) operations and O(1) cloning.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* A lightweight wrapper for Tuples to enable Value-Equality in RecursiveSet.
|
|
9
|
+
* Immutable by design.
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
export class Tuple {
|
|
12
|
+
values;
|
|
13
|
+
constructor(...values) {
|
|
14
|
+
this.values = values;
|
|
15
|
+
}
|
|
16
|
+
get length() {
|
|
17
|
+
return this.values.length;
|
|
18
|
+
}
|
|
19
|
+
get(index) {
|
|
20
|
+
return this.values[index];
|
|
21
|
+
}
|
|
22
|
+
*[Symbol.iterator]() {
|
|
23
|
+
for (const val of this.values) {
|
|
24
|
+
yield val;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
toString() {
|
|
28
|
+
return `(${this.values.map(v => String(v)).join(', ')})`;
|
|
29
|
+
}
|
|
30
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
31
|
+
return this.toString();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class RecursiveSet {
|
|
35
|
+
_tree;
|
|
36
|
+
/**
|
|
37
|
+
* Static comparator for Red-Black Tree ordering.
|
|
38
|
+
* Supports Primitives, RecursiveSets and Tuples.
|
|
39
|
+
* REJECTS plain JS Objects and Arrays to enforce strict semantics.
|
|
40
|
+
*/
|
|
41
|
+
static compare(a, b) {
|
|
42
|
+
if (a === b)
|
|
43
|
+
return 0;
|
|
44
|
+
const isSetA = a instanceof RecursiveSet;
|
|
45
|
+
const isSetB = b instanceof RecursiveSet;
|
|
46
|
+
const isTupA = a instanceof Tuple;
|
|
47
|
+
const isTupB = b instanceof Tuple;
|
|
48
|
+
// Sort Order: Primitives (0) < Tuples (1) < Sets (2)
|
|
49
|
+
const getTypeScore = (isSet, isTup) => {
|
|
50
|
+
if (isSet)
|
|
51
|
+
return 2;
|
|
52
|
+
if (isTup)
|
|
53
|
+
return 1;
|
|
54
|
+
return 0;
|
|
55
|
+
};
|
|
56
|
+
const scoreA = getTypeScore(isSetA, isTupA);
|
|
57
|
+
const scoreB = getTypeScore(isSetB, isTupB);
|
|
58
|
+
if (scoreA !== scoreB)
|
|
59
|
+
return scoreA < scoreB ? -1 : 1;
|
|
60
|
+
// 1. Sets
|
|
61
|
+
if (isSetA && isSetB) {
|
|
62
|
+
const setA = a;
|
|
63
|
+
const setB = b;
|
|
64
|
+
if (setA.size !== setB.size)
|
|
65
|
+
return setA.size < setB.size ? -1 : 1;
|
|
66
|
+
let iterA = setA._tree.begin;
|
|
67
|
+
let iterB = setB._tree.begin;
|
|
68
|
+
while (iterA.valid && iterB.valid) {
|
|
69
|
+
const cmp = RecursiveSet.compare(iterA.key, iterB.key);
|
|
70
|
+
if (cmp !== 0)
|
|
71
|
+
return cmp;
|
|
72
|
+
iterA.next();
|
|
73
|
+
iterB.next();
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
// 2. Tuples
|
|
78
|
+
if (isTupA && isTupB) {
|
|
79
|
+
const tupA = a;
|
|
80
|
+
const tupB = b;
|
|
81
|
+
if (tupA.length !== tupB.length)
|
|
82
|
+
return tupA.length < tupB.length ? -1 : 1;
|
|
83
|
+
for (let i = 0; i < tupA.length; i++) {
|
|
84
|
+
const cmp = RecursiveSet.compare(tupA.get(i), tupB.get(i));
|
|
85
|
+
if (cmp !== 0)
|
|
86
|
+
return cmp;
|
|
87
|
+
}
|
|
88
|
+
return 0;
|
|
24
89
|
}
|
|
90
|
+
// 3. Primitives (guaranteed by add() validation)
|
|
91
|
+
const tA = typeof a;
|
|
92
|
+
const tB = typeof b;
|
|
93
|
+
if (tA !== tB)
|
|
94
|
+
return tA > tB ? 1 : -1;
|
|
95
|
+
// @ts-ignore
|
|
25
96
|
if (a < b)
|
|
26
97
|
return -1;
|
|
98
|
+
// @ts-ignore
|
|
27
99
|
if (a > b)
|
|
28
100
|
return 1;
|
|
29
101
|
return 0;
|
|
30
102
|
}
|
|
31
|
-
// 4. Recursive Sets
|
|
32
|
-
const sizeA = a.size;
|
|
33
|
-
const sizeB = b.size;
|
|
34
|
-
if (sizeA !== sizeB)
|
|
35
|
-
return sizeA < sizeB ? -1 : 1;
|
|
36
|
-
// Lexicographical comparison
|
|
37
|
-
const itA = a[Symbol.iterator]();
|
|
38
|
-
const itB = b[Symbol.iterator]();
|
|
39
|
-
let nextA = itA.next();
|
|
40
|
-
let nextB = itB.next();
|
|
41
|
-
while (!nextA.done) {
|
|
42
|
-
const cmp = compare(nextA.value, nextB.value);
|
|
43
|
-
if (cmp !== 0)
|
|
44
|
-
return cmp;
|
|
45
|
-
nextA = itA.next();
|
|
46
|
-
nextB = itB.next();
|
|
47
|
-
}
|
|
48
|
-
return 0;
|
|
49
|
-
}
|
|
50
|
-
export class RecursiveSet {
|
|
51
|
-
// Red-Black Tree (immutable structure, we replace on mutation)
|
|
52
|
-
_tree; // Type from functional-red-black-tree
|
|
53
103
|
constructor(...elements) {
|
|
54
|
-
this._tree = createTree(compare);
|
|
104
|
+
this._tree = createTree(RecursiveSet.compare);
|
|
55
105
|
for (const el of elements) {
|
|
56
106
|
this.add(el);
|
|
57
107
|
}
|
|
@@ -59,35 +109,28 @@ export class RecursiveSet {
|
|
|
59
109
|
// === Copy-on-Write Support ===
|
|
60
110
|
/**
|
|
61
111
|
* Creates a shallow copy of the set in O(1) time.
|
|
62
|
-
* Due to the immutable nature of the underlying tree,
|
|
63
|
-
* this is extremely efficient (structural sharing).
|
|
64
112
|
*/
|
|
65
113
|
clone() {
|
|
66
114
|
const clone = new RecursiveSet();
|
|
67
|
-
// We replace the empty tree directly with the reference to the current tree.
|
|
68
|
-
// Since the tree is persistent/immutable, this is safe and instant.
|
|
69
115
|
clone._tree = this._tree;
|
|
70
116
|
return clone;
|
|
71
117
|
}
|
|
72
118
|
// === Mutable Operations ===
|
|
73
119
|
add(element) {
|
|
74
|
-
//
|
|
120
|
+
// Validation
|
|
75
121
|
if (typeof element === "number" && Number.isNaN(element)) {
|
|
76
|
-
throw new Error("NaN is not supported
|
|
122
|
+
throw new Error("NaN is not supported");
|
|
77
123
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// 2. Cycle Check (Foundation Axiom)
|
|
85
|
-
if (element instanceof RecursiveSet) {
|
|
86
|
-
if (this._wouldCreateCycle(element)) {
|
|
87
|
-
throw new Error("Foundation axiom violated: membership cycle detected");
|
|
88
|
-
}
|
|
124
|
+
const isSet = element instanceof RecursiveSet;
|
|
125
|
+
const isTup = element instanceof Tuple;
|
|
126
|
+
const isObject = element !== null && typeof element === 'object' && !isSet && !isTup;
|
|
127
|
+
if (isObject) {
|
|
128
|
+
throw new Error("Plain Objects and Arrays are not supported. " +
|
|
129
|
+
"Use Tuple for sequences or RecursiveSet for nested structures.");
|
|
89
130
|
}
|
|
90
|
-
//
|
|
131
|
+
// Idempotency
|
|
132
|
+
if (this.has(element))
|
|
133
|
+
return this;
|
|
91
134
|
this._tree = this._tree.insert(element, true);
|
|
92
135
|
return this;
|
|
93
136
|
}
|
|
@@ -96,22 +139,21 @@ export class RecursiveSet {
|
|
|
96
139
|
return this;
|
|
97
140
|
}
|
|
98
141
|
clear() {
|
|
99
|
-
this._tree = createTree(compare);
|
|
142
|
+
this._tree = createTree(RecursiveSet.compare);
|
|
100
143
|
return this;
|
|
101
144
|
}
|
|
102
|
-
// ===
|
|
145
|
+
// === Set Operations ===
|
|
103
146
|
union(other) {
|
|
104
|
-
const result =
|
|
105
|
-
for (const el of this)
|
|
106
|
-
result.add(el);
|
|
147
|
+
const result = this.clone();
|
|
107
148
|
for (const el of other)
|
|
108
149
|
result.add(el);
|
|
109
150
|
return result;
|
|
110
151
|
}
|
|
111
152
|
intersection(other) {
|
|
112
153
|
const result = new RecursiveSet();
|
|
113
|
-
|
|
114
|
-
|
|
154
|
+
const [smaller, larger] = this.size < other.size ? [this, other] : [other, this];
|
|
155
|
+
for (const el of smaller) {
|
|
156
|
+
if (larger.has(el)) {
|
|
115
157
|
result.add(el);
|
|
116
158
|
}
|
|
117
159
|
}
|
|
@@ -127,13 +169,15 @@ export class RecursiveSet {
|
|
|
127
169
|
return result;
|
|
128
170
|
}
|
|
129
171
|
symmetricDifference(other) {
|
|
130
|
-
return this.
|
|
172
|
+
return this.difference(other).union(other.difference(this));
|
|
131
173
|
}
|
|
132
174
|
powerset() {
|
|
175
|
+
const n = this.size;
|
|
176
|
+
if (n > 30)
|
|
177
|
+
throw new Error("Powerset size exceeds 32-bit integer limit");
|
|
133
178
|
const elements = [];
|
|
134
|
-
this._tree.forEach((key) => { elements.push(key);
|
|
179
|
+
this._tree.forEach((key) => { elements.push(key); });
|
|
135
180
|
const subsets = [];
|
|
136
|
-
const n = elements.length;
|
|
137
181
|
for (let i = 0; i < (1 << n); i++) {
|
|
138
182
|
const subset = new RecursiveSet();
|
|
139
183
|
for (let j = 0; j < n; j++) {
|
|
@@ -145,23 +189,26 @@ export class RecursiveSet {
|
|
|
145
189
|
}
|
|
146
190
|
return new RecursiveSet(...subsets);
|
|
147
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Returns the Cartesian product as a set of Tuples.
|
|
194
|
+
* Uses the Tuple class to ensure structural equality.
|
|
195
|
+
*/
|
|
148
196
|
cartesianProduct(other) {
|
|
149
|
-
const
|
|
197
|
+
const result = new RecursiveSet();
|
|
150
198
|
for (const x of this) {
|
|
151
199
|
for (const y of other) {
|
|
152
|
-
|
|
153
|
-
const valY = y;
|
|
154
|
-
const pair = new RecursiveSet(new RecursiveSet(valX), new RecursiveSet(valX, valY));
|
|
155
|
-
pairs.push(pair);
|
|
200
|
+
result.add(new Tuple(x, y));
|
|
156
201
|
}
|
|
157
202
|
}
|
|
158
|
-
return
|
|
203
|
+
return result;
|
|
159
204
|
}
|
|
160
205
|
// === Predicates ===
|
|
161
206
|
has(element) {
|
|
162
207
|
return this._tree.get(element) !== undefined;
|
|
163
208
|
}
|
|
164
209
|
isSubset(other) {
|
|
210
|
+
if (this.size > other.size)
|
|
211
|
+
return false;
|
|
165
212
|
for (const el of this) {
|
|
166
213
|
if (!other.has(el))
|
|
167
214
|
return false;
|
|
@@ -178,26 +225,7 @@ export class RecursiveSet {
|
|
|
178
225
|
return this.size === 0;
|
|
179
226
|
}
|
|
180
227
|
equals(other) {
|
|
181
|
-
return compare(this, other) === 0;
|
|
182
|
-
}
|
|
183
|
-
// === Internals ===
|
|
184
|
-
_wouldCreateCycle(element) {
|
|
185
|
-
const visited = new Set();
|
|
186
|
-
const stack = [element];
|
|
187
|
-
while (stack.length > 0) {
|
|
188
|
-
const current = stack.pop();
|
|
189
|
-
if (current === this)
|
|
190
|
-
return true;
|
|
191
|
-
if (visited.has(current))
|
|
192
|
-
continue;
|
|
193
|
-
visited.add(current);
|
|
194
|
-
for (const child of current) {
|
|
195
|
-
if (child instanceof RecursiveSet) {
|
|
196
|
-
stack.push(child);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return false;
|
|
228
|
+
return RecursiveSet.compare(this, other) === 0;
|
|
201
229
|
}
|
|
202
230
|
// === Utility ===
|
|
203
231
|
get size() {
|
|
@@ -205,13 +233,16 @@ export class RecursiveSet {
|
|
|
205
233
|
}
|
|
206
234
|
toSet() {
|
|
207
235
|
const result = new Set();
|
|
208
|
-
this._tree.forEach((key) => { result.add(key);
|
|
236
|
+
this._tree.forEach((key) => { result.add(key); });
|
|
209
237
|
return result;
|
|
210
238
|
}
|
|
239
|
+
// Lazy Iterator
|
|
211
240
|
*[Symbol.iterator]() {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
241
|
+
let iter = this._tree.begin;
|
|
242
|
+
while (iter.valid) {
|
|
243
|
+
yield iter.key;
|
|
244
|
+
iter.next();
|
|
245
|
+
}
|
|
215
246
|
}
|
|
216
247
|
toString() {
|
|
217
248
|
if (this.isEmpty())
|
|
@@ -221,10 +252,12 @@ export class RecursiveSet {
|
|
|
221
252
|
if (key instanceof RecursiveSet) {
|
|
222
253
|
elements.push(key.toString());
|
|
223
254
|
}
|
|
255
|
+
else if (key instanceof Tuple) {
|
|
256
|
+
elements.push(key.toString());
|
|
257
|
+
}
|
|
224
258
|
else {
|
|
225
259
|
elements.push(String(key));
|
|
226
260
|
}
|
|
227
|
-
return undefined;
|
|
228
261
|
});
|
|
229
262
|
return `{${elements.join(", ")}}`;
|
|
230
263
|
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,UAA8C,MAAM,2BAA2B,CAAC;AAEvF;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,OAAO,KAAK;IACL,MAAM,CAAI;IAEnB,YAAY,GAAG,MAAS;QACpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,GAAG,CAAoB,KAAQ;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QACd,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC7D,CAAC;IAED,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;CACJ;AAEG,MAAM,OAAO,YAAY;IACb,KAAK,CAAqC;IAElD;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,CAAU,EAAE,CAAU;QACrC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAEtB,MAAM,MAAM,GAAG,CAAC,YAAY,YAAY,CAAC;QACzC,MAAM,MAAM,GAAG,CAAC,YAAY,YAAY,CAAC;QACzC,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC;QAClC,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC;QAElC,qDAAqD;QACrD,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,KAAc,EAAE,EAAE;YACpD,IAAI,KAAK;gBAAE,OAAO,CAAC,CAAC;YACpB,IAAI,KAAK;gBAAE,OAAO,CAAC,CAAC;YACpB,OAAO,CAAC,CAAC;QACb,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE5C,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvD,UAAU;QACV,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,CAA0B,CAAC;YACxC,MAAM,IAAI,GAAG,CAA0B,CAAC;YAExC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;gBAAE,OAAO,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEnE,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAC7B,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAE7B,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvD,IAAI,GAAG,KAAK,CAAC;oBAAE,OAAO,GAAG,CAAC;gBAC1B,KAAK,CAAC,IAAI,EAAE,CAAC;gBACb,KAAK,CAAC,IAAI,EAAE,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,CAAC;QACb,CAAC;QAED,YAAY;QACZ,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,CAAqB,CAAC;YACnC,MAAM,IAAI,GAAG,CAAqB,CAAC;YAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAE3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3D,IAAI,GAAG,KAAK,CAAC;oBAAE,OAAO,GAAG,CAAC;YAC9B,CAAC;YACD,OAAO,CAAC,CAAC;QACb,CAAC;QAED,iDAAiD;QACjD,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC;QACpB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC;QACpB,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEvC,aAAa;QACb,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC;QACrB,aAAa;QACb,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC;QACpB,OAAO,CAAC,CAAC;IACb,CAAC;IAED,YAAY,GAAG,QAAoC;QAC/C,IAAI,CAAC,KAAK,GAAG,UAAU,CAA+B,YAAY,CAAC,OAAO,CAAC,CAAC;QAC5E,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACL,CAAC;IAED,gCAAgC;IAEhC;;OAEG;IACH,KAAK;QACD,MAAM,KAAK,GAAG,IAAI,YAAY,EAAK,CAAC;QACpC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,6BAA6B;IAE7B,GAAG,CAAC,OAA4B;QAC5B,aAAa;QACb,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,YAAY,YAAY,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,YAAY,KAAK,CAAC;QACvC,MAAM,QAAQ,GAAG,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC;QAErF,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACX,8CAA8C;gBAC9C,gEAAgE,CACnE,CAAC;QACN,CAAC;QAED,cAAc;QACd,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IAGD,MAAM,CAAC,OAA4B;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK;QACD,IAAI,CAAC,KAAK,GAAG,UAAU,CAA+B,YAAY,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,yBAAyB;IAEzB,KAAK,CAAC,KAAsB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5B,KAAK,MAAM,EAAE,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,YAAY,CAAC,KAAsB;QAC/B,MAAM,MAAM,GAAG,IAAI,YAAY,EAAK,CAAC;QACrC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACjF,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACvB,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnB,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,UAAU,CAAC,KAAsB;QAC7B,MAAM,MAAM,GAAG,IAAI,YAAY,EAAK,CAAC;QACrC,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnB,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,mBAAmB,CAAC,KAAsB;QACtC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,QAAQ;QACJ,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAE1E,MAAM,QAAQ,GAA+B,EAAE,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAwB,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1E,MAAM,OAAO,GAAsB,EAAE,CAAC;QAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,YAAY,EAAK,CAAC;YACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;oBACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5B,CAAC;YACL,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,YAAY,CAAkB,GAAG,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;;OAGG;IACC,gBAAgB,CAAI,KAAsB;QAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,EAAqD,CAAC;QAErF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACpB,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,qBAAqB;IAErB,GAAG,CAAC,OAA4B;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;IACjD,CAAC;IAED,QAAQ,CAAC,KAAsB;QAC3B,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACzC,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO,KAAK,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,UAAU,CAAC,KAAsB;QAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,cAAc,CAAC,KAAsB;QACjC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,KAAsB;QACzB,OAAO,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,kBAAkB;IAElB,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,KAAK;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAwB,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,gBAAgB;IAChB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QACd,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAC5B,OAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,GAAG,CAAC;YACf,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,CAAC;IACL,CAAC;IAED,QAAQ;QACJ,IAAI,IAAI,CAAC,OAAO,EAAE;YAAE,OAAO,GAAG,CAAC;QAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAY,EAAE,EAAE;YAChC,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAClC,CAAC;iBAAM,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACJ,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACtC,CAAC;IAED,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC3B,CAAC;CACJ;AAED,kBAAkB;AAElB,MAAM,UAAU,QAAQ;IACpB,OAAO,IAAI,YAAY,EAAK,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,OAAU;IACnC,OAAO,IAAI,YAAY,CAAI,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAI,QAAqB;IACjD,OAAO,IAAI,YAAY,CAAI,GAAG,QAAQ,CAAC,CAAC;AAC5C,CAAC"}
|