2024-10-08 15:45:51 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
Authors: Joseph Tooby-Smith
|
|
|
|
|
-/
|
|
|
|
|
import HepLean.Tensors.Tree.Basic
|
|
|
|
|
import Lean.Elab.Term
|
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
## Tensor trees to dot files
|
|
|
|
|
|
|
|
|
|
Dot files are used by graphviz to create visualizations of graphs. Here we define a function
|
|
|
|
|
that converts a tensor tree into a dot file.
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
|
|
|
namespace TensorTree
|
|
|
|
|
|
|
|
|
|
/-- Turns a nodes of tensor trees into nodes and edges of a dot file. -/
|
2024-10-09 15:23:54 +00:00
|
|
|
|
def dotString (m : ℕ) (nt : ℕ) : ∀ {n : ℕ} {c : Fin n → S.C}, TensorTree S c → String := fun
|
2024-10-08 15:45:51 +00:00
|
|
|
|
| tensorNode _ =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
" node" ++ toString m ++ " [label=\"T" ++ toString nt ++ "\"];\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
| add t1 t2 =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let addNode := " node" ++ toString m ++ " [label=\"+\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
|
|
|
|
let edge2 := " node" ++ toString m ++ " -> node" ++ toString (m + 2) ++ ";\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
addNode ++ dotString (m + 1) nt t1 ++ dotString (m + 2) (nt + 1) t2 ++ edge1 ++ edge2
|
|
|
|
|
| perm σ t =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let permNode := " node" ++ toString m ++ " [label=\"perm\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
permNode ++ dotString (m + 1) nt t ++ edge1
|
|
|
|
|
| prod t1 t2 =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let prodNode := " node" ++ toString m ++ " [label=\"⊗\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
|
|
|
|
let edge2 := " node" ++ toString m ++ " -> node" ++ toString (2 * t1.size + m + 2) ++ ";\n"
|
2024-10-08 16:33:40 +00:00
|
|
|
|
prodNode ++ dotString (m + 1) nt t1 ++ dotString (2 * t1.size + m + 2) (nt + 1) t2
|
|
|
|
|
++ edge1 ++ edge2
|
2024-10-17 11:43:33 +00:00
|
|
|
|
| neg t =>
|
|
|
|
|
let negNode := " node" ++ toString m ++ " [label=\"neg\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
|
|
|
|
negNode ++ dotString (m + 1) nt t ++ edge1
|
2024-10-08 15:45:51 +00:00
|
|
|
|
| smul k t =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let smulNode := " node" ++ toString m ++ " [label=\"smul\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
smulNode ++ dotString (m + 1) nt t ++ edge1
|
|
|
|
|
| eval _ _ t1 =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let evalNode := " node" ++ toString m ++ " [label=\"eval\", shape=box];\n"
|
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
evalNode ++ dotString (m + 1) nt t1 ++ edge1
|
2024-10-10 08:57:22 +00:00
|
|
|
|
| contr i j _ t1 =>
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let contrNode := " node" ++ toString m ++ " [label=\"contr " ++ toString i ++ " "
|
2024-10-08 15:45:51 +00:00
|
|
|
|
++ toString j ++ "\", shape=box];\n"
|
2024-10-09 15:23:54 +00:00
|
|
|
|
let edge1 := " node" ++ toString m ++ " -> node" ++ toString (m + 1) ++ ";\n"
|
2024-10-08 15:45:51 +00:00
|
|
|
|
contrNode ++ dotString (m + 1) nt t1 ++ edge1
|
|
|
|
|
|
|
|
|
|
/-- Used to form a dot graph from a tensor tree. use e.g.
|
|
|
|
|
`#tensor_dot {T4 | i j l d ⊗ T5 | i j k a b}ᵀ.dot`.
|
|
|
|
|
Dot files can be viewed by copying and pasting into: https://dreampuf.github.io/GraphvizOnline. -/
|
|
|
|
|
def dot {n : ℕ} {c : Fin n → S.C} (t : TensorTree S c) : String :=
|
2024-10-08 16:33:40 +00:00
|
|
|
|
"// Dot file created by HepLean for a tensor expression.
|
|
|
|
|
// Can be viewed at https://dreampuf.github.io/GraphvizOnline/\n" ++
|
2024-10-08 15:45:51 +00:00
|
|
|
|
"digraph G {\n" ++ dotString 0 0 t ++ "}"
|
|
|
|
|
|
|
|
|
|
section dotElab
|
|
|
|
|
|
|
|
|
|
open Lean.Elab.Command Lean Meta Lean.Elab
|
|
|
|
|
|
2024-10-08 15:47:53 +00:00
|
|
|
|
/-- Syntax for showing the dot file associated with a tensor tree.
|
|
|
|
|
Use as `#tensor_dot {T4 | i j l d ⊗ T5 | i j k a b}ᵀ.dot`. -/
|
2024-10-08 15:45:51 +00:00
|
|
|
|
syntax (name := tensorDot) "#tensor_dot " term : command
|
|
|
|
|
|
|
|
|
|
/-- Adapted from `Lean.Elab.Command.elabReduce` in file copyright Microsoft Corporation. -/
|
2024-10-09 15:23:54 +00:00
|
|
|
|
unsafe def dotElab (term : Syntax) : CommandElabM Unit :=
|
2024-10-08 15:45:51 +00:00
|
|
|
|
withoutModifyingEnv <| runTermElabM fun _ => Term.withDeclName `_reduce do
|
|
|
|
|
let e ← Term.elabTerm term none
|
|
|
|
|
Term.synthesizeSyntheticMVarsNoPostponing
|
|
|
|
|
let e ← Term.levelMVarToParam (← instantiateMVars e)
|
2024-10-08 15:47:53 +00:00
|
|
|
|
withTheReader Core.Context (fun ctx =>
|
|
|
|
|
{ ctx with options := ctx.options.setBool `smartUnfolding false }) do
|
2024-10-08 15:45:51 +00:00
|
|
|
|
let e ← withTransparency (mode := TransparencyMode.all) <|
|
|
|
|
|
reduce e (skipProofs := true) (skipTypes := true)
|
|
|
|
|
let str ← Lean.Meta.evalExpr' String ``String e
|
|
|
|
|
println! str
|
|
|
|
|
|
|
|
|
|
/-- Elaborator for the syntax tensorDot. -/
|
|
|
|
|
@[command_elab tensorDot]
|
|
|
|
|
unsafe def elabTensorDot: CommandElab
|
|
|
|
|
| `(#tensor_dot $term) => dotElab term
|
|
|
|
|
| _ => throwUnsupportedSyntax
|
|
|
|
|
|
|
|
|
|
end dotElab
|
|
|
|
|
|
|
|
|
|
end TensorTree
|