1414
1515 implicit none
1616
17- type vertex_status_t
18- logical :: marked= .false. , checking= .false.
19- end type
20-
2117contains
2218
2319 module procedure construct_from_components
2420 dag% vertices = vertices
25- dag% order = toposort (dag)
21+ dag% order = topological_sort (dag)
2622 call assert(dag% is_sorted_and_acyclic(), " construct_from_components: dag%is_sorted_and_acyclic()" )
2723 end procedure
2824
29- module function toposort (dag ) result(order)
25+ pure module function topological_sort (dag) result(order)
3026 ! ! Provide array of vertex numbers ordered in a way that respects dependencies
3127 type (dag_t), intent (in ) :: dag
3228 integer , allocatable :: order(:), searched(:)
3329 integer v
3430
35- call assert(all ([(allocated (dag% vertices(v)% edges), v= 1 , size (dag% vertices))]), &
36- " dag_s toposort: (all([(allocated(dag%vertices(v)%edges), v=1, size(dag%vertices))])" )
31+ call assert(all (dag% vertices(:)% edges_allocated()), " dag_s topological_sort: all(dag%vertices(:)%edges_allocated())" )
3732
3833 block
3934 integer , allocatable :: discovered(:)
@@ -51,7 +46,7 @@ module function toposort(dag) result(order)
5146
5247 contains
5348
54- recursive subroutine depth_first_search (v , d , s , o )
49+ pure recursive subroutine depth_first_search(v, d, s, o)
5550 integer , intent (in ) :: v, d(:)
5651 integer , intent (out ), allocatable :: s(:)
5752 integer , intent (inout ), allocatable :: o(:)
@@ -80,7 +75,7 @@ recursive subroutine depth_first_search(v, d, s, o)
8075
8176 end subroutine
8277
83- end function toposort
78+ end function topological_sort
8479
8580 module procedure is_sorted_and_acyclic
8681
@@ -97,7 +92,7 @@ end function toposort
9792 integer i, j
9893
9994 do i = 1 , num_vertices
100- associate(edges = > self% vertices(self% order(i))% get_edges ())
95+ associate(edges = > self% vertices(self% order(i))% edges ())
10196 do j = 1 , size (edges)
10297 if (.not. any (edges(j) == self% order(1 :i))) then
10398 is_sorted_and_acyclic = .false.
@@ -116,11 +111,11 @@ end function toposort
116111
117112 module procedure construct_from_json
118113 type (fallible_json_value_t) :: maybe_vertices
114+ type (error_list_t) errors
119115
120116 maybe_vertices = json_object% get_element(" vertices" )
121- associate(errors = > maybe_vertices% errors())
122- call assert(.not. errors% has_any(), " dag_s construct_from_json: .not. errors%has_any()" , char (errors% to_string()))
123- end associate
117+ errors = maybe_vertices% errors()
118+ call assert(.not. errors% has_any(), " dag_s construct_from_json: .not. errors%has_any()" , char (errors% to_string()))
124119
125120 select type (vertices = > maybe_vertices% value_())
126121 type is (json_array_t)
@@ -129,34 +124,32 @@ end function toposort
129124 class default
130125 call assert(.false. , " dag%from_json: vertices was not an array" , char (vertices% to_compact_string()))
131126 end select
132- dag% order = toposort (dag)
127+ dag% order = topological_sort (dag)
133128 end procedure
134129
135130 module procedure to_json
136131 type (fallible_json_string_t) maybe_key
137132 type (error_list_t) errors
133+ type (json_string_t) vertices_key
134+ type (json_array_t) vertices_value
138135
139136 maybe_key = fallible_json_string_t(" vertices" )
140137 errors = maybe_key% errors()
141138 call assert(.not. errors% has_any(), " dag%to_json: .not. errors%has_any()" , char (errors% to_string()))
142139
143- block
144- type (json_array_t) vertices_value
145140
146- vertices_value = json_array_t(json_element_t(self% vertices% to_json()))
141+ vertices_value = json_array_t(json_element_t(self% vertices% to_json()))
147142
148- associate(vertices_key = > maybe_key% string ())
149- json_object = json_object_t([vertices_key], [json_element_t(vertices_value)])
150- end associate
151- end block
143+ vertices_key = maybe_key% string ()
144+ json_object = json_object_t([vertices_key], [json_element_t(vertices_value)])
152145 end procedure
153146
154147 module procedure num_vertices
155148 num_vertices = size (self% vertices)
156149 end procedure
157150
158151 module procedure dependencies_for
159- dependency_ids = self% vertices(vertex_id)% get_edges ()
152+ dependency_ids = self% vertices(vertex_id)% edges ()
160153 end procedure
161154
162155 module procedure depends_on
@@ -169,7 +162,7 @@ end function toposort
169162 integer v
170163
171164 do v = 1 , size (self% vertices)
172- if (any (self% vertices(v)% edges == vertex_num)) dependencies = [dependencies, v]
165+ if (any (self% vertices(v)% edges() == vertex_num)) dependencies = [dependencies, v]
173166 end do
174167 end block
175168
@@ -193,6 +186,20 @@ end function toposort
193186 close (iunit,iostat= istat)
194187 contains
195188
189+ elemental function integer_to_string (i ) result(s)
190+ integer ,intent (in ) :: i
191+ integer , parameter :: max_number_width = 64
192+ character (len= max_number_width) :: s
193+ integer :: istat
194+
195+ write (s,fmt= ' (ss,I0)' ,iostat= istat) i
196+ if (istat== 0 ) then
197+ s = trim (adjustl (s))
198+ else
199+ s = ' ***'
200+ end if
201+ end function integer_to_string
202+
196203 function generate_digraph (self ,rankdir ,dpi ) result(str)
197204 ! ! - Result is the string to write out to a *.dot file. (Called by save_digraph())
198205 implicit none
@@ -210,6 +217,9 @@ function generate_digraph(self,rankdir,dpi) result(str)
210217 character (len=* ),parameter :: tab = ' '
211218 character (len=* ),parameter :: newline = new_line(' ' )
212219
220+
221+ call assert(all (self% vertices(:)% edges_allocated()), " generate_digraph: self%edges_allocated()" )
222+
213223 str = ' digraph G {' // newline// newline
214224 if (present (rankdir)) &
215225 str = str// tab// ' rankdir=' // rankdir// newline// newline
@@ -218,24 +228,24 @@ function generate_digraph(self,rankdir,dpi) result(str)
218228
219229 ! define the vertices:
220230 do i= 1 ,size (self% vertices)
221- label = ' label="' // trim (adjustl (self% vertices(i)% get_label ()))// ' "'
222- attributes = ' [' // trim (adjustl (self% vertices(i)% get_attributes ()))// ' ,' // label// ' ]'
231+ label = ' label="' // trim (adjustl (self% vertices(i)% label ()))// ' "'
232+ attributes = ' [' // trim (adjustl (self% vertices(i)% attributes ()))// ' ,' // label// ' ]'
223233 str = str// tab// integer_to_string(i)// ' ' // attributes// newline
224234 if (i== size (self% vertices)) str = str// newline
225235 end do
226236
227237 ! define the dependencies:
228238 do i= 1 ,size (self% vertices)
229- if ( allocated ( self% vertices(i)% edges)) then
230- n_edges = size (self % vertices(i) % edges )
231- str = str // tab // integer_to_string(i) // merge ( ' -> ' , ' ' , n_edges/= 0 )
232- do j = 1 ,n_edges
233- ! comma-separated list:
234- str = str// integer_to_string(self % vertices(i) % edges(j))
235- if (n_edges> 1 .and. j< n_edges) str = str// ' ,'
236- end do
237- str = str // ' ; ' // newline
238- end if
239+ n_edges = size ( self% vertices(i)% edges())
240+ str = str // tab // integer_to_string(i) // merge ( ' -> ' , ' ' ,n_edges /= 0 )
241+ do j = 1 , n_edges
242+ ! comma-separated list:
243+ associate(edges = > self % vertices(i) % edges())
244+ str = str// integer_to_string(edges(j))
245+ if (n_edges> 1 .and. j< n_edges) str = str// ' ,'
246+ end associate
247+ end do
248+ str = str // ' ; ' // newline
239249 end do
240250
241251 str = str// newline// ' }'
@@ -244,23 +254,6 @@ end function generate_digraph
244254
245255 end procedure
246256
247- elemental function integer_to_string (i ) result(s)
248-
249- integer ,intent (in ) :: i
250- integer , parameter :: max_number_width = 64
251- character (len= max_number_width) :: s
252-
253- integer :: istat
254-
255- write (s,fmt= ' (ss,I0)' ,iostat= istat) i
256- if (istat== 0 ) then
257- s = trim (adjustl (s))
258- else
259- s = ' ***'
260- end if
261-
262- end function integer_to_string
263-
264257 module procedure read_formatted
265258
266259 character (len=* ), parameter :: NEWLINE = NEW_LINE(' A' )
0 commit comments