inference.scm 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
  2. ;;;
  3. ;;; Port Author: Andrew Whatson
  4. ;;;
  5. ;;; Original Authors: Richard Kelsey, Mike Sperber
  6. ;;;
  7. ;;; scheme48-1.9.2/ps-compiler/prescheme/inference.scm
  8. ;;;
  9. ;;; Type Inference
  10. ;;;
  11. ;;; The entry points to the inferencer are:
  12. ;;;
  13. ;;; (unify! type1 type2 context)
  14. ;;; Unify TYPE1 and TYPE2. CONTEXT is used to provide user feedback when type
  15. ;;; errors are detected.
  16. ;;;
  17. ;;; (make-uvar prefix depth . maybe-id)
  18. ;;; Makes a new type variable. PREFIX is a symbol, DEPTH is the current type
  19. ;;; depth (used for polymorphism), and MAYBE-ID is an optional unique
  20. ;;; integer.
  21. ;;;
  22. ;;; (schemify-type type depth)
  23. ;;; Make TYPE polymorphic in any variables bound at DEPTH.
  24. ;;;
  25. ;;; (instantiate-type-scheme scheme depth)
  26. ;;; Return an instantiation of SCHEME at DEPTH.
  27. ;;;
  28. ;;; (reset-inference!)
  29. ;;; Clear various global variables (to be replaced with fluids at some point)
  30. (define-module (ps-compiler prescheme inference)
  31. #:use-module (prescheme scheme48)
  32. #:use-module (prescheme bcomp node)
  33. #:use-module (prescheme bcomp schemify)
  34. #:use-module (ps-compiler prescheme type)
  35. #:use-module (ps-compiler prescheme type-var)
  36. #:use-module (ps-compiler util syntax)
  37. #:use-module (ps-compiler util util)
  38. #:export (unify!
  39. *currently-checking*))
  40. (define (unify! type1 type2 context)
  41. (cond ((really-unify! type1 type2)
  42. => (lambda (error-thunk)
  43. (unify-lost error-thunk type1 type2 context)))))
  44. (define *currently-checking* #f)
  45. (define *current-top-exp* #f)
  46. (define (unify-lost error-thunk type1 type2 context)
  47. (cond ((eq? context 'simplifying)
  48. (bug "unification error while instantiating an integrable procedure"))
  49. ((eq? context 'make-monomorphic)
  50. #f)
  51. (else
  52. (user-type-error-message error-thunk type1 type2 context))))
  53. (define (user-type-error-message error-thunk type1 type2 context)
  54. (format #t "Type error in ~S~% " (schemify context))
  55. (error-thunk)
  56. (if *currently-checking*
  57. (begin
  58. (format #t "~% while reconstructing the type of~% ")
  59. (*currently-checking* (current-output-port))))
  60. (error "type problem"))
  61. (define (really-unify! p1 p2)
  62. (let ((p1 (maybe-follow-uvar p1)) ;; get the current value of P1
  63. (p2 (maybe-follow-uvar p2))) ;; get the current value of P2
  64. (cond ((or (eq? p1 p2)
  65. (eq? p1 type/null)
  66. (eq? p2 type/null))
  67. #f)
  68. ((uvar? p1)
  69. (bind-uvar! p1 p2))
  70. ((uvar? p2)
  71. (bind-uvar! p2 p1))
  72. ((and (eq? p1 type/unit)
  73. (eq? p2 type/unit))
  74. #f)
  75. ((other-type? p1)
  76. (if (and (other-type? p2)
  77. (eq? (other-type-kind p1) (other-type-kind p2))
  78. (= (length (other-type-subtypes p1))
  79. (length (other-type-subtypes p2))))
  80. (unify-lists! (other-type-subtypes p1)
  81. (other-type-subtypes p2))
  82. (mismatch-failure p1 p2)))
  83. (else
  84. (mismatch-failure p1 p2)))))
  85. (define (mismatch-failure t1 t2)
  86. (lambda ()
  87. (format #t "type mismatch~% ")
  88. (display-type t1 (current-output-port))
  89. (format #t "~% ")
  90. (display-type t2 (current-output-port))))
  91. (define (unify-lists! l1 l2)
  92. (let loop ((l1 l1) (l2 l2))
  93. (if (null? l1)
  94. #f
  95. (or (really-unify! (car l1) (car l2))
  96. (loop (cdr l1) (cdr l2))))))
  97. (define (type-conflict message . stuff)
  98. (apply breakpoint message stuff))
  99. ;; For debugging
  100. (define (uvar-name uvar)
  101. (concatenate-symbol (uvar-prefix uvar) "." (uvar-id uvar)))