Skip to content

Commit

Permalink
hom search and acset transformations for mark as deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
Kris Brown committed Jan 22, 2024
1 parent 69ed95b commit 9ca0d62
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 26 deletions.
36 changes: 18 additions & 18 deletions src/categorical_algebra/CSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -427,51 +427,51 @@ TightACSetTransformation(components, X::StructACSet{S}, Y::StructACSet{S}) where

# Component coercion

function coerce_components(S, components, X, Y)
function coerce_components(S, components, X::ACSet{<:PT}, Y) where PT
@assert keys(components) objects(S) attrtypes(S)
ocomps = NamedTuple(
c => coerce_component(c, get(components,c,1:0), nparts(X,c), maxpart(Y,c))
for c in objects(S))
kw = Dict(map(types(S)) do c
c => PT <: MarkAsDeleted ? (dom_parts=parts(X,c), codom_parts=parts(Y,c)) : (;)
end)
ocomps = NamedTuple(map(objects(S)) do c
c => coerce_component(c, get(components, c, 1:0),
nparts(X,c), nparts(Y,c); kw[c]...)
end)
acomps = NamedTuple(map(attrtypes(S)) do c
c => coerce_attrvar_component(c, get(components,c,1:0),
TypeSet(X, c), TypeSet(Y, c), nparts(X,c), maxpart(Y,c))
c => coerce_attrvar_component(c, get(components, c, 1:0),
TypeSet(X, c), TypeSet(Y, c), nparts(X,c), nparts(Y,c); kw[c]...)
end)
return merge(ocomps, acomps)
return merge(ocomps, acomps)
end

function coerce_component(ob::Symbol, f::FinFunction{Int,Int},
dom_size::Int, codom_size::Int)
dom_size::Int, codom_size::Int; kw...)
length(dom(f)) == dom_size || error("Domain error in component $ob")
# length(codom(f)) == codom_size || error("Codomain error in component $ob") # codom size is now Maxpart not nparts
return f
end

coerce_component(::Symbol, f, dom_size::Int, codom_size::Int) =
FinFunction(f, dom_size, codom_size)

coerce_component(::Symbol, f::Column, dom_size::Int, codom_size::Int) = f
coerce_attrvar_component(::Symbol, f::Column, ::TypeSet{T}, ::TypeSet{T},
dom_size::Int, codom_size::Int) where T = f
coerce_component(::Symbol, f, dom_size::Int, codom_size::Int; kw...) =
FinFunction(f, dom_size, codom_size; kw...)

function coerce_attrvar_component(
ob::Symbol, f::AbstractVector,::TypeSet{T}, ::TypeSet{T},
dom_size::Int, codom_size::Int) where {T}
dom_size::Int, codom_size::Int; kw...) where {T}
e = "Domain error in component $ob variable assignment $(length(f)) != $dom_size"
length(f) == dom_size || error(e)
return VarFunction{T}(f, FinSet(codom_size))
end

function coerce_attrvar_component(
ob::Symbol, f::VarFunction,::TypeSet{T},::TypeSet{T},
dom_size::Int, codom_size::Int) where {T}
dom_size::Int, codom_size::Int; kw...) where {T}
# length(dom(f.fun)) == dom_size || error("Domain error in component $ob: $(dom(f.fun))!=$dom_size")
length(f.codom) == codom_size || error("Codomain error in component $ob: $(f.fun.codom)!=$codom_size")
return f
end

function coerce_attrvar_component(
ob::Symbol, f::LooseVarFunction,d::TypeSet{T},cd::TypeSet{T′},
dom_size::Int, codom_size::Int) where {T,T′}
dom_size::Int, codom_size::Int; kw...) where {T,T′}
length(dom(f.fun)) == dom_size || error("Domain error in component $ob")
length(f.codom) == codom_size || error("Codomain error in component $ob: $(f.fun.codom)!=$codom_size")
# We do not check types (equality is too strict)
Expand All @@ -482,7 +482,7 @@ end

