diff --git a/SUPPORTED-SRFIS b/SUPPORTED-SRFIS
index be26a638..62c7e802 100644
--- a/SUPPORTED-SRFIS
+++ b/SUPPORTED-SRFIS
@@ -137,6 +137,7 @@ implemented in latest version is available at https://stklos.net/srfi.html):
- SRFI-230: Atomic Operations
- SRFI-232: Flexible Curried Procedures
- SRFI-233: INI files
+ - SRFI-234: Topological Sorting
- SRFI-235: Combinators
- SRFI-236: Evaluating expressions in an unspecified order
- SRFI-238: Codesets
diff --git a/doc/HTML/stklos-ref.html b/doc/HTML/stklos-ref.html
index 03ad3d27..0377ee2d 100644
--- a/doc/HTML/stklos-ref.html
+++ b/doc/HTML/stklos-ref.html
@@ -26954,7 +26954,7 @@
13. SRFIs
13.1. Supported SRFIs
-
STklos supports 125 finalized SRFIS.
+
STklos supports 126 finalized SRFIS.
Some of these SRFIS are embedded and some are external.
@@ -27086,6 +27086,7 @@
13.1. Supported SRFIs
-
SRFI-230 —
Atomic Operations
-
SRFI-232 —
Flexible Curried Procedures
-
SRFI-233 —
INI files
+-
SRFI-234 —
Topological sorting
-
SRFI-235 —
Combinators
-
SRFI-236 —
Evaluating expressions in an unspecified order
-
SRFI-238 —
Codesets
@@ -27155,7 +27156,7 @@
13.2.2. External SRFIs
List of external SRFIs:
-srfi-1
srfi-2
srfi-4
srfi-5
srfi-7
srfi-9
srfi-13
srfi-14
srfi-17
srfi-19
srfi-25
srfi-26
srfi-27
srfi-29
srfi-35
srfi-36
srfi-37
srfi-41
srfi-43
srfi-48
srfi-51
srfi-54
srfi-59
srfi-60
srfi-61
srfi-64
srfi-66
srfi-69
srfi-74
srfi-89
srfi-94
srfi-95
srfi-96
srfi-100
srfi-113
srfi-115
srfi-116
srfi-117
srfi-125
srfi-127
srfi-128
srfi-129
srfi-130
srfi-132
srfi-133
srfi-134
srfi-135
srfi-137
srfi-141
srfi-144
srfi-151
srfi-152
srfi-154
srfi-156
srfi-158
srfi-160
srfi-161
srfi-162
srfi-170
srfi-171
srfi-173
srfi-174
srfi-175
srfi-178
srfi-180
srfi-185
srfi-189
srfi-190
srfi-196
srfi-207
srfi-214
srfi-215
srfi-216
srfi-217
srfi-221
srfi-222
srfi-223
srfi-224
srfi-227
srfi-228
srfi-229
srfi-230
srfi-232
srfi-233
srfi-235
srfi-236
srfi-238
+
srfi-1
srfi-2
srfi-4
srfi-5
srfi-7
srfi-9
srfi-13
srfi-14
srfi-17
srfi-19
srfi-25
srfi-26
srfi-27
srfi-29
srfi-35
srfi-36
srfi-37
srfi-41
srfi-43
srfi-48
srfi-51
srfi-54
srfi-59
srfi-60
srfi-61
srfi-64
srfi-66
srfi-69
srfi-74
srfi-89
srfi-94
srfi-95
srfi-96
srfi-100
srfi-113
srfi-115
srfi-116
srfi-117
srfi-125
srfi-127
srfi-128
srfi-129
srfi-130
srfi-132
srfi-133
srfi-134
srfi-135
srfi-137
srfi-141
srfi-144
srfi-151
srfi-152
srfi-154
srfi-156
srfi-158
srfi-160
srfi-161
srfi-162
srfi-170
srfi-171
srfi-173
srfi-174
srfi-175
srfi-178
srfi-180
srfi-185
srfi-189
srfi-190
srfi-196
srfi-207
srfi-214
srfi-215
srfi-216
srfi-217
srfi-221
srfi-222
srfi-223
srfi-224
srfi-227
srfi-228
srfi-229
srfi-230
srfi-232
srfi-233
srfi-234
srfi-235
srfi-236
srfi-238
@@ -27330,6 +27331,10 @@
13.2.3. SRFI features
srfi-233 |
+topological-sort |
+srfi-234 |
+
+
combinators |
srfi-235 |
diff --git a/lib/srfi/234.stk b/lib/srfi/234.stk
new file mode 100644
index 00000000..a364b27b
--- /dev/null
+++ b/lib/srfi/234.stk
@@ -0,0 +1,264 @@
+;;;;
+;;;; 234.stk -- Implementation of SRFI-234
+;;;;
+;;;; Copyright © 2020 Jeronimo Pellegrini -
+;;;;
+;;;;
+;;;; This program is free software; you can redistribute it and/or modify
+;;;; it under the terms of the GNU General Public License as published by
+;;;; the Free Software Foundation; either version 3 of the License, or
+;;;; (at your option) any later version.
+;;;;
+;;;; This program is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;;; GNU General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU General Public License
+;;;; along with this program; if not, write to the Free Software
+;;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+;;;; USA.
+;;;;
+;;;; This file is a derivative work from the implementation of
+;;;; this SRFI by Shiro Kawai, John Cowan, Arne Babenhauserheide,
+;;;; it is copyrighted as:
+;;;;
+;;;;;; © 2024 John Cowan, Shiro Kawai, Arthur A. Gleckler, Arne
+;;;;;; Babenhauserheide.
+;;;;;;
+;;;;;; Permission is hereby granted, free of charge, to any person
+;;;;;; obtaining a copy of this software and associated documentation
+;;;;;; files (the "Software"), to deal in the Software without
+;;;;;; restriction, including without limitation the rights to use,
+;;;;;; copy, modify, merge, publish, distribute, sublicense, and/or
+;;;;;; sell copies of the Software, and to permit persons to whom the
+;;;;;; Software is furnished to do so, subject to the following
+;;;;;; conditions:
+;;;;;;
+;;;;;; The above copyright notice and this permission notice
+;;;;;; (including the next paragraph) shall be included in all copies
+;;;;;; or substantial portions of the Software.
+;;;;;;
+;;;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;;;;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+;;;;;; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;;;;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+;;;;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+;;;;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;;;;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+;;;;;; OTHER DEALINGS IN THE SOFTWARE.
+;;;;
+;;;; Author: Jeronimo Pellegrini [j_p@aleph0.info]
+;;;; Creation date: 10-Oct-2024 17:12 (jpellegrini)
+;;;;
+
+(define-module srfi/234
+ (import
+ (scheme base)
+ (scheme case-lambda)
+ (srfi 1)
+ (srfi 11) ;; let-values
+ (srfi 26)) ;; cut
+ (export topological-sort
+ topological-sort/details
+ edgelist->graph
+ edgelist/inverted->graph
+ graph->edgelist
+ graph->edgelist/inverted
+ connected-components)
+
+(define topological-sort
+ (case-lambda
+ ((graph) (topological-sort-impl graph equal? #f))
+ ((graph eq) (topological-sort-impl graph eq #f))
+ ((graph eq nodes) (topological-sort-impl graph eq nodes))))
+
+(define topological-sort/details
+ (case-lambda
+ ((graph) (topological-sort-impl/details graph equal? #f))
+ ((graph eq) (topological-sort-impl/details graph eq #f))
+ ((graph eq nodes) (topological-sort-impl/details graph eq nodes))))
+
+(define (topological-sort-impl graph eq nodes)
+ (let-values (((v0 v1 v2)
+ (topological-sort-impl/details graph eq nodes)))
+ v0))
+
+(define (topological-sort-impl/details graph eq nodes)
+ (define table (map (lambda (n)
+ (cons (car n) 0))
+ graph))
+ (define queue '())
+ (define result '())
+
+ ;; set up - compute number of nodes that each node depends on.
+ (define (set-up)
+ (for-each
+ (lambda (node)
+ (for-each
+ (lambda (to)
+ (define p (assoc to table eq))
+ (if p
+ (set-cdr! p (+ 1 (cdr p)))
+ (set! table (cons
+ (cons to 1)
+ table))))
+ (cdr node)))
+ graph))
+
+ ;; traverse
+ (define (traverse)
+ (unless (null? queue)
+ (let ((n0 (assoc (car queue) graph eq)))
+ (set! queue (cdr queue))
+ (when n0
+ (for-each
+ (lambda (to)
+ (define p (assoc to table eq))
+ (when p
+ (let ((cnt (- (cdr p) 1)))
+ (when (= cnt 0)
+ (set! result (cons to result))
+ (set! queue (cons to queue)))
+ (set-cdr! p cnt))))
+ (cdr n0)))
+ (traverse))))
+
+ (set-up)
+ (set! queue
+ (apply append
+ (map
+ (lambda (p)
+ (if (= (cdr p) 0)
+ (list (car p))
+ '()))
+ table)))
+ (set! result queue)
+ (traverse)
+ (let ((rest (filter (lambda (e)
+ (not (zero? (cdr e))))
+ table)))
+ (if (null? rest)
+ (values
+ (if nodes
+ ;; replace indizes by node values
+ (let loop ((res '()) (result result))
+ (if (null? result)
+ res
+ (loop (cons (vector-ref nodes (car result)) res)
+ (cdr result))))
+ (reverse result))
+ #f #f)
+ (values #f "graph has circular dependency" (map car rest)))))
+
+;; Calculate the connected components from a graph of in-neighbors
+;; implements Kosaraju's algorithm: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
+(define (connected-components graph)
+ (define nodes-with-inbound-links (map car graph))
+ ;; graph of out-neighbors
+ (define graph/inverted (edgelist->graph (graph->edgelist/inverted graph)))
+ (define nodes-with-outbound-links (map car graph/inverted))
+ ;; for simplicity this uses a list of nodes to query for membership. This is expensive.
+ (define visited '())
+ (define vertex-list '())
+ ;; create vertex-list sorted with outbound elements first
+ (define (visit! node)
+ (cond ((member node visited) '())
+ (else
+ ;; mark as visited before traversing
+ (set! visited (cons node visited))
+ ;; this uses the graph: the outbound connections
+ (let ((node-in-graph (assoc node graph)))
+ (when node-in-graph
+ (for-each visit! (cdr node-in-graph))))
+ ;; add to list after traversing
+ (set! vertex-list (cons node vertex-list)))))
+ ;; for simplicity this uses a list of nodes to query for membership. This is expensive.
+ (define in-component '())
+ (define components '())
+ ;; assign nodes to their components
+ (define (assign! u root)
+ (unless (member u in-component)
+ (set! in-component (cons u in-component))
+ (set! components (cons (cons u (car components)) (cdr components)))
+ ;; this uses the graph/inverted: the inbound connections
+ (let ((node-in-graph (assoc u graph/inverted)))
+ (when node-in-graph
+ (for-each (cut assign! <> root) (cdr node-in-graph))))))
+ (define (assign-as-component! u)
+ (unless (member u in-component)
+ (set! components (cons '() components))
+ (assign! u u)))
+ (for-each visit! nodes-with-outbound-links)
+ (for-each assign-as-component! vertex-list)
+ components)
+
+;; convert an edgelist '((a b) (a c) (b e)) to a graph '((a b c) (b e))
+(define edgelist->graph
+ (case-lambda
+ ((edgelist) (edgelist->graph-impl edgelist assoc))
+ ((edgelist asc) (edgelist->graph-impl edgelist asc))))
+(define (edgelist->graph-impl edgelist asc)
+ (let loop ((graph '()) (edges edgelist))
+ (cond
+ ((null? edges) (reverse! graph))
+ ((asc (car (car edges)) graph)
+ (let* ((edge (car edges))
+ (left (car edge))
+ (graph-entry (asc left graph))
+ (right (car (cdr edge))))
+ ;; adjust the right-most cdr
+ (let lp ((entry graph-entry))
+ (if (null? (cdr entry))
+ (set-cdr! entry (list right))
+ (lp (cdr entry))))
+ (loop graph (cdr edges))))
+ ;; use apply list to break up immutable pairs
+ (else (loop (cons (apply list (car edges)) graph) (cdr edges))))))
+
+;; convert an inverted edgelist '((b a) (c a) (e b)) to a graph '((a b c) (b e))
+(define edgelist/inverted->graph
+ (case-lambda
+ ((edgelist) (edgelist/inverted->graph-impl edgelist assoc))
+ ((edgelist asc) (edgelist/inverted->graph-impl edgelist asc))))
+(define (edgelist/inverted->graph-impl edgelist asc)
+ (let loop ((graph '()) (edges edgelist))
+ (cond
+ ((null? edges) (reverse! graph))
+ ((asc (car (cdr (car edges))) graph)
+ (let* ((edge (car edges))
+ (left (car (cdr edge)))
+ (graph-entry (asc left graph))
+ (right (car edge)))
+ ;; adjust the right-most cdr
+ (let lp ((entry graph-entry))
+ (if (null? (cdr entry))
+ (set-cdr! entry (list right))
+ (lp (cdr entry))))
+ (loop graph (cdr edges))))
+ ;; reverse instead of reverse! to avoid immutable lists
+ (else (loop (cons (reverse (car edges)) graph) (cdr edges))))))
+
+(define (graph->edgelist graph)
+ (graph->edgelist/base graph (lambda (top) (list (car top) (car (cdr top))))))
+
+(define (graph->edgelist/inverted graph)
+ (graph->edgelist/base graph (lambda (top) (list (car (cdr top)) (car top)))))
+
+(define (graph->edgelist/base graph top-to-edge-fun)
+ (let loop ((edgelist '()) (graph graph))
+ (cond ((null? graph)
+ (reverse! edgelist))
+ ((null? (car graph))
+ (loop edgelist (cdr graph)))
+ ((null? (cdr (car graph)))
+ (loop edgelist (cdr graph)))
+ (else
+ (let* ((top (car graph))
+ (edge (top-to-edge-fun top))
+ (rest (cdr (cdr top))))
+ (loop (cons edge edgelist)
+ (cons (cons (car top) rest) (cdr graph))))))))
+)
+
+(provide "srfi/234")
diff --git a/lib/srfi/Makefile.am b/lib/srfi/Makefile.am
index 3074353a..cbc49e77 100644
--- a/lib/srfi/Makefile.am
+++ b/lib/srfi/Makefile.am
@@ -143,6 +143,7 @@ SRC_STK = 1.stk \
230.stk \
232.stk \
233.stk \
+ 234.stk \
235.stk \
236.stk \
244.stk
@@ -257,6 +258,7 @@ SRC_OSTK = 1.ostk \
230.ostk \
232.ostk \
233.ostk \
+ 234.ostk \
235.ostk \
236.ostk \
244.ostk
@@ -337,6 +339,7 @@ SUFFIXES = .stk .ostk .stk -incl.c .$(SO) .c
217.ostk: ../stklos/itrie.$(SO)
221.ostk: 41.ostk 158.ostk
224.ostk: ../scheme/comparator.ostk
+234.ostk: 1.ostk 11.ostk 26.ostk
235.ostk: 1.ostk
diff --git a/lib/srfi/Makefile.in b/lib/srfi/Makefile.in
index c6524a4e..ced2e1af 100644
--- a/lib/srfi/Makefile.in
+++ b/lib/srfi/Makefile.in
@@ -510,6 +510,7 @@ SRC_STK = 1.stk \
230.stk \
232.stk \
233.stk \
+ 234.stk \
235.stk \
236.stk \
244.stk
@@ -624,6 +625,7 @@ SRC_OSTK = 1.ostk \
230.ostk \
232.ostk \
233.ostk \
+ 234.ostk \
235.ostk \
236.ostk \
244.ostk
@@ -1057,6 +1059,7 @@ STKLOS_BINARY ?= ../../src/stklos
217.ostk: ../stklos/itrie.$(SO)
221.ostk: 41.ostk 158.ostk
224.ostk: ../scheme/comparator.ostk
+234.ostk: 1.ostk 11.ostk 26.ostk
235.ostk: 1.ostk
25.$(SO): 25-incl.c 25.c
diff --git a/lib/srfis.stk b/lib/srfis.stk
index c4643df5..d9981a84 100644
--- a/lib/srfis.stk
+++ b/lib/srfis.stk
@@ -272,7 +272,7 @@
;; 231 Intervals and Generalized Arrays (Updated^2)
(232 "Flexible Curried Procedures" () "srfi-232")
(233 "INI files" (ini-files) "srfi-233")
- ;; 234 Topological sorting (draft)
+ (234 "Topological sorting" (topological-sort) "srfi-234")
(235 "Combinators" (combinators) "srfi-235")
(236 "Evaluating expressions in an unspecified order" () "srfi-236")
;; 237 R6RS Records (refined)
diff --git a/src/boot.c b/src/boot.c
index 1b3b63bc..da0b6646 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -2186,7 +2186,7 @@ char* STk_boot_consts = "#("
"(lambda (bindings . body) `(%let-syntax ,(map (lambda (x) (let ((macro-name (car x)) (syn-rules (cadr x))) (let ((alt-ellipsis? (not (list? (cadr syn-rules))))) (let ((ellipsis (if alt-ellipsis? (cadr syn-rules) '...)) (keywords (if alt-ellipsis? (cons macro-name (caddr syn-rules)) (cons macro-name (cadr syn-rules)))) (clauses (if alt-ellipsis? (cdddr syn-rules) (cddr syn-rules)))) `(,macro-name (lambda args (%find-macro-clause ',macro-name args ',keywords ',clauses ',ellipsis))))))) bindings) ,@body))" " "
"((SCHEME))" " "
"((srfi0-register-feature! . srfi0-register-feature!) (srfi-0-feature-implementation-file . srfi-0-feature-implementation-file) (require-feature . require-feature) (cond-expand . cond-expand) (%srfi-0-expand . %srfi-0-expand))" " "
-"(srfi-0 (srfi-1 . \"srfi-1\") (lists . \"srfi-1\") (srfi-2 . \"srfi-2\") (and-let* . \"srfi-2\") (srfi-4 . \"srfi-4\") (hvectors . \"srfi-4\") (srfi-5 . \"srfi-5\") srfi-6 (srfi-7 . \"srfi-7\") (program . \"srfi-7\") srfi-8 (srfi-9 . \"srfi-9\") (records . \"srfi-9\") srfi-10 srfi-11 (srfi-13 . \"srfi-13\") (srfi-14 . \"srfi-14\") srfi-15 srfi-16 case-lambda (srfi-17 . \"srfi-17\") srfi-18 (srfi-19 . \"srfi-19\") srfi-22 srfi-23 error (srfi-25 . \"srfi-25\") (srfi-26 . \"srfi-26\") (srfi-27 . \"srfi-27\") (random . \"srfi-27\") srfi-28 (srfi-29 . \"srfi-29\") srfi-30 srfi-31 srfi-34 (srfi-35 . \"srfi-35\") (srfi-36 . \"srfi-36\") (srfi-37 . \"srfi-37\") (args-fold . \"srfi-37\") srfi-38 srfi-39 parameters (srfi-41 . \"srfi-41\") (streams . \"srfi-41\") (srfi-43 . \"srfi-43\") srfi-45 srfi-46 (srfi-48 . \"srfi-48\") (srfi-51 . \"srfi-51\") (rest-list . \"srfi-51\") (srfi-54 . \"srfi-54\") (formatting . \"srfi-54\") srfi-55 (srfi-59 . \"srfi-59\") (srfi-60 . \"srfi-60\") (srfi-61 . \"srfi-61\") srfi-62 (srfi-64 . \"srfi-64\") (testing . \"srfi-64\") (srfi-66 . \"srfi-66\") (srfi-69 . \"srfi-69\") (hash-tables . \"srfi-69\") srfi-70 (srfi-74 . \"srfi-74\") srfi-87 srfi-88 (srfi-89 . \"srfi-89\") (srfi-94 . \"srfi-94\") (srfi-95 . \"srfi-95\") (srfi-96 . \"srfi-96\") srfi-98 (srfi-100 . \"srfi-100\") srfi-111 boxes srfi-112 (srfi-113 . \"srfi-113\") (sets-bags . \"srfi-113\") (srfi-115 . \"srfi-115\") (srfi-116 . \"srfi-116\") (immutable-lists . \"srfi-116\") (srfi-117 . \"srfi-117\") (queues-as-lists . \"srfi-117\") srfi-118 adjustable-strings (srfi-125 . \"srfi-125\") (hash-table . \"srfi-125\") (srfi-127 . \"srfi-127\") (lazy-sequences . \"srfi-127\") (srfi-128 . \"srfi-128\") (comparators-reduced . \"srfi-128\") (srfi-129 . \"srfi-129\") (titlecase . \"srfi-129\") (srfi-130 . \"srfi-130\") (srfi-132 . \"srfi-132\") (sort . \"srfi-132\") (srfi-133 . \"srfi-133\") (vector . \"srfi-133\") (srfi-134 . \"srfi-134\") (immutable-deques . \"srfi-134\") (srfi-135 . \"srfi-135\") (immutable-texts . \"srfi-135\") (srfi-137 . \"srfi-137\") srfi-138 (srfi-141 . \"srfi-141\") (integer-division . \"srfi-141\") srfi-143 (srfi-144 . \"srfi-144\") srfi-145 (srfi-151 . \"srfi-151\") (bitwise-ops . \"srfi-151\") (srfi-152 . \"srfi-152\") (srfi-154 . \"srfi-154\") (srfi-156 . \"srfi-156\") (srfi-158 . \"srfi-158\") (srfi-160 . \"srfi-160\") (srfi-161 . \"srfi-161\") (srfi-162 . \"srfi-128\") srfi-169 (srfi-170 . \"srfi-170\") (posix . \"srfi-170\") (srfi-171 . \"srfi-171\") (transducers . \"srfi-171\") (srfi-173 . \"srfi-173\") (hooks . \"srfi-173\") (srfi-174 . \"srfi-174\") (posix-timespecs . \"srfi-174\") (srfi-175 . \"srfi-175\") (ascii . \"srfi-175\") srfi-176 (srfi-178 . \"srfi-178\") (srfi-180 . \"srfi-180\") (JSON . \"srfi-180\") (json . \"srfi-180\") (srfi-185 . \"srfi-185\") (srfi-189 . \"srfi-189\") (maybe-either . \"srfi-189\") (srfi-190 . \"srfi-190\") srfi-192 srfi-193 srfi-195 (srfi-196 . \"srfi-196\") (srfi-207 . \"srfi-207\") srfi-208 (srfi-214 . \"srfi-214\") (srfi-215 . \"srfi-215\") (srfi-216 . \"srfi-216\") (srfi-217 . \"srfi-217\") srfi-219 (srfi-221 . \"srfi-221\") (srfi-222 . \"srfi-222\") (srfi-223 . \"srfi-223\") (srfi-224 . \"srfi-224\") (srfi-227 . \"srfi-227\") (srfi-228 . \"srfi-228\") (srfi-229 . \"srfi-229\") (srfi-230 . \"srfi-230\") (srfi-232 . \"srfi-232\") (srfi-233 . \"srfi-233\") (ini-files . \"srfi-233\") (srfi-235 . \"srfi-235\") (combinators . \"srfi-235\") (srfi-236 . \"srfi-236\") (srfi-238 . \"srfi-238\") srfi-244 (conditions \"srfi-35\" \"srfi-36\") (generators \"srfi-158\" \"srfi-190\"))" " "
+"(srfi-0 (srfi-1 . \"srfi-1\") (lists . \"srfi-1\") (srfi-2 . \"srfi-2\") (and-let* . \"srfi-2\") (srfi-4 . \"srfi-4\") (hvectors . \"srfi-4\") (srfi-5 . \"srfi-5\") srfi-6 (srfi-7 . \"srfi-7\") (program . \"srfi-7\") srfi-8 (srfi-9 . \"srfi-9\") (records . \"srfi-9\") srfi-10 srfi-11 (srfi-13 . \"srfi-13\") (srfi-14 . \"srfi-14\") srfi-15 srfi-16 case-lambda (srfi-17 . \"srfi-17\") srfi-18 (srfi-19 . \"srfi-19\") srfi-22 srfi-23 error (srfi-25 . \"srfi-25\") (srfi-26 . \"srfi-26\") (srfi-27 . \"srfi-27\") (random . \"srfi-27\") srfi-28 (srfi-29 . \"srfi-29\") srfi-30 srfi-31 srfi-34 (srfi-35 . \"srfi-35\") (srfi-36 . \"srfi-36\") (srfi-37 . \"srfi-37\") (args-fold . \"srfi-37\") srfi-38 srfi-39 parameters (srfi-41 . \"srfi-41\") (streams . \"srfi-41\") (srfi-43 . \"srfi-43\") srfi-45 srfi-46 (srfi-48 . \"srfi-48\") (srfi-51 . \"srfi-51\") (rest-list . \"srfi-51\") (srfi-54 . \"srfi-54\") (formatting . \"srfi-54\") srfi-55 (srfi-59 . \"srfi-59\") (srfi-60 . \"srfi-60\") (srfi-61 . \"srfi-61\") srfi-62 (srfi-64 . \"srfi-64\") (testing . \"srfi-64\") (srfi-66 . \"srfi-66\") (srfi-69 . \"srfi-69\") (hash-tables . \"srfi-69\") srfi-70 (srfi-74 . \"srfi-74\") srfi-87 srfi-88 (srfi-89 . \"srfi-89\") (srfi-94 . \"srfi-94\") (srfi-95 . \"srfi-95\") (srfi-96 . \"srfi-96\") srfi-98 (srfi-100 . \"srfi-100\") srfi-111 boxes srfi-112 (srfi-113 . \"srfi-113\") (sets-bags . \"srfi-113\") (srfi-115 . \"srfi-115\") (srfi-116 . \"srfi-116\") (immutable-lists . \"srfi-116\") (srfi-117 . \"srfi-117\") (queues-as-lists . \"srfi-117\") srfi-118 adjustable-strings (srfi-125 . \"srfi-125\") (hash-table . \"srfi-125\") (srfi-127 . \"srfi-127\") (lazy-sequences . \"srfi-127\") (srfi-128 . \"srfi-128\") (comparators-reduced . \"srfi-128\") (srfi-129 . \"srfi-129\") (titlecase . \"srfi-129\") (srfi-130 . \"srfi-130\") (srfi-132 . \"srfi-132\") (sort . \"srfi-132\") (srfi-133 . \"srfi-133\") (vector . \"srfi-133\") (srfi-134 . \"srfi-134\") (immutable-deques . \"srfi-134\") (srfi-135 . \"srfi-135\") (immutable-texts . \"srfi-135\") (srfi-137 . \"srfi-137\") srfi-138 (srfi-141 . \"srfi-141\") (integer-division . \"srfi-141\") srfi-143 (srfi-144 . \"srfi-144\") srfi-145 (srfi-151 . \"srfi-151\") (bitwise-ops . \"srfi-151\") (srfi-152 . \"srfi-152\") (srfi-154 . \"srfi-154\") (srfi-156 . \"srfi-156\") (srfi-158 . \"srfi-158\") (srfi-160 . \"srfi-160\") (srfi-161 . \"srfi-161\") (srfi-162 . \"srfi-128\") srfi-169 (srfi-170 . \"srfi-170\") (posix . \"srfi-170\") (srfi-171 . \"srfi-171\") (transducers . \"srfi-171\") (srfi-173 . \"srfi-173\") (hooks . \"srfi-173\") (srfi-174 . \"srfi-174\") (posix-timespecs . \"srfi-174\") (srfi-175 . \"srfi-175\") (ascii . \"srfi-175\") srfi-176 (srfi-178 . \"srfi-178\") (srfi-180 . \"srfi-180\") (JSON . \"srfi-180\") (json . \"srfi-180\") (srfi-185 . \"srfi-185\") (srfi-189 . \"srfi-189\") (maybe-either . \"srfi-189\") (srfi-190 . \"srfi-190\") srfi-192 srfi-193 srfi-195 (srfi-196 . \"srfi-196\") (srfi-207 . \"srfi-207\") srfi-208 (srfi-214 . \"srfi-214\") (srfi-215 . \"srfi-215\") (srfi-216 . \"srfi-216\") (srfi-217 . \"srfi-217\") srfi-219 (srfi-221 . \"srfi-221\") (srfi-222 . \"srfi-222\") (srfi-223 . \"srfi-223\") (srfi-224 . \"srfi-224\") (srfi-227 . \"srfi-227\") (srfi-228 . \"srfi-228\") (srfi-229 . \"srfi-229\") (srfi-230 . \"srfi-230\") (srfi-232 . \"srfi-232\") (srfi-233 . \"srfi-233\") (ini-files . \"srfi-233\") (srfi-234 . \"srfi-234\") (topological-sort . \"srfi-234\") (srfi-235 . \"srfi-235\") (combinators . \"srfi-235\") (srfi-236 . \"srfi-236\") (srfi-238 . \"srfi-238\") srfi-244 (conditions \"srfi-35\" \"srfi-36\") (generators \"srfi-158\" \"srfi-190\"))" " "
"%srfi-feature-list" " "
"\"STklos-\"" " "
"\"id-\"" " "
diff --git a/tests/srfis/234.stk b/tests/srfis/234.stk
new file mode 100644
index 00000000..644d3d5b
--- /dev/null
+++ b/tests/srfis/234.stk
@@ -0,0 +1,117 @@
+
+(test "srfi-234.1"
+ '(a b d c)
+ (topological-sort '((a b c)
+ (b d)
+ (c)
+ (d c))))
+
+;; details: multiple values
+(test "srfi-234.2"
+ '((a b d c) #f #f)
+ (let-values
+ (((v0 v1 v2)
+ (topological-sort/details '((a b c)
+ (b d)
+ (c)
+ (d c)))))
+ (list v0 v1 v2)))
+
+;; cycle
+(test "srfi-234.3"
+ #f
+ (topological-sort '((a b)
+ (b a))))
+
+;; cycle error details
+(test "srfi-234.4"
+ '(#f "graph has circular dependency" (a b))
+ (let-values
+ (((v0 v1 v2)
+ (topological-sort/details '((a b)
+ (b a)))))
+ (list v0 v1 v2)))
+
+(test "srfi-234.5"
+ '("a" "b" "d" "c")
+ (topological-sort '(("a" "b" "c")
+ ("b" "d")
+ ("c")
+ ("d" "c"))
+ string=?))
+
+(test "srfi-234.6"
+ '((a b c) (b e))
+ (edgelist->graph '((a b) (a c) (b e))))
+
+(test "srfi-234.7"
+ '((a b) (a c) (b e))
+ (graph->edgelist '((a b c) (b e))))
+
+(test "srfi-234.8"
+ '((a b c) (b e))
+ (edgelist/inverted->graph '((b a) (c a) (e b))))
+
+(test "srfi-234.9"
+ '((b a) (c a) (e b))
+ (graph->edgelist/inverted '((a b c) (b e))))
+
+(test "srfi-234.10"
+ '((0 1) (1 2) (2 0) (3 1 2 4) (4 3 5) (5 2 6) (6 5) (7 4 6 7))
+ (edgelist->graph '((0 1)
+ (1 2)
+ (2 0)
+ (3 1) (3 2) (3 4)
+ (4 3) (4 5)
+ (5 2) (5 6)
+ (6 5)
+ (7 4) (7 6) (7 7))))
+
+(test "srfi-234.11"
+ '((1 0 3) (2 1 3 5) (0 2) (4 3 7) (3 4) (5 4 6) (6 5 7) (7 7))
+ (edgelist/inverted->graph '((0 1)
+ (1 2)
+ (2 0)
+ (3 1) (3 2) (3 4)
+ (4 3) (4 5)
+ (5 2) (5 6)
+ (6 5)
+ (7 4) (7 6) (7 7))))
+
+(test "srfi-234.12"
+ '((2 0 1) (6 5) (3 4) (7))
+ (connected-components
+ (edgelist->graph '((0 1)
+ (1 2)
+ (2 0)
+ (3 1) (3 2) (3 4)
+ (4 3) (4 5)
+ (5 2) (5 6)
+ (6 5)
+ (7 4) (7 6) (7 7)))))
+
+(define (permutations edgelist)
+ (if (null? edgelist) '(())
+ (apply append
+ (map (lambda (edge)
+ (map (lambda (permutation)
+ (cons edge permutation))
+ (permutations (delete edge edgelist))))
+ edgelist))))
+
+(test "srfi-234.13"
+ #t
+ (every (lambda (edgelist)
+ (let* ((graph (edgelist->graph edgelist))
+ (order (topological-sort graph equal?)))
+ (cond
+ ((equal? order '(top left right bottom)) #t)
+ ((equal? order '(top right left bottom)) #t)
+ (else order))))
+ (permutations '((top left) (top right) (left bottom) (right bottom)))))
+
+(test "srfi-234.14"
+ '(libnewsboat regex-rs strprintf)
+ (topological-sort (edgelist->graph '((libnewsboat strprintf)
+ (libnewsboat regex-rs)
+ (regex-rs strprintf)))))