feat: Stats page
This commit is contained in:
parent
811b96cf17
commit
1c303f8741
5 changed files with 272 additions and 129 deletions
3
.github/workflows/docs.yml
vendored
3
.github/workflows/docs.yml
vendored
|
@ -47,6 +47,9 @@ jobs:
|
||||||
- name: make list of informal proofs and lemmas
|
- name: make list of informal proofs and lemmas
|
||||||
run : lake exe informal mkFile mkDot mkHTML
|
run : lake exe informal mkFile mkDot mkHTML
|
||||||
|
|
||||||
|
- name: make stats page
|
||||||
|
run : lake exe stats mkHTML
|
||||||
|
|
||||||
- name: Generate svg from dot
|
- name: Generate svg from dot
|
||||||
run : dot -Tsvg -o ./docs/graph.svg ./docs/InformalDot.dot
|
run : dot -Tsvg -o ./docs/graph.svg ./docs/InformalDot.dot
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,7 @@ import HepLean.Mathematics.LinearMaps
|
||||||
import HepLean.Mathematics.PiTensorProduct
|
import HepLean.Mathematics.PiTensorProduct
|
||||||
import HepLean.Mathematics.SO3.Basic
|
import HepLean.Mathematics.SO3.Basic
|
||||||
import HepLean.Meta.AllFilePaths
|
import HepLean.Meta.AllFilePaths
|
||||||
|
import HepLean.Meta.Basic
|
||||||
import HepLean.Meta.Informal
|
import HepLean.Meta.Informal
|
||||||
import HepLean.Meta.TransverseTactics
|
import HepLean.Meta.TransverseTactics
|
||||||
import HepLean.SpaceTime.Basic
|
import HepLean.SpaceTime.Basic
|
||||||
|
|
178
HepLean/Meta/Basic.lean
Normal file
178
HepLean/Meta/Basic.lean
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
/-
|
||||||
|
Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
|
||||||
|
Released under Apache 2.0 license.
|
||||||
|
Authors: Joseph Tooby-Smith
|
||||||
|
-/
|
||||||
|
import Batteries.Lean.HashSet
|
||||||
|
import Lean
|
||||||
|
import Mathlib.Lean.Expr.Basic
|
||||||
|
import Mathlib.Lean.CoreM
|
||||||
|
import ImportGraph.RequiredModules
|
||||||
|
import HepLean.Meta.Informal
|
||||||
|
/-!
|
||||||
|
|
||||||
|
## Basic Lean meta programming commands
|
||||||
|
|
||||||
|
-/
|
||||||
|
|
||||||
|
namespace HepLean
|
||||||
|
open Lean System Meta
|
||||||
|
|
||||||
|
/-!
|
||||||
|
|
||||||
|
## Imports
|
||||||
|
|
||||||
|
-/
|
||||||
|
|
||||||
|
/-- Gets all imports within HepLean. -/
|
||||||
|
def allImports : IO (Array Import) := do
|
||||||
|
initSearchPath (← findSysroot)
|
||||||
|
let mods : Name := `HepLean
|
||||||
|
let imp : Import := {module := mods}
|
||||||
|
let mFile ← findOLean imp.module
|
||||||
|
unless (← mFile.pathExists) do
|
||||||
|
throw <| IO.userError s!"object file '{mFile}' of module {imp.module} does not exist"
|
||||||
|
let (hepLeanMod, _) ← readModuleData mFile
|
||||||
|
let imports := hepLeanMod.imports.filter (fun c => c.module ≠ `Init)
|
||||||
|
return imports
|
||||||
|
|
||||||
|
/-- Number of files within HepLean. -/
|
||||||
|
def noImports : IO Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
pure imports.size
|
||||||
|
|
||||||
|
/-- Gets all constants from an import. -/
|
||||||
|
def Imports.getConsts (imp : Import) : IO (Array ConstantInfo) := do
|
||||||
|
let mFile ← findOLean imp.module
|
||||||
|
let (modData, _) ← readModuleData mFile
|
||||||
|
pure modData.constants
|
||||||
|
|
||||||
|
/-- Gets all user defined constants from an import. -/
|
||||||
|
def Imports.getUserConsts (imp : Import) : MetaM (Array ConstantInfo) := do
|
||||||
|
let env ← getEnv
|
||||||
|
let x := (← Imports.getConsts imp).filter (fun c => ¬ c.name.isInternal)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isCasesOnRecursor env c.name)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isRecOnRecursor env c.name)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isNoConfusion env c.name)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isBRecOnRecursor env c.name)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.binductionOnSuffix)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.belowSuffix)
|
||||||
|
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.ibelowSuffix)
|
||||||
|
/- Removing syntax category declarations. -/
|
||||||
|
let x := x.filter (fun c => ¬ c.name.toString = "Informal.informalAssignment.quot" )
|
||||||
|
let x := x.filter (fun c => ¬ c.name.toString = "TensorTree.indexExpr.quot" )
|
||||||
|
let x := x.filter (fun c => ¬ c.name.toString = "TensorTree.tensorExpr.quot" )
|
||||||
|
pure x
|
||||||
|
|
||||||
|
/-- Lines from import. -/
|
||||||
|
def Imports.getLines (imp : Import) : IO (Array String) := do
|
||||||
|
let filePath := (mkFilePath (imp.module.toString.split (· == '.'))).addExtension "lean"
|
||||||
|
let lines ← IO.FS.lines filePath
|
||||||
|
return lines
|
||||||
|
|
||||||
|
/-!
|
||||||
|
|
||||||
|
## Name
|
||||||
|
|
||||||
|
-/
|
||||||
|
|
||||||
|
|
||||||
|
/-- Turns a name into a Lean file. -/
|
||||||
|
def Name.toFile (c : Name) : MetaM String := do
|
||||||
|
return s!"./{c.toString.replace "." "/" ++ ".lean"}"
|
||||||
|
|
||||||
|
/-- Given a name, returns the line number. -/
|
||||||
|
def Name.lineNumber (c : Name) : MetaM Nat := do
|
||||||
|
match ← findDeclarationRanges? c with
|
||||||
|
| some decl => pure decl.range.pos.line
|
||||||
|
| none => panic! s!"{c} is a declaration without position"
|
||||||
|
|
||||||
|
/-- Returns the location of a name. -/
|
||||||
|
def Name.location (c : Name) : MetaM String := do
|
||||||
|
let env ← getEnv
|
||||||
|
let x := env.getModuleFor? c
|
||||||
|
match x with
|
||||||
|
| some decl => pure ((← Name.toFile decl) ++ ":" ++ toString (← Name.lineNumber c) ++ " "
|
||||||
|
++ c.toString)
|
||||||
|
| none => panic! s!"{c} is a declaration without position"
|
||||||
|
|
||||||
|
/-- Determines if a name has a location. -/
|
||||||
|
def Name.hasPos (c : Name) : MetaM Bool := do
|
||||||
|
match ← findDeclarationRanges? c with
|
||||||
|
| some _ => pure true
|
||||||
|
| none => pure false
|
||||||
|
|
||||||
|
/-- Determines if a name has a doc string. -/
|
||||||
|
def Name.hasDocString (c : Name) : MetaM Bool := do
|
||||||
|
let env ← getEnv
|
||||||
|
let doc ← Lean.findDocString? env c
|
||||||
|
match doc with
|
||||||
|
| some _ => pure true
|
||||||
|
| none => pure false
|
||||||
|
|
||||||
|
/-- Number of definitions. -/
|
||||||
|
def noDefs : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (fun c => c.isDef)
|
||||||
|
let x ← x.filterM (fun c => (Name.hasPos c.name))
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- Number of definitions. -/
|
||||||
|
def noLemmas : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (fun c => ¬ c.isDef)
|
||||||
|
let x ← x.filterM (fun c => (Name.hasPos c.name))
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- Number of definitions without a doc-string. -/
|
||||||
|
def noDefsNoDocString : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (fun c => c.isDef)
|
||||||
|
let x ← x.filterM (fun c => (Name.hasPos c.name))
|
||||||
|
let x ← x.filterM (fun c => do
|
||||||
|
return Bool.not (← (Name.hasDocString c.name)))
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- Number of definitions without a doc-string. -/
|
||||||
|
def noLemmasNoDocString : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (fun c => ¬ c.isDef)
|
||||||
|
let x ← x.filterM (fun c => (Name.hasPos c.name))
|
||||||
|
let x ← x.filterM (fun c => do
|
||||||
|
return Bool.not (← (Name.hasDocString c.name)))
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- The number of lines in HepLean. -/
|
||||||
|
def noLines : IO Nat := do
|
||||||
|
let imports ← HepLean.allImports
|
||||||
|
let x ← imports.mapM HepLean.Imports.getLines
|
||||||
|
let x := x.flatten
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- The number of informal lemmas in HepLean. -/
|
||||||
|
def noInformalLemmas : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (Informal.isInformal)
|
||||||
|
let x := x.filter (Informal.isInformalLemma)
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
/-- The number of informal definitions in HepLean. -/
|
||||||
|
def noInformalDefs : MetaM Nat := do
|
||||||
|
let imports ← allImports
|
||||||
|
let x ← imports.mapM Imports.getUserConsts
|
||||||
|
let x := x.flatten
|
||||||
|
let x := x.filter (Informal.isInformal)
|
||||||
|
let x := x.filter (Informal.isInformalDef)
|
||||||
|
pure x.toList.length
|
||||||
|
|
||||||
|
end HepLean
|
|
@ -3,68 +3,14 @@ Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
|
||||||
Released under Apache 2.0 license.
|
Released under Apache 2.0 license.
|
||||||
Authors: Joseph Tooby-Smith
|
Authors: Joseph Tooby-Smith
|
||||||
-/
|
-/
|
||||||
import Batteries.Lean.HashSet
|
import HepLean.Meta.Basic
|
||||||
import Lean
|
|
||||||
import Mathlib.Lean.Expr.Basic
|
|
||||||
import Mathlib.Lean.CoreM
|
|
||||||
import HepLean.Meta.Informal
|
|
||||||
import ImportGraph.RequiredModules
|
|
||||||
/-!
|
/-!
|
||||||
|
|
||||||
# Extracting commands with no doc strings.
|
# Extracting commands with no doc strings.
|
||||||
|
|
||||||
-/
|
-/
|
||||||
|
|
||||||
open Lean System Meta
|
open Lean System Meta HepLean
|
||||||
|
|
||||||
def Imports.getConsts (imp : Import) : IO (Array ConstantInfo) := do
|
|
||||||
let mFile ← findOLean imp.module
|
|
||||||
let (modData, _) ← readModuleData mFile
|
|
||||||
pure modData.constants
|
|
||||||
|
|
||||||
def Imports.getUserConsts (imp : Import) : MetaM (Array ConstantInfo) := do
|
|
||||||
let env ← getEnv
|
|
||||||
let x := (← Imports.getConsts imp).filter (fun c => ¬ c.name.isInternal)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isCasesOnRecursor env c.name)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isRecOnRecursor env c.name)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isNoConfusion env c.name)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isBRecOnRecursor env c.name)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.binductionOnSuffix)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.belowSuffix)
|
|
||||||
let x := x.filter (fun c => ¬ Lean.isAuxRecursorWithSuffix env c.name Lean.ibelowSuffix)
|
|
||||||
/- Removing syntax category declarations. -/
|
|
||||||
let x := x.filter (fun c => ¬ c.name.toString = "Informal.informalAssignment.quot" )
|
|
||||||
let x := x.filter (fun c => ¬ c.name.toString = "TensorTree.indexExpr.quot" )
|
|
||||||
let x := x.filter (fun c => ¬ c.name.toString = "TensorTree.tensorExpr.quot" )
|
|
||||||
pure x
|
|
||||||
|
|
||||||
def Name.lineNumber (c : Name) : MetaM Nat := do
|
|
||||||
match ← findDeclarationRanges? c with
|
|
||||||
| some decl => pure decl.range.pos.line
|
|
||||||
| none => panic! s!"{c} is a declaration without position"
|
|
||||||
|
|
||||||
def Name.toFile (c : Name) : MetaM String := do
|
|
||||||
return s!"./{c.toString.replace "." "/" ++ ".lean"}"
|
|
||||||
|
|
||||||
def Name.location (c : Name) : MetaM String := do
|
|
||||||
let env ← getEnv
|
|
||||||
let x := env.getModuleFor? c
|
|
||||||
match x with
|
|
||||||
| some decl => pure ((← Name.toFile decl) ++ ":" ++ toString (← Name.lineNumber c) ++ " "
|
|
||||||
++ c.toString)
|
|
||||||
| none => panic! s!"{c} is a declaration without position"
|
|
||||||
|
|
||||||
def Name.hasPos (c : Name) : MetaM Bool := do
|
|
||||||
match ← findDeclarationRanges? c with
|
|
||||||
| some _ => pure true
|
|
||||||
| none => pure false
|
|
||||||
|
|
||||||
def Name.hasDocString (c : Name) : MetaM Bool := do
|
|
||||||
let env ← getEnv
|
|
||||||
let doc ← Lean.findDocString? env c
|
|
||||||
match doc with
|
|
||||||
| some _ => pure true
|
|
||||||
| none => pure false
|
|
||||||
|
|
||||||
def Imports.NoDocStringDef (imp : Import) : MetaM UInt32 := do
|
def Imports.NoDocStringDef (imp : Import) : MetaM UInt32 := do
|
||||||
let x := (← Imports.getUserConsts imp).filter (fun c => c.isDef)
|
let x := (← Imports.getUserConsts imp).filter (fun c => c.isDef)
|
||||||
|
@ -91,14 +37,7 @@ def Imports.NoDocStringLemma (imp : Import) : MetaM UInt32 := do
|
||||||
pure 0
|
pure 0
|
||||||
|
|
||||||
unsafe def main (args : List String) : IO UInt32 := do
|
unsafe def main (args : List String) : IO UInt32 := do
|
||||||
initSearchPath (← findSysroot)
|
let imports ← allImports
|
||||||
let mods : Name := `HepLean
|
|
||||||
let imp : Import := {module := mods}
|
|
||||||
let mFile ← findOLean imp.module
|
|
||||||
unless (← mFile.pathExists) do
|
|
||||||
throw <| IO.userError s!"object file '{mFile}' of module {imp.module} does not exist"
|
|
||||||
let (hepLeanMod, _) ← readModuleData mFile
|
|
||||||
let imports := hepLeanMod.imports.filter (fun c => c.module ≠ `Init)
|
|
||||||
let _ ← CoreM.withImportModules #[`HepLean] (imports.mapM Imports.NoDocStringDef).run'
|
let _ ← CoreM.withImportModules #[`HepLean] (imports.mapM Imports.NoDocStringDef).run'
|
||||||
if "--lemmas" ∈ args then
|
if "--lemmas" ∈ args then
|
||||||
let _ ← CoreM.withImportModules #[`HepLean] (imports.mapM Imports.NoDocStringLemma).run'
|
let _ ← CoreM.withImportModules #[`HepLean] (imports.mapM Imports.NoDocStringLemma).run'
|
||||||
|
|
|
@ -3,11 +3,7 @@ Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
|
||||||
Released under Apache 2.0 license.
|
Released under Apache 2.0 license.
|
||||||
Authors: Joseph Tooby-Smith
|
Authors: Joseph Tooby-Smith
|
||||||
-/
|
-/
|
||||||
import Batteries.Lean.HashSet
|
import HepLean.Meta.Basic
|
||||||
import Lean
|
|
||||||
import Mathlib.Lean.Expr.Basic
|
|
||||||
import Mathlib.Lean.CoreM
|
|
||||||
import HepLean
|
|
||||||
/-!
|
/-!
|
||||||
|
|
||||||
# HepLean Stats
|
# HepLean Stats
|
||||||
|
@ -17,72 +13,98 @@ This file concerns with statistics of HepLean.
|
||||||
-/
|
-/
|
||||||
|
|
||||||
|
|
||||||
open Lean System Meta
|
open Lean System Meta HepLean
|
||||||
|
|
||||||
structure FileStats where
|
|
||||||
numDefs : Nat
|
|
||||||
numLemsWithoutDocString : Nat
|
|
||||||
numLemsWithDocString : Nat
|
|
||||||
|
|
||||||
def FileStats.add (a b : FileStats) : FileStats where
|
def getStats : MetaM String := do
|
||||||
numDefs := a.numDefs + b.numDefs
|
let noDefsVal ← noDefs
|
||||||
numLemsWithoutDocString := a.numLemsWithoutDocString + b.numLemsWithoutDocString
|
let noLemmasVal ← noLemmas
|
||||||
numLemsWithDocString := a.numLemsWithDocString + b.numLemsWithDocString
|
let noImportsVal ← noImports
|
||||||
|
let noDefsNoDocVal ← noDefsNoDocString
|
||||||
|
let noLemmasNoDocVal ← noLemmasNoDocString
|
||||||
|
let noLinesVal ← noLines
|
||||||
|
let s := s!"
|
||||||
|
Number of Imports: {noImportsVal}
|
||||||
|
Number of Definitions: {noDefsVal}
|
||||||
|
Number of Lemmas: {noLemmasVal}
|
||||||
|
Number of Definitions without doc strings: {noDefsNoDocVal} (out of {noDefsVal})
|
||||||
|
Number of Lemmas without doc strings: {noLemmasNoDocVal} (out of {noLemmasVal})
|
||||||
|
Number of Lines: {noLinesVal}"
|
||||||
|
pure s
|
||||||
|
|
||||||
def FileStats.zero : FileStats where
|
unsafe def Stats.toHtml : MetaM String := do
|
||||||
numDefs := 0
|
let noDefsVal ← noDefs
|
||||||
numLemsWithoutDocString := 0
|
let noLemmasVal ← noLemmas
|
||||||
numLemsWithDocString := 0
|
let noImportsVal ← noImports
|
||||||
|
let noDefsNoDocVal ← noDefsNoDocString
|
||||||
|
let noLemmasNoDocVal ← noLemmasNoDocString
|
||||||
|
let noLinesVal ← noLines
|
||||||
|
let noInformalDefsVal ← noInformalDefs
|
||||||
|
let noInformalLemmasVal ← noInformalLemmas
|
||||||
|
let header := "---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Stats for HepLean</title>
|
||||||
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
|
||||||
|
<style>
|
||||||
|
/* Style the progress bar to be wider and take up more space */
|
||||||
|
progress {
|
||||||
|
width: 80%; /* Adjust to take up more horizontal space */
|
||||||
|
height: 30px; /* Increase height to make it wider */
|
||||||
|
appearance: none; /* Remove default browser styles */
|
||||||
|
}
|
||||||
|
|
||||||
instance : ToString FileStats where
|
/* Change the color for WebKit browsers (Chrome, Safari, etc.) */
|
||||||
toString fs := s!"Number of definitions: {fs.numDefs}\n" ++
|
progress::-webkit-progress-bar {
|
||||||
s!"Number of lemmas without doc string: {fs.numLemsWithoutDocString}\n" ++
|
background-color: #f3f3f3; /* Background color */
|
||||||
s!"Number of lemmas with doc string: {fs.numLemsWithDocString}"
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
def getConstantDoc (constName : Array ConstantInfo) : MetaM (FileStats) := do
|
progress::-webkit-progress-value {
|
||||||
let env ← getEnv
|
background-color: #157878; /* Change this to your desired color */
|
||||||
let mut numDefs := 0
|
border-radius: 5px;
|
||||||
let mut numLemsWithoutDocString := 0
|
}
|
||||||
let mut numLemsWithDocString := 0
|
|
||||||
for c in constName do
|
|
||||||
if ¬ Lean.Name.isInternalDetail c.name then
|
|
||||||
if c.isDef then
|
|
||||||
numDefs := numDefs + 1
|
|
||||||
if c.isThm then
|
|
||||||
let doc ← Lean.findDocString? env c.name
|
|
||||||
if doc == none then
|
|
||||||
numLemsWithoutDocString := numLemsWithoutDocString + 1
|
|
||||||
else
|
|
||||||
numLemsWithDocString := numLemsWithDocString + 1
|
|
||||||
return {numDefs := numDefs,
|
|
||||||
numLemsWithoutDocString := numLemsWithoutDocString,
|
|
||||||
numLemsWithDocString := numLemsWithDocString}
|
|
||||||
|
|
||||||
def getStats (imp : Import) : MetaM FileStats := do
|
/* Change the color for Firefox */
|
||||||
if imp.module == `Init then
|
progress::-moz-progress-bar {
|
||||||
return {numDefs := 0,
|
background-color: #157878; /* Change this to your desired color */
|
||||||
numLemsWithoutDocString := 0,
|
}
|
||||||
numLemsWithDocString := 0}
|
</style>
|
||||||
let mFile ← findOLean imp.module
|
</head>
|
||||||
let (modData, _) ← readModuleData mFile
|
<body>"
|
||||||
let cons := modData.constants
|
let body := s!"
|
||||||
let out ← (getConstantDoc cons)
|
<h1>Stats for HepLean</h1>
|
||||||
return out
|
<h3>Number of Files 📄: {noImportsVal}</h3>
|
||||||
|
<h3>Number of lines 💻: {noLinesVal}</h3>
|
||||||
|
<h3>Number of Definitions (incl. instances): {noDefsVal - noInformalLemmasVal}</h3>
|
||||||
|
<p>- Of which {noDefsVal - noDefsNoDocVal- noInformalLemmasVal} have doc-strings:</p>
|
||||||
|
<progress value=\"{noDefsVal - noDefsNoDocVal- noInformalLemmasVal}\" max=\"{noDefsVal- noInformalLemmasVal}\"></progress>
|
||||||
|
<p>- Of which {noDefsVal - noInformalLemmasVal - noInformalDefsVal} are not informal definitions:</p>
|
||||||
|
<progress value=\"{noDefsVal - noInformalLemmasVal - noInformalDefsVal}\" max=\"{noDefsVal - noInformalLemmasVal}\"></progress>
|
||||||
|
|
||||||
def getStatsArray (a : Array Import) : MetaM (Array FileStats) := do
|
<h3>Number of Lemmas: {noLemmasVal + noInformalLemmasVal}</h3>
|
||||||
return ← a.mapM getStats
|
<p>- Of which {noLemmasVal - noLemmasNoDocVal + noInformalLemmasVal} have doc-strings:</p>
|
||||||
|
<progress value=\"{noLemmasVal - noLemmasNoDocVal + noInformalLemmasVal}\" max=\"{noLemmasVal + noInformalLemmasVal}\"></progress>
|
||||||
|
<p>- Of which {noLemmasVal} are not informal lemmas:</p>
|
||||||
|
<progress value=\"{noLemmasVal}\" max=\"{noLemmasVal + noInformalLemmasVal}\"></progress>
|
||||||
|
"
|
||||||
|
let footer := "
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"
|
||||||
|
pure (header ++ "\n" ++ body ++ "\n" ++ footer)
|
||||||
|
|
||||||
def main (_ : List String) : IO UInt32 := do
|
unsafe def main (args : List String) : IO UInt32 := do
|
||||||
initSearchPath (← findSysroot)
|
let _ ← noImports
|
||||||
let mods : Name := `HepLean
|
let statString ← CoreM.withImportModules #[`HepLean] (getStats).run'
|
||||||
let imp : Import := {module := mods}
|
println! statString
|
||||||
let mFile ← findOLean imp.module
|
if "mkHTML" ∈ args then
|
||||||
unless (← mFile.pathExists) do
|
let html ← CoreM.withImportModules #[`HepLean] (Stats.toHtml).run'
|
||||||
throw <| IO.userError s!"object file '{mFile}' of module {imp.module} does not exist"
|
let htmlFile : System.FilePath := {toString := "./docs/Stats.html"}
|
||||||
let (hepLeanMod, _) ← readModuleData mFile
|
IO.FS.writeFile htmlFile html
|
||||||
let noFiles := hepLeanMod.imports.size - 1
|
IO.println (s!"HTML file made.")
|
||||||
let fileStats ← CoreM.withImportModules #[`HepLean] (getStatsArray hepLeanMod.imports).run'
|
|
||||||
let totalStats := Array.foldl FileStats.add FileStats.zero fileStats
|
|
||||||
IO.println s!"Total number of files: {noFiles}"
|
|
||||||
IO.println totalStats
|
|
||||||
pure 0
|
pure 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue