Fixup contract restricts.
Add useful printing. Add removal of trival constraints. Fix bug in close loop when constraints were not getting closed correctly.
This commit is contained in:
parent
8f13c2f966
commit
e164a959eb
|
@ -39,6 +39,7 @@
|
||||||
racket/match
|
racket/match
|
||||||
racket/list
|
racket/list
|
||||||
racket/format
|
racket/format
|
||||||
|
racket/function
|
||||||
racket/contract
|
racket/contract
|
||||||
racket/dict
|
racket/dict
|
||||||
racket/set
|
racket/set
|
||||||
|
@ -64,20 +65,82 @@
|
||||||
|
|
||||||
(module structs racket/base
|
(module structs racket/base
|
||||||
(require racket/contract
|
(require racket/contract
|
||||||
|
racket/match
|
||||||
|
racket/dict
|
||||||
|
racket/list
|
||||||
racket/set
|
racket/set
|
||||||
syntax/id-table
|
syntax/id-table
|
||||||
"kinds.rkt")
|
"kinds.rkt")
|
||||||
(provide
|
(provide
|
||||||
(contract-out
|
(contract-out
|
||||||
|
;; constraint: value must be below max
|
||||||
[struct constraint ([value kind-max?] [max contract-kind?])]
|
[struct constraint ([value kind-max?] [max contract-kind?])]
|
||||||
[struct kind-max ([variables free-id-table?] [max contract-kind?])]
|
;; kind-max: represents the maximum kind across all of the variables and the specified kind
|
||||||
|
[struct kind-max ([variables free-id-set?] [max contract-kind?])]
|
||||||
|
;; contract-restrict: represents a contract with value, recursive-values maps mentioned
|
||||||
|
;; recursive parts to kind-maxes, constraints are constraints that need to hold
|
||||||
[struct contract-restrict ([value kind-max?]
|
[struct contract-restrict ([value kind-max?]
|
||||||
[recursive-values free-id-table?]
|
[recursive-values free-id-table?]
|
||||||
[constraints (set/c constraint?)])]))
|
[constraints (set/c constraint?)])]))
|
||||||
|
(define free-id-set? free-id-table?)
|
||||||
|
|
||||||
(struct constraint (value max) #:transparent)
|
(struct constraint (value max) #:transparent)
|
||||||
(struct kind-max (variables max) #:transparent)
|
(struct kind-max (variables max) #:transparent
|
||||||
(struct contract-restrict (value recursive-values constraints) #:transparent))
|
#:methods gen:custom-write
|
||||||
|
[(define (write-proc v port mode)
|
||||||
|
(match-define (kind-max variables max) v)
|
||||||
|
(define recur
|
||||||
|
(case mode
|
||||||
|
[(#t) write]
|
||||||
|
[(#f) display]
|
||||||
|
[else (lambda (p port) (print p port mode))]))
|
||||||
|
(define-values (open close)
|
||||||
|
(if (equal? mode 0)
|
||||||
|
(values "(" ")")
|
||||||
|
(values "#<" ">")))
|
||||||
|
(display open port)
|
||||||
|
(fprintf port "kind-max")
|
||||||
|
(display " " port)
|
||||||
|
(display (map syntax-e (dict-keys variables)) port)
|
||||||
|
(display " " port)
|
||||||
|
(recur max port)
|
||||||
|
(display close port))])
|
||||||
|
(struct contract-restrict (value recursive-values constraints)
|
||||||
|
#:methods gen:custom-write
|
||||||
|
[(define (write-proc v port mode)
|
||||||
|
(match-define (contract-restrict value recursive-values constraints) v)
|
||||||
|
(define recur
|
||||||
|
(case mode
|
||||||
|
[(#t) write]
|
||||||
|
[(#f) display]
|
||||||
|
[else (lambda (p port) (print p port mode))]))
|
||||||
|
(define-values (open close)
|
||||||
|
(if (equal? mode 0)
|
||||||
|
(values "(" ")")
|
||||||
|
(values "#<" ">")))
|
||||||
|
(display open port)
|
||||||
|
(fprintf port "contract-restrict")
|
||||||
|
(display " " port)
|
||||||
|
(recur value port)
|
||||||
|
|
||||||
|
(display " (" port)
|
||||||
|
(define (recur-pair name val)
|
||||||
|
(fprintf port "(~a " (syntax->datum name))
|
||||||
|
(recur val port)
|
||||||
|
(display ")" port))
|
||||||
|
(define-values (names vals)
|
||||||
|
(let ((assoc (dict->list recursive-values)))
|
||||||
|
(values (map car assoc) (map cdr assoc))))
|
||||||
|
(when (cons? names)
|
||||||
|
(recur-pair (first names) (first vals))
|
||||||
|
(for ((name (rest names))
|
||||||
|
(val (rest vals)))
|
||||||
|
(display " " port)
|
||||||
|
(recur-pair name val)))
|
||||||
|
(display ") " port)
|
||||||
|
(recur constraints port)
|
||||||
|
(display close port))]
|
||||||
|
#:transparent))
|
||||||
(require 'structs)
|
(require 'structs)
|
||||||
(provide (struct-out kind-max))
|
(provide (struct-out kind-max))
|
||||||
|
|
||||||
|
@ -113,12 +176,22 @@
|
||||||
(~a "required " (name bound) " but generated " (name actual)))
|
(~a "required " (name bound) " but generated " (name actual)))
|
||||||
|
|
||||||
|
|
||||||
|
(define (trivial-constraint? con)
|
||||||
|
(match con
|
||||||
|
[(constraint _ 'impersonator)
|
||||||
|
#t]
|
||||||
|
[(constraint (kind-max (app dict-count 0) actual) bound)
|
||||||
|
(contract-kind<= actual bound)]
|
||||||
|
[else #f]))
|
||||||
|
|
||||||
|
|
||||||
(define (add-constraint cr max)
|
(define (add-constraint cr max)
|
||||||
(if (equal? 'impersonator max)
|
(match cr
|
||||||
cr
|
[(contract-restrict v rec constraints)
|
||||||
(match cr
|
(define con (constraint v max))
|
||||||
[(contract-restrict v rec constraints)
|
(if (trivial-constraint? con)
|
||||||
(contract-restrict v rec (set-add constraints (constraint v max)))])))
|
cr
|
||||||
|
(contract-restrict v rec (set-add constraints con)))]))
|
||||||
|
|
||||||
(define (add-recursive-values cr dict)
|
(define (add-recursive-values cr dict)
|
||||||
(match cr
|
(match cr
|
||||||
|
@ -151,6 +224,20 @@
|
||||||
|
|
||||||
|
|
||||||
(define (instantiate-cr cr lookup-id)
|
(define (instantiate-cr cr lookup-id)
|
||||||
|
(define (instantiate-kind-max km)
|
||||||
|
(match km
|
||||||
|
[(kind-max ids actual)
|
||||||
|
(define-values (bound-ids unbound-ids)
|
||||||
|
(partition (lambda (id) (member id names)) (dict-keys ids)))
|
||||||
|
(merge-kind-maxes 'flat (cons (kind-max (apply free-id-set unbound-ids) actual)
|
||||||
|
(for/list ([id (in-list bound-ids)])
|
||||||
|
(contract-restrict-value (lookup-id id)))))]))
|
||||||
|
|
||||||
|
(define (instantiate-constraint con)
|
||||||
|
(match con
|
||||||
|
[(constraint km bound)
|
||||||
|
(constraint (instantiate-kind-max km) bound)]))
|
||||||
|
|
||||||
(match cr
|
(match cr
|
||||||
[(contract-restrict (kind-max ids max) rec constraints)
|
[(contract-restrict (kind-max ids max) rec constraints)
|
||||||
(define-values (bound-ids unbound-ids)
|
(define-values (bound-ids unbound-ids)
|
||||||
|
@ -159,7 +246,9 @@
|
||||||
(contract-restrict
|
(contract-restrict
|
||||||
(kind-max (apply free-id-set unbound-ids) max)
|
(kind-max (apply free-id-set unbound-ids) max)
|
||||||
rec
|
rec
|
||||||
constraints)
|
(apply set
|
||||||
|
(filter (negate trivial-constraint?)
|
||||||
|
(set-map constraints instantiate-constraint))))
|
||||||
(map lookup-id bound-ids)))]))
|
(map lookup-id bound-ids)))]))
|
||||||
|
|
||||||
(for ([name names] [cr crs])
|
(for ([name names] [cr crs])
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
(t (-polydots (a) -Symbol))
|
(t (-polydots (a) -Symbol))
|
||||||
(t (-polydots (a) (->... (list) (a a) -Symbol)))
|
(t (-polydots (a) (->... (list) (a a) -Symbol)))
|
||||||
|
|
||||||
|
(t (-mu x (-Syntax x)))
|
||||||
|
|
||||||
|
|
||||||
(t/fail ((-poly (a) (-vec a)) . -> . -Symbol)
|
(t/fail ((-poly (a) (-vec a)) . -> . -Symbol)
|
||||||
"cannot generate contract for non-function polymorphic type")
|
"cannot generate contract for non-function polymorphic type")
|
||||||
(t/fail (-> (-poly (a b) (-> (Un a b) (Un a b))) Univ)
|
(t/fail (-> (-poly (a b) (-> (Un a b) (Un a b))) Univ)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user