"""Coerce an arbitrary julia function to a LooseVarFunction assuming no variables"""
function coerce_attrvar_component(ob::Symbol, f::Function, d::TypeSet{T},cd::TypeSet{T′},
dom_size::Int, codom_size::Int) where {T,T′}
dom_size::Int, codom_size::Int; kw...) where {T,T′}
dom_size == 0 || error("Cannot specify $ob component with $f with $dom_size domain variables")
coerce_attrvar_component(ob, LooseVarFunction{T,T′}([], f, FinSet(codom_size)),
d, cd, dom_size,codom_size)
Expand Down
12 changes: 9 additions & 3 deletions src/categorical_algebra/FinSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,21 @@ FinFunction(f::AbstractDict, args...) =
FinFunctionDict(f, (FinSet(arg) for arg in args)...)

function FinFunction(f::AbstractVector, args...;
index=false, known_correct = false)
cod = FinSet(args[end])
index=false, known_correct = false,
dom_parts=nothing, codom_parts=nothing)
cod = FinSet(isnothing(codom_parts) ? args[end] : codom_parts)
f = Vector{Int}(f) # coerce empty vectors
if !known_correct
for (i,t) enumerate(f)
t cod || error("Value $t at index $i is not in $cod.")
if isnothing(dom_parts) || i dom_parts
t cod || error("Value $t at index $i is not in $cod.")
end
end
end
if !index
if !isnothing(dom_parts)
args = (length(f), args[2:end]...)
end
FinDomFunctionVector(f, (FinSet(arg) for arg in args)...)
else
index = index == true ? nothing : index
Expand Down
10 changes: 5 additions & 5 deletions src/categorical_algebra/HomSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ function backtracking_search(f, X::ACSet, Y::ACSet;

# Initialize state variables for search.
assignment = merge(
NamedTuple{Ob}(zeros(Int, nparts(X, c)) for c in Ob),
NamedTuple{Ob}(zeros(Int, maxpart(X, c)) for c in Ob),
NamedTuple{Attr}(Pair{Int,Union{AttrVar,attrtype_type(X,c)}}[
0 => AttrVar(0) for _ in parts(X,c)] for c in Attr)
0 => AttrVar(0) for _ in 1:maxpart(X,c)] for c in Attr)
)
assignment_depth = map(copy, assignment)
inv_assignment = NamedTuple{ObAttr}(
(c in monic ? zeros(Int, nparts(Y, c)) : nothing) for c in ObAttr)
(c in monic ? zeros(Int, maxpart(Y, c)) : nothing) for c in ObAttr)
loosefuns = NamedTuple{Attr}(
isnothing(type_components) ? identity : get(type_components, c, identity) for c in Attr)
state = BacktrackingState(assignment, assignment_depth,
Expand Down Expand Up @@ -293,8 +293,8 @@ function find_mrv_elem(state::BacktrackingState, depth)
S = acset_schema(state.dom)
mrv, mrv_elem = Inf, nothing
Y = state.codom
for c in ob(S), (x, y) in enumerate(state.assignment[c])
y == 0 || continue
for c in ob(S), x in parts(state.dom, c)
state.assignment[c][x] == 0 || continue
n = count(can_assign_elem(state, depth, c, x, y) for y in parts(Y, c))
if n < mrv
mrv, mrv_elem = n, (c, x)
Expand Down
13 changes: 13 additions & 0 deletions test/categorical_algebra/HomSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,17 @@ results = first(is_iso1) ? results : reverse(results)
@test collect(R2[:V]) == [3,1,2]
@test L2(apx2) == Subobject(g1, V=[1,2,3], E=[1,3])

# Mark as deleted
#################
using Catlab, Test
@acset_type AbsMADGraph(SchWeightedGraph, part_type=BitSetParts) <: AbstractGraph
const MADGraph = AbsMADGraph{Symbol}

v1, v2 = MADGraph.(1:2)
@test !is_isomorphic(v1,v2)
rem_part!(v2, :V, 1)
@test is_isomorphic(v1,v2)
@test is_isomorphic(v2,v1)


end # module

0 comments on commit 9ca0d62

Please sign in to comment.