@pattern-algebra/core 0.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.
Files changed (154) hide show
  1. package/README.md +571 -0
  2. package/dist/automaton/complement.d.ts +20 -0
  3. package/dist/automaton/complement.d.ts.map +1 -0
  4. package/dist/automaton/complement.js +36 -0
  5. package/dist/automaton/complement.js.map +1 -0
  6. package/dist/automaton/complement.test.d.ts +2 -0
  7. package/dist/automaton/complement.test.d.ts.map +1 -0
  8. package/dist/automaton/complement.test.js +114 -0
  9. package/dist/automaton/complement.test.js.map +1 -0
  10. package/dist/automaton/determinize.d.ts +41 -0
  11. package/dist/automaton/determinize.d.ts.map +1 -0
  12. package/dist/automaton/determinize.js +310 -0
  13. package/dist/automaton/determinize.js.map +1 -0
  14. package/dist/automaton/determinize.test.d.ts +2 -0
  15. package/dist/automaton/determinize.test.d.ts.map +1 -0
  16. package/dist/automaton/determinize.test.js +134 -0
  17. package/dist/automaton/determinize.test.js.map +1 -0
  18. package/dist/automaton/emptiness.d.ts +41 -0
  19. package/dist/automaton/emptiness.d.ts.map +1 -0
  20. package/dist/automaton/emptiness.js +262 -0
  21. package/dist/automaton/emptiness.js.map +1 -0
  22. package/dist/automaton/emptiness.test.d.ts +2 -0
  23. package/dist/automaton/emptiness.test.d.ts.map +1 -0
  24. package/dist/automaton/emptiness.test.js +154 -0
  25. package/dist/automaton/emptiness.test.js.map +1 -0
  26. package/dist/automaton/index.d.ts +10 -0
  27. package/dist/automaton/index.d.ts.map +1 -0
  28. package/dist/automaton/index.js +11 -0
  29. package/dist/automaton/index.js.map +1 -0
  30. package/dist/automaton/intersect.d.ts +35 -0
  31. package/dist/automaton/intersect.d.ts.map +1 -0
  32. package/dist/automaton/intersect.js +302 -0
  33. package/dist/automaton/intersect.js.map +1 -0
  34. package/dist/automaton/pattern-algebra.d.ts +62 -0
  35. package/dist/automaton/pattern-algebra.d.ts.map +1 -0
  36. package/dist/automaton/pattern-algebra.js +309 -0
  37. package/dist/automaton/pattern-algebra.js.map +1 -0
  38. package/dist/automaton/pattern-algebra.test.d.ts +2 -0
  39. package/dist/automaton/pattern-algebra.test.d.ts.map +1 -0
  40. package/dist/automaton/pattern-algebra.test.js +223 -0
  41. package/dist/automaton/pattern-algebra.test.js.map +1 -0
  42. package/dist/compile/automaton-builder.d.ts +47 -0
  43. package/dist/compile/automaton-builder.d.ts.map +1 -0
  44. package/dist/compile/automaton-builder.js +211 -0
  45. package/dist/compile/automaton-builder.js.map +1 -0
  46. package/dist/compile/compiler.d.ts +32 -0
  47. package/dist/compile/compiler.d.ts.map +1 -0
  48. package/dist/compile/compiler.js +47 -0
  49. package/dist/compile/compiler.js.map +1 -0
  50. package/dist/compile/index.d.ts +8 -0
  51. package/dist/compile/index.d.ts.map +1 -0
  52. package/dist/compile/index.js +8 -0
  53. package/dist/compile/index.js.map +1 -0
  54. package/dist/compile/quick-reject.d.ts +28 -0
  55. package/dist/compile/quick-reject.d.ts.map +1 -0
  56. package/dist/compile/quick-reject.js +147 -0
  57. package/dist/compile/quick-reject.js.map +1 -0
  58. package/dist/containment/analysis.d.ts +60 -0
  59. package/dist/containment/analysis.d.ts.map +1 -0
  60. package/dist/containment/analysis.js +378 -0
  61. package/dist/containment/analysis.js.map +1 -0
  62. package/dist/containment/containment.d.ts +23 -0
  63. package/dist/containment/containment.d.ts.map +1 -0
  64. package/dist/containment/containment.js +681 -0
  65. package/dist/containment/containment.js.map +1 -0
  66. package/dist/containment/containment.test.d.ts +2 -0
  67. package/dist/containment/containment.test.d.ts.map +1 -0
  68. package/dist/containment/containment.test.js +209 -0
  69. package/dist/containment/containment.test.js.map +1 -0
  70. package/dist/containment/index.d.ts +7 -0
  71. package/dist/containment/index.d.ts.map +1 -0
  72. package/dist/containment/index.js +7 -0
  73. package/dist/containment/index.js.map +1 -0
  74. package/dist/core-alpha.d.ts +1253 -0
  75. package/dist/core-beta.d.ts +1253 -0
  76. package/dist/core-public.d.ts +1253 -0
  77. package/dist/core-unstripped.d.ts +1253 -0
  78. package/dist/index.d.ts +32 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +49 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/match/index.d.ts +8 -0
  83. package/dist/match/index.d.ts.map +1 -0
  84. package/dist/match/index.js +8 -0
  85. package/dist/match/index.js.map +1 -0
  86. package/dist/match/matcher.d.ts +40 -0
  87. package/dist/match/matcher.d.ts.map +1 -0
  88. package/dist/match/matcher.js +256 -0
  89. package/dist/match/matcher.js.map +1 -0
  90. package/dist/match/matcher.test.d.ts +2 -0
  91. package/dist/match/matcher.test.d.ts.map +1 -0
  92. package/dist/match/matcher.test.js +185 -0
  93. package/dist/match/matcher.test.js.map +1 -0
  94. package/dist/match/path-utils.d.ts +132 -0
  95. package/dist/match/path-utils.d.ts.map +1 -0
  96. package/dist/match/path-utils.js +223 -0
  97. package/dist/match/path-utils.js.map +1 -0
  98. package/dist/match/path-utils.test.d.ts +2 -0
  99. package/dist/match/path-utils.test.d.ts.map +1 -0
  100. package/dist/match/path-utils.test.js +193 -0
  101. package/dist/match/path-utils.test.js.map +1 -0
  102. package/dist/match/segment-matcher.d.ts +25 -0
  103. package/dist/match/segment-matcher.d.ts.map +1 -0
  104. package/dist/match/segment-matcher.js +267 -0
  105. package/dist/match/segment-matcher.js.map +1 -0
  106. package/dist/parse/brace-expansion.d.ts +34 -0
  107. package/dist/parse/brace-expansion.d.ts.map +1 -0
  108. package/dist/parse/brace-expansion.js +294 -0
  109. package/dist/parse/brace-expansion.js.map +1 -0
  110. package/dist/parse/brace-expansion.test.d.ts +2 -0
  111. package/dist/parse/brace-expansion.test.d.ts.map +1 -0
  112. package/dist/parse/brace-expansion.test.js +105 -0
  113. package/dist/parse/brace-expansion.test.js.map +1 -0
  114. package/dist/parse/index.d.ts +8 -0
  115. package/dist/parse/index.d.ts.map +1 -0
  116. package/dist/parse/index.js +8 -0
  117. package/dist/parse/index.js.map +1 -0
  118. package/dist/parse/parser.d.ts +15 -0
  119. package/dist/parse/parser.d.ts.map +1 -0
  120. package/dist/parse/parser.js +526 -0
  121. package/dist/parse/parser.js.map +1 -0
  122. package/dist/parse/parser.test.d.ts +2 -0
  123. package/dist/parse/parser.test.d.ts.map +1 -0
  124. package/dist/parse/parser.test.js +266 -0
  125. package/dist/parse/parser.test.js.map +1 -0
  126. package/dist/parse/validator.d.ts +30 -0
  127. package/dist/parse/validator.d.ts.map +1 -0
  128. package/dist/parse/validator.js +115 -0
  129. package/dist/parse/validator.js.map +1 -0
  130. package/dist/parse/validator.test.d.ts +2 -0
  131. package/dist/parse/validator.test.d.ts.map +1 -0
  132. package/dist/parse/validator.test.js +45 -0
  133. package/dist/parse/validator.test.js.map +1 -0
  134. package/dist/types/ast.d.ts +158 -0
  135. package/dist/types/ast.d.ts.map +1 -0
  136. package/dist/types/ast.js +2 -0
  137. package/dist/types/ast.js.map +1 -0
  138. package/dist/types/automaton.d.ts +150 -0
  139. package/dist/types/automaton.d.ts.map +1 -0
  140. package/dist/types/automaton.js +2 -0
  141. package/dist/types/automaton.js.map +1 -0
  142. package/dist/types/containment.d.ts +257 -0
  143. package/dist/types/containment.d.ts.map +1 -0
  144. package/dist/types/containment.js +5 -0
  145. package/dist/types/containment.js.map +1 -0
  146. package/dist/types/errors.d.ts +37 -0
  147. package/dist/types/errors.d.ts.map +1 -0
  148. package/dist/types/errors.js +24 -0
  149. package/dist/types/errors.js.map +1 -0
  150. package/dist/types/index.d.ts +10 -0
  151. package/dist/types/index.d.ts.map +1 -0
  152. package/dist/types/index.js +6 -0
  153. package/dist/types/index.js.map +1 -0
  154. package/package.json +48 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Automaton emptiness checking and witness finding.
