Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c428904

Browse files
committedJul 19, 2024
Add checker to validate manually entered reveal transitions
1 parent 580636f commit c428904

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed
 

‎src/cli.ts

+48-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { assert } from 'o1js';
12
import { RegexCompiler } from './compiler.js';
23
import { Command } from 'commander';
34

@@ -9,16 +10,17 @@ program
910
.description('CLI for ZK Regex Compiler in o1js')
1011
.argument('<rawRegex>', 'Raw regex pattern to compile')
1112
.option('-c, --count', 'Enable count for match regex pattern')
12-
.option('-t, --revealTransitions <values...>', 'Transitions to reveal')
13+
.option(
14+
'-t, --revealTransitions <values...>',
15+
'Partial state transitions to reveal'
16+
)
1317
.option('-s, --revealSubpatterns <values...>', 'Regex subpatterns to reveal')
1418
.action((rawRegex, options) => {
1519
// Extract and set the options
1620
const countEnabled = options.count || false;
1721
let revealEnabled = false;
1822

19-
// Initialize transitionInput to undefined
20-
let transitionInput: string[] | [number, number][][] | undefined =
21-
undefined;
23+
let revealInput: string[] | [number, number][][] | undefined = undefined;
2224

2325
// Ensure only one of --revealTransitions or --revealSubpatterns is provided
2426
if (options.revealTransitions && options.revealSubpatterns) {
@@ -28,20 +30,25 @@ program
2830
process.exit(1);
2931
}
3032

33+
// Initialize the RegexCompiler
34+
const compiler = RegexCompiler.initialize(rawRegex, true);
35+
3136
// Set transitionInput and revealEnabled based on the provided option
3237
if (options.revealTransitions) {
3338
revealEnabled = true;
34-
transitionInput = parseTransitions(options.revealTransitions);
39+
revealInput = parseTransitions(options.revealTransitions);
40+
41+
assertTransitionsIncluded(
42+
revealInput,
43+
compiler.extractSubPatternTransitions([rawRegex]).flat()
44+
);
3545
} else if (options.revealSubpatterns) {
3646
revealEnabled = true;
37-
transitionInput = options.revealSubpatterns;
47+
revealInput = options.revealSubpatterns;
3848
}
3949

40-
// Initialize the RegexCompiler
41-
const compiler = RegexCompiler.initialize(rawRegex, true);
42-
4350
// Print the regex circuit based on the options
44-
compiler.printRegexCircuit(countEnabled, revealEnabled, transitionInput);
51+
compiler.printRegexCircuit(countEnabled, revealEnabled, revealInput);
4552
});
4653

4754
// Parse the command-line arguments
@@ -60,6 +67,8 @@ function parseTransitions(inputArray: string[]): [number, number][][] {
6067

6168
// Extract pairs of numbers from the cleaned string
6269
const pairs = cleanedString.match(/\[\d+,\d+\]/g);
70+
71+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
6372
return pairs!.map((pair) => {
6473
const [a, b] = pair.replace(/[[\]]/g, '').split(',').map(Number);
6574
if (isNaN(a) || isNaN(b)) {
@@ -69,3 +78,32 @@ function parseTransitions(inputArray: string[]): [number, number][][] {
6978
});
7079
});
7180
}
81+
82+
/**
83+
* Assert that all transitions to reveal are included in the full transition array.
84+
*
85+
* @param transitionsToReveal - The array of transitions to reveal.
86+
* @param fullTransitions - The full array of transitions.
87+
*/
88+
function assertTransitionsIncluded(
89+
transitionsToReveal: [number, number][][],
90+
fullTransitions: [number, number][]
91+
): void {
92+
// Convert fullTransitions to a Set of strings for quick lookup
93+
const fullTransitionsSet = new Set(
94+
fullTransitions.map((transition) => JSON.stringify(transition))
95+
);
96+
97+
// Check each transition in transitionsToReveal
98+
for (const group of transitionsToReveal) {
99+
for (const transition of group) {
100+
const isIncluded = fullTransitionsSet.has(JSON.stringify(transition));
101+
assert(
102+
isIncluded,
103+
`Transition ${JSON.stringify(transition)} not found!\n` +
104+
`Please enter transitions that are part of your regex pattern transitions: ` +
105+
`[${Array.from(fullTransitionsSet).join(', ')}]`
106+
);
107+
}
108+
}
109+
}

‎src/compiler.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export class RegexCompiler {
372372
return acceptLines;
373373
}
374374

375-
extractSubPatternTransitions(partRegexArray: string[]) {
375+
public extractSubPatternTransitions(partRegexArray: string[]) {
376376
let subPatternDefsArray: [number, number][][] = [];
377377
for (const partRegex of partRegexArray) {
378378
assert(
@@ -467,18 +467,18 @@ export class RegexCompiler {
467467

468468
private writeRevealLines(
469469
revealEnabled: boolean,
470-
transitionInput?: string[] | [number, number][][]
470+
revealInput?: string[] | [number, number][][]
471471
) {
472472
let revealLines: string;
473473
if (revealEnabled) {
474474
let revealedTransitions: [number, number][][];
475475
// Type guard to check if parsedInput is an array of strings
476476
try {
477477
revealedTransitions = this.extractSubPatternTransitions(
478-
transitionInput as string[]
478+
revealInput as string[]
479479
);
480480
} catch (error) {
481-
revealedTransitions = transitionInput as [number, number][][];
481+
revealedTransitions = revealInput as [number, number][][];
482482
}
483483

484484
revealLines =

0 commit comments

Comments
 (0)
Failed to load comments.