@@ -6172,70 +6172,6 @@ defmodule Module.Types.Descr do
61726172 bdd_union ( bdd_intersection ( cd1 , bdd_union ( cd2 , u2 ) ) , bdd_intersection ( u1 , cd2 ) )
61736173 end
61746174
6175- # Intersections are great because they allow us to cut down
6176- # the number of nodes in the tree. So whenever we have a leaf,
6177- # we propagate it throughout the whole tree, cutting down nodes.
6178- defp bdd_intersection ( bdd_leaf ( _ , _ ) = leaf1 , bdd_leaf ( _ , _ ) = leaf2 , leaf_intersection ) do
6179- leaf_intersection . ( leaf1 , leaf2 )
6180- end
6181-
6182- defp bdd_intersection ( bdd , bdd_leaf ( tag , _ ) = leaf , leaf_intersection ) when tag != :open do
6183- bdd_non_open_leaf_intersection ( leaf , bdd , leaf_intersection )
6184- end
6185-
6186- defp bdd_intersection ( bdd_leaf ( tag , _ ) = leaf , bdd , leaf_intersection ) when tag != :open do
6187- bdd_non_open_leaf_intersection ( leaf , bdd , leaf_intersection )
6188- end
6189-
6190- defp bdd_intersection ( bdd1 , bdd2 , _leaf_intersection ) do
6191- bdd_intersection ( bdd1 , bdd2 )
6192- end
6193-
6194- # Take two BDDs, B1 = {a1, C1, U1, D1} and B2 = a2.
6195- #
6196- # We have:
6197- #
6198- # ((a1 and C1) or U1 or (not a1 and D1)) and a2
6199- # (a1 and a2 and C1) or (a2 and U1) or (a2 and not a1 and D1)
6200- #
6201- # When C1 = :bdd_top, (a1 and a2) or (a2 and U2) or (a2 and not a1 and D2)
6202- # When C2 = :bdd_bot, (a2 and U2) or (a2 and not a1 and D2)
6203- defp bdd_non_open_leaf_intersection ( leaf1 , bdd_leaf ( _ , _ ) = leaf2 , leaf_intersection ) do
6204- leaf_intersection . ( leaf1 , leaf2 )
6205- end
6206-
6207- defp bdd_non_open_leaf_intersection ( leaf , { _ , a , :bdd_top , u , d } , leaf_intersection ) do
6208- leaf_intersection . ( a , leaf )
6209- |> bdd_union ( bdd_non_open_leaf_intersection ( leaf , u , leaf_intersection ) )
6210- |> case do
6211- result when d == :bdd_bot ->
6212- result
6213-
6214- result ->
6215- leaf
6216- |> bdd_non_open_leaf_intersection ( d , leaf_intersection )
6217- |> bdd_difference ( a )
6218- |> bdd_union ( result )
6219- end
6220- end
6221-
6222- defp bdd_non_open_leaf_intersection ( leaf , { _ , a , :bdd_bot , u , d } , leaf_intersection ) do
6223- case bdd_non_open_leaf_intersection ( leaf , u , leaf_intersection ) do
6224- result when d == :bdd_bot ->
6225- result
6226-
6227- result ->
6228- leaf
6229- |> bdd_non_open_leaf_intersection ( d , leaf_intersection )
6230- |> bdd_difference ( a )
6231- |> bdd_union ( result )
6232- end
6233- end
6234-
6235- defp bdd_non_open_leaf_intersection ( bdd1 , bdd2 , _leaf_intersection ) do
6236- bdd_intersection ( bdd1 , bdd2 )
6237- end
6238-
62396175 # {lit, c, u, d} = (lit and c) or u or (not lit and d),
62406176 # so its negation is ((lit and not c) or (not lit and not d)) and not u.
62416177 def bdd_negation ( :bdd_top ) , do: :bdd_bot
@@ -6574,13 +6510,15 @@ defmodule Module.Types.Descr do
65746510 defp opt_list_intersection ( bdd_leaf ( :term , :term ) , bdd , _seen ) , do: bdd
65756511 defp opt_list_intersection ( bdd , bdd_leaf ( :term , :term ) , _seen ) , do: bdd
65766512
6577- defp opt_list_intersection ( bdd1 , bdd2 , seen ) do
6513+ defp opt_list_intersection ( bdd_leaf ( _ , _ ) = bdd1 , bdd_leaf ( _ , _ ) = bdd2 , seen ) do
65786514 case opt_bdd_seen ( seen , :list_intersection , bdd1 , bdd2 ) do
65796515 :seen -> list_intersection ( bdd1 , bdd2 )
6580- { :ok , seen } -> bdd_intersection ( bdd1 , bdd2 , & opt_list_leaf_intersection ( & 1 , & 2 , seen ) )
6516+ { :ok , seen } -> opt_list_leaf_intersection ( bdd1 , bdd2 , seen )
65816517 end
65826518 end
65836519
6520+ defp opt_list_intersection ( bdd1 , bdd2 , _seen ) , do: list_intersection ( bdd1 , bdd2 )
6521+
65846522 defp opt_list_leaf_intersection ( bdd_leaf ( list1 , last1 ) , bdd_leaf ( list2 , last2 ) , seen ) do
65856523 intersection_fun = & opt_intersection ( & 1 , & 2 , seen )
65866524
@@ -6810,13 +6748,15 @@ defmodule Module.Types.Descr do
68106748 defp opt_map_intersection ( bdd_leaf ( :open , [ ] ) , bdd , _seen ) , do: bdd
68116749 defp opt_map_intersection ( bdd , bdd_leaf ( :open , [ ] ) , _seen ) , do: bdd
68126750
6813- defp opt_map_intersection ( bdd1 , bdd2 , seen ) do
6751+ defp opt_map_intersection ( bdd_leaf ( _ , _ ) = bdd1 , bdd_leaf ( _ , _ ) = bdd2 , seen ) do
68146752 case opt_bdd_seen ( seen , :map_intersection , bdd1 , bdd2 ) do
68156753 :seen -> map_intersection ( bdd1 , bdd2 )
6816- { :ok , seen } -> bdd_intersection ( bdd1 , bdd2 , & opt_map_leaf_intersection ( & 1 , & 2 , seen ) )
6754+ { :ok , seen } -> opt_map_leaf_intersection ( bdd1 , bdd2 , seen )
68176755 end
68186756 end
68196757
6758+ defp opt_map_intersection ( bdd1 , bdd2 , _seen ) , do: map_intersection ( bdd1 , bdd2 )
6759+
68206760 defp opt_map_leaf_intersection ( bdd_leaf ( tag1 , fields1 ) , bdd_leaf ( tag2 , fields2 ) , seen ) do
68216761 try do
68226762 { tag , fields } =
@@ -7137,13 +7077,15 @@ defmodule Module.Types.Descr do
71377077 defp opt_tuple_intersection ( bdd_leaf ( :open , [ ] ) , bdd , _seen ) , do: bdd
71387078 defp opt_tuple_intersection ( bdd , bdd_leaf ( :open , [ ] ) , _seen ) , do: bdd
71397079
7140- defp opt_tuple_intersection ( bdd1 , bdd2 , seen ) do
7080+ defp opt_tuple_intersection ( bdd_leaf ( _ , _ ) = bdd1 , bdd_leaf ( _ , _ ) = bdd2 , seen ) do
71417081 case opt_bdd_seen ( seen , :tuple_intersection , bdd1 , bdd2 ) do
71427082 :seen -> tuple_intersection ( bdd1 , bdd2 )
7143- { :ok , seen } -> bdd_intersection ( bdd1 , bdd2 , & opt_tuple_leaf_intersection ( & 1 , & 2 , seen ) )
7083+ { :ok , seen } -> opt_tuple_leaf_intersection ( bdd1 , bdd2 , seen )
71447084 end
71457085 end
71467086
7087+ defp opt_tuple_intersection ( bdd1 , bdd2 , _seen ) , do: tuple_intersection ( bdd1 , bdd2 )
7088+
71477089 defp opt_tuple_leaf_intersection ( bdd_leaf ( tag1 , elements1 ) , bdd_leaf ( tag2 , elements2 ) , seen ) do
71487090 intersection_fun = & opt_intersection ( & 1 , & 2 , seen )
71497091
0 commit comments