-
Notifications
You must be signed in to change notification settings - Fork 0
/
GatePlots.jl
97 lines (77 loc) · 2.25 KB
/
GatePlots.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# TODO: Port https://github.com/IainNZ/GraphLayout.jl to modern Julia as a NetworkLayout.jl implementation, then use that for layout
# XXX: Consider xdot output?
module GatePlots
using ..Gates
using RecipesBase
import GraphRecipes: GraphPlot, graphplot
using LaTeXStrings
const Point64 = NTuple{2, Float64}
arc!(path::Vector{Point64}, (x, y)::Point64, radius::Float64, radianspi::AbstractRange) =
append!(path, reim.((x + y*im) .+ radius .* cispi.(radianspi)))
struct GateShape{F} <: Function end
GateShape(::Gate{F}) where F = GateShape{~}()
function (::GateShape{~})(x, y, w, h)
r = 0.1min(w, h)
halfw = w/2
halfh = h/2
left, right = x - halfw, x + halfw
result = [
(left, y - halfh),
(left, y + halfh),
(right - 2r, y)
]
arc!(result, (right - r, y), r, LinRange(1, -1, 10))
push!(result, result[begin])
result
end
function (::GateShape{&})(x, y, w, h)
end
# How to draw: https://spinningnumbers.org/a/logic-gates.html
function (::GateShape{|})()
end
function (::GateShape{⊻})()
end
@recipe function f(x::Gate; outnode=nothing)
wires = IdDict{Gates.SymbolicBool,Int}()
source = Int[]
destiny = Int[]
names = AbstractString[]
shapes = Union{GateShape, Symbol}[]
strokealpha = Float64[]
walk(x::BoolVariable) = get!(wires, x) do
wire = length(wires) + 1
push!(names, latexstring(sprint(show, MIME("text/latex"), x)))
push!(shapes, :circle)
push!(strokealpha, 0)
wire
end
function walk(gate::Gate)
wire = get!(wires, gate) do
push!(names, " ")
push!(shapes, GateShape(gate))
push!(strokealpha, 1)
length(wires) + 1
end
append!(source, fill(wire, axes(gate.inputs)))
append!(destiny, walk.(gate.inputs))
wire
end
if !isnothing(outnode)
wires[gensym()] = 1
push!(names, outnode)
push!(shapes, :rect)
push!(strokealpha, 0)
push!(source, 1)
push!(destiny, 2)
end
walk(x)
names := names
nodeshape := shapes
markerstrokealpha := strokealpha
method --> :buchheim
root --> :right
nodecolor --> :white
GraphPlot((source, destiny))
end
graphplot(x::Gate) = plot(x)
end