Getting Started =============== Prerequisites ------------- **Rust toolchain** Install via `rustup `_:: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh **Z3 SMT solver library** perlchecker links against libz3 at build time. *Ubuntu / Debian*:: sudo apt install libz3-dev *Arch Linux*:: sudo pacman -S z3 *macOS (Homebrew)*:: brew install z3 *From source*: build Z3 from `the Z3 GitHub repository `_ and ensure the headers and shared library are on your include/library path. Building from Source -------------------- Clone the repository and build with Cargo:: git clone https://github.com/dhilst/perlchecker.git cd perlchecker cargo build --release The binary is at ``target/release/perlchecker``. Quick Start ----------- Create a file ``hello.pl``: .. code-block:: perl # sig: (I64) -> I64 # pre: $x >= 0 # post: $result == $x sub identity_with_pre { my ($x) = @_; return $x; } Run the verifier: .. code-block:: console $ cargo run --quiet -- check hello.pl ✔ identity_with_pre: verified The tool proved that for every integer ``$x >= 0``, the function returns exactly ``$x``. What Just Happened? ^^^^^^^^^^^^^^^^^^^ 1. perlchecker extracted the annotated function and its contracts. 2. It parsed the function body into an AST, type-checked it, and lowered it to SSA form. 3. It symbolically executed all paths through the function, treating ``$x`` as a symbolic (unconstrained) integer. 4. For each path, it asked the Z3 SMT solver: "Given the precondition ``$x >= 0`` and this path's constraints, can the postcondition ``$result == $x`` ever be false?" 5. Z3 answered "no" for every path — the function is verified.