fdoc

subroutinedescribe_graphprivate

subroutine describe_graph(p, s, relation, job, w, g, found)

Put the graph of job in g. found is false if it would have only one node or no edges. Nodes go in as they are reached, and edges after them.

Arguments

NameTypeIntentAttributesDescription
ptype(project_t)in

the project

stype(settings_t)in

the settings

relationtype(adjacency_t)in

the relation

jobtype(graph_job_t)in

the graph

wtype(walk_t)inout

the working space

gtype(layout_t)out

the description

foundlogicalout

whether there is a graph

Calls

Source

Show the code
subroutine describe_graph(p, s, relation, job, w, g, found)
    type(project_t), intent(in) :: p        !! the project
    type(settings_t), intent(in) :: s       !! the settings
    type(adjacency_t), intent(in) :: relation   !! the relation
    type(graph_job_t), intent(in) :: job    !! the graph
    type(walk_t), intent(inout) :: w        !! the working space
    type(layout_t), intent(out) :: g        !! the description
    logical, intent(out) :: found           !! whether there is a graph
    integer, allocatable :: next(:)
    integer :: head, k, id, other, j, reached, edges

    w%stamp = w%stamp + 1
    reached = size(job%roots)
    do k = 1, reached
        w%marked(job%roots(k)) = w%stamp
        w%queue(k) = job%roots(k)
        w%levels(k) = 0
    end do
    head = 1
    edges = 0
    do while (head <= reached)
        id = w%queue(head)
        if (w%levels(head) < job%max_depth) then
            if (job%forward) then
                if (allocated(relation%out(id)%ids)) then
                    next = relation%out(id)%ids
                else
                    allocate (next(0))
                end if
            else
                if (allocated(relation%in(id)%ids)) then
                    next = relation%in(id)%ids
                else
                    allocate (next(0))
                end if
            end if
            do j = 1, size(next)
                other = next(j)
                if (p%list%box(other)%e%kind == E_NONE) cycle
                if (w%marked(other) /= w%stamp) then
                    if (reached >= job%max_nodes) cycle
                    w%marked(other) = w%stamp
                    reached = reached + 1
                    w%queue(reached) = other
                    w%levels(reached) = w%levels(head) + 1
                end if
                edges = edges + 1
                if (edges > size(w%from)) call grow_edges(w)
                w%from(edges) = merge(id, other, job%forward)
                w%to(edges) = merge(other, id, job%forward)
            end do
            deallocate (next)
        end if
        head = head + 1
    end do
    found = reached > 1 .and. edges > 0
    if (.not. found) return
    call g%initialize(direction=job%direction, concentrate=.true.)
    do k = 1, reached
        call add_node(p, w%queue(k), k == 1 .and. size(job%roots) == 1, g, w%places(w%queue(k)))
    end do
    do k = 1, edges
        call add_edge(s, relation, w%from(k), w%to(k), w%places, g)
    end do
end subroutine describe_graph

Graphs

Calls

Called by