@@ -1478,61 +1478,62 @@ defmodule Module.Types.Descr do
14781478 false
14791479 else
14801480 # Initialize memoization cache for the recursive phi computation
1481- Process . put ( :phi_cache , % { } )
14821481 arguments = Enum . map ( arguments , & { false , & 1 } )
1483- phi ( arguments , { false , negation ( return ) } , positives )
1482+ { result , _cache } = phi ( arguments , { false , negation ( return ) } , positives , % { } )
1483+ result
14841484 end
14851485 end
14861486 end
14871487
1488- defp all_non_empty_domains? ( positives ) do
1489- Enum . all? ( positives , fn { args , _ret } -> not empty? ( args_to_domain ( args ) ) end )
1490- end
1491-
1492- defp phi ( args , { b , t } , [ ] ) do
1493- Enum . any? ( args , fn { bool , typ } -> bool and empty? ( typ ) end ) or ( b and empty? ( t ) )
1488+ defp phi ( args , { b , t } , [ ] , cache ) do
1489+ { Enum . any? ( args , fn { bool , typ } -> bool and empty? ( typ ) end ) or ( b and empty? ( t ) ) , cache }
14941490 end
14951491
1496- defp phi ( args , { b , ret } , [ { arguments , return } | rest_positive ] ) do
1492+ defp phi ( args , { b , ret } , [ { arguments , return } | rest_positive ] , cache ) do
14971493 # Create cache key from function arguments
14981494 cache_key = { args , { b , ret } , [ { arguments , return } | rest_positive ] }
1499- cache = Process . get ( :phi_cache , % { } )
15001495
15011496 case Map . get ( cache , cache_key ) do
15021497 nil ->
15031498 # Compute result and cache it
1504- result1 = phi ( args , { true , intersection ( ret , return ) } , rest_positive )
1499+ { result1 , cache } = phi ( args , { true , intersection ( ret , return ) } , rest_positive , cache )
15051500
15061501 if not result1 do
1507- Process . put ( :phi_cache , Map . put ( cache , cache_key , false ) )
1508- false
1502+ # Store false result in cache
1503+ cache = Map . put ( cache , cache_key , false )
1504+ { false , cache }
15091505 else
15101506 # This doesn't stop if one intermediate result is false?
1511- result2 =
1507+ { result2 , cache } =
15121508 Enum . with_index ( arguments )
1513- |> Enum . reduce_while ( true , fn { type , index } , acc_result ->
1514- new_result =
1509+ |> Enum . reduce_while ( { true , cache } , fn { type , index } , { acc_result , acc_cache } ->
1510+ { new_result , new_cache } =
15151511 List . update_at ( args , index , fn { _ , arg } -> { true , difference ( arg , type ) } end )
1516- |> phi ( { b , ret } , rest_positive )
1512+ |> phi ( { b , ret } , rest_positive , acc_cache )
15171513
15181514 if new_result do
1519- { :cont , acc_result and new_result }
1515+ { :cont , { acc_result and new_result , new_cache } }
15201516 else
1521- { :halt , false }
1517+ { :halt , { false , new_cache } }
15221518 end
15231519 end )
15241520
15251521 result = result1 and result2
1526- Process . put ( :phi_cache , Map . put ( cache , cache_key , result ) )
1527- result
1522+ # Store result in cache
1523+ cache = Map . put ( cache , cache_key , result )
1524+ { result , cache }
15281525 end
15291526
15301527 cached_result ->
15311528 # Return cached result
1532- cached_result
1529+ { cached_result , cache }
15331530 end
15341531 end
15351532
1533+ defp all_non_empty_domains? ( positives ) do
1534+ Enum . all? ( positives , fn { args , _ret } -> not empty? ( args_to_domain ( args ) ) end )
1535+ end
1536+
15361537 defp fun_union ( bdd1 , bdd2 ) do
15371538 case { bdd1 , bdd2 } do
15381539 { :fun_top , _ } -> :fun_top
0 commit comments