Skip to main content

isabelle-query

query is a command-line tool for querying an Isabelle/Isar project — its entries (definitions, lemmas, theorems, datatypes), call graph, theory dependencies, outstanding sorrys, dead code, and the shape of its proofs.

It parses the project's .thy sources on every invocation, so results always match the current tree: no Isabelle build, no proof replay. A large project parses in a fraction of a second, and the whole AFP in a couple of minutes. It is aimed at projects big enough that grep-and-examine has stopped working — AFP entries, the AFP itself, or industrial verification.

Pure Python. One runtime dependency, isabelle-layout — the ROOT and theory-header parser, split out so that reading an Isabelle project's structure does not require installing a CLI. pip fetches it for you.

Commands

query summary              # theory overview table (-S: corpus/session aggregate)
query theory MyTheory      # entries in a theory (-n for terse names)
query find <regex>         # search entry names (--statement: search statements; --and: all patterns)
query show <name>          # a named entry's declaration + body
query enclosing FILE:LINE  # which entry + proof block owns a line; inverse of outline
query callers <name> [-r]  # who references a name  (reverse; -r = transitive)
query callees <name> [-r]  # what a name references (forward)
query deps <theory> [-r]   # what a theory imports  (forward; reverse: uses)
query refs <theory>        # what a theory cites, by owning theory (citation-level)
query graph [citation|imports]  # the whole graph as JSON (-f dot for Graphviz)
query sorry                # outstanding sorry's
query unused               # dead-code / unused-entry analysis
query shape <view>         # proof-shape metrics (summary|steps|lemma|widest|census)

Every subcommand takes -h; query -h lists all 20.

Examples

Point query at any session directory with -R (or --root):

query -R AFP/thys largest                          # the biggest entries, by line count
query -R AFP/thys callers metric_domain_tfin_def   # every proof step that cites a fact
query -R AFP/thys find --statement tfin            # lemmas *stated about* tfin, whatever their name
query -R AFP/thys find --statement --and length tfin  # ...and mentioning length too (--and intersects)
query -R AFP/thys enclosing Tfin.thy:412           # the lemma and nearest proof block a build error sits in
query -R AFP/thys enclosing Tfin:88..140           # every entry a diff hunk touches
query -R AFP/thys grep simp Tfin.thy:88..140       # search just a hunk

Locations and spans share one grammar (theory:line, theory:A..B), so the tool's output is valid input: a locus from callers / sorry pastes into enclosing, and a span from outline / largest — or a proof block from enclosing's own drill-down (▸ have key 11..14) — pastes into lines.

What it reads

Only live Isar text. A name in a comment, a \<comment> note, a text block or an ML body is not a citation, so it never invents a caller or hides a dead lemma — and a definition left behind in a comment is not an entry. Regions are found by a character-level scan, not by line, so by (simp add: foo) (* not bar *) keeps foo and drops bar.

Layout carries no meaning: Isar is whitespace-insensitive, so a declaration is recognised wherever a command can start, at any indentation and any block depth. Discovery loads what isabelle build compiles — each session's declared theories plus the closure of their in-entry imports.

See SCANNING.md for the details: locale scope, method names that collide with fact names, corpus aggregation, and the prose view.

Proof-shape metrics

query shape measures the shape of individual proof steps — how big a step is, how deeply nested, how many facts it holds at once, how much is re-said, and how it is discharged. All source-level, no build.

query shape summary                  # per-theory aggregate table
query shape lemma <name>             # one proof: every step
query -R AFP/thys shape census       # per-proof JSONL over a whole corpus

See METRICS.md for the command reference, the metric table, and the JSONL record schema.

Exit status

0 the command ran; 1 the request could not be resolved (unknown theory or path, no subcommand); 2 bad usage — an argparse error, or a root that could not be read; 141 a downstream reader closed the pipe (query shape census | head), as a shell reports for SIGPIPE.

A root that yields no theories is reported on stderr and never as an empty success, so a script can tell a broken run from an honestly empty one:

$ query -R /typo/path shape census
query: /typo/path: no such directory (given to -R/--root)
$ echo $?
2

Installation

Requires Python 3.9 or greater. Installs the command on your PATH under two names — query, the short form used throughout these docs, and isabelle-query, matching the distribution — and pulls isabelle-layout from PyPI. They are the same program, and it reports whichever you typed, so isabelle-query -h documents isabelle-query.

pip install isabelle-query     # from PyPI
pip install .                  # from a checkout

An editable install, for working on the tool itself:

git clone https://github.com/ott2/isabelle-query
cd isabelle-query
python -m venv .venv && source .venv/bin/activate   # optional but recommended
pip install -e .

Documentation

file what
SCANNING.md how query reads a project — what counts as a declaration, a citation, and a session
METRICS.md query shape command reference and metric definitions
CONTRIBUTING.md the CLI contract and where design decisions are recorded

Authors & license

By András Salamon, with Claude Opus 4.6, 4.7, 4.8, and 5. MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

isabelle_query-0.7.0.tar.gz (357.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

isabelle_query-0.7.0-py3-none-any.whl (199.1 kB view details)

Uploaded Python 3

File details

Details for the file isabelle_query-0.7.0.tar.gz.

File metadata

  • Download URL: isabelle_query-0.7.0.tar.gz
  • Upload date:
  • Size: 357.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for isabelle_query-0.7.0.tar.gz
Algorithm Hash digest
SHA256 12c534b8c03f3abb3beb900abc92c2d172ec11ca088be187955a041a665a06e8
MD5 712880fde59612781f84880a2686fe5b
BLAKE2b-256 ab43275106cf620e4ae7da738b2f8f6d1749dd95219534661e565f489403e921

See more details on using hashes here.

File details

Details for the file isabelle_query-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: isabelle_query-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 199.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for isabelle_query-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 446d31a9a3f3e07f40a3d6326a4a86582da1afd7e92211c9d58c9fc8933d4f1d
MD5 f5dfd5f200ac2e02d1538655f435284e
BLAKE2b-256 5b9574c3b4cda5c19e51edc37eae7dd09ab58f76bab88db9172b61f58377558f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.7.0 This release

2 files

0.6.7

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page