PhysLean/HepLean/Meta/Informal.lean
2024-09-19 07:57:32 -04:00

157 lines
6.4 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
Released under Apache 2.0 license.
Authors: Joseph Tooby-Smith
-/
import Lean
/-!
## Informal definitions and lemmas
-/
open Lean Elab System
/-! TODO: Derive a means to extract informal definitions and informal lemmas. -/
/-! TODO: Can likely make this a bona-fide command. -/
/-- The structure representating an informal definition. -/
structure InformalDefinition where
/-- The name of the informal definition. This is autogenerated. -/
name : Name
/-- The mathematical description of the definition. -/
math : String
/-- The physics description of the definition. -/
physics : String
/-- References. -/
ref : String
/-- The names of top-level commands we expect this definition to depend on. -/
dependencies : List Name
/-- The structure representating an informal proof. -/
structure InformalLemma where
/-- The name of the informal lemma. This is autogenerated. -/
name : Name
/-- The mathematical description of the lemma. -/
math : String
/-- The physics description of the lemma. -/
physics : String
/-- A description of the proof. -/
proof : String
/-- References. -/
ref : String
/-- The names of top-level commands we expect this lemma to depend on. -/
dependencies : List Name
namespace Informal
/-- The Parser.Category we will use for assignments. -/
declare_syntax_cat informalAssignment
/-- The syntax describing an informal assignment of `ident` to a string. -/
syntax (name := informalAssignment) ident ":≈" str : informalAssignment
/-- The syntax describing an informal assignment of `ident` to a list. -/
syntax (name := informalAssignmentDeps) ident ":≈" "[" sepBy(term, ",") "]" : informalAssignment
/-- The syntax for the command informal_definition. -/
syntax (name := informal_definition) "informal_definition " ident
" where " (colGt informalAssignment)* : command
/-- The macro turning `informal_definition ... where ...` into a definition. -/
macro "informal_definition " name:ident " where " assignments:informalAssignment* : command => do
let mut math_def? : Option (TSyntax `term) := none
let mut physics_def? : Option (TSyntax `term) := none
let mut ref_def? : Option (TSyntax `term) := none
let mut dep_def? : Option (TSyntax `term) := none
for assignment in assignments do
match assignment with
| `(informalAssignment| physics :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for physics"
physics_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignment| math :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for math"
math_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignment| ref :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for ref"
ref_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignmentDeps| deps :≈ [$deps,*]) =>
dep_def? := some (← `([$deps,*]))
| _ => Macro.throwError "invalid assignment syntax in informal_definition"
unless math_def?.isSome do
Macro.throwError "A 'math' assignments is required"
`(
/-- An informal definition. -/
def $name : InformalDefinition := {
name := $(Lean.quote name.getId),
physics := $(physics_def?.getD (← `("No physics description provided"))),
math := $(math_def?.getD (panic! "math not assigned")),
ref := $(ref_def?.getD (← `("No references provided"))),
dependencies := $(dep_def?.getD (← `([])))
})
/-- The syntax for the command `informal_lemma`. -/
syntax (name := informal_lemma) "informal_lemma " ident " where "
(colGt informalAssignment)* : command
/-- The macro turning `informal_lemma ... where ...` into a definition. -/
macro "informal_lemma " name:ident " where " assignments:informalAssignment* : command => do
let mut math_def? : Option (TSyntax `term) := none
let mut physics_def? : Option (TSyntax `term) := none
let mut proof_def? : Option (TSyntax `term) := none
let mut ref_def? : Option (TSyntax `term) := none
let mut dep_def? : Option (TSyntax `term) := none
for assignment in assignments do
match assignment with
| `(informalAssignment| physics :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for physics"
physics_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignment| math :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for math"
math_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignment| proof :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for proof"
proof_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignment| ref :≈ $val:str) =>
let some strVal := val.raw.isStrLit? | Macro.throwError "Expected string literal for ref"
ref_def? := some (← `($(Lean.quote strVal)))
| `(informalAssignmentDeps| deps :≈ [$deps,*]) =>
dep_def? := some (← `([$deps,*]))
| _ => Macro.throwError "invalid assignment syntax"
unless math_def?.isSome do
Macro.throwError "A 'math' assignments is required"
`(
/-- An informal lemma. -/
def $name : InformalLemma := {
name := $(Lean.quote name.getId),
physics := $(physics_def?.getD (← `("No physics description provided"))),
math := $(math_def?.getD (panic! "math not assigned")),
proof := $(proof_def?.getD (← `("No proof description provided"))),
ref := $(ref_def?.getD (← `("No references provided"))),
dependencies := $(dep_def?.getD (← `([])))
})
/-- Is true if and only if a `ConstantInfo` corresponds to an `InformalLemma` or a
`InformalDefinition`. -/
def isInformal (c : ConstantInfo) : Bool :=
match c with
| ConstantInfo.defnInfo c =>
if c.type.isAppOf ``InformalDefinition c.type.isAppOf ``InformalLemma then true else false
| _ => false
/-- Is true if and only if a `ConstantInfo` corresponds to an `InformalLemma`. -/
def isInformalLemma (c : ConstantInfo) : Bool :=
match c with
| ConstantInfo.defnInfo c =>
if c.type.isAppOf ``InformalLemma then true else false
| _ => false
/-- Is true if and only if a `ConstantInfo` corresponds to an `InformalDefinition`. -/
def isInformalDef (c : ConstantInfo) : Bool :=
match c with
| ConstantInfo.defnInfo c =>
if c.type.isAppOf ``InformalDefinition then true else false
| _ => false
end Informal