machinechecked 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. machinechecked-0.1.0.dist-info/METADATA +108 -0
  2. machinechecked-0.1.0.dist-info/RECORD +58 -0
  3. machinechecked-0.1.0.dist-info/WHEEL +5 -0
  4. machinechecked-0.1.0.dist-info/entry_points.txt +3 -0
  5. machinechecked-0.1.0.dist-info/licenses/LICENSE +201 -0
  6. machinechecked-0.1.0.dist-info/top_level.txt +1 -0
  7. prooflens/__init__.py +1 -0
  8. prooflens/__main__.py +3 -0
  9. prooflens/assess.py +504 -0
  10. prooflens/audit.py +115 -0
  11. prooflens/bundle.py +70 -0
  12. prooflens/cli.py +542 -0
  13. prooflens/config.py +145 -0
  14. prooflens/data/ProofLensProbe.lean +469 -0
  15. prooflens/data/prooflens.sty +75 -0
  16. prooflens/data/schema/evidence.schema.json +24 -0
  17. prooflens/data/schema/inventory.schema.json +55 -0
  18. prooflens/data/schema/manifest-claim.schema.json +126 -0
  19. prooflens/data/schema/manifest-index.schema.json +128 -0
  20. prooflens/evidence.py +60 -0
  21. prooflens/export.py +227 -0
  22. prooflens/formalization.py +106 -0
  23. prooflens/manifest.py +296 -0
  24. prooflens/pdfclaims.py +129 -0
  25. prooflens/pipeline.py +331 -0
  26. prooflens/probe.py +126 -0
  27. prooflens/promote.py +204 -0
  28. prooflens/review_queue.py +138 -0
  29. prooflens/reviews.py +105 -0
  30. prooflens/schemas.py +19 -0
  31. prooflens/server.py +63 -0
  32. prooflens/simple.py +628 -0
  33. prooflens/sources.py +164 -0
  34. prooflens/tex.py +408 -0
  35. prooflens/util.py +66 -0
  36. prooflens/web/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  37. prooflens/web/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  38. prooflens/web/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  39. prooflens/web/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  40. prooflens/web/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  41. prooflens/web/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  42. prooflens/web/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  43. prooflens/web/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  44. prooflens/web/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  45. prooflens/web/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  46. prooflens/web/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  47. prooflens/web/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  48. prooflens/web/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  49. prooflens/web/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  50. prooflens/web/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  51. prooflens/web/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  52. prooflens/web/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. prooflens/web/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  54. prooflens/web/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  55. prooflens/web/assets/index-B2GDDbsW.css +1 -0
  56. prooflens/web/assets/index-DN7uLe7p.js +285 -0
  57. prooflens/web/assets/pdf.worker.min-yatZIOMy.mjs +21 -0
  58. prooflens/web/index.html +14 -0
