Alectryon normally produces plain HTML files. For very large proofs, these files can get quite large (sometimes hundreds of megabytes), but they also tend to be highly redundant; hence, Alectryon also has the ability to generate “minified” HTML files that contain special pointers (“backreferences”) to previous parts of the document. These backreferences are resolved dynamically when the page is displayed in a web browser.
Use the following command to compile this file with minification (in Sphinx' conf.py, you can use alectryon.docutils.HTML_MINIFICATION = True instead):
alectryon --html-minification minification.rst # reST → HTML; produces ‘minification.html’
Here is an example proof, written in a way that generates lots of redundant objects (for example, section variables appear in the proof context at every step of the proof):
Require Import List. Import ListNotations. Section Folds. Context {A} (op: A -> A -> A) (init: A). Context (init_comm: forall a, op init a = op a init). Context (op_assoc: forall x y z, op (op x y) z = op x (op y z)).
Step 1: prove that init can be moved around:
A: Type
op: A -> A -> A
init: A
init_comm: forall a : A, op init a = op a init
op_assoc: forall x y z : A, op (op x y) z = op x (op y z)
l: list Aforall a : A, fold_left op l (op init a) = op a (fold_left op l init)256789forall a : A, fold_left op [] (op init a) = op a (fold_left op [] init)56789
a: Aa
IHl: forall a : A, fold_left op l (op init a) = op a (fold_left op l init)forall a0 : A, fold_left op (a :: l) (op init a0) = op a0 (fold_left op (a :: l) init)10forall a : A, op init a = op a init14forall a0 : A, fold_left op l (op (op init a0) a) = op a0 (fold_left op l (op init a))5678915op init a = op a init5678915a16
a0: Afold_left op l (op (op init a0) a) = op a0 (fold_left op l (op init a))eauto using init_comm.21262826fold_left op l (op init (op a0 a)) = op a0 (fold_left op l (op init a))26op (op a0 a) (fold_left op l init) = op a0 (fold_left op l (op init a))26op a0 (op a (fold_left op l init)) = op a0 (fold_left op l (op init a))reflexivity. Qed.26op a0 (fold_left op l (op init a)) = op a0 (fold_left op l (op init a))
Step 2: prove that fold_left and fold_right are equivalent.
10forall l : list A, fold_left op l init = fold_right op init l3f4fold_left op l init = fold_right op init l56789a
l':= l: list A4656789
l':= []: list Afold_left op [] init = fold_right op init []5678915a
l':= a :: l: list A
IHl: let l' := l in fold_left op l init = fold_right op init lfold_left op (a :: l) init = fold_right op init (a :: l)4finit = init54fold_left op l (op init a) = op a (fold_right op init l)59reflexivity.5a545e54fold_left op l (op init a) = op a (fold_left op l init)reflexivity. Qed. End Folds.54op a (fold_left op l init) = op a (fold_left op l init)