3
+ * @packageDocumentation
4
+ */
5
+ import type { SegmentAutomaton } from '../types';
6
+ /**
7
+ * Check if an automaton's language is empty.
8
+ *
9
+ * Uses reachability analysis from the initial state to any accepting state.
10
+ *
11
+ * @param automaton - The automaton to check
12
+ * @returns true if the automaton accepts no strings
13
+ *
14
+ * @public
15
+ */
16
+ export declare function isEmpty(automaton: SegmentAutomaton): boolean;
17
+ /**
18
+ * Find a witness string accepted by the automaton.
19
+ *
20
+ * If the automaton is non-empty, returns a path (sequence of segments)
21
+ * that leads to an accepting state.
22
+ *
23
+ * @param automaton - The automaton to find a witness for
24
+ * @returns A witness path string, or undefined if the language is empty
25
+ *
26
+ * @public
27
+ */
28
+ export declare function findWitness(automaton: SegmentAutomaton): string | undefined;
29
+ /**
30
+ * Count the number of accepting paths of a given length.
31
+ *
32
+ * Useful for understanding the "size" of a pattern's language.
33
+ *
34
+ * @param automaton - The automaton
35
+ * @param maxDepth - Maximum path length to consider
36
+ * @returns Object with counts per depth
37
+ *
38
+ * @public
39
+ */
40
+ export declare function countPaths(automaton: SegmentAutomaton, maxDepth: number): Map<number, number>;
41
+ //# sourceMappingURL=emptiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emptiness.d.ts","sourceRoot":"","sources":["../../src/automaton/emptiness.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAuC,MAAM,UAAU,CAAA;AAErF;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAW5D;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAoF3E;AAsED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA4C7F"}
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Automaton emptiness checking and witness finding.
3
+ * @packageDocumentation
4
+ */
5
+ /**
6
+ * Check if an automaton's language is empty.
7
+ *
8
+ * Uses reachability analysis from the initial state to any accepting state.
9
+ *
10
+ * @param automaton - The automaton to check
11
+ * @returns true if the automaton accepts no strings
12
+ *
13
+ * @public
14
+ */
15
+ export function isEmpty(automaton) {
16
+ // Check if any accepting state is reachable from initial state
17
+ const reachable = findReachableStates(automaton);
18
+ for (const acceptingId of automaton.acceptingStates) {
19
+ if (reachable.has(acceptingId)) {
20
+ return false; // Found a reachable accepting state
21
+ }
22
+ }
23
+ return true; // No accepting state is reachable
24
+ }
25
+ /**
26
+ * Find all states reachable from the initial state.
27
+ */
28
+ function findReachableStates(automaton) {
29
+ const reachable = new Set();
30
+ const worklist = [automaton.initialState];
31
+ while (worklist.length > 0) {
32
+ const stateId = worklist.pop();
33
+ if (reachable.has(stateId))
34
+ continue;
35
+ reachable.add(stateId);
36
+ const state = automaton.states[stateId];
37
+ if (!state)
38
+ continue;
39
+ for (const transition of state.transitions) {
40
+ const targets = getTransitionTargets(transition);
41
+ for (const target of targets) {
42
+ if (!reachable.has(target)) {
43
+ worklist.push(target);
44
+ }
45
+ }
46
+ }
47
+ }
48
+ return reachable;
49
+ }
50
+ /**
51
+ * Get all target states from a transition.
52
+ */
53
+ function getTransitionTargets(transition) {
54
+ switch (transition.type) {
55
+ case 'literal':
56
+ case 'wildcard':
57
+ case 'epsilon':
58
+ return [transition.target];
59
+ case 'globstar':
60
+ return [transition.selfLoop, transition.exit];
61
+ }
62
+ }
63
+ /**
64
+ * Find a witness string accepted by the automaton.
65
+ *
66
+ * If the automaton is non-empty, returns a path (sequence of segments)
67
+ * that leads to an accepting state.
68
+ *
69
+ * @param automaton - The automaton to find a witness for
70
+ * @returns A witness path string, or undefined if the language is empty
71
+ *
72
+ * @public
73
+ */
74
+ export function findWitness(automaton) {
75
+ const visited = new Set();
76
+ const queue = [{ stateId: automaton.initialState, path: [] }];
77
+ // First, handle epsilon closure from initial state
78
+ const initialClosure = epsilonClosure(automaton, automaton.initialState);
79
+ for (const stateId of initialClosure) {
80
+ if (automaton.states[stateId]?.accepting) {
81
+ return '/'; // Empty path matches
82
+ }
83
+ }
84
+ // Add all states in initial closure to queue
85
+ for (const stateId of initialClosure) {
86
+ if (stateId !== automaton.initialState) {
87
+ queue.push({ stateId, path: [] });
88
+ }
89
+ }
90
+ while (queue.length > 0) {
91
+ const { stateId, path } = queue.shift();
92
+ if (visited.has(stateId))
93
+ continue;
94
+ visited.add(stateId);
95
+ const state = automaton.states[stateId];
96
+ if (!state)
97
+ continue;
98
+ // Check if this state is accepting
99
+ if (state.accepting && path.length > 0) {
100
+ return '/' + path.join('/');
101
+ }
102
+ // Explore transitions
103
+ for (const transition of state.transitions) {
104
+ if (transition.type === 'epsilon') {
105
+ // Epsilon: same path, different state
106
+ if (!visited.has(transition.target)) {
107
+ queue.push({ stateId: transition.target, path });
108
+ }
109
+ }
110
+ else if (transition.type === 'literal') {
111
+ // Literal: extend path with the segment
112
+ if (!visited.has(transition.target)) {
113
+ queue.push({
114
+ stateId: transition.target,
115
+ path: [...path, transition.segment],
116
+ });
117
+ }
118
+ }
119
+ else if (transition.type === 'wildcard') {
120
+ // Wildcard: generate a sample segment that matches
121
+ const sample = generateMatchingSample(transition.pattern, transition.patternSource);
122
+ if (!visited.has(transition.target)) {
123
+ queue.push({
124
+ stateId: transition.target,
125
+ path: [...path, sample],
126
+ });
127
+ }
128
+ }
129
+ else if (transition.type === 'globstar') {
130
+ // Globstar exit: try exiting immediately (zero segments)
131
+ const exitClosure = epsilonClosure(automaton, transition.exit);
132
+ for (const exitState of exitClosure) {
133
+ if (!visited.has(exitState)) {
134
+ queue.push({ stateId: exitState, path });
135
+ }
136
+ }
137
+ // Globstar self-loop: consume one segment and continue
138
+ if (!visited.has(transition.selfLoop)) {
139
+ queue.push({
140
+ stateId: transition.selfLoop,
141
+ path: [...path, 'x'], // Generic segment
142
+ });
143
+ }
144
+ }
145
+ }
146
+ }
147
+ return undefined; // No accepting state found
148
+ }
149
+ /**
150
+ * Compute epsilon closure from a single state.
151
+ */
152
+ function epsilonClosure(automaton, startState) {
153
+ const closure = new Set();
154
+ const worklist = [startState];
155
+ while (worklist.length > 0) {
156
+ const stateId = worklist.pop();
157
+ if (closure.has(stateId))
158
+ continue;
159
+ closure.add(stateId);
160
+ const state = automaton.states[stateId];
161
+ if (!state)
162
+ continue;
163
+ for (const transition of state.transitions) {
164
+ if (transition.type === 'epsilon') {
165
+ if (!closure.has(transition.target)) {
166
+ worklist.push(transition.target);
167
+ }
168
+ }
169
+ else if (transition.type === 'globstar') {
170
+ // Globstar exit is epsilon-reachable
171
+ if (!closure.has(transition.exit)) {
172
+ worklist.push(transition.exit);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ return closure;
178
+ }
179
+ /**
180
+ * Generate a sample segment that matches a pattern.
181
+ */
182
+ function generateMatchingSample(pattern, patternSource) {
183
+ // Try to generate a sensible sample based on the pattern source
184
+ if (patternSource.includes('.ts')) {
185
+ return 'file.ts';
186
+ }
187
+ if (patternSource.includes('.js')) {
188
+ return 'file.js';
189
+ }
190
+ if (patternSource.startsWith('*.')) {
191
+ const ext = patternSource.slice(1);
192
+ return `sample${ext}`;
193
+ }
194
+ if (patternSource.endsWith('*')) {
195
+ const prefix = patternSource.slice(0, -1);
196
+ return `${prefix}sample`;
197
+ }
198
+ if (patternSource.startsWith('*')) {
199
+ const suffix = patternSource.slice(1);
200
+ return `sample${suffix}`;
201
+ }
202
+ // Default: try some common segments
203
+ const samples = ['file', 'dir', 'foo', 'bar', 'test', 'src', 'index.ts'];
204
+ for (const sample of samples) {
205
+ if (pattern.test(sample)) {
206
+ return sample;
207
+ }
208
+ }
209
+ return 'segment';
210
+ }
211
+ /**
212
+ * Count the number of accepting paths of a given length.
213
+ *
214
+ * Useful for understanding the "size" of a pattern's language.
215
+ *
216
+ * @param automaton - The automaton
217
+ * @param maxDepth - Maximum path length to consider
218
+ * @returns Object with counts per depth
219
+ *
220
+ * @public
221
+ */
222
+ export function countPaths(automaton, maxDepth) {
223
+ const counts = new Map();
224
+ // Dynamic programming: count[state][depth] = number of paths
225
+ // This is exponential in worst case, so we cap at maxDepth
226
+ const memo = new Map();
227
+ const countFrom = (stateId, depth) => {
228
+ if (depth > maxDepth)
229
+ return 0;
230
+ const key = `${stateId}:${depth}`;
231
+ if (memo.has(key))
232
+ return memo.get(key);
233
+ const state = automaton.states[stateId];
234
+ if (!state)
235
+ return 0;
236
+ let total = 0;
237
+ // Count if accepting at this depth
238
+ if (state.accepting) {
239
+ total++;
240
+ counts.set(depth, (counts.get(depth) ?? 0) + 1);
241
+ }
242
+ // Count paths through transitions
243
+ for (const transition of state.transitions) {
244
+ if (transition.type === 'epsilon') {
245
+ total += countFrom(transition.target, depth);
246
+ }
247
+ else if (transition.type === 'globstar') {
248
+ total += countFrom(transition.exit, depth);
249
+ total += countFrom(transition.selfLoop, depth + 1);
250
+ }
251
+ else {
252
+ const target = transition.type === 'literal' || transition.type === 'wildcard' ? transition.target : 0;
253
+ total += countFrom(target, depth + 1);
254
+ }
255
+ }
256
+ memo.set(key, total);
257
+ return total;
258
+ };
259
+ countFrom(automaton.initialState, 0);
260
+ return counts;
261
+ }
262
+ //# sourceMappingURL=emptiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emptiness.js","sourceRoot":"","sources":["../../src/automaton/emptiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=emptiness.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emptiness.test.d.ts","sourceRoot":"","sources":["../../src/automaton/emptiness.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { isEmpty, findWitness, countPaths } from './emptiness';
3
+ import { buildAutomaton } from '../compile/automaton-builder';
4
+ import { parsePattern } from '../parse';
5
+ import { compilePattern } from '../compile';
6
+ import { matchPath } from '../match';
7
+ describe('isEmpty', () => {
8
+ describe('non-empty automata', () => {
9
+ it('returns false for simple pattern', () => {
10
+ const pattern = parsePattern('src/index.ts');
11
+ const automaton = buildAutomaton(pattern);
12
+ expect(isEmpty(automaton)).toBe(false);
13
+ });
14
+ it('returns false for wildcard pattern', () => {
15
+ const pattern = parsePattern('*.ts');
16
+ const automaton = buildAutomaton(pattern);
17
+ expect(isEmpty(automaton)).toBe(false);
18
+ });
19
+ it('returns false for globstar pattern', () => {
20
+ const pattern = parsePattern('**/*.ts');
21
+ const automaton = buildAutomaton(pattern);
22
+ expect(isEmpty(automaton)).toBe(false);
23
+ });
24
+ it('returns false for alternation pattern', () => {
25
+ const pattern = parsePattern('{src,lib}/*.ts');
26
+ const automaton = buildAutomaton(pattern);
27
+ expect(isEmpty(automaton)).toBe(false);
28
+ });
29
+ });
30
+ describe('empty automata', () => {
31
+ // Note: isEmpty uses graph reachability, not semantic emptiness.
32
+ // For automata with wildcard transitions, the intersection may have
33
+ // reachable accepting states even if the language is semantically empty.
34
+ // Full semantic emptiness would require checking satisfiability of
35
+ // intersected wildcard patterns, which is beyond current implementation.
36
+ it('returns true for automaton with no accepting states', () => {
37
+ const pattern = parsePattern('src/index.ts');
38
+ const automaton = buildAutomaton(pattern);
39
+ // Create an automaton with no accepting states
40
+ const emptyAutomaton = {
41
+ ...automaton,
42
+ acceptingStates: [],
43
+ states: automaton.states.map((s) => ({ ...s, accepting: false })),
44
+ };
45
+ expect(isEmpty(emptyAutomaton)).toBe(true);
46
+ });
47
+ it('returns true for automaton with unreachable accepting state', () => {
48
+ const pattern = parsePattern('src/index.ts');
49
+ const automaton = buildAutomaton(pattern);
50
+ // Remove all transitions from initial state to make accepting states unreachable
51
+ const disconnectedAutomaton = {
52
+ ...automaton,
53
+ states: automaton.states.map((s, i) => (i === automaton.initialState ? { ...s, transitions: [] } : s)),
54
+ };
55
+ expect(isEmpty(disconnectedAutomaton)).toBe(true);
56
+ });
57
+ });
58
+ });
59
+ describe('findWitness', () => {
60
+ describe('finding witnesses', () => {
61
+ it('returns a matching path for simple pattern', () => {
62
+ const pattern = parsePattern('src/index.ts');
63
+ const automaton = buildAutomaton(pattern);
64
+ const witness = findWitness(automaton);
65
+ expect(witness).toBeDefined();
66
+ expect(witness).toContain('src');
67
+ expect(witness).toContain('index.ts');
68
+ });
69
+ it('returns a matching path for wildcard pattern', () => {
70
+ const pattern = parsePattern('*.ts');
71
+ const automaton = buildAutomaton(pattern);
72
+ const witness = findWitness(automaton);
73
+ expect(witness).toBeDefined();
74
+ expect(witness).toMatch(/\.ts$/);
75
+ });
76
+ it('returns a matching path for globstar pattern', () => {
77
+ const pattern = parsePattern('src/**/*.ts');
78
+ const automaton = buildAutomaton(pattern);
79
+ const witness = findWitness(automaton);
80
+ expect(witness).toBeDefined();
81
+ expect(witness).toMatch(/^\/src\//);
82
+ expect(witness).toMatch(/\.ts$/);
83
+ });
84
+ it('returns undefined for automaton with no accepting states', () => {
85
+ const pattern = parsePattern('src/index.ts');
86
+ const automaton = buildAutomaton(pattern);
87
+ // Create an automaton with no accepting states
88
+ const emptyAutomaton = {
89
+ ...automaton,
90
+ acceptingStates: [],
91
+ states: automaton.states.map((s) => ({ ...s, accepting: false })),
92
+ };
93
+ const witness = findWitness(emptyAutomaton);
94
+ expect(witness).toBeUndefined();
95
+ });
96
+ });
97
+ describe('witness validity', () => {
98
+ it('witness actually matches the pattern', () => {
99
+ const compiled = compilePattern(parsePattern('src/**/*.ts'));
100
+ const witness = findWitness(compiled.automaton);
101
+ expect(witness).toBeDefined();
102
+ // The witness is already a path string, verify it matches
103
+ expect(matchPath(witness, compiled)).toBe(true);
104
+ });
105
+ });
106
+ });
107
+ describe('countPaths', () => {
108
+ describe('bounded patterns', () => {
109
+ it('returns correct count for single literal', () => {
110
+ const pattern = parsePattern('src/index.ts');
111
+ const automaton = buildAutomaton(pattern);
112
+ const counts = countPaths(automaton, 5);
113
+ // Exactly one path of length 2
114
+ expect(counts.get(2)).toBe(1);
115
+ });
116
+ it('returns counts for multiple depths', () => {
117
+ const pattern = parsePattern('src/*.ts');
118
+ const automaton = buildAutomaton(pattern);
119
+ const counts = countPaths(automaton, 5);
120
+ // Should have paths at depth 2
121
+ expect(counts.get(2)).toBeGreaterThanOrEqual(1);
122
+ });
123
+ });
124
+ describe('unbounded patterns', () => {
125
+ it('returns counts up to maxDepth for globstar', () => {
126
+ const pattern = parsePattern('src/**');
127
+ const automaton = buildAutomaton(pattern);
128
+ const counts = countPaths(automaton, 5);
129
+ // Should have paths at depths 1, 2, 3, 4, 5
130
+ expect(counts.get(1)).toBeGreaterThanOrEqual(1);
131
+ expect(counts.get(2)).toBeGreaterThanOrEqual(1);
132
+ });
133
+ });
134
+ describe('empty patterns', () => {
135
+ it('returns zero paths for automaton with no accepting states', () => {
136
+ const pattern = parsePattern('src/index.ts');
137
+ const automaton = buildAutomaton(pattern);
138
+ // Create an automaton with no accepting states
139
+ const emptyAutomaton = {
140
+ ...automaton,
141
+ acceptingStates: [],
142
+ states: automaton.states.map((s) => ({ ...s, accepting: false })),
143
+ };
144
+ const counts = countPaths(emptyAutomaton, 5);
145
+ // All counts should be 0 or map should be empty
146
+ let total = 0;
147
+ for (const count of counts.values()) {
148
+ total += count;
149
+ }
150
+ expect(total).toBe(0);
151
+ });
152
+ });
153
+ });
154
+ //# sourceMappingURL=emptiness.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emptiness.test.js","sourceRoot":"","sources":["../../src/automaton/emptiness.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Automaton operations for pattern containment checking.
3
+ * @packageDocumentation
4
+ */
5
+ export { determinize, DEFAULT_MAX_DFA_STATES, type DeterminizeOptions } from './determinize';
6
+ export { complement } from './complement';
7
+ export { intersect, union } from './intersect';
8
+ export { isEmpty, findWitness, countPaths } from './emptiness';
9
+ export { patternIntersect, patternUnion, patternComplement, patternDifference } from './pattern-algebra';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/automaton/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Automaton operations for pattern containment checking.
3
+ * @packageDocumentation
4
+ */
5
+ export { determinize, DEFAULT_MAX_DFA_STATES } from './determinize';
6
+ export { complement } from './complement';
7
+ export { intersect, union } from './intersect';
8
+ export { isEmpty, findWitness, countPaths } from './emptiness';
9
+ // Pattern-level set operations
10
+ export { patternIntersect, patternUnion, patternComplement, patternDifference } from './pattern-algebra';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/automaton/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAA2B,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE9D,+BAA+B;AAC/B,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Automaton intersection using product construction.
3
+ * @packageDocumentation
4
+ */
5
+ import type { SegmentAutomaton } from '../types';
6
+ /**
7
+ * Compute the intersection of two automata using product construction.
8
+ *
9
+ * The resulting automaton accepts a string iff both input automata accept it.
10
+ * L(A ∩ B) = L(A) ∩ L(B)
11
+ *
12
+ * @param a - First automaton
13
+ * @param b - Second automaton
14
+ * @returns Intersection automaton
15
+ *
16
+ * @public
17
+ */
18
+ export declare function intersect(a: SegmentAutomaton, b: SegmentAutomaton): SegmentAutomaton;
19
+ /**
20
+ * Compute the union of two automata using NFA construction.
21
+ *
22
+ * The resulting automaton accepts a string iff either input automaton accepts it.
23
+ * L(A ∪ B) = L(A) ∪ L(B)
24
+ *
25
+ * We use NFA union: create a new initial state with epsilon transitions
26
+ * to both automata's initial states, then merge the states.
27
+ *
28
+ * @param a - First automaton
29
+ * @param b - Second automaton
30
+ * @returns Union automaton (NFA)
31
+ *
32
+ * @public
33
+ */
34
+ export declare function union(a: SegmentAutomaton, b: SegmentAutomaton): SegmentAutomaton;
35
+ //# sourceMappingURL=intersect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intersect.d.ts","sourceRoot":"","sources":["../../src/automaton/intersect.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAuD,MAAM,UAAU,CAAA;AAErG;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAEpF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAyChF"}