117 |
118 |
frame: {frame}. state: {asyncState.current}, mousePos: {mousePos ? mousePos.join(", ") : "none"}, mouseButtonState: {mouseButtonState}
119 |
120 | }
121 |
122 | export default Svg
123 |
--------------------------------------------------------------------------------
/ProofWidgets/Demos/RbTree.lean:
--------------------------------------------------------------------------------
1 | module
2 |
3 | public meta import ProofWidgets.Presentation.Expr
4 | public meta import ProofWidgets.Component.Panel.SelectionPanel
5 |
6 | public meta section
7 |
8 | /-! ## References:
9 | - Chris Okasaki. "Functional Pearls: Red-Black Trees in a Functional Setting". 1993 -/
10 |
11 | inductive RBColour where
12 | | red | black
13 |
14 | inductive RBTree (α : Type u) where
15 | | empty : RBTree α
16 | | node (color : RBColour) (l : RBTree α) (a : α) (r : RBTree α) : RBTree α
17 |
18 | namespace RBTree
19 |
20 | def contains [Ord α] (a : α) : RBTree α → Bool
21 | | empty => false
22 | | node _ l b r => match compare a b with
23 | | .lt => l.contains a
24 | | .eq => true
25 | | .gt => r.contains a
26 |
27 | def balance : RBColour → RBTree α → α → RBTree α → RBTree α
28 | | .black, (node .red (node .red a x b) y c), z, d
29 | | .black, (node .red a x (node .red b y c)), z, d
30 | | .black, a, x, (node .red (node .red b y c) z d)
31 | | .black, a, x, (node .red b y (node .red c z d)) =>
32 | node .red (node .black a x b) y (node .black c z d)
33 | | color, a, x, b => node color a x b
34 |
35 | def insert [Ord α] (a : α) (s : RBTree α) : RBTree α :=
36 | makeBlack (ins s)
37 | where
38 | ins : RBTree α → RBTree α
39 | | empty => node .red empty a empty
40 | | node c l b r => match compare a b with
41 | | .lt => balance c (ins l) b r
42 | | .eq => node c l b r
43 | | .gt => balance c l b (ins r)
44 | makeBlack : RBTree α → RBTree α
45 | | empty => empty
46 | | node _ l b r => node .black l b r
47 |
48 | end RBTree
49 |
50 | /-! # Metaprogramming utilities for red-black trees -/
51 |
52 | open Lean
53 |
54 | def empty? (e : Expr) : Bool :=
55 | e.app1? ``RBTree.empty matches some _
56 |
57 | @[inline] def Lean.Expr.app5? (e : Expr) (fName : Name) : Option (Expr × Expr × Expr × Expr × Expr) :=
58 | if e.isAppOfArity fName 5 then
59 | some (
60 | e.appFn!.appFn!.appFn!.appFn!.appArg!,
61 | e.appFn!.appFn!.appFn!.appArg!,
62 | e.appFn!.appFn!.appArg!,
63 | e.appFn!.appArg!,
64 | e.appArg!)
65 | else
66 | none
67 |
68 | def node? (e : Expr) : Option (Expr × Expr × Expr × Expr) := do
69 | let some (_, color, l, a, r) := e.app5? ``RBTree.node | none
70 | return (color, l, a, r)
71 |
72 | unsafe def evalColourUnsafe (e : Expr) : MetaM RBColour :=
73 | Lean.Meta.evalExpr' RBColour ``RBColour e
74 |
75 | @[implemented_by evalColourUnsafe]
76 | opaque evalColour (e : Expr) : MetaM RBColour
77 |
78 | /-- Like `RBTreeColour`, but with `blue` standing in for unknown, symbolic `c : RBTreeColour`. -/
79 | inductive RBTreeVarsColour where
80 | | red | black | blue
81 | deriving FromJson, ToJson
82 |
83 | open Widget in
84 | /-- Like `RBTree` but with concrete node contents replaced by quoted, pretty-printed code,
85 | and an extra constructor for similarly pretty-printed symbolic subtrees.
86 |
87 | Tangent: what is the transformation of polynomial functors from the original type to
88 | one with this kind of symbolic data? -/
89 | inductive RBTreeVars where
90 | | empty : RBTreeVars
91 | | var : CodeWithInfos → RBTreeVars
92 | | node (color : RBTreeVarsColour) (l : RBTreeVars) (a : CodeWithInfos) (r : RBTreeVars) : RBTreeVars
93 | deriving Server.RpcEncodable
94 |
95 | /-! # `Expr` presenter to display red-black trees -/
96 |
97 | structure RBDisplayProps where
98 | tree : RBTreeVars
99 | deriving Server.RpcEncodable
100 |
101 | open ProofWidgets
102 |
103 | @[widget_module]
104 | def RBDisplay : Component RBDisplayProps where
105 | javascript := include_str ".." / ".." / ".lake" / "build" / "js" / "rbTree.js"
106 |
107 | open scoped Jsx in
108 | partial def drawTree? (e : Expr) : MetaM (Option Html) := do
109 | if let some _ := node? e then
110 | return some