User Guide¶
File Structure¶
A perlchecker input file contains one or more Perl functions. Each function
that should be verified must have an annotation block — a contiguous group of
#-prefixed comment lines — placed immediately above the sub keyword.
Functions without annotations are ignored.
# sig: (I64) -> I64
# pre: $x >= 0
# post: $result >= 0
sub my_function {
my ($x) = @_;
return $x;
}
Warning
There must be no blank lines between the annotation block and the
sub line. A blank line causes an extraction error.
Function Rules¶
Every annotated function must follow these rules:
Parameter binding first. The first statement must be
my ($param1, $param2, ...) = @_;.Explicit return. Every execution path must end with a
returnstatement.No recursion. Direct or indirect recursion is rejected.
Same-file calls only. Functions can call other annotated functions in the same file. The callee must appear before the caller.
Pure functions. No global variables, no I/O side effects (
print,say, andwarnare accepted but treated as no-ops for verification).
Running the Tool¶
$ perlchecker check FILE.pl [OPTIONS]
Options:
Flag |
Default |
Description |
|---|---|---|
|
5 |
Maximum loop unroll depth |
|
1024 |
Maximum symbolic execution paths per function |
|
5000 |
Z3 solver timeout in milliseconds |
See Configuration for tuning guidance.
Understanding Output¶
Verified¶
✔ function_name: verified
The postcondition holds for all inputs satisfying the precondition, across all execution paths (up to the loop unroll bound).
Counterexample Found¶
✘ function_name: counterexample found
Function function_name failed:
x = 42
y = -1
The solver found concrete input values that satisfy the precondition but violate the postcondition. These values are a witness showing the function is incorrect.
No Annotated Functions¶
Found 0 annotated functions
The file contains no functions with annotation blocks.
Errors¶
Parse errors, type errors, and verification errors are printed to stderr. See Error Reference for a complete list.
Multi-Function Files¶
A file can contain multiple annotated functions. They are verified in source
order. When function B calls function A, the verifier inlines A
at the call site — it does not re-verify A separately for each caller.
# sig: (I64) -> I64
# post: $result == $x + 1
sub inc {
my ($x) = @_;
return $x + 1;
}
# sig: (I64) -> I64
# post: $result == $x + 1
sub call_inc {
my ($x) = @_;
return inc($x);
}
$ perlchecker check multi.pl
✔ inc: verified
✔ call_inc: verified
Debugging with Tracing¶
Set RUST_LOG to see internal pipeline details:
$ RUST_LOG=debug perlchecker check file.pl
Levels: error, warn, info, debug, trace.