table.scm 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #| -*-Scheme-*-
  2. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
  3. 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  4. 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Massachusetts
  5. Institute of Technology
  6. This file is part of MIT/GNU Scheme.
  7. MIT/GNU Scheme is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11. MIT/GNU Scheme is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with MIT/GNU Scheme; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
  18. USA.
  19. |#
  20. ;;;; Property Tables
  21. (declare (usual-integrations))
  22. ;;; Properties are n-dimensional sparse tables implemented as
  23. ;;; nests of association lists.
  24. ;;; For any given sequence of keys, there can be both a value
  25. ;;; and a subtable. A table is a list of a value and some entries.
  26. ;;; An entry is a pair, whose CAR is a key and whose CDR is a
  27. ;;; the subtable for that key.
  28. (define (make-table table-name assoc)
  29. (let ((local-table (list *no-value*)))
  30. (define (lookup keys)
  31. (define (loop keys table)
  32. (if (null? keys) (car table)
  33. (let ((entry (assoc (car keys) (cdr table))))
  34. (if entry
  35. (loop (cdr keys) (cdr entry))
  36. *no-value*))))
  37. (loop keys local-table))
  38. (define (smash! keys value)
  39. (define (loop keys table)
  40. (if (null? keys) (set-car! table value)
  41. (let ((entry (assoc (car keys) (cdr table))))
  42. (if entry
  43. (loop (cdr keys) (cdr entry))
  44. (set-cdr! table
  45. (cons (cons (car keys)
  46. (make-subtable (cdr keys) value))
  47. (cdr table)))))))
  48. (loop keys local-table)
  49. local-table)
  50. (define (make-subtable keys value)
  51. (if (null? keys) (list value)
  52. (list *no-value*
  53. (cons (car keys)
  54. (make-subtable (cdr keys) value)))))
  55. (define (accumulator! increment-procedure initial-value keys value)
  56. (define (loop keys table)
  57. (if (null? keys)
  58. (if (eq? (car table) *no-value*)
  59. (set-car! table (increment-procedure value initial-value))
  60. (set-car! table (increment-procedure value (car table))))
  61. (let ((entry (assoc (car keys) (cdr table))))
  62. (if entry
  63. (loop (cdr keys) (cdr entry))
  64. (set-cdr! table
  65. (cons (cons (car keys)
  66. (make-subtable (cdr keys)
  67. (increment-procedure value
  68. initial-value)))
  69. (cdr table)))))))
  70. (loop keys local-table)
  71. local-table)
  72. (define (remove! keys) (smash! keys *no-value*))
  73. (vector table-name lookup smash! accumulator! remove!)))
  74. (define *no-value* (list '*no-value*))
  75. (define (no-value? value)
  76. (eq? value *no-value*))
  77. (define (get table . keys)
  78. ((vector-ref table 1) keys))
  79. (define* ((getter table) . keys)
  80. ((vector-ref table 1) keys))
  81. (define (put! table value . keys)
  82. ((vector-ref table 2) keys value)
  83. 'done)
  84. (define* ((putter! table) value . keys)
  85. ((vector-ref table 2) keys value)
  86. 'done)
  87. (define (get-with-default table default . keys)
  88. (let ((v ((vector-ref table 1) keys)))
  89. (if (eq? v *no-value*)
  90. default
  91. v)))
  92. (define* ((getter-with-default table default) . keys)
  93. (let ((v ((vector-ref table 1) keys)))
  94. (if (eq? v *no-value*)
  95. default
  96. v)))
  97. (define (get-with-check table . keys)
  98. (let ((v ((vector-ref table 1) keys)))
  99. (if (eq? v *no-value*)
  100. (error "can't find value in table"
  101. (list table keys))
  102. v)))
  103. (define* ((getter-with-check table) . keys)
  104. (let ((v ((vector-ref table 1) keys)))
  105. (if (eq? v *no-value*)
  106. (error "can't find value in table"
  107. (list table keys))
  108. v)))
  109. (define (add-to-list! object table . keys)
  110. ((vector-ref table 3) cons '() keys object)
  111. 'done)
  112. (define (adjoin-to-list! object table . keys)
  113. ((vector-ref table 3) list-adjoin '() keys object)
  114. 'done)
  115. (define (store! object table . keys)
  116. ((vector-ref table 2) keys object)
  117. 'done)
  118. ;;; Elementary table utilities implemented in ALISTs
  119. (define (lookup key table)
  120. (let ((val (assq key table)))
  121. (if val
  122. (cadr val)
  123. (error "key not in table -- LOOKUP" key))))
  124. (define (rlookup key table)
  125. (cond ((null? table) false)
  126. ((null? (cdar table)) (rlookup key (cdr table)))
  127. ((eq? key (cadar table)) (car table))
  128. (else (rlookup key (cdr table)))))
  129. (define (rassq key table)
  130. (cond ((null? table) false)
  131. ((eq? key (cdar table)) (car table))
  132. (else (rassq key (cdr table)))))
  133. (define (rassoc key table)
  134. (cond ((null? table) false)
  135. ((equal? key (cdar table)) (car table))
  136. (else (rassoc key (cdr table)))))
  137. (define (disassoc key alist)
  138. (cond ((null? alist) '())
  139. ((equal? key (caar alist))
  140. (cdr alist))
  141. (else
  142. (cons (car alist)
  143. (disassoc key (cdr alist))))))
  144. ;;; Elementary table utility implemented as PLISTs
  145. (define (default-lookup name default list)
  146. (let ((L (memq name list)))
  147. (if L (cadr L) default)))
  148. (define (table-of is? keys values)
  149. (define (lookup key)
  150. (let next ((ks keys) (vs values))
  151. (cond ((null? ks)
  152. (error "Key not in table" key))
  153. ((is? key (car ks)) (car vs))
  154. (else (next (cdr ks) (cdr vs))))))
  155. lookup)