simple-tree.scm 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. (define-module (simple-tree)
  2. #:export (make-node
  3. node?
  4. node-key
  5. node-val
  6. node-children
  7. get-node-by-path
  8. leaf?
  9. inner-node?
  10. list->tree))
  11. (use-modules (srfi srfi-9) ; structs
  12. (srfi srfi-9 gnu)) ; for functional structs (not part of srfi-9 directly)
  13. (define-immutable-record-type <node>
  14. ;; define constructor
  15. (make-node key val children)
  16. ;; define predicate
  17. node?
  18. ;; define accessors and functional setters
  19. (key node-key set-node-key)
  20. (val node-val set-node-val)
  21. (children node-children set-node-children))
  22. (define* (get-node-by-path node path #:optional (default #f) #:key (use-longest-prefix #f))
  23. "Returns the node from the tree of nodes given as NODE for which the
  24. sequence of node keys from the root to that node is the list given as
  25. PATH. If a DEFAULT is given, that DEFAULT is returned, whenever there
  26. is no node with the given PATH. If the keyword argument
  27. USE-LONGEST-PREFIX is provided, the function will return the node,
  28. which was the last node while traversing the tree, before the PATH
  29. diverged from the node keys in the tree."
  30. (define* (get-child-by-key children key #:optional (default #f))
  31. (cond [(null? children) (make-node 'result default '())]
  32. [(equal? (node-key (car children)) key)
  33. (car children)]
  34. [else (get-child-by-key (cdr children) key)]))
  35. #;(display (simple-format #f "current node:~s\n" node))
  36. #;(display (simple-format #f "current path:~s\n" path))
  37. (define* (search-tree node path #:optional (default #f) #:key (use-longest-prefix #f))
  38. (cond [(null? path) node]
  39. [(equal? (car path) (node-key node))
  40. #;(display (simple-format #f "part of path is equal to node key\n"))
  41. (cond
  42. ;; if there are no more path segments we arrived at the
  43. ;; target node
  44. [(null? (cdr path)) node]
  45. ;; if there are no more children but still some path
  46. ;; elements
  47. [(null? (node-children node))
  48. #;(display (simple-format #f "no children!\n"))
  49. #;(display (simple-format #f "default: ~s\n" default))
  50. #;(display (simple-format #f "use-longest-prefix: ~s\n" use-longest-prefix))
  51. (if use-longest-prefix node default)]
  52. ;; otherwise we need to get the next child to go deeper
  53. [else
  54. #;(display (simple-format #f "getting the next child node\n"))
  55. (let ([next-node (get-child-by-key (node-children node) (cadr path))])
  56. (if next-node
  57. (search-tree next-node
  58. (cdr path)
  59. default
  60. #:use-longest-prefix use-longest-prefix)
  61. ;; if there are no more nodes, but we still have some
  62. ;; path left
  63. (if use-longest-prefix node default)))])]
  64. [else default]))
  65. ;; wrap default in a result node so that always a node is returned
  66. (search-tree node
  67. path
  68. (make-node 'default-result default '())
  69. #:use-longest-prefix use-longest-prefix))
  70. (define (leaf? node)
  71. (null? (node-children node)))
  72. (define (inner-node? node)
  73. (not (leaf? node)))
  74. (define (list->tree nested-list)
  75. (define (get-key lst)
  76. (car lst))
  77. (define (get-val lst)
  78. (cadr lst))
  79. (define (get-children lst)
  80. (caddr lst))
  81. (cond [(null? nested-list) '()]
  82. [else (make-node (get-key nested-list)
  83. (get-val nested-list)
  84. (map list->tree (get-children nested-list)))]))