@@ -28,13 +28,7 @@ defmodule Module.Types.Descr do
28
28
@ bit_number @ bit_integer ||| @ bit_float
29
29
30
30
# Remark: those use AST for BDDs
31
- defmacrop map_literal ( tag , fields ) , do: { :{} , [ ] , [ { tag , fields } , :bdd_top , :bdd_bot , :bdd_bot ] }
32
-
33
- defmacrop tuple_literal ( tag , elements ) ,
34
- do: { :{} , [ ] , [ { tag , elements } , :bdd_top , :bdd_bot , :bdd_bot ] }
35
-
36
- defmacrop list_literal ( list , last ) ,
37
- do: { :{} , [ ] , [ { list , last } , :bdd_top , :bdd_bot , :bdd_bot ] }
31
+ defmacrop bdd_leaf ( arg1 , arg2 ) , do: { arg1 , arg2 }
38
32
39
33
defmacrop domain_key ( key ) ,
40
34
do: { :domain_key , key }
@@ -57,10 +51,10 @@ defmodule Module.Types.Descr do
57
51
# Remark: those are explicit BDD constructors. The functional constructors are `bdd_new/1` and `bdd_new/3`.
58
52
@ fun_top :bdd_top
59
53
@ atom_top { :negation , :sets . new ( version: 2 ) }
60
- @ map_top { { :open , % { } } , :bdd_top , :bdd_bot , :bdd_bot }
61
- @ non_empty_list_top { { :term , :term } , :bdd_top , :bdd_bot , :bdd_bot }
62
- @ tuple_top { { :open , [ ] } , :bdd_top , :bdd_bot , :bdd_bot }
63
- @ map_empty { { :closed , % { } } , :bdd_top , :bdd_bot , :bdd_bot }
54
+ @ map_top { :open , % { } }
55
+ @ non_empty_list_top { :term , :term }
56
+ @ tuple_top { :open , [ ] }
57
+ @ map_empty { :closed , % { } }
64
58
65
59
@ none % { }
66
60
@ term % {
@@ -1096,7 +1090,7 @@ defmodule Module.Types.Descr do
1096
1090
# Note: Function domains are expressed as tuple types. We use separate representations
1097
1091
# rather than unary functions with tuple domains to handle special cases like representing
1098
1092
# functions of a specific arity (e.g., (none,none->term) for arity 2).
1099
- defp fun_new ( inputs , output ) , do: bdd_new ( { inputs , output } )
1093
+ defp fun_new ( inputs , output ) , do: bdd_leaf ( inputs , output )
1100
1094
1101
1095
# Creates a function type from a list of inputs and an output
1102
1096
# where the inputs and/or output may be dynamic.
@@ -1853,7 +1847,7 @@ defmodule Module.Types.Descr do
1853
1847
end
1854
1848
end
1855
1849
1856
- defp list_new ( list_type , last_type ) , do: bdd_new ( { list_type , last_type } )
1850
+ defp list_new ( list_type , last_type ) , do: bdd_leaf ( list_type , last_type )
1857
1851
1858
1852
defp non_empty_list_literals_intersection ( list_literals ) do
1859
1853
try do
@@ -1918,14 +1912,14 @@ defmodule Module.Types.Descr do
1918
1912
@ compile { :inline , list_union: 2 }
1919
1913
defp list_union ( bdd1 , bdd2 ) , do: bdd_union ( bdd1 , bdd2 )
1920
1914
1921
- defp is_list_top? ( list_literal ( list , tail ) ) , do: list == :term and tail == :term
1915
+ defp is_list_top? ( bdd_leaf ( list , tail ) ) , do: list == :term and tail == :term
1922
1916
defp is_list_top? ( _ ) , do: false
1923
1917
1924
- defp list_intersection ( list_literal ( list1 , last1 ) , list_literal ( list2 , last2 ) ) do
1918
+ defp list_intersection ( bdd_leaf ( list1 , last1 ) , bdd_leaf ( list2 , last2 ) ) do
1925
1919
try do
1926
1920
list = non_empty_intersection! ( list1 , list2 )
1927
1921
last = non_empty_intersection! ( last1 , last2 )
1928
- list_literal ( list , last )
1922
+ bdd_leaf ( list , last )
1929
1923
catch
1930
1924
:empty -> :bdd_bot
1931
1925
end
@@ -1948,11 +1942,11 @@ defmodule Module.Types.Descr do
1948
1942
# b) If only the last type differs, subtracts it
1949
1943
# 3. Base case: adds bdd2 type to negations of bdd1 type
1950
1944
# The result may be larger than the initial bdd1, which is maintained in the accumulator.
1951
- defp list_difference ( list_literal ( list1 , last1 ) = bdd1 , list_literal ( list2 , last2 ) = bdd2 ) do
1945
+ defp list_difference ( bdd_leaf ( list1 , last1 ) = bdd1 , bdd_leaf ( list2 , last2 ) = bdd2 ) do
1952
1946
cond do
1953
- disjoint? ( list1 , list2 ) or disjoint? ( last1 , last2 ) -> list_literal ( list1 , last1 )
1947
+ disjoint? ( list1 , list2 ) or disjoint? ( last1 , last2 ) -> bdd_leaf ( list1 , last1 )
1954
1948
subtype? ( list1 , list2 ) and subtype? ( last1 , last2 ) -> :bdd_bot
1955
- equal? ( list1 , list2 ) -> list_literal ( list1 , difference ( last1 , last2 ) )
1949
+ equal? ( list1 , list2 ) -> bdd_leaf ( list1 , difference ( last1 , last2 ) )
1956
1950
true -> bdd_difference ( bdd1 , bdd2 )
1957
1951
end
1958
1952
end
@@ -2386,7 +2380,7 @@ defmodule Module.Types.Descr do
2386
2380
defguardp is_optional_static ( map )
2387
2381
when is_map ( map ) and is_map_key ( map , :optional )
2388
2382
2389
- defp map_new ( tag , fields = % { } ) , do: bdd_new ( { tag , fields } )
2383
+ defp map_new ( tag , fields = % { } ) , do: bdd_leaf ( tag , fields )
2390
2384
2391
2385
defp map_only? ( descr ) , do: empty? ( Map . delete ( descr , :map ) )
2392
2386
@@ -2397,10 +2391,10 @@ defmodule Module.Types.Descr do
2397
2391
end
2398
2392
end
2399
2393
2400
- defp map_union ( map_literal ( tag1 , fields1 ) , map_literal ( tag2 , fields2 ) ) do
2394
+ defp map_union ( bdd_leaf ( tag1 , fields1 ) , bdd_leaf ( tag2 , fields2 ) ) do
2401
2395
case maybe_optimize_map_union ( { tag1 , fields1 , [ ] } , { tag2 , fields2 , [ ] } ) do
2402
- { tag , fields , [ ] } -> map_literal ( tag , fields )
2403
- nil -> bdd_union ( map_literal ( tag1 , fields1 ) , map_literal ( tag2 , fields2 ) )
2396
+ { tag , fields , [ ] } -> bdd_leaf ( tag , fields )
2397
+ nil -> bdd_union ( bdd_leaf ( tag1 , fields1 ) , bdd_leaf ( tag2 , fields2 ) )
2404
2398
end
2405
2399
end
2406
2400
@@ -2500,13 +2494,13 @@ defmodule Module.Types.Descr do
2500
2494
if subtype? ( v2 , v1 ) , do: :right_subtype_of_left
2501
2495
end
2502
2496
2503
- defp is_map_top? ( map_literal ( :open , fields ) ) when map_size ( fields ) == 0 , do: true
2497
+ defp is_map_top? ( bdd_leaf ( :open , fields ) ) when map_size ( fields ) == 0 , do: true
2504
2498
defp is_map_top? ( _ ) , do: false
2505
2499
2506
- defp map_intersection ( map_literal ( tag1 , fields1 ) , map_literal ( tag2 , fields2 ) ) do
2500
+ defp map_intersection ( bdd_leaf ( tag1 , fields1 ) , bdd_leaf ( tag2 , fields2 ) ) do
2507
2501
try do
2508
- map_literal = map_literal_intersection ( tag1 , fields1 , tag2 , fields2 )
2509
- bdd_new ( map_literal )
2502
+ { tag , fields } = map_literal_intersection ( tag1 , fields1 , tag2 , fields2 )
2503
+ bdd_leaf ( tag , fields )
2510
2504
catch
2511
2505
:empty -> :bdd_bot
2512
2506
end
@@ -2522,7 +2516,7 @@ defmodule Module.Types.Descr do
2522
2516
end
2523
2517
2524
2518
# Optimizations on single maps.
2525
- defp map_difference ( map_literal ( tag , fields ) = map1 , map_literal ( neg_tag , neg_fields ) = map2 ) do
2519
+ defp map_difference ( bdd_leaf ( tag , fields ) = map1 , bdd_leaf ( neg_tag , neg_fields ) = map2 ) do
2526
2520
# Case 1: we are removing an open map with one field. Just do the difference of that field.
2527
2521
if neg_tag == :open and map_size ( neg_fields ) == 1 do
2528
2522
[ { key , value } ] = Map . to_list ( neg_fields )
@@ -2531,13 +2525,13 @@ defmodule Module.Types.Descr do
2531
2525
if empty? ( t_diff ) do
2532
2526
:bdd_bot
2533
2527
else
2534
- map_literal ( tag , Map . put ( fields , key , t_diff ) )
2528
+ bdd_leaf ( tag , Map . put ( fields , key , t_diff ) )
2535
2529
end
2536
2530
else
2537
2531
# Case 2: the maps have all but one key in common. Do the difference of that key.
2538
2532
case map_all_but_one ( tag , fields , neg_tag , neg_fields ) do
2539
2533
{ :one , diff_key } ->
2540
- map_literal ( tag , Map . update! ( fields , diff_key , & difference ( & 1 , neg_fields [ diff_key ] ) ) )
2534
+ bdd_leaf ( tag , Map . update! ( fields , diff_key , & difference ( & 1 , neg_fields [ diff_key ] ) ) )
2541
2535
2542
2536
_ ->
2543
2537
bdd_difference ( map1 , map2 )
@@ -2718,7 +2712,7 @@ defmodule Module.Types.Descr do
2718
2712
2719
2713
# Optimization: if the key does not exist in the map, avoid building
2720
2714
# if_set/not_set pairs and return the popped value directly.
2721
- defp map_fetch_static ( % { map: map_literal ( tag_or_domains , fields ) } , key )
2715
+ defp map_fetch_static ( % { map: bdd_leaf ( tag_or_domains , fields ) } , key )
2722
2716
when not is_map_key ( fields , key ) do
2723
2717
map_key_tag_to_type ( tag_or_domains ) |> pop_optional_static ( )
2724
2718
end
@@ -2892,8 +2886,8 @@ defmodule Module.Types.Descr do
2892
2886
end
2893
2887
end
2894
2888
2895
- def map_refresh_domain ( % { map: map_literal ( tag , fields ) } , domain , type ) do
2896
- % { map: bdd_new ( { map_refresh_tag ( tag , domain , type ) , fields } ) }
2889
+ def map_refresh_domain ( % { map: bdd_leaf ( tag , fields ) } , domain , type ) do
2890
+ % { map: bdd_leaf ( map_refresh_tag ( tag , domain , type ) , fields ) }
2897
2891
end
2898
2892
2899
2893
def map_refresh_domain ( % { map: bdd } , domain , type ) do
@@ -3076,7 +3070,7 @@ defmodule Module.Types.Descr do
3076
3070
3077
3071
defp unfold_domains ( domains = % { } ) , do: domains
3078
3072
3079
- defp map_get_static ( % { map: map_literal ( tag_or_domains , fields ) } , key_descr ) do
3073
+ defp map_get_static ( % { map: bdd_leaf ( tag_or_domains , fields ) } , key_descr ) do
3080
3074
# For each non-empty kind of type in the key_descr, we add the corresponding key domain in a union.
3081
3075
domains = unfold_domains ( tag_or_domains )
3082
3076
@@ -3261,7 +3255,7 @@ defmodule Module.Types.Descr do
3261
3255
3262
3256
# Takes a static map type and removes a key from it.
3263
3257
# This allows the key to be put or deleted later on.
3264
- defp map_take_static ( % { map: map_literal ( tag , fields ) } = descr , key , initial )
3258
+ defp map_take_static ( % { map: bdd_leaf ( tag , fields ) } = descr , key , initial )
3265
3259
when not is_map_key ( fields , key ) do
3266
3260
case tag do
3267
3261
:open -> { true , maybe_union ( initial , fn -> term ( ) end ) , descr }
@@ -3733,11 +3727,11 @@ defmodule Module.Types.Descr do
3733
3727
{ acc , dynamic? }
3734
3728
end
3735
3729
3736
- defp tuple_new ( tag , elements ) , do: tuple_literal ( tag , elements )
3730
+ defp tuple_new ( tag , elements ) , do: bdd_leaf ( tag , elements )
3737
3731
3738
- defp tuple_intersection ( tuple_literal ( tag1 , elements1 ) , tuple_literal ( tag2 , elements2 ) ) do
3732
+ defp tuple_intersection ( bdd_leaf ( tag1 , elements1 ) , bdd_leaf ( tag2 , elements2 ) ) do
3739
3733
case tuple_literal_intersection ( tag1 , elements1 , tag2 , elements2 ) do
3740
- { tag , elements } -> tuple_literal ( tag , elements )
3734
+ { tag , elements } -> bdd_leaf ( tag , elements )
3741
3735
:empty -> :bdd_bot
3742
3736
end
3743
3737
end
@@ -3973,11 +3967,11 @@ defmodule Module.Types.Descr do
3973
3967
end
3974
3968
3975
3969
defp tuple_union (
3976
- tuple_literal ( tag1 , elements1 ) = tuple1 ,
3977
- tuple_literal ( tag2 , elements2 ) = tuple2
3970
+ bdd_leaf ( tag1 , elements1 ) = tuple1 ,
3971
+ bdd_leaf ( tag2 , elements2 ) = tuple2
3978
3972
) do
3979
3973
case maybe_optimize_tuple_union ( { tag1 , elements1 } , { tag2 , elements2 } ) do
3980
- { tag , elements } -> tuple_literal ( tag , elements )
3974
+ { tag , elements } -> bdd_leaf ( tag , elements )
3981
3975
nil -> bdd_union ( tuple1 , tuple2 )
3982
3976
end
3983
3977
end
@@ -4418,9 +4412,6 @@ defmodule Module.Types.Descr do
4418
4412
4419
4413
## BDD helpers
4420
4414
4421
- @ compile { :inline , bdd_new: 1 }
4422
- defp bdd_new ( literal ) , do: { literal , :bdd_top , :bdd_bot , :bdd_bot }
4423
-
4424
4415
defp bdd_map ( bdd , fun ) do
4425
4416
case bdd do
4426
4417
:bdd_bot ->
0 commit comments