@@ -0,0 +1,75 @@
1
+ % prooflens.sty -- records where every numbered claim of a paper is typeset.
2
+ %
3
+ % Loaded before \documentclass by `prooflens tex` (latexmk -usepretex), so the paper's source is
4
+ % not modified. For every tracked environment it writes to \jobname.plx, one record per line:
5
+ %
6
+ % paper <width> <height> page size in sp
7
+ % begin <id> <env> <line> <file> where the environment opens in the source
8
+ % prev <id> <label> \@currentlabel when it opens (a head number
9
+ % equal to it was not stepped by the environment)
10
+ % (the file with its path as \input gave it)
11
+ % number <id> <currentlabel> the number the environment received
12
+ % label <id> <name> <currentlabel> every \label inside the environment
13
+ % pos <id> <begin|head|end> <page> <x> <y> position at shipout, in sp from bottom left;
14
+ % head is the baseline of the first line
15
+ %
16
+ % The environments tracked are \prooflensEnvs (a comma list), set by the caller before loading,
17
+ % or the default list below. Requires pdfTeX or LuaTeX (\pdfsavepos) and LaTeX 2020-10 or later
18
+ % (hooks, \CurrentFile, \ReadonlyShipoutCounter).
19
+ \NeedsTeXFormat{LaTeX2e}[2020/10/01]
20
+ \ProvidesPackage{prooflens}[2026/10/15 ProofLens claim anchors]
21
+
22
+ \ifdefined\pdfsavepos\else
23
+ \ifdefined\savepos
24
+ \let\pdfsavepos\savepos \let\pdflastxpos\lastxpos \let\pdflastypos\lastypos
25
+ \fi
26
+ \fi
27
+
28
+ \ifdefined\prooflensEnvs\else
29
+ \def\prooflensEnvs{theorem,lemma,proposition,corollary,definition,assumption,remark,%
30
+ example,conjecture,claim,hypothesis,convention}
31
+ \fi
32
+
33
+ \newwrite\plx@out
34
+ \newcount\plx@id
35
+ \def\plx@cur{0}
36
+
37
+ \AddToHook{begindocument/end}{%
38
+ \immediate\openout\plx@out=\jobname.plx\relax
39
+ \immediate\write\plx@out{paper \the\paperwidth\space\the\paperheight}}
40
+ \AddToHook{enddocument/end}{\immediate\closeout\plx@out}
41
+
42
+ % A position record, written at shipout so that the page and coordinates are final.
43
+ \def\plx@pos#1{%
44
+ \edef\plx@tmp{\noexpand\write\plx@out{pos \plx@cur\space #1
45
+ \noexpand\the\noexpand\ReadonlyShipoutCounter\space
46
+ \noexpand\the\noexpand\pdflastxpos\space\noexpand\the\noexpand\pdflastypos}}%
47
+ \pdfsavepos\plx@tmp}
48
+
49
+ \def\plx@begin#1{%
50
+ \global\advance\plx@id\@ne
51
+ \edef\plx@cur{\the\plx@id}%
52
+ \immediate\write\plx@out{begin \plx@cur\space #1 \the\inputlineno\space\CurrentFilePath\ifx\CurrentFilePath\@empty\else/\fi\CurrentFile}%
53
+ \protected@edef\plx@tmp{\@currentlabel}%
54
+ \immediate\write\plx@out{prev \plx@cur\space\detokenize\expandafter{\plx@tmp}}%
55
+ \plx@pos{begin}%
56
+ % The number is \@currentlabel when the first paragraph of the environment (its head) starts.
57
+ \AddToHookNext{para/begin}{%
58
+ \plx@pos{head}%
59
+ \protected@edef\plx@tmp{\@currentlabel}%
60
+ \immediate\write\plx@out{number \plx@cur\space\detokenize\expandafter{\plx@tmp}}}%
61
+ \let\plx@savedlabel\label
62
+ \def\label##1{%
63
+ \protected@edef\plx@tmp{\@currentlabel}%
64
+ \immediate\write\plx@out{label \plx@cur\space\detokenize{##1} \detokenize\expandafter{\plx@tmp}}%
65
+ \plx@savedlabel{##1}}}
66
+
67
+ \def\plx@end{\plx@pos{end}}
68
+
69
+ \@for\plx@env:=\prooflensEnvs\do{%
70
+ \edef\plx@tmp{%
71
+ \noexpand\AddToHook{env/\plx@env/begin}{\noexpand\plx@begin{\plx@env}}%
72
+ \noexpand\AddToHook{env/\plx@env/end}{\noexpand\plx@end}}%
73
+ \plx@tmp}
74
+
75
+ \endinput
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/cgarryZA/ProofLens/schema/evidence.schema.json",
4
+ "title": "ProofLens evidence record",
5
+ "type": "object",
6
+ "required": ["id", "created", "body"],
7
+ "properties": {
8
+ "id": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
9
+ "created": {"type": "string"},
10
+ "body": {
11
+ "type": "object",
12
+ "required": ["schema", "provenance", "inventory", "reviews", "lean", "tex", "assessment"],
13
+ "properties": {
14
+ "schema": {"const": "prooflens/evidence@0"},
15
+ "provenance": {"type": "object", "required": ["tool", "project", "papers"]},
16
+ "inventory": {"type": "object", "required": ["claims"]},
17
+ "reviews": {"type": "object", "required": ["files", "records"]},
18
+ "lean": {"type": ["object", "null"]},
19
+ "tex": {"type": "object"},
20
+ "assessment": {"type": "object", "required": ["claims", "findings"]}
21
+ }
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/cgarryZA/ProofLens/schema/inventory.schema.json",
4
+ "title": "ProofLens claim inventory",
5
+ "description": "Every claim of the papers, with its scope and, for a formal claim, the clauses mapped to Lean declarations.",
6
+ "type": "object",
7
+ "required": ["claims"],
8
+ "properties": {
9
+ "note": {"type": "string"},
10
+ "papers": {"type": "object"},
11
+ "claims": {"type": "array", "items": {"$ref": "#/$defs/claim"}}
12
+ },
13
+ "$defs": {
14
+ "scope": {"enum": ["formal", "definition", "expository", "literature", "empirical",
15
+ "proof-step", "part-of", "duplicate"]},
16
+ "claim": {
17
+ "type": "object",
18
+ "required": ["id", "paper", "scope", "clauses"],
19
+ "properties": {
20
+ "id": {"type": "string", "pattern": "^[A-Za-z0-9]+:.+$"},
21
+ "paper": {"type": "string"},
22
+ "commit": {"type": ["string", "null"]},
23
+ "kind": {"type": "string"},
24
+ "number": {"type": "string"},
25
+ "title": {"type": "string"},
26
+ "label": {"type": ["string", "null"]},
27
+ "location": {"type": ["string", "null"]},
28
+ "source_sha256": {"type": ["string", "null"], "pattern": "^[0-9a-f]{64}$"},
29
+ "scope": {"$ref": "#/$defs/scope"},
30
+ "scope_note": {"type": "string"},
31
+ "scope_reviewed": {"type": "boolean"},
32
+ "clauses": {"type": "array", "items": {"$ref": "#/$defs/clause"}}
33
+ }
34
+ },
35
+ "clause": {
36
+ "type": "object",
37
+ "required": ["name"],
38
+ "properties": {
39
+ "name": {"type": "string"},
40
+ "spec": {"type": ["string", "null"]},
41
+ "accept": {"type": ["string", "null"]},
42
+ "refute": {"type": ["string", "null"]},
43
+ "corrects": {"type": ["string", "null"]},
44
+ "witness": {"type": ["string", "null"]},
45
+ "defs": {"type": "array", "items": {"type": "string"}},
46
+ "regimes": {"type": "array", "items": {
47
+ "type": "object", "required": ["name"],
48
+ "properties": {"name": {"type": "string"}, "description": {"type": "string"},
49
+ "witness": {"type": ["string", "null"]}}}}
50
+ },
51
+ "not": {"required": ["accept", "refute"],
52
+ "properties": {"accept": {"type": "string"}, "refute": {"type": "string"}}}
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/cgarryZA/ProofLens/schema/manifest-claim.schema.json",
4
+ "title": "ProofLens claim passport",
5
+ "type": "object",
6
+ "required": [
7
+ "schema",
8
+ "release",
9
+ "id",
10
+ "paper",
11
+ "status",
12
+ "clauses",
13
+ "findings",
14
+ "decls"
15
+ ],
16
+ "properties": {
17
+ "schema": {
18
+ "const": "prooflens/manifest@0"
19
+ },
20
+ "release": {
21
+ "type": "string"
22
+ },
23
+ "id": {
24
+ "type": "string"
25
+ },
26
+ "status": {
27
+ "type": "string"
28
+ },
29
+ "statement_tex": {
30
+ "type": [
31
+ "string",
32
+ "null"
33
+ ]
34
+ },
35
+ "clauses": {
36
+ "type": "array",
37
+ "items": {
38
+ "type": "object",
39
+ "required": [
40
+ "name",
41
+ "state",
42
+ "ladder"
43
+ ],
44
+ "properties": {
45
+ "state": {
46
+ "enum": [
47
+ "unspecified",
48
+ "unchecked",
49
+ "open",
50
+ "proved",
51
+ "refuted",
52
+ "malformed",
53
+ "stated"
54
+ ]
55
+ },
56
+ "ladder": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "object",
60
+ "required": [
61
+ "rung",
62
+ "state"
63
+ ],
64
+ "properties": {
65
+ "state": {
66
+ "enum": [
67
+ "pass",
68
+ "fail",
69
+ "open",
70
+ "author",
71
+ "none",
72
+ "n/a",
73
+ "pdf-only",
74
+ "not-run",
75
+ "unverified"
76
+ ]
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ },
84
+ "findings": {
85
+ "type": "array",
86
+ "items": {
87
+ "$ref": "#/$defs/finding"
88
+ }
89
+ },
90
+ "decls": {
91
+ "type": "object",
92
+ "additionalProperties": {
93
+ "type": "string",
94
+ "pattern": "^[0-9a-f]{24}$"
95
+ },
96
+ "description": "Each declaration of the claim's closures, by name, with the key of its record data/decls/<key>.json (the first 24 hex digits of the SHA-256 of the record)"
97
+ },
98
+ "blockers": {
99
+ "type": "array",
100
+ "items": {
101
+ "type": "string"
102
+ }
103
+ }
104
+ },
105
+ "$defs": {
106
+ "finding": {
107
+ "type": "object",
108
+ "required": [
109
+ "id",
110
+ "tier",
111
+ "code",
112
+ "subject",
113
+ "message"
114
+ ],
115
+ "properties": {
116
+ "tier": {
117
+ "enum": [
118
+ "violation",
119
+ "warning",
120
+ "obligation"
121
+ ]
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/cgarryZA/ProofLens/schema/manifest-index.schema.json",
4
+ "title": "ProofLens manifest index",
5
+ "type": "object",
6
+ "required": [
7
+ "schema",
8
+ "release",
9
+ "evidence",
10
+ "papers",
11
+ "claims",
12
+ "summary",
13
+ "classes",
14
+ "findings"
15
+ ],
16
+ "properties": {
17
+ "schema": {
18
+ "const": "prooflens/manifest@0"
19
+ },
20
+ "release": {
21
+ "type": "string"
22
+ },
23
+ "evidence": {
24
+ "type": "string",
25
+ "pattern": "^[0-9a-f]{64}$"
26
+ },
27
+ "created": {
28
+ "type": "string"
29
+ },
30
+ "project": {
31
+ "type": "object"
32
+ },
33
+ "lean": {
34
+ "type": [
35
+ "object",
36
+ "null"
37
+ ]
38
+ },
39
+ "tool": {
40
+ "type": "object"
41
+ },
42
+ "papers": {
43
+ "type": "array",
44
+ "items": {
45
+ "type": "object",
46
+ "required": [
47
+ "id",
48
+ "mode",
49
+ "pdf"
50
+ ],
51
+ "properties": {
52
+ "id": {
53
+ "type": "string"
54
+ },
55
+ "mode": {
56
+ "enum": [
57
+ "latex",
58
+ "pdf"
59
+ ]
60
+ },
61
+ "pdf": {
62
+ "type": [
63
+ "string",
64
+ "null"
65
+ ]
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "summary": {
71
+ "type": "object"
72
+ },
73
+ "findings": {
74
+ "type": "object"
75
+ },
76
+ "claims": {
77
+ "type": "array",
78
+ "items": {
79
+ "type": "object",
80
+ "required": [
81
+ "id",
82
+ "paper",
83
+ "status",
84
+ "class",
85
+ "file",
86
+ "counts"
87
+ ],
88
+ "properties": {
89
+ "id": {
90
+ "type": "string"
91
+ },
92
+ "paper": {
93
+ "type": "string"
94
+ },
95
+ "status": {
96
+ "type": "string"
97
+ },
98
+ "class": {
99
+ "enum": [
100
+ "accepted",
101
+ "proved",
102
+ "refuted",
103
+ "open",
104
+ "malformed",
105
+ "out-of-scope",
106
+ "unspecified"
107
+ ]
108
+ },
109
+ "anchor": {
110
+ "type": [
111
+ "object",
112
+ "null"
113
+ ]
114
+ },
115
+ "file": {
116
+ "type": "string"
117
+ },
118
+ "counts": {
119
+ "type": "object"
120
+ }
121
+ }
122
+ }
123
+ },
124
+ "search": {
125
+ "type": "string"
126
+ }
127
+ }
128
+ }
prooflens/evidence.py ADDED
@@ -0,0 +1,60 @@
1
+ """The evidence store: content-addressed, append-only records of what the pipeline established.
2
+
3
+ A record is `{"id", "created", "body"}` with `id` the SHA-256 of the canonical JSON of `body`. A
4
+ new run with any difference produces a new record; an existing record is never rewritten.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import datetime as _dt
10
+ import json
11
+ from pathlib import Path
12
+
13
+ from .util import canonical_json, content_id, read_json
14
+
15
+ SCHEMA = "prooflens/evidence@0"
16
+
17
+
18
+ class EvidenceError(RuntimeError):
19
+ pass
20
+
21
+
22
+ def store(out_dir: Path, body: dict) -> str:
23
+ body = dict(body, schema=SCHEMA)
24
+ eid = content_id(body)
25
+ path = out_dir / "evidence" / f"{eid}.json"
26
+ if path.exists():
27
+ old = read_json(path)
28
+ if content_id(old["body"]) != eid:
29
+ raise EvidenceError(f"evidence record {path} does not match its id")
30
+ return eid
31
+ path.parent.mkdir(parents=True, exist_ok=True)
32
+ rec = {"id": eid, "created": _dt.datetime.now(_dt.timezone.utc).isoformat(timespec="seconds"),
33
+ "body": json.loads(canonical_json(body))}
34
+ tmp = path.with_suffix(".tmp")
35
+ tmp.write_text(json.dumps(rec, ensure_ascii=False, sort_keys=True), encoding="utf-8")
36
+ tmp.replace(path)
37
+ return eid
38
+
39
+
40
+ def load(out_dir: Path, eid: str) -> dict:
41
+ path = out_dir / "evidence" / f"{eid}.json"
42
+ rec = read_json(path)
43
+ if content_id(rec["body"]) != eid:
44
+ raise EvidenceError(f"evidence record {path} does not match its id")
45
+ return rec
46
+
47
+
48
+ def record_release(out_dir: Path, name: str, eid: str) -> Path:
49
+ """Name a release; a release name, once given, keeps its evidence."""
50
+ path = out_dir / "releases" / f"{name}.json"
51
+ if path.exists():
52
+ old = read_json(path)
53
+ if old["evidence"] != eid:
54
+ raise EvidenceError(f"release {name} already names evidence {old['evidence']}")
55
+ return path
56
+ path.parent.mkdir(parents=True, exist_ok=True)
57
+ path.write_text(json.dumps({"release": name, "evidence": eid,
58
+ "created": _dt.datetime.now(_dt.timezone.utc)
59
+ .isoformat(timespec="seconds")}, indent=1) + "\n")
60
+ return path