Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 110 additions & 6 deletions doc/docusaurus/docs/uplc-cli-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,112 @@ You can also build `uplc` from source by cloning the Plutus repository, running

`uplc` supports a variety of subcommands.
Run `uplc --help` to see the available subcommands, and `uplc <subcommand> --help` to see the options of a particular subcommand.
Both `uplc --help` and the `--help` of the most commonly used subcommands end with a short, worked **Examples** section, so the fastest way to remember how a command is invoked is usually to ask it.

## Subcommands at a glance

| Subcommand | What it does |
| --- | --- |
| `evaluate` | Run a UPLC program on the CEK machine and print the result. |
| `time` | Time the evaluation of a UPLC program on the CEK machine. |
| `debug` | Step through a UPLC program interactively on the CEK machine. |
| `apply` | Apply one script to others, producing `(... ((f g1) g2) ... gn)`. |
| `apply-to-flat-data` / `apply-to-cbor-data` | Apply a script to flat- or CBOR-encoded `Data` arguments. |
| `convert` | Convert a program between formats (textual, flat, hex, blueprint, …). |
| `print` | Parse a program and pretty-print it. |
| `optimise` / `optimize` | Run the UPLC optimisation pipeline. |
| `benchmark` | Benchmark evaluation with [Criterion](https://hackage.haskell.org/package/criterion). |
| `example` | Show built-in example programs (`uplc example -a` lists them). |
| `dump-cost-model` | Dump the cost model parameters. |
| `print-builtin-signatures` | Print the signatures of the built-in functions. |

## Shell completion

`uplc` can generate a completion script for `bash`, `zsh`, or `fish`.
Completion covers subcommand names, option flags, file paths (for `-i`, `-o`, `--eval-apply`, …), and the allowed values of enumerated options such as `--if`/`--of`, `--print-mode`, `--trace-mode`, and `-S`/`--builtin-semantics-variant`.

To enable completion in the **current** shell:

```bash
# bash
source <(uplc --bash-completion-script "$(command -v uplc)")
```

```bash
# zsh — the generated script is a completion function body, so it cannot be
# sourced directly; install it as `_uplc` on your $fpath instead:
mkdir -p ~/.zsh/completions
uplc --zsh-completion-script "$(command -v uplc)" > ~/.zsh/completions/_uplc
fpath+=(~/.zsh/completions)
autoload -U compinit && compinit
```

```bash
# fish
uplc --fish-completion-script (command -v uplc) | source
```

To install completion **permanently**, write the generated script to the location your shell loads completions from, for example:

```bash
# bash (system-wide; use a user directory if you prefer)
uplc --bash-completion-script "$(command -v uplc)" | sudo tee /etc/bash_completion.d/uplc > /dev/null

# zsh (a directory on your $fpath; add the fpath+= and compinit lines above to your .zshrc)
uplc --zsh-completion-script "$(command -v uplc)" > ~/.zsh/completions/_uplc

# fish
uplc --fish-completion-script (command -v uplc) > ~/.config/fish/completions/uplc.fish
```

The same flags work for the `plc` and `pir` tools; just substitute the program name.

## Evaluating scripts

`uplc evaluate` runs a UPLC program on the CEK machine.
As with every subcommand, if `-i` is omitted the program is read from stdin, which makes it easy to use in a pipeline:

```bash
uplc evaluate -i program.uplc
echo '(program 1.1.0 (con integer 42))' | uplc evaluate
```

Scripts as they appear on-chain (in blueprints, wallets, or block explorers) are usually hex-encoded, so pass `--if hex`:

```bash
uplc evaluate --if hex -i script.hex
```

By default evaluation is silent about resource usage. To see how much CPU and memory a program consumes, pick a budget mode:

- `--counting` (`-c`) — run to completion and report the total budget spent.
- `--tallying` (`-t`) — like `--counting`, but also break the cost down per builtin and per AST-node type.
- `--restricting ExCPU:ExMemory` (`-R`) — run within the given budget and fail if it is exceeded, e.g. `--restricting 1000000:5000`.
- `--restricting-enormous` (`-r`) — run within a very large (effectively unlimited) budget and print the budget **remaining** afterwards. Evaluation already uses this enormous budget by default; `-r` only adds the report. To see what a run *consumed*, use `--counting` or `--tallying`.

```bash
uplc evaluate -i program.uplc --tallying
```

To capture `trace` output emitted by the program, use `--trace-mode`, e.g. `--trace-mode Logs`.

## Applying arguments to a script

A validator becomes a runnable program only once its arguments (datum, redeemer, script context, …) have been applied.
`uplc apply` builds that application for you.
Use `apply` when the arguments are themselves UPLC scripts, and `apply-to-flat-data` / `apply-to-cbor-data` when they are encoded `Data` values (the common case for on-chain arguments):

```bash
# arguments are UPLC scripts
uplc apply --if flat Validator.flat Datum.flat Redeemer.flat Context.flat --of flat -o Script.flat

# arguments are CBOR-encoded Data
uplc apply-to-cbor-data --if flat Validator.flat Datum.cbor Redeemer.cbor Context.cbor --of flat -o Script.flat
```

You can then evaluate the fully-applied script with `uplc evaluate`.

# Script optimization
## Script optimization

For most users, the most immediately useful subcommand is `optimize` (or `optimise`), which optimizes UPLC programs.
It runs the same UPLC optimization pipeline that the Plinth compiler uses internally: case-of-known-constructor, inlining, common subexpression elimination (CSE), and more.
Expand All @@ -26,14 +130,14 @@ uplc optimize -i MyValidator.uplc -o MyValidator-opt.uplc
By default, both input and output files use the textual format.
If `-i` or `-o` is omitted, `uplc` reads from stdin and writes to stdout, so it fits naturally into shell pipelines.

## The optimization report
### The optimization report

Running `uplc optimize` prints an _optimization report_ to stderr.
The report lists each pass that ran, in order, and shows the AST size before and after every pass, along with the size delta.
When evaluation is enabled (see below), each row additionally shows the CPU and memory cost at that stage and the deltas against the previous stage.
When `--certify --certifier-report` is used, the same per-pass numbers are also included in the certifier report file.

## Input and output formats
### Input and output formats

`uplc` has always supported textual and flat-encoded scripts, but two recent additions make it much easier to plug into existing toolchains:

Expand Down Expand Up @@ -63,7 +167,7 @@ The full list of supported formats is:
- `hex` — `serialised` plus hex encoding (what blueprints and most tools use)
- `blueprint` — blueprint JSON

## Configuring the optimization pipeline
### Configuring the optimization pipeline

The `opt-*` flags let you configure the optimization pipeline.
Run `uplc optimize --help` to see the full list.
Expand All @@ -77,7 +181,7 @@ Higher values mean more aggressive inlining, and more inlining usually reduces c
`--opt-cse-which-subterms` controls how aggressive common subexpression elimination is: `all` is more aggressive than the default `exclude-work-free`.
Aggressive CSE typically reduces size (more duplicates get factored out) but can raise cost (each factored subterm adds a small evaluation overhead).

## Certifying optimizations
### Certifying optimizations

`uplc` includes certifiers for optimization passes.
Each pass is formalized in Agda as a translation relation between pre- and post-terms together with a procedure that decides whether the relation holds.
Expand Down Expand Up @@ -110,7 +214,7 @@ The certifier has three output modes:
For blueprints, the certifier runs once per validator.
Report filenames and project directories have the validator's title appended automatically.

## Evaluating before and after each optimization
### Evaluating before and after each optimization

The `--eval*` flags supply arguments to the script and run it on the CEK machine at every stage of the optimization pipeline, recording the execution cost at each step.
The CPU and memory cost at every stage are then shown alongside AST sizes in the optimization report.
Expand Down
16 changes: 8 additions & 8 deletions doc/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
},
"dependencies": {
"@cmfcmf/docusaurus-search-local": "^1.1.0",
"@docusaurus/core": "^3.6.0",
"@docusaurus/plugin-google-gtag": "^3.6.0",
"@docusaurus/preset-classic": "^3.6.0",
"@docusaurus/theme-mermaid": "^3.6.0",
"@docusaurus/core": "^3.10.2",
"@docusaurus/plugin-google-gtag": "^3.10.2",
"@docusaurus/preset-classic": "^3.10.2",
"@docusaurus/theme-mermaid": "^3.10.2",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.6.0",
"@docusaurus/tsconfig": "^3.6.0",
"@docusaurus/types": "^3.6.0",
"@docusaurus/module-type-aliases": "^3.10.2",
"@docusaurus/tsconfig": "^3.10.2",
"@docusaurus/types": "^3.10.2",
"typescript": "~5.2.2",
"ajv": ">=8.18.0"
},
Expand All @@ -42,7 +42,7 @@
"@babel/runtime-corejs3": "7.29.7",
"@babel/runtime": "7.29.7",
"@babel/helpers": "7.29.7",
"image-size": "1.2.1",
"image-size": "2.0.2",
"estree-util-value-to-estree": "3.3.3",
"http-proxy-middleware": "2.0.10",
"webpack-dev-server": "5.2.5",
Expand Down
Loading
Loading