|
21 | 21 | one-of/c))
|
22 | 22 |
|
23 | 23 | (lazy-require
|
24 |
| - ("../infer/infer.rkt" (infer)) |
| 24 | + ("../infer/infer.rkt" (infer intersect)) |
25 | 25 | ("prop-ops.rkt" (-and))
|
26 | 26 | ("../typecheck/tc-subst.rkt" (instantiate-obj+simplify))
|
27 | 27 | ("../typecheck/tc-envops.rkt" (env+ implies-in-env?)))
|
|
186 | 186 | ;; NOTE: This function takes into account that domains are
|
187 | 187 | ;; contravariant w.r.t. subtyping, i.e. callers should NOT
|
188 | 188 | ;; flip argument order.
|
189 |
| -(define/cond-contract (Arrow-domain-subtypes* A dom1 rst1 dom2 rst2 [objs #f]) |
| 189 | +(define/cond-contract (positional-domain-subtypes* A dom1 rst1 dom2 rst2 [objs #f]) |
190 | 190 | (->* (list?
|
191 | 191 | (listof Type?)
|
192 | 192 | (or/c #f Rest? RestDots?)
|
|
198 | 198 | [((cons t1 ts1) (cons t2 ts2))
|
199 | 199 | (subtype-seq A
|
200 | 200 | (subtype* t2 t1 (and objs (car objs)))
|
201 |
| - (Arrow-domain-subtypes* ts1 rst1 ts2 rst2 (and objs (cdr objs))))] |
| 201 | + (positional-domain-subtypes* ts1 rst1 ts2 rst2 (and objs (cdr objs))))] |
202 | 202 | [(_ _)
|
203 | 203 | (subtype* A
|
204 | 204 | (-Tuple* dom2 (Rest->Type rst2))
|
205 | 205 | (-Tuple* dom1 (Rest->Type rst1)))]))
|
206 | 206 |
|
| 207 | +(define/cond-contract (Arrow-domain-subtypes* A dom1 rst1 kws1 dom2 rst2 kws2 [objs #f]) |
| 208 | + (->* (list? |
| 209 | + (listof Type?) |
| 210 | + (or/c #f Rest? RestDots?) |
| 211 | + (listof Keyword?) |
| 212 | + (listof Type?) |
| 213 | + (or/c #f Rest? RestDots?) |
| 214 | + (listof Keyword?)) |
| 215 | + ((listof Object?)) |
| 216 | + (or/c #f list?)) |
| 217 | + (subtype-seq A |
| 218 | + (positional-domain-subtypes* dom1 rst1 dom2 rst2 objs) |
| 219 | + (kw-subtypes* kws1 kws2))) |
| 220 | + |
207 | 221 | (define-syntax-rule (with-fresh-ids len ids . body)
|
208 | 222 | (let-values ([(ids seq) (for/fold ([ids '()]
|
209 | 223 | [seq (temp-ids)])
|
|
220 | 234 | [((Arrow: dom1 rst1 kws1 raw-rng1)
|
221 | 235 | (Arrow: dom2 rst2 kws2 raw-rng2))
|
222 | 236 | (define A* (subtype-seq A
|
223 |
| - (Arrow-domain-subtypes* dom1 rst1 dom2 rst2) |
| 237 | + (positional-domain-subtypes* dom1 rst1 dom2 rst2) |
224 | 238 | (kw-subtypes* kws1 kws2)))
|
225 | 239 | (cond
|
226 | 240 | [(not A*) #f]
|
|
254 | 268 | (instantiate-obj d ids)))
|
255 | 269 | (define A* (subtype-seq A
|
256 | 270 | (kw-subtypes* kws1 '())
|
257 |
| - (Arrow-domain-subtypes* dom1 rst1 dom2 #f (map -id-path ids)))) |
| 271 | + (positional-domain-subtypes* dom1 rst1 dom2 #f (map -id-path ids)))) |
258 | 272 | (cond
|
259 | 273 | [(not A*) #f]
|
260 | 274 | [else
|
|
310 | 324 | (define rst (match raw-rst
|
311 | 325 | [(? Type?) (make-Rest (list raw-rst))]
|
312 | 326 | [_ raw-rst]))
|
313 |
| - (Arrow-domain-subtypes* A dom rst argtys #f)) |
| 327 | + (positional-domain-subtypes* A dom rst argtys #f)) |
314 | 328 |
|
315 | 329 |
|
316 | 330 | ;;************************************************************
|
|
812 | 826 | [((Fun: arrows2) _)
|
813 | 827 | (cond
|
814 | 828 | [(null? arrows1) #f]
|
815 |
| - [else (for/fold ([A A]) |
816 |
| - ([a2 (in-list arrows2)] |
817 |
| - #:break (not A)) |
818 |
| - (for/or ([a1 (in-list arrows1)]) |
819 |
| - (arrow-subtype* A a1 a2)))])] |
| 829 | + [else |
| 830 | + (for/fold ([A A]) |
| 831 | + ([a2 (in-list arrows2)] |
| 832 | + #:break (not A)) |
| 833 | + (match-define (Arrow: dom2 rst2 kws2 raw-cdom2) a2) |
| 834 | + ;; A <: C₁ ∩ ... ∩ Cₙ |
| 835 | + ;; D₁ ∩ ... ∩ Dₙ <: B |
| 836 | + ;; ------------------------ |
| 837 | + ;; (C₁→D₁∩...∩Cₙ→Dₙ) <: A→B |
| 838 | + (define raw-cdom1 |
| 839 | + (for/fold ([cdom #f]) |
| 840 | + ([a1 (in-list arrows1)]) |
| 841 | + (match-define (Arrow: dom1 rst1 kws1 raw-cdom1) a1) |
| 842 | + (cond |
| 843 | + [(Arrow-domain-subtypes* A dom1 rst1 kws1 dom2 rst2 kws2) |
| 844 | + (if cdom (intersect-values cdom raw-cdom1) raw-cdom1)] |
| 845 | + [else cdom]))) |
| 846 | + (cond |
| 847 | + [(not raw-cdom1) #f] |
| 848 | + [else |
| 849 | + (with-fresh-ids (length dom2) ids |
| 850 | + (define mapping |
| 851 | + (for/list ([idx (in-naturals)] |
| 852 | + [id (in-list ids)] |
| 853 | + [t (in-list dom2)]) |
| 854 | + (list* idx id t))) |
| 855 | + (subval* A |
| 856 | + (instantiate-obj+simplify raw-cdom1 mapping) |
| 857 | + (instantiate-obj raw-cdom2 ids)))]))])] |
820 | 858 | [((? DepFun? dfun) _)
|
821 | 859 | (for/or ([a1 (in-list arrows1)])
|
822 | 860 | (arrow-subtype-dfun* A a1 dfun))]
|
|
1229 | 1267 | #false]
|
1230 | 1268 | [_ (continue<: A t1 t2 obj)])]
|
1231 | 1269 | [else: (continue<: A t1 t2 obj)])
|
| 1270 | + |
| 1271 | + |
| 1272 | +;; intersects two monomorphic Values (i.e. see rep/values-rep) |
| 1273 | +;; if the values are strictly incompatible, we return ⊥, |
| 1274 | +(define (intersect-values v1 v2) |
| 1275 | + (match* (v1 v2) |
| 1276 | + [(v v) v] |
| 1277 | + [((ValuesDots: rs1 dty1 dbound) |
| 1278 | + (ValuesDots: rs2 dty2 dbound)) |
| 1279 | + (make-ValuesDots (map intersect-results rs1 rs2) (intersect dty1 dty2) dbound)] |
| 1280 | + [((? ValuesDots?) _) v1] |
| 1281 | + [(_ (? ValuesDots?)) v2] |
| 1282 | + [((AnyValues: p1) (AnyValues: p2)) (make-AnyValues (-and p1 p2))] |
| 1283 | + [((AnyValues: p) (Values: (cons (Result: t (PropSet: p+ p-) o) rst))) |
| 1284 | + (make-Values (cons (make-Result t (-PS (-and p p+) (-and p p-)) o) rst))] |
| 1285 | + [((Values: (cons (Result: t (PropSet: p+ p-) o) rst)) (AnyValues: p)) |
| 1286 | + (make-Values (cons (make-Result t (-PS (-and p p+) (-and p p-)) o) rst))] |
| 1287 | + [((Values: rs1) (Values: rs2)) |
| 1288 | + (cond |
| 1289 | + [(= (length rs1) (length rs2)) |
| 1290 | + (make-Values (map intersect-results rs1 rs2))] |
| 1291 | + [else (make-AnyValues -ff)])])) |
| 1292 | + |
| 1293 | +;; intersects two Results (i.e. see rep/core-rep.rkt) pointwise |
| 1294 | +(define (intersect-results r1 r2) |
| 1295 | + (match* (r1 r2) |
| 1296 | + [((Result: t1 (PropSet: p1+ p1-) o1) |
| 1297 | + (Result: t2 (PropSet: p2+ p2-) o2)) |
| 1298 | + (make-Result (intersect t1 t2) (-PS (-and p1+ p2+) (-and p1- p2-)) (intersect-objects o1 o2))])) |
0 commit comments