 AlgebraicJulia
/
Catlab.jl

### BUG: Handle degenerate case of conjunctive query with no output ports.

These are effectively counting queries. Evan Patterson 2 weeks ago
parent
commit
7f60702330
3 changed files with 24 additions and 10 deletions
1. 4
benchmark/Graphs.jl
2. 24
src/wiring_diagrams/Algebras.jl
3. 6
test/wiring_diagrams/Algebras.jl

#### 4 benchmark/Graphs.jl View File

 @ -83,9 +83,9 @@ function ntriangles(g::T, ::TriangleHomomorphism) where T  count end function ntriangles(g, ::TriangleQuery)  length(query(g, triangle_query))  length(query(g, ntriangles_query)) end const triangle_query = @relation (v1=v1, v2=v2, v3=v3) begin const ntriangles_query = @relation (;) begin  E(src=v1, tgt=v2)  E(src=v2, tgt=v3)  E(src=v1, tgt=v3)

#### 24 src/wiring_diagrams/Algebras.jl View File

 @ -127,15 +127,19 @@ end   """ Evaluate a conjunctive query on an attributed C-set.   The query is a undirected wiring diagram whose boxes and ports are assumed to be named through attributes :name and :port_name/:outer_port_name. To define such a diagram, use the named form of the [@relation](@ref) macro. The query is a undirected wiring diagram (UWD) whose boxes and ports are assumed to be named through attributes :name and :port_name/:outer_port_name. To define such a diagram, use the named form of the [@relation](@ref) macro.   This function straightforwardly wraps the [oapply](@ref) method for multispans, which implements the UWD algebra of multispans. The result is a table, by default a TypedTable, whose columns correspond to the outer ports of the UWD. If the UWD has no outer ports, the query is a counting query and the result is a vector whose length is the number of results.   For its implementation, this function wraps the [oapply](@ref) method for multispans, which defines the UWD algebra of multispans. """ function query(X::AbstractACSet, diagram::UndirectedWiringDiagram,  params=NamedTuple(); table_type::Type=TypedTables.Table)  params=(;); table_type::Type=TypedTables.Table)  # For each box in the diagram, extract span from ACSet.  spans = map(boxes(diagram), subpart(diagram, :name)) do b, name  apex = FinSet(nparts(X, name)) @ -159,8 +163,12 @@ function query(X::AbstractACSet, diagram::UndirectedWiringDiagram,  # Call oapply and make a table out of the resulting span.  outer_names = subpart(diagram, :outer_port_name)  outer_span = oapply(diagram, spans, Ob=SetOb, Hom=FinDomFunction{Int})  table = NamedTuple{Tuple(outer_names)}(Tuple(map(collect, outer_span)))  make_table(table_type, table)  if isempty(outer_names)  fill((;), length(apex(outer_span)))  else  table = NamedTuple{Tuple(outer_names)}(Tuple(map(collect, outer_span)))  make_table(table_type, table)  end end   end

#### 6 test/wiring_diagrams/Algebras.jl View File

 @ -62,6 +62,10 @@ paths2 = @relation (start=start, stop=stop) begin  E(src=start, tgt=mid)  E(src=mid, tgt=stop) end count_paths2 = @relation (;) begin  E(src=start, tgt=mid)  E(src=mid, tgt=stop) end   # Graph underlying a commutative squares. square = Graph(4) @ -75,11 +79,13 @@ add_vertices!(squares2, 2) add_edges!(squares2, [2,4,5], [5,6,6]) result = query(squares2, paths2) @test tuples(columns(result)...) == [(1,4), (1,4), (1,5), (2,6), (2,6), (3,6)] @test length(query(squares2, count_paths2)) == 6   result = query(squares2, paths2, (start=1,)) @test tuples(columns(result)...) == [(1,4), (1,4), (1,5)] result = query(squares2, paths2, (start=1, stop=4)) @test result == Table((start=[1,1], stop=[4,4])) @test length(query(squares2, count_paths2, (start=1, stop=4))) == 2   cycles3 = @relation (edge1=e, edge2=f, edge3=g) where (e,f,g,u,v,w) begin  E(_id=e, src=u, tgt=v)