27
27
28
28
type Var
29
29
name:: Symbol
30
- lb:: Ty
31
- ub:: Ty
30
+ lb
31
+ ub
32
32
Var (n, lb= BottomT, ub= AnyT) = new (n, lb, ub)
33
33
end
34
34
35
- function show (io:: IO , v:: Var )
35
+ function show_var_bounds (io:: IO , v:: Var )
36
36
if v. lb != = BottomT
37
37
show (io, v. lb)
38
38
print (io, " <:" )
39
39
end
40
- print (io, v. name, " <:" )
41
- show (io, v. ub)
40
+ print (io, v. name)
41
+ if v. ub != = AnyT
42
+ print (io, " <:" )
43
+ show (io, v. ub)
44
+ end
42
45
end
43
46
47
+ show (io:: IO , v:: Var ) = print (io, v. name)
48
+
44
49
type ForAllT <: Ty
45
50
var:: Var
46
- T:: Ty
51
+ T
52
+ ForAllT (v:: Var , t) = new (v, t)
53
+ ForAllT (v:: Var , t:: Type ) = new (v, convert (Ty, t))
47
54
end
48
55
49
56
function show (io:: IO , x:: ForAllT )
50
- print (io, " @UnionAll " )
51
- show (io, x. var)
52
- print (io, " " )
57
+ if x. T === x. var && x. var. ub != = AnyT
58
+ print (io, " ¬" , x. var. ub)
59
+ return
60
+ end
61
+ print (io, " (∀ " )
62
+ show_var_bounds (io, x. var)
63
+ print (io, " . " )
53
64
show (io, x. T)
65
+ print (io, " )" )
54
66
end
55
67
56
68
AnyT = TagT (TypeName (:Any ), ())
@@ -62,7 +74,7 @@ inst(typename::TypeName, params...) = TagT(typename, params)
62
74
63
75
inst (t:: TagT ) = t
64
76
65
- inst (t:: ForAllT , param) = subst (t. T, Dict (t. var => param))
77
+ inst (t:: ForAllT , param) = subst (t. T, Dict {Any,Any} (t. var => param))
66
78
inst (t:: ForAllT , param, rest... ) = inst (inst (t,param), rest... )
67
79
68
80
super (t:: TagT ) = inst (t. name. super, t. params... )
@@ -85,6 +97,8 @@ tupletype(xs...) = inst(TupleName, xs...)
85
97
86
98
isequal_type (x:: Ty , y:: Ty ) = issub (x, y, true )
87
99
100
+ issub (x, y, env, inv) = (x === y)
101
+
88
102
function issub (x:: Ty , y:: Ty , inv:: Bool = false )
89
103
env = Dict ()
90
104
ans = issub (x, y, env, inv)
@@ -200,7 +214,22 @@ function add_constraint!(env, var, c::SupConstraint)
200
214
end
201
215
end
202
216
217
+ ctr = 1
218
+ rename (x) = x
219
+ function rename (x:: ForAllT )
220
+ global ctr
221
+ v = Var (symbol (string (" a" ,ctr)), x. var. lb, rename (x. var. ub))
222
+ ctr += 1
223
+ ForAllT (v, rename (inst (x, v)))
224
+ end
225
+
203
226
function issub_var (a:: Var , b, env, invariant)
227
+ if b === AnyT
228
+ return true
229
+ end
230
+ if haskey (env, a) && ! invariant
231
+ return issub (rename (env[a][1 ]. rhs), b, env, invariant)
232
+ end
204
233
add_constraint! (env, a, invariant ? EqConstraint (b) : SubConstraint (b))
205
234
return true
206
235
end
@@ -220,17 +249,30 @@ function issub(a::Ty, b::Var, env, invariant)
220
249
end
221
250
222
251
function issub (a:: ForAllT , b:: ForAllT , env, invariant)
252
+ println (a, " <: " , b); sleep (.5 )
253
+
223
254
# 1. handle bounds
224
- # this could be the crucial bit: we make the bounds covariant
225
- if ! (issub (a. var. ub, b. var. ub, env, false ) &&
226
- issub (b. var. lb, a. var. lb, env, false ))
255
+ if ! (issub (b. var. ub, a. var. ub, copy (env), false ) &&
256
+ issub (a. var. lb, b. var. lb, copy (env), false ))
227
257
return false
228
258
end
259
+
229
260
# 2. handle expression
230
- fresh = Var (symbol (string (" _" ,a. var. name," _" ,b. var. name)), a. var. lb, a. var. ub)
231
- add_constraint! (env, fresh, SupConstraint (a. var. lb))
232
- add_constraint! (env, fresh, SubConstraint (a. var. ub))
233
- inner = issub (inst (a, fresh), inst (b, fresh), env, invariant)
261
+ # for contravariance, fresh<:b.var.ub, for covariance fresh<:a.var.ub
262
+ lb = b. var. lb
263
+ ub = b. var. ub
264
+ # var = Var(symbol(string("a",ctr)), lb, ub)
265
+ # global ctr += 1
266
+ var = b. var
267
+
268
+ env = copy (env)
269
+ # add_constraint!(env, var, SupConstraint(lb))
270
+ add_constraint! (env, var, SubConstraint (ub))
271
+
272
+ a = inst (a, var)
273
+ b = b. T
274
+
275
+ inner = issub (a, b, env, invariant)
234
276
return inner
235
277
end
236
278
@@ -302,6 +344,8 @@ const tndict = ObjectIdDict()
302
344
303
345
xlate (t) = xlate (t, ObjectIdDict ())
304
346
347
+ xlate (t, env) = t
348
+
305
349
function xlate (t:: UnionType , env)
306
350
if t === Union ()
307
351
return BottomT
@@ -365,3 +409,54 @@ ArrayT =
365
409
let ArrayName = TypeName (:Array , @UnionAll T @UnionAll N inst (AbstractArrayT, T, N))
366
410
@UnionAll T @UnionAll N inst (ArrayName, T, N)
367
411
end
412
+
413
+ function non_terminating ()
414
+ # undecidable F_<: instance
415
+ ¬ T = @UnionAll α<: T α
416
+
417
+ θ = @UnionAll α ¬ (@UnionAll β< :α ¬ β)
Has conversations. Original line has conversations.
418
+
419
+ a0 = Var (:a0 )
420
+ env = Dict {Any,Any} (a0 => Any[SubConstraint (θ)])
421
+
422
+ issub (a0, (@UnionAll a1<: a0 ¬ a1), env, false )
423
+ end
424
+
425
+ using Base. Test
426
+
427
+ issub_strict (x,y) = issub (x,y) && ! issub (y,x)
428
+
429
+ # level 1: no varags, union, UnionAll
430
+ function test_1 ()
431
+ @test issub_strict (Int, Integer)
432
+ @test issub_strict (Array{Int,1 }, AbstractArray{Int,1 })
433
+
434
+ @test isequal_type (Int, Int)
435
+ @test isequal_type (Integer, Integer)
436
+ @test isequal_type (Array{Int,1 }, Array{Int,1 })
437
+ @test isequal_type (AbstractArray{Int,1 }, AbstractArray{Int,1 })
438
+
439
+ @test issub_strict ((Int,Int), (Integer,Integer))
440
+ @test issub_strict ((Array{Int,1 },), (AbstractArray{Int,1 },))
441
+
442
+ @test isequal_type ((Integer,Integer), (Integer,Integer))
443
+
444
+ @test ! issub ((Int,Int), (Int,))
445
+ @test ! issub ((Int,), (Integer,Integer))
446
+ end
447
+
448
+ # level 2: varargs
449
+ function test_2 ()
450
+ @test issub_strict ((Int,Int), (Int... ,))
451
+ @test issub_strict ((Int,Int), (Int,Int... ,))
452
+ @test issub_strict ((Int,Int), (Int,Integer... ,))
453
+ @test issub_strict ((Int,Int), (Int,Int,Integer... ,))
454
+ @test issub_strict ((Int,Int... ), (Int... ,))
455
+ @test issub_strict ((Int,Int,Int... ), (Int... ,))
456
+ @test issub_strict ((Int,Int,Int... ), (Integer,Int... ,))
457
+ @test issub_strict ((Int... ,), (Any... ,))
458
+ @test issub_strict ((), (Any... ,))
459
+
460
+ @test isequal_type ((Int... ,), (Int... ,))
461
+ @test isequal_type ((Integer... ,), (Integer... ,))
462
+ end