value-sets.scm 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. (define-module (analyzer value-sets)
  2. #:use-module (srfi srfi-9)
  3. #:use-module (srfi srfi-1)
  4. #:export (value-set value-set-type
  5. make-value-set value-set?
  6. value-set-values set-value-set-values!
  7. value-set-properties set-value-set-properties!
  8. value-set-nothing value-set-anything
  9. value-set-can-be-anything? value-set-has-values?
  10. value-set-has-value? value-set-has-property?
  11. value-set-nothing? value-set-has-no-properties?
  12. value-set-with-values
  13. value-set-value-satisfying
  14. value-set-union!
  15. value-set-add-value!
  16. value-set-add-property!
  17. vs-cons
  18. vs-car
  19. vs-cdr
  20. primitive-procedure-type
  21. primitive-procedure
  22. primitive-procedure?
  23. primitive-procedure-evaluator
  24. prim-cons prim-car prim-cdr))
  25. #|
  26. To keep things simple in the beginning, it's best to just have a few simple types and a few compound types. We attempt the following four simple types:
  27. - booleans
  28. - numbers (but no differentiation within numbers)
  29. - strings
  30. - symbols
  31. and we use pairs as our only compound data type (this includes lists).
  32. We also need a small vocabulary of procedures. Here's one:
  33. - not
  34. - boolean?
  35. - number?
  36. - +
  37. - string?
  38. - symbol?
  39. - eq?
  40. |#
  41. (define-record-type value-set-type
  42. #| a value set has two sorts of things:
  43. - values is a list of individual Scheme values
  44. - properties is a list of representations of sets of Scheme values, like
  45. integers. the value-set describes the union of these two items
  46. properties is a list of possible descriptions. each description is a
  47. list of primitive predicates that this value would satisfy. so
  48. properties is like a propositional logic formula in disjunctive normal
  49. form.
  50. |#
  51. (value-set values properties)
  52. value-set?
  53. (values value-set-values set-value-set-values!)
  54. (properties value-set-properties set-value-set-properties!))
  55. ;; convenience constructors
  56. (define (value-set-anything)
  57. (value-set '() '((anything))))
  58. (define (value-set-nothing)
  59. (value-set '() '()))
  60. (define (value-set-with-values . vals)
  61. (value-set vals '()))
  62. ;; and predicates
  63. (define (value-set-has-values? vs)
  64. (or (not (null? (value-set-values vs)))
  65. (not (null? (value-set-properties vs)))))
  66. (define (value-set-can-be-anything? vs)
  67. (let loop ((props (value-set-properties vs)))
  68. (cond ((null? props) #f)
  69. ((eq? (caar props) 'anything) #t)
  70. (else (loop (cdr props))))))
  71. (define (value-set-nothing? vs)
  72. (and (null? (value-set-values vs))
  73. (null? (value-set-properties vs))))
  74. (define (value-set-has-value? vs v)
  75. (memq v (value-set-values vs)))
  76. (define (value-set-has-property? vs p)
  77. (assq p (value-set-properties vs)))
  78. (define (value-set-has-no-properties? vs)
  79. (null? (value-set-properties vs)))
  80. ;; and a selector
  81. (define (value-set-value-satisfying vs pred)
  82. (let loop ((vals (value-set-values vs)))
  83. (cond ((null? vals) #f)
  84. ((pred (car vals)) (car vals))
  85. (else (loop (cdr vals))))))
  86. ;; and three modifiers. these are really three cases of the same thing -
  87. ;; a general case and two special ones. they are the basic operation on
  88. ;; value sets.
  89. ;; this function sets t to the union of t and x.
  90. ;; it uses a recursive merge if one of the values is a pair.
  91. (define (value-set-union! t x)
  92. (cond ((value-set-can-be-anything? x)
  93. (set-value-set-values! t '())
  94. (set-value-set-properties! t '((anything))))
  95. (else
  96. (for-each (lambda (v) (value-set-add-value! t v))
  97. (value-set-values x))
  98. (for-each (lambda (p) (value-set-add-property! t p))
  99. (value-set-properties x)))))
  100. (define (value-set-add-value! t v)
  101. (if (pair? v)
  102. (let ((old-pair (value-set-value-satisfying t pair?)))
  103. (if old-pair
  104. (begin (value-set-union! (car old-pair) (car v))
  105. (value-set-union! (cdr old-pair) (cdr v)))
  106. (set-value-set-values! t (cons v (value-set-values t)))))
  107. (if (not (memv v (value-set-values t)))
  108. (set-value-set-values! t (cons v (value-set-values t))))))
  109. (define (value-set-add-property! t p)
  110. (cond ((equal? p '(anything))
  111. (set-value-set-properties! t '((anything)))
  112. (set-value-set-values! t '()))
  113. ((equal? p '(number?))
  114. (set-value-set-properties! t '((number?))))
  115. (else
  116. (error "Don't know how to add property" p))))
  117. (define-record-type primitive-procedure-type
  118. ;; this type holds the value-set version of a primitive procedure
  119. (primitive-procedure evaluator)
  120. primitive-procedure?
  121. (evaluator primitive-procedure-evaluator))
  122. ;; all procedures take an extra first argument, the "target", which is
  123. ;; the value set of their return value.
  124. (define (vs-cons t a b)
  125. (value-set-add-value! t
  126. (cons a b)))
  127. (define (vs-car t p)
  128. (if (value-set-can-be-anything? p)
  129. (value-set-union! t (value-set-anything))
  130. (let ((pair (value-set-value-satisfying p pair?)))
  131. (if pair
  132. (value-set-union! t (car pair))))))
  133. (define (vs-cdr t p)
  134. (if (value-set-can-be-anything? p)
  135. (value-set-union! t (value-set-anything))
  136. (let ((pair (value-set-value-satisfying p pair?)))
  137. (if pair
  138. (value-set-union! t (cdr pair))))))
  139. (define prim-cons (primitive-procedure vs-cons))
  140. (define prim-car (primitive-procedure vs-car))
  141. (define prim-cdr (primitive-procedure vs-cdr))