Skip to content

Commit

Permalink
Trie -> Dtry
Browse files Browse the repository at this point in the history
  • Loading branch information
olynch committed Jul 2, 2024
1 parent 946a7b0 commit 3b14597
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 213 deletions.
22 changes: 11 additions & 11 deletions dynamics.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

Affordances:
- [x] DSL for writing down functions, composing, etc.
- [ ] A function `tcompose(t::Trie{AlgebraicFunction})::AlgebraicFunction`, implementing the Trie-algebra structure on morphisms
- [ ] A function `tcompose(t::Dtry{AlgebraicFunction})::AlgebraicFunction`, implementing the Dtry-algebra structure on morphisms
- [ ] Interpret/compile a symbolic function into a real function
- [ ] Serialize symbolic functions
- [ ] Compilation
Expand All @@ -35,12 +35,12 @@
```

Affordances:
- A function `tcompose(arena::Trie{Arena})::Arena`, implementing the Trie-algebra structure on objects
- A function `tcompose(arena::Dtry{Arena})::Arena`, implementing the Dtry-algebra structure on objects
- [ ] Multilenses
Sketch:
```julia
struct MultiLens
inner_boxes::Trie{Arena}
inner_boxes::Dtry{Arena}
outer_box::Arena
# used for namespacing `params` in composition, must not overlap with `inner_boxes`
name::Symbol
Expand All @@ -53,7 +53,7 @@
```

Affordances:
- A function `ocompose(l::MultiLens, args::Trie{MultiLens})::MultiLens` implementing the Trie-multicategory structure
- A function `ocompose(l::MultiLens, args::Dtry{MultiLens})::MultiLens` implementing the Dtry-multicategory structure
- [ ] Systems
Sketch:
```julia
Expand All @@ -69,7 +69,7 @@
```

Affordances:
- A function `oapply(l::MultiLens, args::Trie{System})::System` implementing the action of the Trie-multicategory of multilenses on systems.
- A function `oapply(l::MultiLens, args::Dtry{System})::System` implementing the action of the Dtry-multicategory of multilenses on systems.

## Resource sharers

Expand All @@ -82,20 +82,20 @@
end
struct Rhizome
boxes::Trie{Interface}
junctions::Trie{VariableType}
mapping::Dict{TrieVar, TrieVar}
boxes::Dtry{Interface}
junctions::Dtry{VariableType}
mapping::Dict{DtryVar, DtryVar}
end
```

Affordances:
- `ocompose(r::Rhizome, rs::Trie{Rhizome})::Rhizome`
- `ocompose(r::Rhizome, rs::Dtry{Rhizome})::Rhizome`

In `ocompose`, the names of the junctions in the top-level rhizome dominate.
- [ ] Systems
```julia
struct ResourceSharer
variables::Trie{VariableType}
variables::Dtry{VariableType}
params::AlgType
output::AlgType
# (params, state) -> state
Expand All @@ -106,6 +106,6 @@
```

Affordances:
- `oapply(r::Rhizome, sharers::Trie{ResourceSharer})::ResourceSharer`
- `oapply(r::Rhizome, sharers::Dtry{ResourceSharer})::ResourceSharer`

In `oapply`, variables get renamed to the junctions that they are attached to.
82 changes: 41 additions & 41 deletions src/nonstdlib/dynamics/ResourceSharers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module ResourceSharers
export Rhizome, @rhizome, ResourceSharer, @resource_sharer, Variable

using ...Syntax
using ...Util.Tries
using ...Util.Tries: flatten, node
using ...Util.Dtrys
using ...Util.Dtrys: flatten, node
using ...Syntax.GATs: tcompose
using ...Util
using MLStyle
Expand Down Expand Up @@ -33,10 +33,10 @@ Fields:
"""
struct PortVariable
type::AlgType
junction::TrieVar
junction::DtryVar
end

const Interface = Trie{AlgType}
const Interface = Dtry{AlgType}

"""
A rhizome is a variant of a UWD where the underlying cospan is epi-monic.
Expand All @@ -49,12 +49,12 @@ This also differs from the ACSet-based UWDs in the following ways
1. We use tries instead of numbering things sequentially.
2. All of the "functions out" of the tries are handled by just storing data in
the leaves of the tries, rather than having external "column vectors".
So e.g. we would use `Trie{Int}` rather than a pair of `Trie{Nothing}`,
`Dict{TrieVar, Int}`.
So e.g. we would use `Dtry{Int}` rather than a pair of `Dtry{Nothing}`,
`Dict{DtryVar, Int}`.
3. We use an indexed rather than fibered representation for inner ports
on boxes. That is, we have a function Boxes -> Set rather than a function
InnerPorts -> Boxes. Following 2., this is just stored in the leaf nodes
of the trie of boxes, hence `Trie{Trie{PortVariable}}`.
of the trie of boxes, hence `Dtry{Dtry{PortVariable}}`.
4. We don't have separate sets for outer ports and junctions: rather each
junction is marked as "exposed" or not. This simplifies naming. Also see
[`Variable`](@ref).
Expand All @@ -66,11 +66,11 @@ of enforcing this would be to do something like
```
struct Box
ports::Trie{PortVariable}
ports::Dtry{PortVariable}
end
struct Rhizome
stuff::Trie{Union{Variable, Box}}
stuff::Dtry{Union{Variable, Box}}
end
```
Expand All @@ -81,36 +81,36 @@ struct Rhizome
theory::GAT
mcompose::AlgClosure
mzero::AlgClosure
boxes::Trie{Trie{PortVariable}}
junctions::Trie{Variable}
boxes::Dtry{Dtry{PortVariable}}
junctions::Dtry{Variable}
end

"""
ocompose(r::Rhizome, rs::Trie{Rhizome})
ocompose(r::Rhizome, rs::Dtry{Rhizome})
This implements the composition operation for the Trie-multicategory of
This implements the composition operation for the Dtry-multicategory of
rhizomes. This is the better way of doing the [operad of undirected wiring][1].
TODO: add link to arXiv paper on Trie-multicategories once it goes up.
TODO: add link to arXiv paper on Dtry-multicategories once it goes up.
See [2] for a reference on general T-multicategories, then trust me for now
that Trie is a cartesian monoid.
that Dtry is a cartesian monoid.
[1]: [The operad of wiring diagrams: formalizing a graphical language for
databases, recursion, and plug-and-play circuits](https://arxiv.org/abs/1305.0297)
[2]: [Higher Operads, Higher Categories](https://arxiv.org/abs/math/0305049)
"""
function ocompose(r::Rhizome, rs::Trie{Rhizome})
# paired :: Trie{Tuple{Trie{PortVariable}, Rhizome}}
function ocompose(r::Rhizome, rs::Dtry{Rhizome})
# paired :: Dtry{Tuple{Dtry{PortVariable}, Rhizome}}
paired = zip(r.boxes, rs)
boxes = flatten(mapwithkey(Trie{Trie{PortVariable}}, paired) do k, (interface, r′)
# k :: TrieVar
# interface :: Trie{PortVariable}
boxes = flatten(mapwithkey(Dtry{Dtry{PortVariable}}, paired) do k, (interface, r′)
# k :: DtryVar
# interface :: Dtry{PortVariable}
# r′ :: Rhizome
# We want to create the new collection of boxes

map(Trie{PortVariable}, r′.boxes) do b
# b :: Trie{PortVariable}
map(Dtry{PortVariable}, r′.boxes) do b
# b :: Dtry{PortVariable}
map(PortVariable, b) do p
# p :: PortVariable
# p.junction :: namespace(b.junctions)
Expand All @@ -129,10 +129,10 @@ function ocompose(r::Rhizome, rs::Trie{Rhizome})
end)
# Add all unexposed junctions
newjunctions = flatten(
map(Trie{Variable}, rs) do r′
map(Dtry{Variable}, rs) do r′
internal_junctions = filter(j -> !j.exposed, r′.junctions)
if isnothing(internal_junctions)
Tries.node(OrderedDict{Symbol, Trie{Variable}}())
Dtrys.node(OrderedDict{Symbol, Dtry{Variable}}())

Check warning on line 135 in src/nonstdlib/dynamics/ResourceSharers.jl

View check run for this annotation

Codecov / codecov/patch

src/nonstdlib/dynamics/ResourceSharers.jl#L135

Added line #L135 was not covered by tests
else
internal_junctions

Check warning on line 137 in src/nonstdlib/dynamics/ResourceSharers.jl

View check run for this annotation

Codecov / codecov/patch

src/nonstdlib/dynamics/ResourceSharers.jl#L137

Added line #L137 was not covered by tests
end
Expand Down Expand Up @@ -215,7 +215,7 @@ macro rhizome(theorymod, head, body)
# macroexpand `theory` to get the actual theory
theory = macroexpand(__module__, :($theorymod.Meta.@theory))
# parse the name and junctions out of `head`
junctions = OrderedDict{TrieVar, Variable}()
junctions = OrderedDict{DtryVar, Variable}()
(name, args) = @match head begin
Expr(:call, name::Symbol, args...) => (name, args)
end
Expand All @@ -229,16 +229,16 @@ macro rhizome(theorymod, head, body)
type = fromexpr(theory, typeexpr, AlgType)
junctions[v] = Variable(true, type)
end
junctions = Trie(junctions)
junctions = Dtry(junctions)

boxes = OrderedDict{TrieVar, Trie{PortVariable}}()
boxes = OrderedDict{DtryVar, Dtry{PortVariable}}()
# for each line in body, add a box to boxes
for line in body.args
(box, args) = @match line begin
_::LineNumberNode => continue
Expr(:call, name, args...) => (parse_var(name), args)
end
interface = OrderedDict{TrieVar, PortVariable}()
interface = OrderedDict{DtryVar, PortVariable}()
for arg in args
(pname, junction) = @match arg begin
pname::Symbol => (pname, pname)
Expand All @@ -252,14 +252,14 @@ macro rhizome(theorymod, head, body)
j = junctions[jvar]
interface[v] = PortVariable(j.type, jvar)
end
boxes[box] = Trie(interface)
boxes[box] = Dtry(interface)
end
:(
$name = $Rhizome(
$theory,
$theorymod.Meta.Constructors.:(+),
$theorymod.Meta.Constructors.zero,
$(Trie(boxes)),
$(Dtry(boxes)),
$(junctions),
)
) |> esc
Expand All @@ -273,7 +273,7 @@ TODO: there should be a smart constructor that takes an AlgClosure and finds
the right method of it for the variables and params.
"""
struct ResourceSharer
variables::Trie{Variable}
variables::Dtry{Variable}
params::AlgType
# (tcompose(variables[..].type), params) -> tcompose(variables)
update::AlgMethod
Expand Down Expand Up @@ -309,7 +309,7 @@ macro resource_sharer(theory, name, body)
end

function parse_namespace(theory::GAT, expr::Expr0)
vs = OrderedDict{TrieVar, AlgType}()
vs = OrderedDict{DtryVar, AlgType}()
argexprs = @match expr begin
Expr(:tuple, args...) => args
_ => [expr]
Expand All @@ -324,7 +324,7 @@ function parse_namespace(theory::GAT, expr::Expr0)
type = fromexpr(theory, typeexpr, AlgType)
vs[v] = type
end
Trie(vs)
Dtry(vs)
end

function ResourceSharer(theory::GAT; variables::Expr0, params::Expr0, update::Expr0)
Expand Down Expand Up @@ -371,7 +371,7 @@ Arguments
Produces an AlgMethod going from tcompose(t1) to tcompose(first.(t2))
"""
function pullback(t1::Trie{AlgType}, t2::Trie{Tuple{AlgType, TrieVar}}; argname=:x)
function pullback(t1::Dtry{AlgType}, t2::Dtry{Tuple{AlgType, DtryVar}}; argname=:x)
ty1 = tcompose(t1)
ty2 = tcompose(map(first, t2))
ctx = TypeScope(argname => ty1)
Expand Down Expand Up @@ -399,13 +399,13 @@ Arguments
Produces an AlgMethod going from tcompose(first.(t2)) to tcompose(t1)
"""
function pushforward(
t1::Trie{AlgType},
t2::Trie{Tuple{AlgType, TrieVar}},
t1::Dtry{AlgType},
t2::Dtry{Tuple{AlgType, DtryVar}},
mcompose::AlgClosure,
mzero::AlgClosure;
argname=:x
)
preimages = Dict{TrieVar, Vector{TrieVar}}()
preimages = Dict{DtryVar, Vector{DtryVar}}()
traversewithkey(t2) do k, (_, v)
if haskey(preimages, v)
push!(preimages[v], k)
Expand All @@ -429,7 +429,7 @@ function pushforward(
AlgMethod(ctx, body, "", [LID(1)], ty1)
end

function oapply(r::Rhizome, sharers::Trie{ResourceSharer})
function oapply(r::Rhizome, sharers::Dtry{ResourceSharer})
new_variables = filter(v -> !v.exposed, flatten(
map(sharers) do sharer
sharer.variables
Expand All @@ -443,13 +443,13 @@ function oapply(r::Rhizome, sharers::Trie{ResourceSharer})
state = map(v -> v.type, variables)
state_type = tcompose(state)

# full_state : Trie{Tuple{AlgType, TrieVar}}
# full_state : Dtry{Tuple{AlgType, DtryVar}}
# This is a trie mapping all the variables in all of the systems
# to their type, and to the variable in the reduced system that they
# map to
full_state = flatten(
mapwithkey(Trie{Tuple{AlgType, TrieVar}}, zip(r.boxes, sharers)) do b, (interface, sharer)
mapwithkey(Tuple{AlgType, TrieVar}, sharer.variables) do k, v
mapwithkey(Dtry{Tuple{AlgType, DtryVar}}, zip(r.boxes, sharers)) do b, (interface, sharer)
mapwithkey(Tuple{AlgType, DtryVar}, sharer.variables) do k, v
if v.exposed
(v.type, interface[k].junction)
else
Expand Down
2 changes: 1 addition & 1 deletion src/syntax/GATs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using ..Scopes
import ..ExprInterop: fromexpr, toexpr

import ..Scopes: retag, rename, reident
using ...Util.Tries
using ...Util.Dtrys
using AbstractTrees

import AlgebraicInterfaces: equations
Expand Down
22 changes: 11 additions & 11 deletions src/syntax/gats/ast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,14 @@ retag(reps::Dict{ScopeTag, ScopeTag}, t::AlgTerm) = AlgTerm(retag(reps, t.body))

reident(reps::Dict{Ident}, t::AlgTerm) = AlgTerm(reident(reps, t.body))

Check warning on line 164 in src/syntax/gats/ast.jl

View check run for this annotation

Codecov / codecov/patch

src/syntax/gats/ast.jl#L164

Added line #L164 was not covered by tests

function tcompose(t::AbstractTrie{AlgTerm})
function tcompose(t::AbstractDtry{AlgTerm})
@match t begin
Tries.Leaf(v) => v
Tries.Node(bs) =>
Dtrys.Leaf(v) => v
Dtrys.Node(bs) =>
AlgTerm(AlgNamedTuple{AlgTerm}(OrderedDict{Symbol, AlgTerm}(
(n, tcompose(v)) for (n, v) in bs
)))
Tries.Empty() =>
Dtrys.Empty() =>

Check warning on line 173 in src/syntax/gats/ast.jl

View check run for this annotation

Codecov / codecov/patch

src/syntax/gats/ast.jl#L173

Added line #L173 was not covered by tests
AlgTerm(AlgNamedTuple{AlgTerm}(OrderedDict{Symbol, AlgTerm}()))
end
end
Expand Down Expand Up @@ -270,12 +270,12 @@ function AlgSort(t::AlgType)
end
end

function tcompose(t::AbstractTrie{AlgType})
function tcompose(t::AbstractDtry{AlgType})
@match t begin
Tries.Node(bs) =>
Dtrys.Node(bs) =>
AlgType(AlgNamedTuple(OrderedDict(k => tcompose(v) for (k,v) in AbstractTrees.children(t))))
Tries.Leaf(v) => v
Tries.Empty() => AlgType(AlgNamedTuple(OrderedDict{Symbol, AlgType}()))
Dtrys.Leaf(v) => v
Dtrys.Empty() => AlgType(AlgNamedTuple(OrderedDict{Symbol, AlgType}()))

Check warning on line 278 in src/syntax/gats/ast.jl

View check run for this annotation

Codecov / codecov/patch

src/syntax/gats/ast.jl#L278

Added line #L278 was not covered by tests
end
end

Expand Down Expand Up @@ -327,10 +327,10 @@ end
headof(a::AlgDot) = a.head
bodyof(a::AlgDot) = a.body

function Base.getindex(a::AlgTerm, v::TrieVar)
function Base.getindex(a::AlgTerm, v::DtryVar)
@match v begin
Tries.Root() => a
Tries.Nested((n, v′)) => getindex(AlgTerm(AlgDot(n, a)), v′)
Dtrys.Root() => a
Dtrys.Nested((n, v′)) => getindex(AlgTerm(AlgDot(n, a)), v′)
end
end

Expand Down
Loading

0 comments on commit 3b14597

Please sign in to comment.