Skip to main content

isabelle-block

Mechanical edits to regions of Isabelle theory files, where a region is named by a line span or by the name of a lemma.

block move Foo.thy:helper_lemma before first_user     # hoist a helper
block delete Foo.thy:dead_lemma
block move Foo.thy:1669..2657 before Bar.thy:46       # between theories
block reargs 'cost $1 $2' 'Suc (len $1)' Foo.thy --expect 14

Name addressing is the reason to use it. Foo.thy:helper_lemma resolves, through isabelle-query's parser, to the lemma's span, from its doc block through the last line of its proof. So an edit needs no line arithmetic, and it cannot go stale between looking a lemma up and editing it.

Install

python3 -m pip install git+https://github.com/ott2/isabelle-block@v0.1.3

This puts block on your PATH. Needs Python 3.9 or later; depends on isabelle-query and isabelle-layout, which pip fetches from PyPI. It needs no Isabelle process.

isabelle-block is not on PyPI yet. It will be published there once the standalone tool has seen more use; until then, install a tagged release from GitHub as above.

Verbs

verb does
move SRC:REGION before DEST relocate a block, within a file or between files
copy SRC:REGION before DEST place a copy and keep the source
delete FILE:REGION excise a block
emit FILE:REGION print a block verbatim
replace FILE:REGION NEWFILE swap a block for a file's contents
sub OLD NEW FILE[:REGION]... literal substring substitution
resub PAT NEW FILE[:REGION]... regex substitution; a match may span lines
reargs 'F $1 $2' TMPL FILE[:REGION]... rewrite F's applications by their (bracket-aware) arguments; skips prose
split SRC 'NAME|IMPORTS|RANGES'... [--cut] cut a theory into several
merge BASE.thy SRC.thy... splice theory bodies into one

A REGION is A..B (or A-B), a single line N, an entry NAME, or all, which is also what a bare FILE means. A DEST is LINE, NAME, FILE:LINE or FILE:NAME; the block lands immediately before it, preamble included.

Modifiers:

  • --dry-run reports the edit and writes nothing.
  • --expect N makes sub, resub and reargs refuse unless exactly N substitutions are made.
  • --except NAME leaves an entry out of every region.
  • --no-preamble starts a resolved span at the entry, not its doc block.
  • --with-preamble keeps the doc block even when it sits directly under a section heading. Such a text may introduce the section rather than document the entry, and the source cannot say which. So there, delete, move and replace refuse until you choose one of these two flags.
  • --keep-heading / --with-heading: deleting the only entry under a heading refuses until you say whether the heading stays (bare) or the whole section goes with the entry.
  • --land-above-text / --land-below-text: a block moved or copied before NAME, landing under a heading, refuses when NAME's doc block sits directly under that heading, since the text may introduce the section. Say whether the block lands above the text or between it and NAME.
  • --root DIR names the session root whose keyword table name resolution uses. By default it is discovered as query discovers it: an environment variable, a .isabelle-query marker, or the nearest ROOT. The table matters because a theory may use a command that another theory in its session declares.
  • --no-trailing-blank cuts verbatim, without blank-line healing.

A refusal for want of a choice lists every open choice at once, so one rerun with a flag from each pair goes through.

A block moved before NAME that starts with its own heading, of the same or higher rank as the heading above NAME, lands above that heading. So it becomes a section beside NAME's, and does not swallow NAME.

block --help gives the full grammar, and block VERB --help gives one verb's.

Every run ends with an explicit PASS: or FAIL: line, and the exit status agrees. emit prints its PASS: on stderr, so block emit … > FILE is a clean copy. A refusal writes nothing.

Editing by line span and plain substitution are what ed, sed, sd and fastmod already do. comby does bracket-aware rewriting much as reargs does. block is worth installing if your edits need what those tools cannot see:

  • lemma names as addresses;
  • the difference between Isar code and prose (text, headings, \<comment>);
  • edits at theory level.

docs/related-tools.md compares them in detail.

Status

This is alpha, extracted from the NDTHT formalisation's bin/block.py, where it did the project's mechanical theory surgery. The planned verbs (rename, a caller-checked delete and an import-checked move) are in tasks.md.

Development

python3 -m venv .venv
.venv/bin/pip install -e '.[test]'
.venv/bin/pytest

Authors & license

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

Metadata

Release files for isabelle-block 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for isabelle-block 0.1.3
File Size Uploaded Provenance
isabelle_block-0.1.3.tar.gz 31.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for isabelle-block 0.1.3
File Interpreter ABI Platform
isabelle_block-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 54.1 kB

Release files / isabelle_block-0.1.3.tar.gz

Download URL isabelle_block-0.1.3.tar.gz
Size 31.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a29fa629ca447ba85326879f9d1b969809811db6ea11f36cf4e190b40f60a569
BLAKE2b-256 checksum
How to use checksums
ce73fb5acbe9f73724c53ce8bdcbf452d81070e52b650445011d9dfbe5ae2fd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Release files / isabelle_block-0.1.3-py3-none-any.whl

Download URL isabelle_block-0.1.3-py3-none-any.whl
Size 22.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7b1e5f5753a2e1e0ff77d8874bfa6078e5c079179748bfbb42fc62f200428794
BLAKE2b-256 checksum
How to use checksums
d87e7312b8a999fc4e04b7ac3db89ae74ca1d30683f49b58f5fdf6c03d97e932
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.9

Security for isabelle-block 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page